将彩色图像分割进BGR三个通道,然后分别显示其直方图,代码如下:
#ifndef ColorHistogramND_h #define ColorHistogramND_h #endif /* ColorHistogramND_h */ class ColorHistogramND { private: cv::Mat image; int histSize[1],hisWidth,hisHeight; //直方图的大小及宽度、高度 float range[2]; //值范围 const float *ranges; cv::Mat channelsBGR[3]; //分离的BGR通道 cv::MatND outputBGR[3]; //输出直方图分量 public: ColorHistogramND() { //准备用于彩色图像的默认参数 histSize[0]=256; //每个维度256个箱子 hisWidth=500; hisHeight=500; range[0]=0.0;//从0开始(含) range[1]=255.0;//到256(不含) ranges=&range[0]; } //导入图片 bool importImage(cv::String path){ image = cv::imread(path); if (!image.data) return false; return true; } //分离通道 void splitChannels() { split(image, channelsBGR); }; //计算直方图 void getColorHistogram() { calcHist(&channelsBGR[0], 1, 0, cv::Mat(), outputBGR[0], 1, histSize, &ranges); calcHist(&channelsBGR[1], 1, 0, cv::Mat(), outputBGR[1], 1, histSize, &ranges); calcHist(&channelsBGR[2], 1, 0, cv::Mat(), outputBGR[2], 1, histSize, &ranges); for(int i=0;i<histSize[0];i++) { std::cout << i << "B:" << outputBGR[0].at<float>(i); std::cout <<"G:" << outputBGR[1].at<float>(i); std::cout << "R:" << outputBGR[2].at<float>(i) << std::endl; } } //显示直方图 void displayColorHisttogram() { cv::Mat bgrHist[3]; for (int i = 0; i < 3; i++) { bgrHist[i] = cv::Mat(hisWidth, hisHeight, CV_8UC3, cv::Scalar::all(0)); } normalize(outputBGR[0], outputBGR[0], 0, hisWidth - 20, cv::NORM_MINMAX); normalize(outputBGR[1], outputBGR[1], 0, hisWidth - 20, cv::NORM_MINMAX); normalize(outputBGR[2], outputBGR[2], 0, hisWidth - 20, cv::NORM_MINMAX); for (int i = 0; i < histSize[0]; i++) { int val = cv::saturate_cast<int>(outputBGR[0].at<float>(i)); rectangle(bgrHist[0], cv::Point(i * 2 + 10, bgrHist[0].rows), cv::Point((i + 1) * 2 + 10, bgrHist[0].rows - val), cvScalar(255, 0, 0), 1, 8); val = cv::saturate_cast<int>(outputBGR[1].at<float>(i)); rectangle(bgrHist[1], cv::Point(i * 2 + 10, bgrHist[1].rows), cv::Point((i + 1) * 2 + 10, bgrHist[1].rows - val), cvScalar(0, 255, 0), 1, 8); val = cv::saturate_cast<int>(outputBGR[2].at<float>(i)); rectangle(bgrHist[2], cv::Point(i * 2 + 10, bgrHist[2].rows), cv::Point((i + 1) * 2 + 10, bgrHist[2].rows - val), cvScalar(0, 0, 255), 1, 8); } cv::imshow("B", bgrHist[0]); imshow("G", bgrHist[1]); imshow("R", bgrHist[2]); imshow("image", image); } }; 主程序如下:
#include <iostream> #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/opencv.hpp> #include "ColorHistogramND.h" using namespace cv; using namespace std; int main() { //Mat image=imread("/Users/zhangxiaoyu/Desktop/lena.jpg"); //if(image.empty()) //{ //cout<<"Error!cannot be read...../n"; //return -1; //} string path="/Users/zhangxiaoyu/Desktop/lena.jpg"; ColorHistogramND hist; if(!hist.importImage(path)) { cout<<"Import error!!"<<endl; return -1; } hist.splitChannels(); hist.getColorHistogram(); hist.displayColorHisttogram(); waitKey(0); return 0; } 显示如下:
原始图片如下: