图像直方图包含丰富的图像细节信息,反映了图像像素点的概率分布情况,它统计了每一个强度值具有的像素个数。灰度级范围是[0,L-1]的数字图像的直方图是离散函数h(rk)=nk,其中是rk第k级灰度值,nk是图像中灰度为rk的像素个数。在实践中,经常用乘积MN表示的图像像素总数除它的每个分量来归一化直方图,M、N是图像的行列数。因此归一化后的直方图由p(rk)=nk/MN给出。直方图的横坐标表示灰度级,纵坐标表示图像中该灰度级出现的次数(频率)。
一般来说,在暗图像中,直方图的分量集中在灰度级较低的一侧。亮图像的直方图分量集中在灰度级值较高的一侧。低对比度的图像具有较窄的直方图,且集中于灰度级的中部。高对比度的图像中直方图的分量覆盖了很宽的灰度级范围。
图1 亮图像及其灰度直方图
图2 暗图像及其灰度直方图
图3 高对比度图像及其灰度直方图
图4 低对比度图像及其灰度直方图
opencv中提供了calchist函数用于计算图像的直方图。其声明如下:
void calcHist(const Mat* arrays, int narrays, const int* channels, InputArray mask, OutputArray hist, int dims, const int* histSize, const float** ranges, bool uniform=true, bool accumulate=false );
- arrays:源输入图像数组,可以是多幅图像,所有的图像必须有同样的深度(CV_8U or CV_32F),同时一副图像可以有多个channes。
- narrays:源输入数组中的元素个数
- channels:用来计算直方图的通道维数数组,第一个数组的通道由0到arrays[0].channels()-1列出,第二个数组的通道从arrays[0].channels()到arrays[0].channels()+arrays[1].channels()-1以此类推
- mask:可选的掩膜,如果该矩阵不是空的,则必须是8位的并且与arrays[i]的大小相等,掩膜的非零值标记需要在直方图中统计的数组元素;
- hist:输出直方图,是一个稠密或者稀疏的dims维的数组
- dims:直方图的维数,必须为正,并且不大于CV_MAX_DIMS(当前的OpenCV版本中为32,即最大可以统计32维的直方图);