12-直方图

灰度直方图
灰度直方图是表示图像中灰度值分布的直方图,标绘了图像中每个灰度值的像素数
横坐标:图像中各个像素点的灰度级
纵坐标:具有该灰度级的像素个数

归一化直方图
归一化直方图是表示图像中灰度值分布的概率之和等于1
横坐标:图像中各个像素点的灰度级
纵坐标:出现这个灰度级的概率

需要注意的,直方图术语:
dims:需要统计的特征的数目。当dims=1时,表示我们仅统计灰度值
bins:每个特征空间子区段的数目
range:每个特征空间的取值范围

使用python中matplotlib库来绘制直方图
import matplotlib.pyplot as plt
函数hist(数据源,像素级),根据数据源和像素级绘制直方图
其中,数据源必须是一维数组图像;像素级一般是256,指[0,255]
通过ravel()函数,将多维的数组,转化为一维的形式

# 将绘制的图显示在窗口
%matplotlib qt5

import cv2
import matplotlib.pyplot as plt

img = cv2.imread(r"image\boat.jpg",cv2.IMREAD_COLOR)
# 彩色图像转化为灰度图
img = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

# ravel()函数,将二维的图像,转化为一维的数组
img_2 = img.ravel()

cv2.imshow("original",img)

# 1.设置rc参数显示中文标题,设置字体为SimHei显示中文
plt.rcParams['font.sans-serif'] = 'SimHei'
plt.rcParams['axes.unicode_minus'] = False
# 2.绘制灰度直方图
plt.hist(img_2,256)
plt.xlabel("灰度级")
plt.ylabel("像素个数")
plt.title("灰度直方图")
# 3.显示灰度直方图
plt.show()

cv2.waitKey(0)
cv2.destroyAllWindows()

使用opencv来绘制统计直方图
hist = cv2.calcHist(images,channels,mask,histSize,ranges[,accumulate])
返回的hist直方图,相当于纵坐标的值,也就是具有灰度级像素个数的二维数组
1>channels:指定通道
通道的编号需要用中括号括起来,当输入图像是灰度图时,对应的通道是[0];当输入图像是彩色图像时,通道[0],[1],[2]分别对应B,G,R
2>mask:掩码图像
统计整幅图像的直方图,设为None;统计图像某一部分的直方图时,需要掩码图像
3>histSize:BINS的数量
每个特征空间子区段的数目,一般是256,需要用中括号括起来
4>range:每个特征空间的取值范围
一般是[0,255],需要用中括号括起来
5>accumulate:累计标识(可选参数)
默认值为False,如果被设置为True,则直方图在开始分配时不会被清零。也就是说计算一组图像的直方图

import cv2
import numpy as np

# 输入图像是灰度图
img = cv2.imread(r"image\boat.bmp",cv2.IMREAD_GRAYSCALE)

# 绘制统计直方图
hist = cv2.calcHist([img],[0],None,[256],[0,255])

print("统计直方图的类型:",type(hist))
print("统计直方图的大小:",hist.size)
print("统计直方图的形状:",hist.shape)

通过python的matplotlib库,绘制opencv的统计直方图
import matplotlib.pyplot as plt
(如果是彩色图像,需要分别绘制BGR三个通道的直方图)
# 将绘制的图显示在窗口
%matplotlib qt5

import cv2
import matplotlib.pyplot as plt

# 输入图像时彩色图像
img = cv2.imread(r"image\girl.bmp",cv2.IMREAD_COLOR)
cv2.imshow("original",img)

# 绘制统计直方图
histb = cv2.calcHist([img],[0],None,[256],[0,255])
histg = cv2.calcHist([img],[1],None,[256],[0,255])
histr = cv2.calcHist([img],[2],None,[256],[0,255])

# 1.设置rc参数显示中文标题,设置字体为SimHei显示中文
plt.rcParams['font.sans-serif'] = 'SimHei'
plt.rcParams['axes.unicode_minus'] = False
# 2.绘制灰度直方图
plt.plot(histb,color="b")
plt.plot(histg,color="g")
plt.plot(histr,color="r")
plt.xlabel("灰度级")
plt.ylabel("像素个数")
plt.title("统计直方图")
# 3.显示灰度直方图
plt.show()

cv2.waitKey(0)
cv2.destroyAllWindows()

使用掩膜mask的直方图
图像掩模一般用来对处理的图像(全部或者局部)进行遮挡,来控制图像处理的区域或处理过程

生成掩膜mask图像,一般需要两步:
1> mask = np.zeros(image.shape,np.uint8)
第一步,建立与原图一样大小的mask图像,并将所有像素初始化为0,也就是一张全黑色的图
2> mask[200:400,200:400] = 255
第二步,将mask图中指定区域的所有像素值设置为255,也就是将整个指定区域变成了白色

 

还是使用opencv来绘制统计直方图
hist = cv2.calcHist(images,channels,mask,histSize,ranges[,accumulate])

import cv2
import numpy as np
import matplotlib.pyplot as plt

img = cv2.imread(r"image\boat.bmp",cv2.IMREAD_GRAYSCALE)
cv2.imshow("original",img)

# 生成掩膜mask图像
mask = np.zeros(img.shape,np.uint8)
mask[200:400,200:400] = 255
cv2.imshow("mask",mask)

# 绘制统计直方图
hist = cv2.calcHist([img],[0],mask,[256],[0,255])

# 1.设置rc参数显示中文标题,设置字体为SimHei显示中文
plt.rcParams['font.sans-serif'] = 'SimHei'
plt.rcParams['axes.unicode_minus'] = False
# 2.绘制灰度直方图
plt.plot(hist)
plt.xlabel("灰度级")
plt.ylabel("像素个数")
plt.title("统计直方图")
# 3.显示灰度直方图
plt.show()

cv2.waitKey(0)
cv2.destroyAllWindows()

 直方图均衡化
直方图均衡化是一种简单有效的图像增强技术,将图像的直方图分布变成近似均匀分布,从而增强图像的对比度,使色彩细节更丰富,多用于车牌识别、人脸识别场景

直方图均衡化的过程:
1> 计算累计直方图
2> 将累计直方图进行区间转换

 

 

使用opencv绘制直方图均衡化
dst = cv2.equalizeHist(src)
其中,src是源图像,dst是目标图像(处理结果)

import cv2
import numpy as np
import matplotlib.pyplot as plt 

img = cv2.imread(r"image\equ.bmp",cv2.IMREAD_GRAYSCALE)

# 设置rc参数显示中文标题,设置字体为SimHei显示中文
plt.rcParams['font.sans-serif'] = 'SimHei'
plt.rcParams['axes.unicode_minus'] = False

# 绘制灰度直方图
# ravel()函数,将二维的图像,转化为一维的数组
plt.hist(img.ravel(),256)
plt.xlabel("灰度级")
plt.ylabel("像素个数")
plt.title("灰度直方图")

# 绘制均衡直方图
# plt.figure()函数,创建自定义图像
plt.figure()
equ = cv2.equalizeHist(img)
plt.hist(equ.ravel(),256)
plt.xlabel("灰度级")
plt.ylabel("像素个数")
plt.title("均衡直方图")
# 3.显示灰度直方图
plt.show()

cv2.imshow("original",img)
cv2.imshow("result",equ)

cv2.waitKey(0)
cv2.destroyAllWindows()

需要注意:也可以通过plt.subplot()函数,绘制多个子窗口
import matplotlib.pyplot as plt
plt.subplot(nrows,ncols,plot_number)
其中,nrows是行数,ncols是列数,plot_number是窗口序号

# 将绘制的图显示在窗口
%matplotlib qt5

import cv2
import numpy as np
import matplotlib.pyplot as plt 

img = cv2.imread(r"image\equ.bmp",cv2.IMREAD_GRAYSCALE)

# 设置rc参数显示中文标题,设置字体为SimHei显示中文
plt.rcParams['font.sans-serif'] = 'SimHei'
plt.rcParams['axes.unicode_minus'] = False

# 通过plt.subplot()绘制一个一行两列的子窗口
# 1.绘制灰度直方图
plt.subplot(1,2,1)
plt.hist(img.ravel(),256)
plt.xlabel("灰度级")
plt.ylabel("像素个数")
plt.title("灰度直方图")

# 2.绘制均衡直方图
plt.subplot(1,2,2)
equ = cv2.equalizeHist(img)
plt.hist(equ.ravel(),256)
plt.xlabel("灰度级")
plt.ylabel("像素个数")
plt.title("均衡直方图")
# 3.显示灰度直方图
plt.show()

需要注意:也可以通过plt.imshow()函数,显示opencv读入的图像
import matplotlib.pyplot as plt
plt.imshow(x,cmap)
其中,x是要绘制的图像,cmap是颜色图谱

# 将绘制的图显示在窗口
%matplotlib qt5

import cv2
import numpy as np
import matplotlib.pyplot as plt 

# 读取一个彩色图像
img = cv2.imread(r"image\girl.bmp",cv2.IMREAD_COLOR)
# 彩色图像转换灰度图像
img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

# 设置rc参数显示中文标题,设置字体为SimHei显示中文
plt.rcParams['font.sans-serif'] = 'SimHei'
plt.rcParams['axes.unicode_minus'] = False

# 通过plt.subplot()绘制一个一行两列的子窗口
# 1.显示彩色图像
plt.subplot(1,2,1)
# 拆分通道
b,g,r = cv2.split(img)
# 合并通道
rgb_img = cv2.merge([r,g,b])
plt.imshow(rgb_img)
plt.title("彩色图像")
# 关闭坐标轴
plt.axis("off")

# 2.显示灰度图像
plt.subplot(1,2,2)
plt.imshow(img_gray,cmap=plt.cm.gray)
plt.title("灰度图像")
# 关闭坐标轴
plt.axis("off")

# 3.显示灰度直方图
plt.show()

 

 

 

 

 

 

 

 

 

 

 

 

 

 

posted @ 2021-09-23 10:43  马铃薯1  阅读(548)  评论(0编辑  收藏  举报