懒得自己写了
http://www.xufangxi.cn/CPlusPlus/76.html
calcHist只针对单通道,也比较和灰度直方图的概念
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
cv::Mat GetHist(const cv::Mat src);
int main()
{
cv::Mat src = cv::imread("d:\\blueSky.bmp");
//得到源始图片直方图
cv::Mat srcHist = GetHist(src);
//分割R、G、B通道进行直方图均衡化处理
std::vector<cv::Mat> arrMat;
cv::split(src,arrMat);
for(int i = 0; i < arrMat.size(); i++)
{
cv::equalizeHist(arrMat[i],arrMat[i]);
}
//合并均衡化后的图片
cv::Mat equalImage;
cv::merge(arrMat,equalImage);
//得到均衡化后图的直方图
cv::Mat equalHist = GetHist(equalImage);
//将源图、直方图合成一张图
cv::Mat mergeImage(src.cols * 2, src.rows * 2,CV_8UC3);
src.copyTo(mergeImage(cv::Rect(0,0,src.cols,src.rows)));
srcHist.copyTo(mergeImage(cv::Rect(src.cols,0,srcHist.cols,srcHist.rows)));
equalImage.copyTo(mergeImage(cv::Rect(0,src.rows,src.cols,src.rows)));
equalHist.copyTo(mergeImage(cv::Rect(src.cols,src.rows,equalImage.cols,equalImage.rows)));
//中间画线分隔
cv::line(mergeImage,cv::Point(0,mergeImage.rows/2),cv::Point(mergeImage.cols,mergeImage.rows/2),cv::Scalar(0,0,255),3);
return 0;
}
cv::Mat GetHist(const cv::Mat src)
{
// 设定bin数目
int histSize = 255;
// 设定取值范围 ( R,G,B) )
float range[] = {0,255};
const float* histRange = {range};
// 分割成3个单通道图像 ( R, G 和 B )
std::vector<cv::Mat> rgb_hist;
cv::split(src,rgb_hist);
cv::Mat r_hist,g_hist,b_hist;
// 计算直方图:
cv::calcHist(&rgb_hist[0],1,0,cv::Mat(),b_hist,1,&histSize,&histRange);
cv::calcHist(&rgb_hist[1],1,0,cv::Mat(),g_hist,1,&histSize,&histRange);
cv::calcHist(&rgb_hist[2],1,0,cv::Mat(),r_hist,1,&histSize,&histRange);
// 创建直方图画布
int hist_w = 300;
int hist_h = 300;
int bin_w = cvRound((double)hist_w/histSize);
// 将直方图归一化到范围 [ 0, histImage.rows ]
cv::normalize(r_hist,r_hist,0,r_hist.rows,cv::NORM_MINMAX,-1);
cv::normalize(g_hist,g_hist,0,g_hist.rows,cv::NORM_MINMAX,-1);
cv::normalize(b_hist,b_hist,0,b_hist.rows,cv::NORM_MINMAX,-1);
// 在直方图画布上画出直方图
cv::Mat drawHist(hist_h,hist_w,CV_8UC3,cv::Scalar::all(0));
for(int i = 1; i < histSize; i++)
{
cv::line(drawHist,cv::Point(bin_w*(i-1),hist_h-cvRound(r_hist.at<float>(i-1))),
cv::Point(bin_w*i,hist_h-cvRound(r_hist.at<float>(i))),cv::Scalar(0,0,255),1);
cv::line(drawHist,cv::Point(bin_w*(i-1),hist_h-cvRound(g_hist.at<float>(i-1))),
cv::Point(bin_w*i,hist_h-cvRound(g_hist.at<float>(i))),cv::Scalar(0,255,0),1);
cv::line(drawHist,cv::Point(bin_w*(i-1),hist_h-cvRound(b_hist.at<float>(i-1))),
cv::Point(bin_w*i,hist_h-cvRound(b_hist.at<float>(i))),cv::Scalar(255,0,0),1);
}
return drawHist;
}