OpenCV学习笔记13 OpenCV图像处理模块ImgProc Module. Image Processing(六)

来源:互联网 发布:java把数组变成字符串 编辑:程序博客网 时间:2024/05/17 21:40

3.15 直方图均衡化 - Histogram Equalization


概念
1. 直方图是图像中像素强度分布的图形表达方式。
2. 它统计了每个强度值像素数量。
3. 直方图均衡化是通过拉伸像素强度分布范围来增强图像对比度的一种方法。
4. 直方图均衡化就是拉伸像素比较集中的强度(灰度)值的范围。

在OpenCV中使用 EqualizeHist 函数实现直方图均衡化。
equalizeHist( src, dst );
src dst 参数要保证是灰度图才可以进行直方图均衡化。


3.16 直方图计算 - Histogram Calculation


1. 直方图是对图像中像素强度的分布的统计,这种像素强度不单指灰度,任何能有效描述图像的特征(如梯度,方向等)都可以进行统计,构成直方图。需要统计的特征的数目称为dims,如仅统计灰度值则 dims = 1。如果统计的是两个特征,直方图就是三维的,x轴和y轴分别代表一个特征,z轴是落入(binx,biny)组合范围内的样本数目。以此类推到更高维特征空间。
2. 像素强度也不单指一个值(如灰度值),也可以是一个像素强度的区间范围,统计落在该区间内的像素数目。这个区间范围在直方图中称为 bins,表示子区段范围的大小。如灰度图中灰度范围大小划分为[0,15] [16,31]...[240,255],则 bins = 16。
3. 每个特征空间的取值范围称为 range,如灰度特征空间的取值范围是[0,255]。

使用 calcHist 函数,用来计算数组集合(通常是一幅图像或多通道图像的一个通道)的直方图。
使用 split 函数将图像分割成单通道数组。
使用 normalize 函数归一化数组。

/// 分割成3个单通道图像 ( R, G 和 B ) vector<Mat> rgb_planes; <span style="white-space:pre"></span>// 用来存储R,G,B三个通道 split( src, rgb_planes );<span style="white-space:pre"></span>// 将彩色的源图像分割成三个通道的图像 /// 设定bin数目 int histSize = 255; /// 下面这三项设置针对calcHist函数的参数 float range[] = { 0, 255 } ;<span style="white-space:pre"></span>// 取值范围 const float* histRange = { range }; bool uniform = true; bool accumulate = false; //  Mat r_hist, g_hist, b_hist; /// 计算直方图: calcHist( &rgb_planes[0], 1, 0, Mat(), r_hist, 1, &histSize, &histRange, uniform, accumulate ); calcHist( &rgb_planes[1], 1, 0, Mat(), g_hist, 1, &histSize, &histRange, uniform, accumulate ); calcHist( &rgb_planes[2], 1, 0, Mat(), b_hist, 1, &histSize, &histRange, uniform, accumulate ); // 创建直方图画布 int hist_w = 400; int hist_h = 400; int bin_w = cvRound( (double) hist_w/histSize ); Mat histImage( hist_w, hist_h, CV_8UC3, Scalar( 0,0,0) ); /// 将直方图归一化到范围 [ 0, histImage.rows ] normalize(r_hist, r_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat() ); normalize(g_hist, g_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat() ); normalize(b_hist, b_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat() ); /// 在直方图画布上画出直方图 for( int i = 1; i < histSize; i++ )   {     line( histImage, Point( bin_w*(i-1), hist_h - cvRound(r_hist.at<float>(i-1)) ) ,                      Point( bin_w*(i), hist_h - cvRound(r_hist.at<float>(i)) ),                      Scalar( 0, 0, 255), 2, 8, 0  );     line( histImage, Point( bin_w*(i-1), hist_h - cvRound(g_hist.at<float>(i-1)) ) ,                      Point( bin_w*(i), hist_h - cvRound(g_hist.at<float>(i)) ),                      Scalar( 0, 255, 0), 2, 8, 0  );     line( histImage, Point( bin_w*(i-1), hist_h - cvRound(b_hist.at<float>(i-1)) ) ,                      Point( bin_w*(i), hist_h - cvRound(b_hist.at<float>(i)) ),                      Scalar( 255, 0, 0), 2, 8, 0  );    }

calcHist 函数的参数解释:
&rgb_planes[0]: 输入数组(或数组集),多个数组应具有相同的深度和大小,数据类型应为CV_8U或CV_32F,通道数目任意。
1: 输入数组的个数 (这里我们使用了一个单通道图像,我们也可以输入数组集 )
0: 需要统计的通道 (dim)索引 ,这里我们只是统计了灰度 (且每个数组都是单通道)所以只要写 0 就行了。多个通道需要像histrange那样设置通道索引。
Mat(): 掩码( 0 表示忽略该像素), 如果未定义,则不使用掩码。
r_hist: 储存直方图的矩阵。
1: 直方图维数。
histSize: 每个维度的bin数目,程序中bin = 1。
histRange: 每个维度的取值范围。
uniform accumulate: 都有true和false两个选项。uniform = true 说明 bin的大小相等,直方图中每个子区段范围是相等的。accumulate = true 说明函数将输入数组的直方图计算结果输出到r_hist中时没有清空r_hist原有的数据,将直方图数据进行了累加。accumulate = false 则先清空r_hist再输出直方图数据。


3.17 直方图对比 - Histogram Comparison



要比较两个直方图H1和H2的相似度,需要选择一个相似度比较的衡量标准 d(H1,H2)。
使用 compareHist 函数实现对两个直方图相似度的比较。该函数提供了4种比较衡量标准来计算相似度:
1. 直接相关(Correlation)- CV_COMP_CORREL
2. 卡方(Chi-Square)- CV_COMP_CHISQR
3. 交叉(Intersection)- CV_COMP_INTERSECT
4. 巴氏距离(Bhattacharyya距离)- CV_COMP_BHATTACHARYYA

直方图对比步骤:
1. 加载需要对比的图像
2. 用 cvtColor 函数将图像转换到HSV颜色空间
3. 用上节介绍的 calcHist normalize 函数计算图像的直方图,并归一化以便比较
4. 用 compareHist 函数进行直方图比较,得到直方图相似度数值

double base_base = compareHist( hist_base, hist_comp, compare_method );

hist_base hist_comp 是需要比较的两幅图像的直方图,compare_method 是比较方法,有上面介绍的四种。函数的返回值是一个double型数值,表示了两幅图像直方图的相似度情况,不同的比较方法返回的数值不同。



0 0