將彩色圖像分割進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;
}
顯示如下:
原始圖片如下: