【图像处理】彩色图像自适应对比度增强(OpenCV实现)

版权声明:【fishing-pan:https://blog.csdn.net/u013921430转载请注明出处】 https://blog.csdn.net/u013921430/article/details/83865427

【fishing-pan:https://blog.csdn.net/u013921430 转载请注明出处】

  提到图像增强,第一印象就是直方图均衡与直方图规定化,这是最常见的也是非常有效的全局图像增强方法。在前不久的一次组会讨论中,课题组的一位同学提到了“自适应图像增强”,虽然自己以前也用过,但是一时间忘记了原理,就去复习了一下,其实他使用的方法的全称应该叫自适应直方图均衡,对应的是Matlab 中的adapthisteq 函数;

  我在复习的过程中,偶然发现了另一个图像增强的算法,也就是这篇文章中要提到的——自适应对比度增强(Adaptive Contrast Enhancement,ACE),下面就从原理到实现,来好好聊一下这种方法。

自适应对比度增强

  在图像处理的方法中,自适应方法是与图像本身信息相关,根据图像对图特征对图像进行处理的一系列方法,这些方法往往具有更好的鲁棒性、普适性。而本文中提到的这种ACE方法由 N a r e n d r a P M Narendra P M 等人在《Real-Time Adaptive Contrast Enhancement》中提到,原理简单易懂,有兴趣的朋友可以点击链接去阅读。

   对于图像中的每一个点,分别计算其局部均值与局部标准差;
M ( i , j ) = 1 ( 2 n + 1 ) ( 2 m + 1 ) s = i n i + n k = j m j + m f ( s , k ) M(i,j)=\frac{1}{(2n+1)(2m+1)}\sum_{s=i-n}^{i+n}\sum_{k=j-m}^{j+m}f(s,k)
σ 2 ( i , j ) = 1 ( 2 n + 1 ) ( 2 m + 1 ) s = i n i + n k = j m j + m ( f ( s , k ) M ( i , j ) ) 2 \sigma ^{2}(i,j)=\frac{1}{(2n+1)(2m+1)}\sum_{s=i-n}^{i+n}\sum_{k=j-m}^{j+m}(f(s,k)-M(i,j))^{2}
  上述式子中, f ( s , k ) f(s,k) 代表坐标为 ( s , k ) (s,k) 的点的像素值, M ( i , j ) M(i,j) 为以点 ( i , j ) (i,j) 为中心,窗口大小为 [ ( 2 n + 1 ) ( 2 m + 1 ) ] [(2n+1),(2m+1)] 的区域的局部均值,对应的 σ 2 ( i , j ) \sigma ^{2}(i,j) 为局部的方差, σ ( i , j ) \sigma (i,j) 为局部图像的标准差。
  
  在求得局部均值与标准差后,就可以对图像进行增强了,具体的公式如下;
I ( i , j ) = M ( i , j ) + G ( f ( i , j ) M ( i , j ) ) I(i,j)=M(i,j)+G(f(i,j)-M(i,j))
G = α M σ ( i , j ) 0 < α < 1 G=\alpha \frac{M}{\sigma (i,j)}\qquad 0<\alpha<1
  上式中, I ( i , j ) I(i,j) 为增强后的像素值, M M 为全局均值(你也可以把它设为某一合理数值), α \alpha 是一个系数参数,一般取小于1大于0的小数。

  再来分析一下,上面式子的含义;如果将每个点的局部均值 M ( i , j ) M(i,j) 构成一张图,其实就是均值滤波的结果,而在《数字图像傅里叶变换的物理意义及简单应用》中,我提到过均值滤波是一种低通滤波,获得的是图像的低频部分,也就是背景部分, f ( i , j ) M ( i , j ) f(i,j)-M(i,j) 就可以用来量化图像中的一个点是高频还是低频。而在一般情况下, G G 都是大于1的,所以通过 G ( f ( i , j ) M ( i , j ) ) G(f(i,j)-M(i,j)) 可以实现对图像的高频部分的放大,进而对图像进行增强。
在这里插入图片描述
  再来看看参数 G G ,经过上面的过程可以看出,如果 G G 是一个固定参数,比如都取5,通过式子中的局部均值,我们已经能够将图像实现一定程度上的自适应增强了。那么为什么还要在参数G中引入标准差呢?

  我们回忆一下对比度增强的初衷,对比度增强是为了让本身对比度不强的图像的对比度变得明显,而对本身对比度很强的图像,是没必要做增强的。那么在同一图像中,我们尤其需要增强对比度不强的部分。而方差表示的是图像的像素值的均匀性,我们可以认为方差越大的局部区域,其像素值越不均匀,对比度越强;反之,方差越小的局部区域,其像素值越均匀,对比度越弱。因此,在参数 G G 中除以了局部标准差,可以让图像中对比度较弱的部分的增强效果更加明显。

  其次,如果对整张图像中所有点进行等比例增强,图像中本身就是高频的部分出现过增强的现象,图像看起来十分奇怪。

彩色图像的ACE

  在网上看到有人说,对彩色图像增强可以分别对RGB三通道进行增强后进行合并。这个观点是错误的,因为分别对各个通道进行增强,会引起图像色相的变化,图像会变的不是其原来的颜色了。

  所以需要将图像转到HSI色彩空间,或者是YCrCb颜色空间。前者只需要对I亮度通道进行增强,而H、S分别代表的色调和饱和度通道不需要变化。后者用Y通道表示亮度,只需要对Y通道进行增强即可。增强之后再合并通道,转换回RGB空间便完成了对彩色图像的增强。

代码

在这里我只提供一个adaptContrastEnhancement函数的代码,完整的代码也很简单,可以点击下载。无C币的可以直接在博客留言,我也会发送到你的邮箱。

//--------------------------
//Adaptive Contrast Enhancement(自适应对比度增强,ACE)
//不用先生,2018.11.08
//
//函数功能:获取图像的局部均值与局部标准差的图
//函数名称:adaptContrastEnhancement
//函数参数:Mat &scr:输入图像,为三通道RGB图像;
//函数参数:Mat &dst:增强后的输出图像,为三通道RGB图像;
//函数参数:int winSize:局部均值的窗口大小,应为单数;
//函数参数:int maxCg:增强幅度的上限;
//返回类型:bool
//--------------------

bool adaptContrastEnhancement(Mat &scr, Mat &dst, int winSize,int maxCg)
{
	if (!scr.data)  //判断图像是否被正确读取;
	{
		cerr << "自适应对比度增强函数读入图片有误";
		return false;
	}

	Mat ycc;                        //转换空间到YCrCb;
	cvtColor(scr, ycc, COLOR_RGB2YCrCb);

	vector<Mat> channels(3);        //分离通道;
	split(ycc, channels);

	
	Mat localMeansMatrix(scr.rows , scr.cols , CV_32FC1);
	Mat localVarianceMatrix(scr.rows , scr.cols , CV_32FC1);
	
	if (!getVarianceMean(channels[0], localMeansMatrix, localVarianceMatrix, winSize))   //对Y通道进行增强;
	{
		cerr << "计算图像均值与标准差过程中发生错误";
		return false;
	}

	Mat temp = channels[0].clone();

	Scalar  mean;
	Scalar  dev;
	meanStdDev(temp, mean, dev);

	float meansGlobal = mean.val[0];
	Mat enhanceMatrix(scr.rows, scr.cols, CV_8UC1);

	for (int i = 0; i < scr.rows; i++)            //遍历,对每个点进行自适应调节
	{
		for (int j = 0; j < scr.cols; j++)
		{
			if (localVarianceMatrix.at<float>(i, j) >= 0.01)
			{
				float cg = 0.2*meansGlobal / localVarianceMatrix.at<float>(i, j);
				float cgs = cg > maxCg ? maxCg : cg;
				cgs = cgs < 1 ? 1 : cgs;
				
				int e = localMeansMatrix.at<float>(i, j) + cgs* (temp.at<uchar>(i, j) - localMeansMatrix.at<float>(i, j));
				if (e > 255){ e = 255; }
				else if (e < 0){ e = 0; }
				enhanceMatrix.at<uchar>(i, j) = e;
			}
			else
			{
				enhanceMatrix.at<uchar>(i, j) = temp.at<uchar>(i, j);
			}
		}
			
	}
	
	channels[0] = enhanceMatrix;    //合并通道,转换颜色空间回到RGB
	merge(channels, ycc);

	cvtColor(ycc, dst, COLOR_YCrCb2RGB);
		
}

运行结果

在这里插入图片描述
在这里插入图片描述

  可以明显看出,图像中原先对比度不强的部分,如树干、江面、远景。经过增强后,都有了明显的改善,而本身对比度已经明显的区域,就没有太大的改变。

已完。。

参考

  1. Narendra P M, Fitch R C. Real-time adaptive contrast enhancement[J]. IEEE transactions on pattern analysis and machine intelligence, 1981 (6): 655-661.
  2. http://www.cnblogs.com/Imageshop/p/3324282.html

猜你喜欢

转载自blog.csdn.net/u013921430/article/details/83865427