# OpenCV3入门（十一）图像直方图

2019/04/10 10:10

## 2、OpenCV直方图

OpenCV使用calcHist函数实现直方图计算，函数原型如下图。

CV_EXPORTS void calcHist( const Mat* images, int nimages,
OutputArray hist, int dims, const int* histSize,
const float** ranges, bool uniform = true, bool accumulate = false );

onst Mat* images：输入图像组

int nimages：输入图像的个数

const int* channels：需要统计直方图的第几通道

OutputArray hist：输出的直方图的数组

int dims：直方图的维度，需要统计直方图通道的个数

const int* histSize：指的是直方图分成多少个区间，就是 bin的个数

const float** ranges： 统计像素值的区间，每个维度数值的取值范围

bool uniform=true：是否对得到的直方图数组进行归一化处理

bool accumulate=false：在多个图像时，是否累计计算像素值得个数

Mat src = imread("D:\\WORK\\5.OpenCV\\LeanOpenCV\\pic_src\\img1.bmp");
imshow("原图", src);

MatND dstHist;
int dims = 1;
float hranges[] = { 0,255 };
const float *ranges[]= { hranges };
int size = 256;
int channels = 0;

calcHist(&src, 1, &channels, Mat(), dstHist, dims, &size, ranges);

double maxVal = 0;
double minVal = 0;
cv::minMaxLoc(dstHist, &minVal, &maxVal, 0, 0);
Mat histImg(size, size, CV_8U, cv::Scalar(0));
int hpt = static_cast<int>(0.9*size);

for (int h = 0; h < 256; h++)
{
float binVal = dstHist.at<float>(h);
int intensity = static_cast<int>(binVal * hpt / maxVal);
cv::line(histImg, Point(h, size-1), Point(h+1, size-1 - intensity), Scalar::all(255));
}

imshow("直方图", histImg);
waitKey(0);

Mat src = imread("D:\\WORK\\5.OpenCV\\LeanOpenCV\\pic_src\\pic5.bmp");
imshow("原图", src);

int histsize = 256;
float range[] = { 0,256 };
const float*histRanges = { range };

vector<Mat>bgr_planes;
split(src, bgr_planes);
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);

Mat histImg = Mat::zeros(256, 256*3, CV_8UC3);
for (int h = 0; h < 256; h++)
{
float binVal_r = r_hist.at<float>(h);
float binVal_g = g_hist.at<float>(h);
float binVal_b = b_hist.at<float>(h);

rectangle(histImg, Point(h, 256 - 1), Point(h + 1, 256 - binVal_r), Scalar(255, 0, 0));
rectangle(histImg, Point(h+255, 256 - 1), Point(h +255+ 1, 256 - binVal_g), Scalar(0, 255, 0));
rectangle(histImg, Point(h+510, 256 - 1), Point(h + 510+ 1, 256 - binVal_b), Scalar(0, 0, 255));
}
imshow("直方图", histImg);

## 3、直方图均衡化

Mat blue, green, red, dst;
blue  = bgr_planes[0];
green = bgr_planes[1];
red   = bgr_planes[2];

equalizeHist(blue, blue);
equalizeHist(green, green);
equalizeHist(red, red);
merge(bgr_planes, 3, dst);
imshow("均衡化图", dst);

vector<Mat> bgr_planes2;
split(dst, bgr_planes2);
calcHist(&bgr_planes2[0], 1, 0, Mat(), b_hist, 1, &histsize, &histRanges, true, false);
calcHist(&bgr_planes2[1], 1, 0, Mat(), g_hist, 1, &histsize, &histRanges, true, false);
calcHist(&bgr_planes2[2], 1, 0, Mat(), r_hist, 1, &histsize, &histRanges, true, false);

histImg = Mat::zeros(256, 256 * 3, CV_8UC3);
for (int h = 0; h < 256; h++)
{
float binVal_r = r_hist.at<float>(h);
float binVal_g = g_hist.at<float>(h);
float binVal_b = b_hist.at<float>(h);

rectangle(histImg, Point(h, 256 - 1), Point(h + 1, 256 - binVal_r), Scalar(255, 0, 0));
rectangle(histImg, Point(h + 255, 256 - 1), Point(h + 255 + 1, 256 - binVal_g), Scalar(0, 255, 0));
rectangle(histImg, Point(h + 510, 256 - 1), Point(h + 510 + 1, 256 - binVal_b), Scalar(0, 0, 255));
}

## 5、参考文献

1、《OpenCV3 编程入门》，电子工业出版社，毛星雨著

3、OpenCV图像直方图

https://blog.csdn.net/leonardohaig/article/details/88240112

4、图像处理基础(8)：图像的灰度直方图、直方图均衡化、直方图规定化（匹配）

https://www.cnblogs.com/wangguchangqing/p/7098213.html

5、OpenCV实现图像的直方图处理

https://www.cnblogs.com/noticeable/p/10449867.html

6、【OpenCV学习笔记】之直方图（Histogram）

https://blog.csdn.net/zhu_hongji/article/details/81663161

https://www.cnblogs.com/pingwen/p/12380776.html

0
0 收藏

0 评论
0 收藏
0