CLAHE算法学习

0.前言

图像识别工程开发中需要增强图像对比度,便于后续处理,接触到了CLAHE(Contrast Limited Adaptive Histogram Equalization),记录一下其中的学习过程。

1.直方图均衡

1.1灰度直方图

灰度图中像素值的分布为0-255,以灰度值为横坐标,纵坐标为该灰度值对应的像素点数目/比例,则得到了灰度图像的直方图,体现的是图像中灰度的整体分布情况。

OpenCV中提供了相应的计算函数calcHist(),可以得到相应分布范围的像素点数;将其绘制出来观察,更为直观。下图为某输入图像和其灰度直方图分布。

CLAHE算法学习_第1张图片

一般性规律:对于灰度图像,以个人观察意愿将其分为前景和背景区域,前景是我们所感兴趣的区域,背景则反之。若前景和背景的灰度差异大,则易于人们观察,否则不易观察。一般来说若图像的灰度直方图集中在某个区域,其整体对比度较差,不易于我们区分前景和背景;反之若灰度直方图分布较为均匀,则整体对比度较好,易于我们区分前景和背景。

1.2直方图均衡化(Histogram Equalization, HE)

1)效果

直方图均衡化就是一种使图像的灰度直方图分布更佳均匀的变换方法。OpenCV中的equalizeHist()实现了该功能

CLAHE算法学习_第2张图片

左侧为原始灰度图,中间上方为其灰度分布;右侧为HE处理后得到的图像,中间下方为其灰度分布;对比灰度分布可知右方图像的灰度分布更为均匀,图像效果上来看结果图像对比度更强。

2)数学原理

先说概率分布与概率密度函数,看一下下图中的题目回想一下以前的数学知识。

CLAHE算法学习_第3张图片

接下来对概率密度函数的变换做一些数学推导,输入公式比较麻烦,截图为图像粘贴进来。

CLAHE算法学习_第4张图片

这里可以看到转换函数T()为单调递增函数,不过结果图的直方图分布并不是理想的一条水平线;原因在于我们是在连续分布上推导得到转换函数,作用于离散分布,且不允许产生非整数形式的新结果。不过整体看来该转换函数使新的分布具有展开直方图分布的效果,增强了整体的对比度。

2.CLAHE

上述的HE算法得到的结果存在一些问题,主要包括:1)部分区域由于对比度增强过大,成为噪点;2)一些区域调整后变得更暗/更亮,丢失细节信息。

2.1CLHE

针对问题1),有人提出了CLHE,即加入对比度限制的HE算法。转换函数T受像素灰度概率分布的影响:其变化率与概率密度成比例;概率密度过大,会导致原始像素经过变换后灰度值过高,对比度增强过大。

因此需要限制对比度,即限制灰度的分布;同时还需要确保概率密度的积分仍然为1。

如下图所示,一般操作为设置直方图分布的阈值,将超过该阈值的分布“均匀”分散至概率密度分布上,由此来限制转换函数(累计直方图)的增幅。

CLAHE算法学习_第5张图片

下图是使用CLHE和HE的对比,左侧图像为HE结果,中间上方图像为其灰度直方图;右侧图像为CLHE结果,中间下方图像为其灰度直方图;观察灰度直方图可看到上述的限制效果;同时CLHE结果中噪点的分布相对于HE结果要小一些。

CLAHE算法学习_第6张图片

2.2 AHE

针对问题2),有人提出自适应直方图均衡算法(AHE),基本思想为:对原图中每个像素,计算其周围一个邻域内的直方图,并使用HE映射得到新的像素值。为了能够处理图像边缘的像素,一般先对原始图像做镜像扩边处理。

不过这样做计算量偏大,为了减少计算量,一般先把原始图像分为MXN个子区域,分别对每个子区域进行HE变换。但是这样又产生了新的问题,子区域相接处像素值分布不连续,产生很强的分割线,如下图所示。

CLAHE算法学习_第7张图片

为了解决该问题,有人提出加入双线性插值的AHE,也就形成了完整的CLAHE。算法流程如下:

1)将图像分为多个矩形块大小,对于每个矩形块子图,分别计算其灰度直方图和对应的变换函数(累积直方图)

2)将原始图像中的像素按照分布分为三种情况处理;对比下图,红色区域中的像素按照其所在子图的变换函数进行灰度映射,绿色区域中的像素按照所在的两个相邻子图变换函数变换后进行线性插值得到;紫色区域中的像素按照其所在的四个相邻子图变换函数变换后双线性插值得到

CLAHE算法学习_第8张图片

3. OpenCV中的CLAHE

OpenCV中提供了CLAHE的实现和接口,调用也十分简单,其提供的两个设置接口分别用于设置自适应处理中的阈值,和子图的大小。下面是调用OpenCV的HE和CLAHE处理的示例代码和结果图像。

void opencvEqualizeHist()
{
	Mat img, img_gray, result;
	Mat clahe_result;
	img = imread("test.jpg");
	cvtColor(img, img_gray, CV_BGR2GRAY);
	equalizeHist(img_gray, result);

	cv::Ptr clahe = cv::createCLAHE();
	clahe->setClipLimit(4);
	clahe->setTilesGridSize(cv::Size(10, 10));
	clahe->apply(img_gray, clahe_result);

	imshow("src", img_gray);
	imshow("result", result);
	imshow("clahe_result", clahe_result);

	waitKey();
}

对比可发现CLAHE的结果相对于HE的结果,未出现结果像素相比于原图因调整得更亮/更暗而丢失了细节的情况,且局部对比度更强。

4.参考

https://www.cnblogs.com/aoru45/p/10633313.html

https://blog.csdn.net/superjunenaruto/article/details/52431941

https://www.jianshu.com/p/5e8392ec1940

https://www.cnblogs.com/Imageshop/archive/2013/04/07/3006334.html

https://blog.csdn.net/eternity1118_/article/details/51492105

https://www.cnblogs.com/jsxyhelu/p/6435601.html

你可能感兴趣的:(opencv学习)