1.直方图是一种能快速描述图像整体像素值分布的统计信息。
也就是说明某一像素值范围的像素点的个数,X轴为像素值,Y为个数。
2.直方图只能描述颜色的分布,不能描述数据几何上的信息。
也就是只知道这个像素值范围的点的个数是多少,但是不知道哪个位置上上这个点多。
由于图像数据是numpy的ndarray形式,因此可以用numpy的histogram得到直方图的信息,再用matplotlib绘制出图像。
img_gray_data = cv2.imread('./images/messi.jpg', cv2.IMREAD_GRAYSCALE) #读入灰度图像
#img_gray_data.ravel()的ravel是把图像由二维变成1维
hist, bins = np.histogram(img_gray_data.ravel(), bins=10) #通过histogram就可以得到每段像素值范围bins的像素点个数hist
print(hist)
#得到[20458 34568 33355 28645 41040 15380 8186 3597 1212 975]
print(bins)
# 得到[ 0. 25.3 50.6 75.9 101.2 126.5 151.8 177.1 202.4 227.7 253. ]
绘制直方图
plt.hist(img_gray_data.ravel(), bins=50);
因为彩色图像有三个通道,我们可以把它的三个通道分别取出来进行绘制。则可以看每个通道上像素的分布,得到原图中哪种颜色比较多。
# 彩色图像直方图
img_bgr_data = cv2.imread('./images/messi.jpg')
plt.figure(figsize=(15, 5)) #设置画布的大小
# B通道 直方图
ax1 = plt.subplot(131)
ax1.hist(img_bgr_data[:, :, 0].ravel(), bins=50, color='b')
# G通道 直方图
ax2 = plt.subplot(132)
ax2.hist(img_bgr_data[:, :, 1].ravel(), bins=50, color='g')
# R通道 直方图
ax3 = plt.subplot(133)
ax3.hist(img_bgr_data[:, :, 2].ravel(), bins=50, color='r')
由下面的彩色图像直方图可以看出,原图中的绿色较多,蓝色和红色相对较少。
增强图像数据的对比度有利于特征的提取,不论是从肉眼还是算法来看都有帮助。
直方图均衡化可以自动调整图像的对比度。
如下图整个图片灰蒙蒙的,很多细节性的东西都看不太清。我们首先画一下它的直方图,来看一下像素分布情况。
绘制上图的直方图
wiki_img = cv2.imread('./images/wiki.jpg', cv2.IMREAD_GRAYSCALE)
cv2.imshow('wiki_img', wiki_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
plt.hist(wiki_img.ravel(), bins=256, range=[0, 256])
plt.show()
由直方图可以看到它的像素都集中在100到200之间,因此整个图片看起来非常不清楚。因此我们就需要通过一种方法让他的直方图均匀分布在0到255之间,这种方法就是直方图均衡化。
cv2.equalizeHist
equ_wiki_img = cv2.equalizeHist(wiki_img) #进行直方图均衡化
cv2.imshow('equ_wiki_img', equ_wiki_img) #显示均衡化的图
cv2.waitKey(0)
cv2.destroyAllWindows()
plt.hist(equ_wiki_img.ravel(), bins=256, range=[0, 256]) #画出均衡化后的直方图
plt.show()