openCV学习笔记(四):绘制直方图和calcHist()函数、normalize()函数的解析
openCV学习笔记(4):绘制直方图和calcHist()函数、normalize()函数的解析
——normalize()函数
opencv版本:2.3.1
配置环境:openCV学习笔记(一):opencv2.3.1与vs2010安装配置
#include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <iostream> #include <conio.h> using namespace cv; using namespace std; int main() { char *imageSrc = "I:\\OpenCV Learning\\picture\\sumpalace.jpg"; Mat image = imread(imageSrc,1); /**********************************/ //Mat grayImage = imread(imageSrc,0); /**********************************/ if(!image.data) { cout<<"error"<<endl; return -1; } imshow("原始图像",image); vector<Mat> rgbPlanes; split(image,rgbPlanes); /**********************************/ /*rgbPlanes矢量(可增长数组),通过split()函数,将image的R,G,B通道分别加入到rgbPlanes[0]、rgbPlanes[1]、rgbPlanes[2] /**********************************/ //Mat *grayImage = &grayImage0; /**********************************/ int histSize = 256; //R、G、B值范围为[0,255] float range[] = {0,255}; const float *histRange = {range}; //三个矩阵,分别保存R、G、B直方图 Mat redHist,greenHist,blueHist; /**********************************/ //Mat grayHist; /**********************************/ //计算R、G、B直方图,calcHist()函数的参数解析见后面 calcHist( &rgbPlanes[0], 1, 0, Mat(), redHist, 1, &histSize, &histRange,true,false); calcHist( &rgbPlanes[1], 1, 0, Mat(), greenHist, 1, &histSize, &histRange,true,false); calcHist( &rgbPlanes[2], 1, 0, Mat(), blueHist, 1, &histSize, &histRange,true,false); /**********************************/ //calcHist(&grayImage,1,0,Mat(), grayHist, 1, &histSize, &histRange,true,false); /**********************************/ //定义显示直方图的画布 int histWidth = 400; int histHeight = 400; int binWidth = cvRound((double)histWidth/histSize); Mat histImage(histWidth,histHeight,CV_8UC3,Scalar(0,0,0)); //归一化处理normalize()函数的参数解析见后面 normalize(redHist,redHist,0,histImage.rows,NORM_MINMAX,-1,Mat()); normalize(greenHist,greenHist,0,histImage.rows,NORM_MINMAX,-1,Mat()); normalize(blueHist,blueHist,0,histImage.rows,NORM_MINMAX,-1,Mat()); /**********************************/ //normalize(grayHist,grayHist,0,histImage.rows,NORM_MINMAX,-1,Mat()); /**********************************/ //画直方图 for( int i = 1; i < histSize; i++ ) { line( histImage, Point( binWidth*(i-1), histHeight - cvRound(redHist.at<float>(i-1)) ) , Point( binWidth*(i), histHeight - cvRound(redHist.at<float>(i)) ), Scalar( 0, 0, 255), 2, 8, 0 ); // rectangle(histImage,Point( binWidth*(i-1), histHeight), // Point( binWidth*(i-1), histHeight - cvRound(redHist.at<float>(i))), Scalar(0,0,255), CV_FILLED); line( histImage, Point( binWidth*(i-1), histHeight - cvRound(greenHist.at<float>(i-1)) ) , Point( binWidth*(i), histHeight - cvRound(greenHist.at<float>(i)) ), Scalar( 0, 255, 0), 2, 8, 0 ); line( histImage, Point( binWidth*(i-1), histHeight - cvRound(blueHist.at<float>(i-1)) ) , Point( binWidth*(i), histHeight - cvRound(blueHist.at<float>(i)) ), Scalar( 255, 0, 0), 2, 8, 0 ); /**********************************/ /*line( histImage, Point( binWidth*(i-1), histHeight - cvRound(grayHist.at<float>(i-1)) ) , Point( binWidth*(i), histHeight - cvRound(grayHist.at<float>(i)) ), Scalar( 255, 255, 255), 2, 8, 0 );*/ /**********************************/ } // 显示直方图 imshow("直方图", histImage ); waitKey(); return 0; }
直方图-
原图-
解释(此部分来自http://www.opencv.org.cn/opencvdoc/2.3.2/html/doc/tutorials/imgproc/histograms/histogram_calculation/histogram_calculation.html)
——calcHist()函数
参数说明如下:
- &rgbPlanes[0]: 输入数组(或数组集)
- 1: 输入数组的个数 (这里我们使用了一个单通道图像,我们也可以输入数组集 )
- 0: 需要统计的通道 (dim)索引 ,这里我们只是统计了灰度 (且每个数组都是单通道)所以只要写 0 就行了。
- Mat(): 掩码( 0 表示忽略该像素), 如果未定义,则不使用掩码
- redHist: 储存直方图的矩阵
- 1: 直方图维数
- histSize: 每个维度的bin数目
- histRange: 每个维度的取值范围
- uniform 和 accumulate: bin大小相同,清楚直方图痕迹
该函数接受下列参数:
- redhist: 输入数组
- redhist: 归一化后的输出数组(支持原地计算)
- 0 及 histImage.rows: 这里,它们是归一化 redhist 之后的取值极限
- NORM_MINMAX: 归一化方法 (例中指定的方法将数值缩放到以上指定范围)
- -1: 指示归一化后的输出数组与输入数组同类型
- Mat(): 可选的掩码