直方图是图像处理过程中的一种非常重要的分析工具。直方图从图像内部灰度级的角度对图像进行表述,包含十分丰富而重要的信息。从直方图的角度对图像进行处理,可以达到增强图像显示效果
的目的。
灰度级
,纵坐标是具有该灰度级(像素值)的像素个数
。一般情况下,我们把直线图和直方图都称为直方图。
在实际处理中,图像直方图的x轴区间一般是[0, 255],对应的是8位位图的256个灰度级;y轴对应的是具有相应灰度级的像素点的个数。
虽然8位的图像都具有256个灰度级(每一个像素可以有256个灰度值),但是属于不同灰度级的像素数量是很不一样的。
有时为了便于表示,也会采用归一化直方图
。在归一化直方图中,x轴仍然表示灰度级
;y轴不再表示灰度级出现的次数,而是灰度级出现的频率
。
在OpenCV的官网上,特别提出了要注意三个概念:DIMS、BINS、RANGE。
● DIMS:表示在绘制直方图时,收集的参数的数量。一般情况下,直方图中收集的数据只有一种,就是灰度级。因此,该值为1。
● RANGE:表示要统计的灰度级范围,一般为[0, 255]。0对应的是黑色,255对应的是白色。
● BINS:参数子集的数目。在处理数据的过程中,有时需要将众多的数据划分为若干个组,再进行分析。
直方图意义: 直方图是图像中像素强度分布的图形表达方式。
直方图统计了每一个强度值所具有的像素个数。
dims:需要统计的特征的数目。例如:`dims=1`,表示我们仅统计灰度值。
bins:每个特征空间子区段的数目。
range:每个特征空间的取值范围。
Python的模块matplotlib.pyplot中的hist()函数能够方便地绘制直方图,我们通常采用该函数直接绘制直方图。
除此以外,OpenCV中的cv2.calcHist()函数能够计算统计直方图,还可以在此基础上绘制图像的直方图。下面分别讨论这两种方式。
模块matplotlib.pyplot提供了一个类似于MATLAB绘图方式的框架,可以使用其中的matplotlib.pyplot.hist()函数(以下简称为hist()函数)来绘制直方图。
此函数的作用是根据数据源
和灰度级分组
绘制直方图。
matplotlib.pyplot.hist(X,BINS)
● X:数据源,必须是一维的。图像通常是二维的,需要使用ravel()函数将图像处理为一维数据源以后,再作为参数使用。
● BINS:BINS的具体值,表示灰度级的分组情况。
函数ravel()的作用是将二维数组降维成一维数组。
示例:
import cv2
import matplotlib.pyplot as plt
o = cv2.imread('timg.jpg')
plt.hist(o.ravel(),16)
plt.show()
原图:
直方图:
从图中可以看到,整个灰度级被划分为16个子集
OpenCV提供了函数cv2.calcHist()用来计算图像的统计直方图,该函数能统计各个灰度级的像素点个数。利用matplotlib.pyplot模块中的plot()函数,可以将函数cv2.calcHist()的统计结果绘制成直方图。
1.用cv2.calcHist()函数统计图像直方图信息函数cv2.calcHist()用于统计图像直方图信息
hist = cv2.calcHist( images, channels, mask, histSize,ranges, accumulate )
● hist:返回的统计直方图,是一个一维数组,数组内的元素是各个灰度级的像素个数。
● images:原始图像,该图像需要使用“[ ]”括起来。
● channels:指定通道编号。通道编号需要用“[ ]”括起来,如果输入图像是单通道灰度图像,该参数的值就是[0]。对于彩色图像,它的值可以是[0]、[1]、[2],分别对应通道B、G、R。
● mask:掩模图像。当统计整幅图像的直方图时,将这个值设为None。当统计图像某一部分的直方图时,需要用到掩模图像。
● histSize:BINS的值,该值需要用“[ ]”括起来。例如,BINS的值是256,需要使用“[256]”作为此参数值。
● ranges:即像素值范围。例如,8位灰度图像的像素值范围是[0,255]。
● accumulate:累计(累积、叠加)标识,默认值为False。如果被设置为True,则直方图在开始计算时不会被清零,计算的是多个直方图的累积结果,用于对一组图像计算直方图。该参数允许从多个对象中计算单个直方图,或者实时更新直方图。该参数是可选的,一般情况下不需要设置。
2.plot()函数的使用使用matplotlib.pyplot模块内的plot()函数,可以将函数cv2.calcHist()的返回值绘制为图像直方图。
3.绘制统计直方图
示例:
import cv2
import matplotlib.pyplot as plt
o=cv2.imread("histogram.jpg")
histb = cv2.calcHist([o], [0], None, [256], [0,255])
histg = cv2.calcHist([o], [1], None, [256], [0,255])
histr = cv2.calcHist([o], [2], None, [256], [0,255])
plt.subplot(131)
plt.plot(histb, color='b')
plt.subplot(132)
plt.plot(histg, color='g')
plt.subplot(133)
plt.plot(histr, color='r')
plt.savefig('histogram.png')
plt.show()
本例先通过函数cv2.calcHist()分别得到[0]、[1]、[2]三个通道(即B、G、R三个通道)的统计直方图数据,然后再通过plot()函数将这些数据绘制成直方图。
原图: