前言
如果你想了解更多有关于计算机视觉、OpenCV、机器学习、深度学习等相关技术的内容,想与更多大佬一起沟通,那就扫描下方二维码加入我们吧!
1、calcHist函数是干什么滴?
这个问题嘛,看看标题,标题,对啊,你这么聪明,一定猜得到:
calcHist函数是用来计算图像直方图的。
2、calcHist函数调用形式
C++: void calcHist(const Mat* images, int nimages, const int* channels, InputArray mask, OutputArray hist, int dims, const int* histSize, const float** ranges, bool uniform=true, bool accumulate=false )
参数详解:
onst Mat* images:输入图像
int nimages:输入图像的个数
const int* channels:需要统计直方图的第几通道
InputArray mask:掩膜,,计算掩膜内的直方图 ...Mat()
OutputArray hist:输出的直方图数组
int dims:需要统计直方图通道的个数
const int* histSize:指的是直方图分成多少个区间,就是 bin的个数
const float** ranges: 统计像素值得区间
bool uniform=true::是否对得到的直方图数组进行归一化处理
bool accumulate=false:在多个图像时,是否累计计算像素值得个数
3、实战分析及代码展示
我们需要把下面这个图像的直方图计算并画在画布上。一共有如下几个步骤:
1.创建一些矩阵;
2.加载原图像;
3.使用OpenCV函数 split() 将图像分割成3个单通道图像;
4.设定像素取值范围,我们知道像素值的范围是 [0,255];
5.使用OpenCV函数calcHist() 分别计算三个通道的直方图;
6.创建显示直方图的画布并使用 normalize() 函数归一化直方图;
7.最后显示直方图并等待用户退出程序;
#define INPUT_TITLE "input image"
#define OUTPUT_TITLE "直方图计算"
#include<iostream>
#include<opencv2\opencv.hpp>
using namespace std;
using namespace cv;
int main() {
Mat src, dst;
//加载图像
src = imread("D:/equalizeHist.jpg");
if (!src.data)
{
cout << "ERROR : could not load image.";
return -1;
}
namedWindow(INPUT_TITLE, CV_WINDOW_AUTOSIZE);
namedWindow(OUTPUT_TITLE, CV_WINDOW_AUTOSIZE);
imshow(INPUT_TITLE, src);
//分通道显示
vector<Mat> bgr_planes;
split(src, bgr_planes);
//设定像素取值范围
int histSize = 256;
float range[] = { 0,256 };
const float *histRanges = { range };
//三个通道分别计算直方图
Mat b_hist, g_hist, r_hist;
calcHist(&bgr_planes[0], 1, 0, Mat(), b_hist, 1, &histSize, &histRanges, true, false);
calcHist(&bgr_planes[1], 1, 0, Mat(), g_hist, 1, &histSize, &histRanges, true, false);
calcHist(&bgr_planes[2], 1, 0, Mat(), r_hist, 1, &histSize, &histRanges, true, false);
//创建直方图画布并归一化处理
int hist_h = 400;
int hist_w = 512;
int bin_w = hist_w / histSize;
Mat histImage(hist_w, hist_h, CV_8UC3, Scalar(0, 0, 0));
normalize(b_hist, b_hist, 0, hist_h, NORM_MINMAX, -1, Mat());
normalize(g_hist, g_hist, 0, hist_h, NORM_MINMAX, -1, Mat());
normalize(r_hist, r_hist, 0, hist_h, NORM_MINMAX, -1, Mat());
//render histogram chart 在直方图画布上画出直方图
for (int i = 0; i < histSize; i++)
{
line(histImage, Point((i - 1)*bin_w, hist_h - cvRound(b_hist.at<float>(i - 1))),
Point((i)*bin_w, hist_h - cvRound(b_hist.at<float>(i))), Scalar(255, 0, 0), 2, LINE_AA);
line(histImage, Point((i - 1)*bin_w, hist_h - cvRound(g_hist.at<float>(i - 1))),
Point((i)*bin_w, hist_h - cvRound(g_hist.at<float>(i))), Scalar(0, 255, 0), 2, LINE_AA);
line(histImage, Point((i - 1)*bin_w, hist_h - cvRound(r_hist.at<float>(i - 1))),
Point((i)*bin_w, hist_h - cvRound(r_hist.at<float>(i))), Scalar(0, 0, 255), 2, LINE_AA);
}
imshow(OUTPUT_TITLE, histImage);
waitKey(0);
return 0;
}
![](https://i-blog.csdnimg.cn/blog_migrate/e3ee3e941f4c7d5a0e250146ab203be6.png)