暗通道图像去雾

一、          实验原理

在绝大多数非天空的局部区域里,某一些像素总会有至少一个颜色通道有很低的值。换言之,该区域光强度的最小值是个很小的数。

  我们给暗通道一个数学定义,对于任意的输入图像J,其暗通道可以用下式表达:

clip_image002[9]

      式中Jc表示彩色图像的每个通道 Ω(x)表示以像素X为中心的一个窗口。 

   式(5)的意义用代码表达也很简单,首先求出每个像素RGB分量中的最小值,存入一副和原始图像大小相同的灰度图中,然后再对这幅灰度图进行最小值滤波,滤波的半径由窗口大小决定,一般有WindowSize = 2 * Radius + 1;         

      暗通道先验的理论指出:

clip_image004[9]

     实际生活中造成暗原色中低通道值主要有三个因素:a)汽车、建筑物和城市中玻璃窗户的阴影,或者是树叶、树与岩石等自然景观的投影;b)色彩鲜艳的物体或表面,在RGB的三个通道中有些通道的值很低(比如绿色的草地/树/植物,红色或黄色的花朵/叶子,或者蓝色的水面);c)颜色较暗的物体或者表面,例如灰暗色的树干和石头。总之,自然景物中到处都是阴影或者彩色,这些景物的图像的暗原色总是很灰暗的。

首先,在计算机视觉和计算机图形中,下述方程所描述的雾图形成模型被广泛使用:

clip_image006[9]

其中,I(X)就是我们现在已经有的图像(待去雾的图像),J(x)是我们要恢复的无雾的图像,A是全球大气光成分, t(x)为透射率。现在的已知条件就是I(X),要求目标值J(x),显然,这是个有无数解的方程,因此,就需要一些先验了。

  将式(1)稍作处理,变形为下式:

clip_image008[9]

    如上所述,上标C表示R/G/B三个通道的意思。

    首先假设在每一个窗口内透射率t(x)为常数,定义他为clip_image010[14],并且A值已经给定,然后对式(7)两边求两次最小值运算,得到下式:

clip_image012[9]

    上式中,J是待求的无雾的图像,根据前述的暗原色先验理论有:

clip_image014[9]

     因此,可推导出:

clip_image016[9]

    把式(10)带入式(8)中,得到:

clip_image018[9]

    这就是透射率clip_image010[15]的预估值。

    在现实生活中,即使是晴天白云,空气中也存在着一些颗粒,因此,看远处的物体还是能感觉到雾的影响,另外,雾的存在让人类感到景深的存在,因此,有必要在去雾的时候保留一定程度的雾,这可以通过在式(11)中引入一个在[0,1] 之间的因子,则式(11)修正为:

clip_image020[9]

     本文中所有的测试结果依赖于:  ω=0.95

     上述推论中都是假设全球大气光A值时已知的,在实际中,我们可以借助于暗通道图来从有雾图像中获取该值。具体步骤如下:

     1 从暗通道图中按照亮度的大小取前0.1%的像素。

         2 在这些位置中,在原始有雾图像I中寻找对应的具有最高亮度的点的值,作为A值。

     到这一步,我们就可以进行无雾图像的恢复了。由式(1)可知:  J = ( I - A)/t + A  ,现在I,A,t都已经求得了,因此,完全可以进行J的计算。

     当投射图t 的值很小时,会导致J的值偏大,从而使淂图像整体向白场过度,因此一般可设置一阈值T0,当t值小于T0时,令t=T0,本文中所有效果图均以T0=0.1为标准计算。

     因此,最终的恢复公式如下:

clip_image022[9]

 

二、实验步骤

1、找出每个像素的RGB三通道的最小值、形成图像的暗通道图像。

2、在暗通道图片中每个像素的周围15*15的矩形中找像素最小的值,作为该像素的值。

3、由12式算出投射图。

具体代码如下:

void dark_channel(unsigned char* des,const unsigned char* img,int width,int height)

{

         int A = 0;

         for(int y = 0; y < height; y++)

                   {

                            for(int x = 0; x < width; x++)

                            {

                                     int B = img[y * width * 3 + x * 3 + 0];

                                     int G = img[y * width * 3 + x * 3 + 1];

                                     int R = img[y * width * 3 + x * 3 + 2];

                                     if(B<G)

                                               des[y * width + x]=B;

                                     else

                                               des[y * width + x]=G;

                                     if(R<des[y * width + x])

                                               des[y * width + x]=R;

                            }

                   }

         for(int y = 0; y < 5; y++)

                   {

                            for(int x = 0; x < width; x++)

                            {

                                               if(des[y * width + x]>A)

                                                        A=des[y * width + x];

                            }

                   }                

         int patch= 6;

         printf("A的值%d",A);

         double w=0.95*A/255;

         unsigned char* ocl = new unsigned char[width * height];

         memcpy(ocl,des,width * height);

         for(int y = patch; y < height-patch; y++)

                   {

                            for(int x = patch; x < width-patch; x++)

                            {

                                     for(int i = -patch; i < patch+1; i++)

                                     {

                                               for(int j = -patch; j < patch+1; j++)

                                               {

                                                        if(des[(y + i) * width + (x + j)]<ocl[y * width + x])

                                                                 ocl[y * width + x]=des[(y + i) * width + (x + j)];

                                               }

                                     }

                                     ocl[y * width + x]=int(255-w*ocl[y * width + x]);

                            }

                   }

         memcpy(des,ocl,width * height);

}

二、          实验结果

clip_image024[9]clip_image026[9]

posted @ 2016-03-11 10:32  HUSTLX  阅读(1073)  评论(0编辑  收藏  举报