图像去雾(二)Retinex图像增强算法

前一段时间研究了一下图像增强算法,发现Retinex理论在彩色图像增强、图像去雾、彩色图像恢复方面拥有很好的效果,下面介绍一下我对该算法的理解。

Retinex理论

    Retinex理论始于Land和McCann于20世纪60年代作出的一系列贡献,其基本思想是人感知到某点的颜色和亮度并不仅仅取决于该点进入人眼的绝对光线,还和其周围的颜色和亮度有关。Retinex这个词是由视网膜(Retina)和大脑皮层(Cortex)两个词组合构成的.Land之所以设计这个词,是为了表明他不清楚视觉系统的特性究竟取决于此两个生理结构中的哪一个,抑或是与两者都有关系。

     Land的Retinex模型是建立在以下的基础之上的:

     一、真实世界是无颜色的,我们所感知的颜色是光与物质的相互作用的结果。我们见到的水是无色的,但是水膜—肥皂膜却是显现五彩缤纷,那是薄膜表面光干涉的结果;

     二、每一颜色区域由给定波长的红、绿、蓝三原色构成的;

     三、三原色决定了每个单位区域的颜色。Retinex 理论的基本内容是物体的颜色是由物体对长波(红)、中波(绿)和短波(蓝)光线的反射能力决定的,而不是由反射光强度的绝对值决定的;物体的色彩不受光照非均性的影响,具有一致性,即Retinex理论是以色感一致性(颜色恒常性)为基础的。如下图所示,观察者所看到的物体的图像S是由物体表面对入射光L反射得到的,反射率R由物体本身决定,不受入射光L变化。

                                                          图像去雾(二)Retinex图像增强算法_第1张图片

Retinex理论的基本假设是原始图像S是光照图像L和反射率图像R的乘积,即可表示为下式的形式:

                                                                

基于Retinex的图像增强的目的就是从原始图像S中估计出光照L,从而分解出R,消除光照不均的影响,以改善图像的视觉效果,正如人类视觉系统那样。在处理中,通常将图像转至对数域,即

                                                                

从而将乘积关系转换为和的关系:

                                                                     

Retinex方法的核心就是估测照度L,从图像S中估测L分量,并去除L分量,得到原始反射分量R,即:

                                                                          

函数 f(x) 实现对照度L的估计(可以去这么理解,实际很多都是直接估计r分量)。

Retinex理论的理解

如果大家看论文,那么在接下去的篇幅当中,肯定会介绍两个经典的Retinex算法:基于路径的Retinex以及基于中心/环绕Retinex。在介绍两个经典的Retinex算法之前,我先来讲一点个人的理解,以便第一次接触该理论的朋友能够更快速地理解。当然,如果我的理解有问题,也请大家帮忙指出。

Retinex理论就我理解,与降噪类似,该理论的关键就是合理地假设了图像的构成。如果将观察者看到的图像看成是一幅带有乘性噪声的图像,那么入射光的分量就是一种乘性的,相对均匀,且变换缓慢的噪声。Retinex算法所做的就是合理地估计图像中各个位置的噪声,并除去它。

在极端情况下,我们大可以认为整幅图像中的分量都是均匀的,那么最简单的估计照度L的方式就是在将图像变换到对数域后对整幅图像求均值。因此,我设计了以下算法来验证自己的猜想,流程如下:

(1) 将图像变换到对数域

                                                                               

(2) 归一化去除加性分量

                                                                             

(3) 对步骤3得到的结果求指数,反变换到实数域

                                                                           

这里为了简化描述,省略了对图像本身格式的变换,算法用Matlab实现:

% ImOriginal:原始图像
% type:'add'表示分量是加性的,如雾天图像;'mult'表示分量是乘性的,如对照度的估计
[m,n,z] = size(ImOriginal);
ImOut = uint8(zeros(m,n,z));
for i = 1:z
    if strcmp(type,'add')
        ImChannel = double(ImOriginal(:,:,i))+eps;
    elseif strcmp(type,'mult')
        ImChannel = log(double(ImOriginal(:,:,i))+eps);
    else
        error('type must be ''add'' or ''mult''');
    end
    ImOut(:,:,i) = EnhanceOneChannel(ImChannel);
end
ImOut = max(min(ImOut,255), 0);
end

function ImOut = EnhanceOneChannel(ImChannel)
% 计算计算单个通道的反射分量
% 1.对全图进行照射分量估计
% 2.减去照射分量
% 3.灰度拉伸
ImChannel = ImChannel./max(ImChannel(:));
ImRetinex = round(exp(ImChannel.*5.54));
ImOut = uint8(ImRetinex);
end

                                                               图像去雾(二)Retinex图像增强算法_第2张图片

                                                                               测试原图

                                                               图像去雾(二)Retinex图像增强算法_第3张图片

                                                                          经典Retinex算法结果

                                                               图像去雾(二)Retinex图像增强算法_第4张图片

                                                                           上述方法结果

从对比中可以看到,对于去除照度,还原图像本身来讲,效果还可以,并且不会在边缘位置产生光晕现象。缺点就是在去除照度分量L过程中,保留的反射分量R我在上述算法中使用归一化后直接进行反变换。这一步的作用可以近似看成去除一个均匀的直流分量,即均匀的照度分量。由于操作都是全局的,这里默认假设了所有位置的照射分量都是相同的,因此在灰度拉伸的时候没有照顾到局部的特性,图像整体亮度偏暗。当然,全局的照度估计对于图像的增强肯定有相当的局限性,其增强效果在色彩的还原和亮度处理等方面还是有一定缺陷的。

个人认为,Retinex算法的关键还是正确的分析了噪声的性质。相信很多人都看到利用基于Retinex的图像水下增强、基于Retinex的图像去雾等等,我也好奇,那就试试吧。大雾图片嘛谁没有,前一阵子大雾天,没事拍了几张照片,终于用上了,请看对比图:

                                                             图像去雾(二)Retinex图像增强算法_第5张图片

                                                                                 有雾原图

                                                             图像去雾(二)Retinex图像增强算法_第6张图片

                                                                        经典Retinex去雾效果

                                                              图像去雾(二)Retinex图像增强算法_第7张图片

                                                                         上述方法去雾效果

还是老规矩,这时候对比试验还是最能说明效果的,为此选了一幅干扰很大的图像。基本上各位要是显示器比较差一点,从原图当中是很难看出大雾后面的东西。从去雾效果来看,上述方法的效果并不比经典算法要差,至少在去雾的效果上,本实验结果从主观上给人的感觉还是不错的。

在上述案例中,最重要的就是正确分析有雾图像的结构,与Retinex理论一开始的核心思想有区别的是,在针对这种加性的干扰时,经典的Retinex算法在处理过程中,其实仅仅是利用其估计加性的干扰分量;当然,抛开Retinex理论对照度、反射率对最终图像形成的核心思想(如图1),后续最重要的就是对这个加性的干扰的估计了。

对于有雾的图像,我们大可以看作透过一块磨砂玻璃去看一幅清晰的图像,这样大家就能很好理解为什么认为在这个案例中,将雾的干扰认为是一个加性的了。诸如后面两个经典的算法,所有的这类算法归根结底就是更好地利用原图像中的像素点去估计原始照度。从上面例程上可以看出,使用一个全局估计对局部的增强是比较差的,如果存在照度不均匀(雾的浓度不均匀),或者背景颜色亮度很高等情况时,处理结果会趋向恶劣,效果比较差。

当然,经典也不是完美,从图中可以看到,经典的算法容易出现光晕效果(蓝色书本文字周围一圈白色)。

 

 

你可能感兴趣的:(去雾)