OpenCV中直方图的计算和绘制
主要记录一下几个关键的API:
cvRound(
输入一个浮点数
);//返回一个整型数,取整的方法为四舍五入
split(
输入多通道图像,
数组或者vector变量。
);
计算直方图
calcHist(
&分割后的单通道图像,
输入数组的个数,
需要统计的通道索引,
Mat()掩码
储存直方图的矩阵,
直方图的维数,
&每个维度的bin数,
&每个维度的取值范围,
true,
false
);
归一化,将直方图bin中的值缩放到指定的范围:
normalize(
输入数组,
归一化后的输出数组,
归一化范围的小值,
归一化范围的大值,
NORM_MINMAX归一化方法,
-1,指示归一化后的输出数组与输入数组同类型,
Mat()掩码
);
下面你是一个手敲的demo:
#include "opencv2/opencv.hpp"
#include <vector>
using namespace std;
using namespace cv;
int main()
{
Mat src = imread("/home/dynamicw/Project/C++_Project/opencvtest/src/lesson01/source/grass.jpg");
imshow("src",src);
vector<Mat> planes;
split(src,planes);
imshow("b",planes.at(0));
imshow("g",planes.at(1));
imshow("r",planes.at(2));
int histSize = 255;
float range[] = {0,255};
const float* histRange = {range};
Mat r_hist,g_hist,b_hist;
calcHist(&planes[0],1,0,Mat(),r_hist,1,&histSize,&histRange,true,false);
calcHist(&planes[1],1,0,Mat(),g_hist,1,&histSize,&histRange,true,false);
calcHist(&planes[2],1,0,Mat(),b_hist,1,&histSize,&histRange,true,false);
Mat histImage(400,400,CV_8UC3,Scalar(0,0,0));
normalize(r_hist,r_hist,0,400,NORM_MINMAX,-1,Mat());
normalize(g_hist,g_hist,0,400,NORM_MINMAX,-1,Mat());
normalize(b_hist,b_hist,0,400,NORM_MINMAX,-1,Mat());
int bin_w = cvRound((double)400/histSize);
for(int i = 1;i < histSize;i++)
{
line(histImage,Point(bin_w*(i-1),400-cvRound(r_hist.at<float>(i-1))),Point(bin_w*(i),cvRound(400-r_hist.at<float>(i))),Scalar(0,0,255),2,8);
line(histImage,Point(bin_w*(i-1),400-cvRound(g_hist.at<float>(i-1))),Point(bin_w*(i),cvRound(400-g_hist.at<float>(i))),Scalar(0,255,0),2,8);
line(histImage,Point(bin_w*(i-1),400-cvRound(b_hist.at<float>(i-1))),Point(bin_w*(i),cvRound(400-b_hist.at<float>(i))),Scalar(255,0,0),2,8);
}
imshow("hist",histImage);
waitKey(0);
return 0;
}