打印图像直接用这个函数:
import cv2 #opencv读取的格式是BGR
import numpy as np
import matplotlib.pyplot as plt#Matplotlib是RGB
%matplotlib inline
def cv_show(img,name):
cv2.imshow(name,img)
cv2.waitKey()
cv2.destroyAllWindows()
图像中的直方图概念,将图像分解成像素点,直方图对像素点进行统计。
如左图读进来一个灰度图,用数值的形式展示出来,直方图就是统计0-255个像素值的分布情况,其中横坐标是0-255的像素值,纵坐标是每个像素值出现的次数。
需要用到这个函数:cv2.calcHist(images,channels,mask,histSize,ranges)
所以后面两个参数基本不用改了。
读进来一个小猫的灰度图,获取像素统计信息:
img = cv2.imread('cat.jpg',0) #0表示灰度图
hist = cv2.calcHist([img],[0],None,[256],[0,256])
print(hist.shape)
hist就是一个二维的ndarray,打印结果:
(256, 1)
将这个直方图用matplotlib画出来:
plt.hist(img.ravel(),256);
plt.show()
打印结果:
将刚刚的小猫图对三个颜色通道都进行统计:
img = cv2.imread('cat.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])
怎样创建一个掩码,以及掩码的定义:
# 创建mast
mask = np.zeros(img.shape[:2], np.uint8)
print (mask.shape)
mask[100:300, 100:400] = 255
cv_show(mask,'mask')
打印结果:
(414, 500)
这个掩码只有两部分,一部分为黑一部分为白,当把这个掩码图像和原始图像结合在一起的效果就是图三。掩码图像和原始图像大小是一样的,掩码覆盖的地方设置成255,其他地方设置成0,掩码图像和原始图像结合相当于截取操作。
掩码的定义,就是利用np.zeros来定义,大小按照图像长宽的尺寸,然后按照数组的索引范围选择要保存的部位,把要保存的地方全部赋值为255。
把原始图像读进来:
img = cv2.imread('cat.jpg', 0)
cv_show(img,'img')
masked_img = cv2.bitwise_and(img, img, mask=mask)#与操作
cv_show(masked_img,'masked_img')
对带掩码和不带掩码的图像都做一下直方图统计,通过子图的方式进行展示:
如图这个直方图的像素分布特别不均匀,如何让他的像素分布稍微均匀一点呢?
均衡化的过程就是像素值的分布从左1变成左2,最后的效果是左3
比如下图的这两个个像素点表格,左边是原始图像,右边是均衡化后的图像。将原来的像素分布用一个固定的计算方法映射到另一个分布:
这个过程是怎么做的呢?
img = cv2.imread('clahe.jpg',0) #0表示灰度图 #clahe
plt.hist(img.ravel(),256);
plt.show()
equ = cv2.equalizeHist(img)
plt.hist(equ.ravel(),256)
plt.show()
res = np.hstack((img,equ))
cv_show(res,'res')
均衡化实际上是整体上对像素进行了一个平均的处理操作,这意味着可能会丢失一些细节。那如何避免出现这种情况呢?我们可以将图像分成若干个部分,然后各个部分做自己的均衡化,这样就缓冲了细节的丢失。
在openCV中已经给了我们一些现成的函数来进行这个操作,这就是自适应直方图均衡化。
首先将自适应直方图均衡化的方法生成出来:
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')