图像处理之直方图均衡化

639 阅读4分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第31天

1 直方图均衡化

很多时候,我们用相机拍摄的照片的效果往往会不尽人意。这时,可以对这些图像进行一些处理,来扩大图像的动态范围。这种情况下最常用到的技术就是直方图均衡化。未经均衡化的图片范例如图a、b所示。

2.png

在图a中,我们可以看到,左边的图像比较淡,因为其数值范围变化比较小,可以在这幅图的直方图(图b)中明显地看到。因为处理的是8位图像,其亮度值是从0到255,但直方图值显示的实际亮度却集中在亮度范围的中间区域。为了解决这个问题,就可以用到直方图均衡化技术,先来看看其概念。

2 直方图均衡化的概念和特点

直方图均衡化是灰度变换的一个重要应用,它高效且易于实现,广泛应用于图像增强处理中。图像的像素灰度变化是随机的,直方图的图形高低不齐,直方图均衡化就是用一定的算法使直方图大致平和的方法。均衡化效果示例如图c、d所示。

3.png

4.png

简而言之,直方图均衡化是通过拉伸像素强度分布范围来增强图像对比度的一种方法。

均衡化处理后的图像只能是近似均匀分布。均衡化图像的动态范围扩大了,但其本质是扩大了量化间隔,而量化级别反而减少了,因此,原来灰度不同的象素经处理后可能变的相同,形成了一片相同灰度的区域,各区域之间有明显的边界,从而出现了伪轮廓。

在原始图像对比度本来就很高的情况下,如果再均衡化则灰度调和,对比度会降低。在泛白缓和的图像中,均衡化会合并一些象素灰度,从而增大对比度。均衡化后的图片如果再对其均衡化,则图像不会有任何变化。如图e、f所示。

5.png

通过图f可以发现,经过均衡化的图像,其频谱更加舒展,有效地利用了0~255的空间,图像表现力更加出色。

3 实现直方图均衡化:equalizeHist()函数

在OpenCV中,直方图均衡化的功能实现由 equalizeHist函数完成。我们一起看看它的函数描述。

C++:

void equalizeHist(InputArray src, OutputArray dst)

  • 第一个参数,InputArray类型的src,输入图像,即源图像,填Mat类的对象即可,需为8位单通道的图像。
  • 第二个参数,OutputArray 类型的 dst,函数调用后的运算结果存在这里,需和源图片有一样的尺寸和类型。

采用如下步骤对输入图像进行直方图均衡化。

1)计算输入图像的直方图H。

2)进行直方图归一化,直方图的组距的和为255。

3)计算直方图积分:

6.png

4)以H'作为查询表进行图像变换:

7.png

言而言之,由 equalizeHist()函数实现的灰度直方图均衡化算法,就是把直方图的每个灰度级进行归一化处理,求每种灰度的累积分布,得到一个映射的灰度映射表,然后根据相应的灰度值来修正原图中的每个像素。

4 示例

代码:

//---------------------------------【头文件、命名空间包含部分】---------------------------
//          描述:包含程序所使用的头文件和命名空间
//---------------------------------------------------------------------------------------
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
using namespace cv;

//--------------------------------------【main( )函数】----------------------------------------
//          描述:控制台应用程序的入口函数,我们的程序从这里开始执行
//--------------------------------------------------------------------------------------------
int main( )
{
	// 【1】加载源图像
	Mat srcImage, dstImage;
	srcImage = imread( "1.jpg", 1 );
	if(!srcImage.data ) { printf("读取图片错误,请确定目录下是否有imread函数指定图片存在~! \n"); return false; } 

	// 【2】转为灰度图并显示出来
	cvtColor( srcImage, srcImage, CV_BGR2GRAY );
	imshow( "原始图", srcImage );

	// 【3】进行直方图均衡化
	equalizeHist( srcImage, dstImage );

	// 【4】显示结果
	imshow( "经过直方图均衡化后的图", dstImage );

	// 等待用户按键退出程序
	waitKey(0);
	return 0;

}

效果图:

原图

0.PNG

效果图

0-1.PNG