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; }