半年以来的图像去雾总结-图像去雾(一)暗通道去雾

图像去雾最好的算法原型最好的莫过于何凯明博士的论文--好好阅读,必有灵感

在接下来的博客中,我会分步介绍各个图像去雾算法的研究和对比,在这里,首先介绍最经典的何凯明博士的暗通道去雾算法了,后面的博客有关于何博士算法的改进,有其他去雾算法的测试对比。

暗通道去雾算法

暗通道去雾算法,在其他博客都有详细的介绍,在这里我也是借鉴其他各位总结的东西,写点内容。

       一、实验原理

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

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

                                                                                          (1)

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

      暗通道先验的理论指出:

                                                                                                                         (2)

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

                                                                                                 (3)

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

                                                                                   (4)

 如上所述,上标C表示R/G/B三个通道的意思。首先假设在每一个窗口内透射率t(x)为常数,定义它为 \widetilde{t}(x),并且A值已经给定,然后对式(4)两边求两次最小值运算,得到下式:

                (5)

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

                                                                          (6)

 因此,可推导出:

                                                                                                 (7)

 把式(7)带入式(5)中,得到:

                                                                          (8)

 这就是透射率 \widetilde{t}(x) 的预估值。

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

                                                                         (9)

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

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

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

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

     到这一步,我们就可以进行无雾图像的恢复了。由式(3)可知: J = ( I - A)/t + A  ,现在I,A,t都已经求得了,因此,完全可以进行J的计算。当投射图t 的值很小时,会导致J的值偏大,从而使淂图像整体向白场过度,因此一般可设置一阈值T0,当t值小于T0时,令t=T0,本文中所有效果图均以T0=0.1为标准计算。

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

                                                                                          (10)

二、实验步骤

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

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

3、由(9)式算出投射图。

具体代码如下:

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(BA)
                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)]

 三、最终实验结果

可以清楚的看出来,左边的是原图,右边是去雾后的图片,去雾效果还算理想。

另外附上何博士的原文地址:

http://xueshu.baidu.com/s?wd=paperuri%3A%2882db63209f43fcf5add7b429e6b37e23%29&filter=sc_long_sign&tn=SE_xueshusource_2kduw22v&sc_vurl=http%3A%2F%2Fieeexplore.ieee.org%2Fxpls%2Ficp.jsp%3Farnumber%3D5206515&ie=utf-8&sc_us=6975395480982385039

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