图像直方图的绘制
图像直方图的绘制是用来统计图像中不同像素值出现的数量,下面向大家展示一下相关的代码:
img = cv2.imread('E:\Anaconda\Anaconda3.8\Pict.jpg',0)
hist = cv2.calcHist([img],[0],None,[256],[0,256])
hist.shape
首先读入目标图像,0表示对图像进行灰度处理,转化为灰度图像输出。
[img]是将目标图像传入函数,
[0]表示的是图像的channel,用中括号括,如果是灰度图就是[0],如果是彩色图就是[0],[1],[2],根据传入的对应的BGR来定。
None对应的是不加掩膜图像,如果不加掩膜图像则为None,如果加掩膜图像则替换为mask。
[256]表示的是Bin的数目
[0,256]表示的是像素值范围
最后我们来输出一下直方图的参数
256表示一共用256个bin,1表示每个bin的宽度为1
plt.hist(img.ravel(),256);
plt.show()
接着用plt输出直方图
我们这样就得到了相应的直方图。
接下来我们来输入彩色图进行一下直方图的输出。
#一定要输入彩色图
img = cv2.imread('E:\Anaconda\Anaconda3.8\Pict.jpg')
color = ('b','g','r')
for i,col in enumerate(color):
histr = cv2.calcHist([img],[i],None,[256],[0,256])
plt.plot(histr,color = col)
plt.xlim([0,256])
for函数是对三个通道进行遍历
i 是颜色通道的索引,按照b,g,r的顺序索引相应的颜色通道
下面我们来查看一下plt的输出结果:
直方图绘制完成后,发现有的区域像素较为聚集,为了解决此问题,我们需要对直方图进行一系列的处理。
直方图的均衡化处理
#直方图的均衡化:
img = cv2.imread('E:\Anaconda\Anaconda3.8\Pict.jpg',0)
equ = cv2.equalizeHist(img)
plt.hist(equ.ravel(),256);
plt.show()
以上便是对图像直方图进行均衡化处理的公式,直接套公式即可。
下面我们来看一下输出的图像
我们发现图像直方图变得分布不在过于聚集,达到了直方图均衡化的效果。
均衡化以后,图像会丢失部分细节:
向大家展示一下效果图:
自适应均衡化
#均衡化的缺点:会丢失一些细节
#解决方法:可以把图分为不同的小块,分别进行均衡化处理
解决方法的代码如下:
clahe = cv2.createCLAHE(clipLimit=2.0,tileGridSize=(8,8))
res_clahe = clahe.apply((img))
res= np.hstack((img,equ,res_clahe))
cv_show(res,'res')
自适应均衡化的公式给定如上,不需要对其原理进行进一步的了解
自适应化得到的结果与原图和和均衡化的对比图展示如下:
我们不难发现,自适应均衡化不仅提高了图片的亮度,而且还较大程度的保留了原有的数据细节。
mask掩膜图像
上文已经有提到掩膜图像,下面向大家介绍一下什么是掩膜图像。
所谓掩膜图像,就是设立一个矩阵,在选定部分为一,未选定部分为零,然后用该矩阵乘以原有图像的矩阵,得到的结果未框选的部分变为0,即变为黑色。图像仅保留被框选的部分。
下面向大家展示一下相关的代码:
#创建mask
#第一步是固定格式。2是选取的颜色通道
mask=np.zeros(img.shape[:2],np.uint8)
#设定该范围内的图像为白色,故使范围内等于255
mask[0:900,100:2000] = 255
def cv_show(mask,name):
cv2.imshow(name,mask)
cv2.waitKey(0)
cv2.destroyAllWindows()
#cv_show(mask,'mask')
img=cv2.imread('E:\Anaconda\Anaconda3.8\Pict.jpg',0)
masked_img = cv2.bitwise_and(img,img,mask = mask)#与操作,将两个矩阵相乘
hist_full = cv2.calcHist([img],[0],None,[256],[0,256])
hist_mask = cv2.calcHist([img],[0],mask,[256],[0,256])
plt.subplot(221),plt.imshow(img,'gray')
plt.subplot(222),plt.imshow(mask,'gray')
plt.subplot(223),plt.imshow(masked_img,'gray')
plt.subplot(224),plt.plot(hist_full),plt.plot(hist_mask)
plt.xlim([0,256])
plt.show()
效果图展示如下:
我们不难发现,所框选的区域越大,得到的直方图就越接近于原图的直方图。
关于直方图的介绍就这么多,下一张向大家介绍傅里叶变换。