暗通道去雾与自适应直方图均衡去雾之比较

本文主要对比两种去雾增强算法的优略。

1. 暗通道去雾方法

           这种方法目前研究的比较多。虽然大家认为去雾已经被研究烂了,但是从工程实践的角度看,仍然存在很多问题。却不说暗通道先验对天空本身的不合理假设,就单说时间复杂度。对于视频图像处理来说,视频编解码就已经占了大量的CPU时间,而如果其它一些图像增强的算法也要占用大量的计算时间,就会导致了很多所谓的the state of art 的算法在工程实践上,依然并不可行。举一个很简单的例子,目前普通PC单核的处理能力只能编码2-4路的720P的H264码流,如果图像增强算法的处理时间大于15ms,则意味着在普通PC上这种算法并不可行。

      关于暗通道去雾的原理,下面几篇网络文章可以参考。

http://www.cnblogs.com/Imageshop/p/3281703.html

http://blog.csdn.net/celerychen2009/article/details/8839098



2. 对比度受限自适应直方图增强去雾方法


        直方图增强是一种古老的技术。不过给我的印象是,对于大部分图像,简单的直方图增强的效果很不好。不过,前几天看到网络上一位牛人的文章,让我对直方图增强有了新的认识。当然,不是直接用直方图,而是对比度受限自适应直方图增强。


       自适应直方图是使用多个直方图,例如对整个图像可以划分为8x8个小块,称为8x8的tiles,则总共会有64个直方图。用这64个直方图来做,tiles的边界处用线性插值的方法实现平滑的过渡。具体原理可以参考下面的博文:

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

http://www.cnblogs.com/Imageshop/p/3395968.html


3. 算法实现


   3.1 暗通道去雾的快速算法。


         暗通道去雾的快速算法改进主要集中在对透射率的refine上。有很多的非线性边缘保持滤波可以用。我起初使用的是非线性各向异性扩散方程,非线性扩散在KAZE特征提取中被采用,其相关的网络资源可以参考:http://blog.csdn.net/chenyusiyuan/article/details/8710462。采用加法分裂算子来离散化偏微分方程,仅需很少的几次迭代就可以收敛,如果采用跳跃格式的迭代算法,则可以不必求解三对角线性方程组,这种方法是快速稳定高效的。

      采用双边滤波也是一种不错的选择,然而双边滤波的快速算法实在是快不起来。一种更快更好的方案是采用引导滤波guided filter. guided filter应该是目前最快的边缘保持滤波了,我的实现方案表明,其计算时间比我的快速高斯滤波算法还要快。


  3.2 对比度受限自适应直方图的实现


      这个算法实现相对比较简单,没有暗通道去雾那么多过程。

      例如对于2x2的tiles,如果图像是64x64的,则每个block的大小是32x32,对每一个32x32的小块,计算直方图,然后根据相应的参数重新调整直方图再映射回去。当然,如果图像的尺寸不是tiles的整数倍的时候需要进行对称拓展。最后,在tiles的边缘处进行插值是比较耗时的操作。本文直接给出笔者的实现代码:

static clahe_interpolation( int width, int height, int stride, cv8u* src, cv8u* dst,int channel, 
						   Size2i* tileSize, int tiles_y, int tiles_x, cv8u* ptr_lut_data, int lut_step)
{
	int i,j;
	if (channel == 1){
		for (j = 0; j < height; j++){
			cv8u* pTmpSrc = src + j * stride;
			cv8u* pTmpDst = dst + j * stride;
			int tyf_i =  (j << CLAHE_Q)/tileSize->height - (1 << (CLAHE_Q -1));
			int ty1_i = tyf_i >> CLAHE_Q;
			int ty2_i = ty1_i + 1;

			int ya_i = tyf_i - (ty1_i << CLAHE_Q);
			cv8u* lutPlane1,*lutPlane2;

			ty1_i = (ty1_i < 0) ? 0 : (ty1_i);
			ty2_i = (ty2_i > tiles_y - 1) ? (tiles_y - 1) : (ty2_i);


			lutPlane1 = &ptr_lut_data[ty1_i * tiles_x * lut_step];
			lutPlane2 = &ptr_lut_data[ty2_i * tiles_x * lut_step];

			for (i = 0; i < width; i++){
				int srcVal;
				int ind1,ind2;
				int res_i;
				int txf_i = (i << CLAHE_Q)/tileSize->width - (1 << (CLAHE_Q -1));
				int tx1_i = txf_i >> CLAHE_Q;
				int tx2_i = tx1_i + 1;
				int xa_i = txf_i - (tx1_i << CLAHE_Q);
				int tf_1_i,tf_2_i,tf_3_i,tf_4_i;
				
				srcVal = *pTmpSrc++;

				tx1_i = (tx1_i < 0) ? 0 : (tx1_i);
				tx2_i = (tx2_i > tiles_x - 1) ? (tiles_x - 1) : (tx2_i);

				ind1 = tx1_i * lut_step + srcVal;
				ind2 = tx2_i * lut_step + srcVal;


				tf_1_i = (((1 << CLAHE_Q) - xa_i) * ( (1 << CLAHE_Q) - ya_i)) >> CLAHE_Q;
				tf_2_i = ((xa_i) * ((1 << CLAHE_Q) - ya_i)) >> CLAHE_Q;
				tf_3_i = (((1 << CLAHE_Q) - xa_i) * (ya_i)) >> CLAHE_Q;
				tf_4_i = ((xa_i) * (ya_i)) >> CLAHE_Q;

				res_i  = lutPlane1[ind1] * tf_1_i;
				res_i += lutPlane1[ind2] * tf_2_i;
				res_i += lutPlane2[ind1] * tf_3_i;
				res_i += lutPlane2[ind2] * tf_4_i;
				res_i = (res_i + (1 << (CLAHE_Q - 1))) >> CLAHE_Q;

				*pTmpDst++ = FCV_CLAMP0255_INT(res_i);
			}
		}
    }
}

   3.3 性能比较


4. 去雾效果比较

   最后还是给几张去雾效果图:

                          暗通道去雾效果                                                                             对比度受限自适应HE效果


                                   原图      


暗通道去雾


对比度受限自适应HE


原图


暗通道去雾


对比度受限自适应HE


原图



不足之处分析:

1. 暗通道去雾在较远的天空处存在失真的块效应,通过适当的参数调节可以有效减弱但没法完全避免。没有一个统一的参数来针对所有的图像。

2. 暗通道去雾对于某些低对比度却存在大量天空的区域可能完全失效,效果惨不忍睹。

3. 暗通道去雾的效果可能把整幅图像的亮度降低了,可以通过融合了亮度调整到透射率的优化之中来减轻这种现象。

4. 对比度受限自适应HE可能存在颜色的过饱和现象,自适应HE更适合图像整个对比度较低的场合。

5. 对比度受限自适应HE的计算成本很低,对于D1尺寸的图片其处理时间小于15ms。




posted @ 2013-11-05 10:14  celerychen  阅读(4908)  评论(0编辑  收藏  举报