Opencv学习笔记(十三)直方图均衡化

553 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路

一、直方图均衡化数学原理介绍

首先介绍图像直方图的概念,图像的直方图指的是以图像的灰度值(划分)为横轴,图像中所有像素中对应该灰度值(划分)出现的数目(也可归一化)作为纵轴,所构建出的一种直方图,它所描述的是图片整体范围内灰度值的分布情况。如果一张图片的灰度分布过于的集中,呈现出的对比度就较低,人眼难以分辨出,所以我们需要进行直方图均衡化,使得图像的灰度值更加均匀的分布在色彩空间内,大致实现方式则是将像素数目多且更亮的灰度值进行扩展,让它变得更亮;对于那些像素数目少并且不那么亮的灰度值进行归并,让它更暗。

前后对比图如下: 在这里插入图片描述 在这里插入图片描述

直方图均衡化的数学推导较为复杂,具体过程可见参考文献,现不加证明的给出均衡化前后灰度值变换公式:

设一副图像的像素数目为nn,共有ll个灰度划分,nkn_k代表灰度值处于第kk个划分的像素数目,像素空间深度为DD(通常就是255),则第kk个灰度划分出现的概率为:

P(rk)=nkn,0rk1,k=012......l1P(r_k)={{n_k}\over{n}},0\le r_k \le 1,k=0、1、2......l-1

变换后的灰度值可表示为:

sk=i=0kninD,0rk1,k=012......l1s_k=\displaystyle\sum_{i=0}^k{{n_i}\over{n}}*D,0\le r_k \le 1,k=0、1、2......l-1

二、直方图均衡化使用实例

opencv中给出了直方图均衡化函数原型如下:

void equalizeHist( InputArray src, OutputArray dst );

参数即为输入输出图像,应该为8位单通道图像,具有相同大小和类型。

使用实例如下:

int main()
{
	Mat src = imread("E:\\material\\lowcontrast.jpg",0);
	Mat dst;
	if (src.empty())
	{
		cout << "not found the picture";
		return -1;
	}
	Mat hist1, hist2;
	imshow("原图", src);
	int histSize = 256;
	float range[] = { 0,256 };
	const float* histRanges = { range };
	calcHist(&src,1,0,Mat(),hist1,1,&histSize,&histRanges);
	equalizeHist(src, dst);
	calcHist(&dst, 1, 0, Mat(), hist2, 1, &histSize, &histRanges);
	imshow("处理后的图", dst);

	//创建直方图画布并归一化处理
	int hist_h = 600;
	int hist_w = 800;
	int bin_w = hist_w / histSize;
	Mat histImage(hist_w, hist_h, CV_8UC3, Scalar(0, 0, 0));
	normalize(hist1, hist1, 0, hist_h, NORM_MINMAX, -1, Mat());
	normalize(hist2, hist2, 0, hist_h, NORM_MINMAX, -1, Mat());

	//render histogram chart  在直方图画布上画出直方图
	for (int i = 1; i < histSize; i++)
	{
		line(histImage, Point((i - 1) * bin_w, hist_h - cvRound(hist1.at<float>(i - 1))),
			Point((i)* bin_w, hist_h - cvRound(hist1.at<float>(i))), Scalar(255, 0, 0));
		line(histImage, Point((i - 1) * bin_w, hist_h - cvRound(hist2.at<float>(i - 1))),
			Point((i)* bin_w, hist_h - cvRound(hist2.at<float>(i))), Scalar(0, 255, 0));
	}
	imshow("hist", histImage);
	waitKey(0);
}

参考文献

直方图均衡化的数学原理

直方图均衡化

【opencv学习笔记】025之直方图计算 - calcHist函数详解