在实际的应用场景中,我们可以根据需求 调整计算的直方图区间,针对灰度直方图,我们可以将区间[0,255]分成不同的区间范围,然后分别统计各个区间的灰度分布,进而实现自定义的直方图:
代码示例如下:
#include <iostream>
#include <opencv2/opencv.hpp>
int main(int argc,char* argv[])
{
cv::Mat srcImage = cv::imread("E:/CodeBlocks/data/lena.jpg");
if (!srcImage.data)
{
std::cerr << "fail to load image" << std::endl;
return -1;
}
//转换为灰度图像
cv::Mat grayImage;
cv::cvtColor(srcImage,grayImage,cv::COLOR_BGR2GRAY);
//设置计算直方图的参数
const int channles[1] = {0};
const int histSize[1] = {256};
float range[] = {0,40,80,120,160,200,220,255};
const float *ranges[1] = {range};
cv::MatND hist;
cv::calcHist(&grayImage,1,channles,cv::Mat(),hist,1,histSize,ranges,true,false);
//求直方图中得最大值
double maxVal = 0.0;
cv::minMaxLoc(hist,0,&maxVal,0,0);
//设置直方图绘图参数
int Hist_size = hist.rows;
cv::Mat histImage(Hist_size,Hist_size,CV_8U,cv::Scalar(255));
for(int i=0; i< Hist_size;i++)
{
float binVal = hist.at<float>(i);
//归一化
int intensity = static_cast<int>(binVal * Hist_size / maxVal);
//绘制直方图信息
cv::line(histImage,cv::Point(i,Hist_size),cv::Point(i,Hist_size-intensity),cv::Scalar::all(0),2,8,0);
}
cv::imshow("srcImage",srcImage);
cv::imshow("gray",grayImage);
cv::imshow("hist",histImage);
cv::waitKey(0);
cv::destroyAllWindows();
return 0;
}
结果:
![330b22435c7bd53fe542e8e64d6807f7.png](https://i-blog.csdnimg.cn/blog_migrate/d054602ab4a780b5b3582a9e158e0da6.jpeg)
![7fa06f2c7ae00eba15527be98b81af02.png](https://i-blog.csdnimg.cn/blog_migrate/18f6b240772db6a9dc076b7a12e0692a.png)