opencv得到图像的RGB颜色直方图

时间:2023-01-09 23:10:45

图像处理中,直方图是一个很强有力的工具. 其实直方图就是对颜色像素的统计,将统计值放到相应的bin中. 这里就涉及到bin的概念了,刚开始的时候对这个概念很疑惑.

bin的概念:颜色空间划分的区间即是直方图的bin. 举个例子,灰度图有256个值,如果把每个值划分一个单独的区间,则可以说直方图有256个bin,当然bin越大,颜色区分就越细,但是同时也增加了计算的复杂性.


下面的代码实现了图像RGB三个通道直方图的获取和显示.


#include<opencv2\opencv.hpp>
#include<iostream>
using namespace std;
using namespace cv;

class HistogramND{
private:
Mat image;//源图像
int hisSize[1],hisWidth,hisHeight;//直方图的大小,宽度和高度
float range[2];//直方图取值范围
const float *ranges;
Mat channelsRGB[3];//分离的BGR通道
MatND outputRGB[3];//输出直方图分量
public:
HistogramND(){
hisSize[0] = 256;
hisWidth = 400;
hisHeight = 400;
range[0] = 0.0;
range[1] = 255.0;
ranges = &range[0];
}

//导入图片
bool importImage(String path){
image = imread(path);
if (!image.data)
return false;
return true;
}

//分离通道
void splitChannels(){
split(image, channelsRGB);
}

//计算直方图
void getHistogram(){
calcHist(&channelsRGB[0],1,0,Mat(),outputRGB[0],1,hisSize,&ranges);
calcHist(&channelsRGB[1],1,0,Mat(),outputRGB[1], 1, hisSize, &ranges);
calcHist(&channelsRGB[2],1,0,Mat(),outputRGB[2], 1, hisSize, &ranges);

//输出各个bin的值
for (int i = 0; i < hisSize[0]; ++i){
cout << i << " B:" << outputRGB[0].at<float>(i);
cout <<" G:" << outputRGB[1].at<float>(i);
cout << " R:" << outputRGB[2].at<float>(i) << endl;
}
}

//显示直方图
void displayHisttogram(){
Mat rgbHist[3];
for (int i = 0; i < 3; i++)
{
rgbHist[i] = Mat(hisWidth, hisHeight, CV_8UC3, Scalar::all(0));
}
normalize(outputRGB[0], outputRGB[0], 0, hisWidth - 20, NORM_MINMAX);
normalize(outputRGB[1], outputRGB[1], 0, hisWidth - 20, NORM_MINMAX);
normalize(outputRGB[2], outputRGB[2], 0, hisWidth - 20, NORM_MINMAX);
for (int i = 0; i < hisSize[0]; i++)
{
int val = saturate_cast<int>(outputRGB[0].at<float>(i));
rectangle(rgbHist[0], Point(i * 2 + 10, rgbHist[0].rows), Point((i + 1) * 2 + 10, rgbHist[0].rows - val), Scalar(0, 0, 255), 1, 8);
val = saturate_cast<int>(outputRGB[1].at<float>(i));
rectangle(rgbHist[1], Point(i * 2 + 10, rgbHist[1].rows), Point((i + 1) * 2 + 10, rgbHist[1].rows - val), Scalar(0, 255, 0), 1, 8);
val = saturate_cast<int>(outputRGB[2].at<float>(i));
rectangle(rgbHist[2], Point(i * 2 + 10, rgbHist[2].rows), Point((i + 1) * 2 + 10, rgbHist[2].rows - val), Scalar(255, 0, 0), 1, 8);
}

cv::imshow("R", rgbHist[0]);
imshow("G", rgbHist[1]);
imshow("B", rgbHist[2]);
imshow("image", image);
}
};


int main(){
string path = "E:\\VS2013\\bran.jpg";
HistogramND hist;
if (!hist.importImage(path)){
cout << "Import Error!" << endl;
return -1;
}
hist.splitChannels();
hist.getHistogram();
hist.displayHisttogram();
waitKey(0);
return 0;
}

结果截图:

opencv得到图像的RGB颜色直方图

opencv得到图像的RGB颜色直方图