#include "Histogram.h"
#include <iostream>
cv::MatND Histogram::getHistogram(const cv::Mat &image)
{
cv::MatND hist;
cv::calcHist(&image, //看一下函数声明就会明白参数的意思
1, // histogram of 1 image only
channels, // the channel used
cv::Mat(), // no mask is used
hist, // the resulting histogram
1, // it is a 1D histogram
histSize, // number of bins
ranges // pixel value range
);
return hist;
}
cv::Mat Histogram::getHisotgramImage(const cv::Mat &image)
{
//得到图像的信道数
int channels = image.channels();
//将直方图最大值缩小为灰度级数的90%
int hpt = static_cast<int>(0.9*histSize[0]);
//初始化直方图矩阵,注意这里的画布一定要是三基色,要不然画不了彩色的line
cv::Mat histImg(histSize[0]*channels, histSize[0], CV_8UC3, cv::Scalar(255,255,255));
std::vector<cv::Mat> images;
std::vector<cv::Scalar> scalars;
//如果是1通道图像则直方图是灰色
if(channels == 1)
scalars.push_back(CV_RGB(0,0,0));
else
{
//注意Scalar的顺序是BGR
scalars.push_back(CV_RGB(0,0,255));
scalars.push_back(CV_RGB(0,255,0));
scalars.push_back(CV_RGB(255,0,0));
}
double minVal = 0;
double maxVal = 0;
//将通道分离,逐个求直方图
cv::split(image, images);
for(int c=0; c<channels; c++)
{
cv::MatND hist = getHistogram(images[c]);
//得到直方图的最大值和最小值和位置,以便对直方图缩放
cv::minMaxLoc(hist, &minVal, &maxVal, 0, 0);
std::cout<<scalars[c]<<std::endl;
for(int h=0; h<histSize[0]; h++)
{
float binVal = hist.at<float>(h);
int intensity = static_cast<int>(binVal*hpt/maxVal);
//在histImg中画直线,要注意图像的坐标系
cv::line(histImg, cv::Point(h, histSize[0]*(c+1)), cv::Point(h,histSize[0]*(c+1)- intensity),scalars[c]);
}
}
return histImg;
}