基础知识:
(1) calcHist(),第1个参数为原数组区域列表;第二个参数为有计算几个原数组;参数3为需要统计的通道索引数;参数4为操作掩码,第5个参数为存放目标直方图矩阵;参数6为需要计算的直方图的维数;参数7为每一维的bin的个数;参数8为每一维数值的取值范围,参数10为每个bin的大小是否相同的标志,默认为1,即bin的大小都相同;参数11为直方图建立时清除内存痕迹标志,默认为0,即清除
(2) normalize():根据某种范数或者数值范围归一化数组,参数1表示需要归一化的数组;参数2为归一化后的目的数组;参数3表示输出数值的最小值/最大值或者输出数值的范数; 参数4表示输出数值的最小值/最大值;参数5表示归一化数组使用的归一化类型,默认值为使用L2范数;参数6为对应元素的掩膜矩阵,默认值为空,即不采用掩膜操作;
(3) 画图时要注意矩阵的原点在左上角,而直方图的原点在
#include<opencv2/core/core.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<vector>
#include<iostream>
using namespace std;
using namespace cv;
int main(){
Mat image=imread("F:\\opencv_test\\1.jpg");
Mat rhist,ghist,bhist;
vector<Mat>planes;
split(image,planes);
int channels=0;
int dims=1;
int histsize=255;
float range[]={0,255};
const float *hrang[]={range};
calcHist(&planes[0],1,&channels,Mat(),bhist,dims,&histsize,hrang);
calcHist(&planes[1],1,&channels,Mat(),ghist,dims,&histsize,hrang);
calcHist(&planes[2],1,&channels,Mat(),rhist,dims,&histsize,hrang);
int width=400,height=400;
int binwidth=cvRound((double)width/histsize);
Mat imageHist1(400,400,CV_8UC3,Scalar(0,0,0));
Mat imageHist2(400,400,CV_8UC3,Scalar(0,0,0));
Mat imageHist3(400,400,CV_8UC3,Scalar(0,0,0));
normalize(bhist,bhist,0,imageHist1.rows,NORM_MINMAX);
normalize(ghist,ghist,0,imageHist2.rows,NORM_MINMAX);
normalize(rhist,rhist,0,imageHist3.rows,NORM_MINMAX);
for( int i = 1; i < histsize; i++ )
{
//画出来的是一条曲线
line( imageHist1,Point( binwidth*(i-1), height - cvRound(bhist.at<float>(i-1)) ) ,
Point( binwidth*(i), height - cvRound(bhist.at<float>(i)) ),
Scalar( 255, 0, 0), 1, 8, 0 );
line( imageHist2,Point( binwidth*(i-1), height - cvRound(ghist.at<float>(i-1)) ) ,
Point( binwidth*(i), height - cvRound(ghist.at<float>(i)) ),
Scalar( 0, 255, 0), 1, 8, 0 );
line(imageHist3,Point( binwidth*(i-1), height - cvRound(rhist.at<float>(i-1)) ) ,
Point( binwidth*(i), height - cvRound(rhist.at<float>(i)) ),
Scalar( 0, 0, 255), 1, 8, 0 );
}
namedWindow("1");
imshow("1", imageHist1);
namedWindow("2");
imshow("2",imageHist2);
namedWindow("3");
imshow("3",imageHist3);
waitKey(0);
return 0;
}
//画出来的是柱状图
int main(){
Mat image=imread("F:\\opencv_test\\6.tif");
Mat result;
int channels=0;
int dims=1;
int histSize=256;
float rang[]={0,255};
const float *range={rang};
calcHist(&image,1,&channels,Mat(),result,dims,&histSize,&range);
normalize(result,result,1,0,NORM_MINMAX);//把其中的值映射到0到1之间,即归一化
int yValue=1,xValue=255;
Mat imageHist(256,256,CV_8U);
for(int i=0;i<256;i++){
line(imageHist,Point(i,255),Point(i,255-cvRound(result.at<float>(i)*255)),Scalar(255,0,0));
}
namedWindow("1",0);
imshow("1",imageHist);
waitKey(0);
return 0;