OpenCV直方图的绘制
1.直方图的绘制
直方图是通过将整个变量值范围划分为小的值范围,然后计算每个间隔中落入多少个值来创建的。
使用calcHist函数计算直方图,函数原型:
void calcHist( const Mat* images, int nimages,
const int* channels, InputArray mask,
SparseMat& hist, int dims,
const int* histSize, const float** ranges,
bool uniform = true, bool accumulate = false );
参数说明
/*
* 输入图像
* 输入图像数
* 数字通道尺寸
* 可选的 掩码矩阵
* 存储计算结果
* 直方图 维度(图像 取值的 空间维度)
* 要计算的 区间数(每个像素值一个区间)
* 输入变量的范围, 可能的 像素值 ,范围0~255
*/
响应按钮的回调函数
void showHistoCallback(int state, void* userData)
{
vector<Mat> bgr;
split( img, bgr );
int numbins= 256;
float range[] = { 0, 256 } ;
const float* histRange = { range };
Mat b_hist, g_hist, r_hist;
calcHist( &bgr[0], 1, 0, Mat(), b_hist, 1, &numbins, &histRange );
calcHist( &bgr[1], 1, 0, Mat(), g_hist, 1, &numbins, &histRange );
calcHist( &bgr[2], 1, 0, Mat(), r_hist, 1, &numbins, &histRange );
int width= 512;
int height= 300;
Mat histImage( height, width, CV_8UC3, Scalar(20,20,20) );
normalize(b_hist, b_hist, 0, height, NORM_MINMAX );
normalize(g_hist, g_hist, 0, height, NORM_MINMAX );
normalize(r_hist, r_hist, 0, height, NORM_MINMAX );
int binStep= cvRound((float)width/(float)numbins);
for( int i=1; i< numbins; i++)
{
line( histImage, Point( binStep*(i-1), height-cvRound(b_hist.at<float>(i-1) ) ), Point( binStep*(i), height-cvRound(b_hist.at<float>(i) ) ),Scalar(255,0,0) );
line( histImage, Point( binStep*(i-1), height-cvRound(g_hist.at<float>(i-1) ) ),Point( binStep*(i), height-cvRound(g_hist.at<float>(i) ) ),Scalar(0,255,0) );
line( histImage, Point( binStep*(i-1), height-cvRound(r_hist.at<float>(i-1) ) ), Point( binStep*(i), height-cvRound(r_hist.at<float>(i) ) ),Scalar(0,0,255) );
}
imshow("Histogram", histImage);
}
结果如下:
2.图像均衡(直方图均衡化)
均衡彩色图像,可获取均匀分布的直方图,均衡的结果是图像对比度的增加。均衡能够使对比度较低的局部区域获得高对比度,从而分散最频繁的强度。
两个主要缺点:背景噪声的增加以及随之而来的有用信号的减少。
为了均衡彩色图像,只需均衡亮度通道。
void equalizeCallback(int state, void* userData)
{
Mat result;
// Convert BGR image to YCbCr
Mat ycrcb;
cvtColor( img, ycrcb, COLOR_BGR2YCrCb);
// Split image into channels
vector<Mat> channels;
split( ycrcb, channels );
// Equalize the Y channel only
equalizeHist( channels[0], channels[0] );
// Merge the result channels
merge( channels, ycrcb );
// Convert color ycrcb to BGR
cvtColor( ycrcb, result, COLOR_YCrCb2BGR );
// Show image
imshow("Equalized", result);
}
均衡后的直方图: