美学原理因中值滤波或双方滤波模式的图像去雾效果的钻。

一、前言  

  实际上很久从前,当自身正接触图像去雾技术时,起始实现的凡因中值滤波的图像去雾,并且也发早晚的意义,在本人的Imageshop的合并软件面临之去雾方案就是是以此的实现,可是那些效果没本文好。

   
 而基于双方滤波的方案,也是死已经耳闻了,前不久时有发生心上人传被自己同首国内的互相滤波去雾的舆论,总体思路及基于中值的切近,想想干脆将当时简单个在同开只比吧。

其次、算法的流水线

     算法的无限基础之法则仍旧基于大气散射模型的,即:

                   
 美学原理 1

  已了然条件就是输入图像I(X),求J(x);

   
 在参考杂谈同样种就幅图像去雾方法遭遇凡透过中值滤波的不二法门来去雾的,而舆论遵照双方滤波的实时图像去雾技术研商选取了两者滤波,倘使您而实现代码,可能用少首杂谈做起来看,因为以舆论1挨的叙述没有称理解什么通过取得的雾浓度数据来取得无雾的图像。

   
 简单的吧,算法的流程可讲述如下:

  1、定义F(X)=A(1-t(x)),称之为大气光幕或者为雾浓度。

   
 2、计算美学原理 2,并接纳和何硕士杂谈中好像之主意测算全局大气光值A。

   
 3、计算美学原理 3,即对M(x)举行着值滤波。

   
 4、计算美学原理 4,注意式子中之相对值。

   
 5、计算美学原理 5,式中P为操纵去雾程度之因子,取值范围[0,1]。

   
 6、通过式子美学原理 6获取去雾后的图像。

   
 下边的洋洋算式是由不同随笔里截图的,因而表明上有点前后未雷同,但未影响高手明白其意思。

   
 假诺是行使双边滤波算子,则步骤3与4面临的median运算符需修改也bilaterfilter,其他的手续一样。

  算法的规律我摆不清,反正看之愈发多逾迷糊了。

其三、算法的职能

     
算法的成效依然小意外,有些图得到了一定不错的遵从。

 美学原理 7  美学原理 8  美学原理 9

 美学原理 10  美学原理 11  美学原理 12

 美学原理 13  美学原理 14  美学原理 15

 美学原理 16  美学原理 17  美学原理 18

 美学原理 19  美学原理 20  美学原理 21

 美学原理 22  美学原理 23  美学原理 24

          美学原理, 原图                          
   去雾图                          
 对应之恢宏光幕

 
 这里的大度光幕和何凯明的论文中之透射率图无是与一个定义,由此不有所可比性。

 
 于大方光幕的公式中,我们看来有全局大气光A的影响,可是上述总括F(X)的长河着实无涉嫌到A,分外无语啊。

 
 从效能及看,我所列举的这么些事例都或不错的,特别是率先帧图,用何凯明的暗通道我向来尚未调出这种功能。

 
 上述都是故着值滤波做的效用,在一部分图像对应大气光幕图及足见见,图像的边缘处暴发局部小圆弧,这多少个都是矩形半径中值滤波的分明划痕,而因双方滤波的本身啊行过,并从未如参考随想2说的那么有稍许立异,感觉相互互相,而且有些图还会师世突变,因而自觉得写这多少个散文纯粹是为着发杂谈。 

季、代码实现细节

   
 在代码实现上,个人感觉没有啊难题,先要暗通道,然后便是几单中值滤波或者是二者滤波,求全局大气光的经过还关系到最好小值滤波,紧要的代码如下:

void _stdcall HazeRemovalBasedOnMedianBlur(unsigned char * Scan0, int Width,int Height,int Stride,int DarkRadius,int MedianRadius,int P)
{
    int  X, Y, Diff,Min,F;
    unsigned char* Pointer, *DarkP, *FilterP,* FilterPC;
    unsigned char * DarkChannel = (unsigned char*)malloc(Width * Height);
    unsigned char * Filter = (unsigned char*)malloc(Width * Height);
    unsigned char * FilterClone = (unsigned char*)malloc(Width * Height);

    for (Y = 0; Y < Height; Y++)
    {
        Pointer = Scan0 + Y * Stride;
        DarkP = DarkChannel + Y * Width;             // 由实际图像计算得到的图像暗通道     
        for (X = 0; X < Width; X++)
        {
            Min = *Pointer;
            if (Min > *(Pointer + 1)) Min = *(Pointer + 1);
            if (Min > *(Pointer + 2)) Min = *(Pointer + 2);
            *DarkP = (unsigned char)Min;
            DarkP++;
            Pointer += 3;
        }
    }
    memcpy(Filter, DarkChannel, Width * Height);                        // 求全局大气光A时会破坏DarkChannel中的数据

    MinValue(DarkChannel, Width, Height,Width,DarkRadius);                // 求取暗通道值

    // 利用暗通道来估算全局大气光值A
    int Sum, Value,Threshold = 0;
    int SumR = 0, SumG = 0, SumB = 0, AtomR, AtomB, AtomG, Amount = 0;
    int* Histgram = (int*)calloc(256 , sizeof(int));    
    for (Y = 0; Y < Width * Height; Y++) Histgram[DarkChannel[Y]]++;
    for (Y = 255, Sum = 0; Y >= 0; Y--)
    {
        Sum += Histgram[Y];
        if (Sum > Height * Width * 0.01)
        {
            Threshold = Y;                                        // 选取暗通道值中前1%最亮的像素区域为候选点
            break;
        }
    }
    AtomB = 0; AtomG = 0; AtomR = 0;
    for (Y = 0, DarkP = DarkChannel; Y < Height; Y++)
    {
        Pointer = Scan0 + Y * Stride;
        for (X = 0; X < Width; X++)
        {
            if (*DarkP >= Threshold)                            //    在原图中选择满足候选点的位置的像素作为计算全局大气光A的信息                        
            {
                SumB += *Pointer;
                SumG += *(Pointer + 1);
                SumR += *(Pointer + 2);
                Amount++;
            }
            Pointer += 3;
            DarkP++;
        }
    }
    AtomB = SumB / Amount;
    AtomG = SumG / Amount;
    AtomR = SumR / Amount;

    memcpy(DarkChannel,Filter, Width * Height);                        // 恢复DarkChannel中的数据
    MedianBlur(Filter,Width,Height,Width,MedianRadius,50);          // 步骤1:使用中值滤波平滑,这样处理的重要性是在平滑的同时保留了图像中的边界部分,但是实际这里用中值滤波和用高斯滤波效果感觉差不多
    memcpy(FilterClone, Filter, Width * Height);

    DarkP = DarkChannel;
    FilterP = Filter;
    for (Y = 0; Y < Height * Width; Y++)              //利用一重循环来计算提高速度
    {
        Diff = *DarkP - *FilterP;                    //通过对|DarkP -FilterP |执行中值滤波来估计的局部标准差,这样可以保证标准差估计的鲁棒性
        if (Diff < 0) Diff = -Diff;
        *FilterP = (unsigned char)Diff;
        DarkP++;
        FilterP++;
    }
    MedianBlur(Filter,Width,Height,Width,MedianRadius,50);

    FilterPC = FilterClone;
    FilterP = Filter;
    for (Y = 0; Y < Height * Width; Y++)
    {
        Diff = *FilterPC - *FilterP;                    // 步骤2:然后考虑到有较好对比度的纹理区域可能没有雾, 这部分区域就不需要做去雾处理
        if (Diff < 0) Diff = 0;                            // 这里可以这样做是因为在最后有个max(....,0)的过程,
        *FilterP = (unsigned char)Diff;
        FilterPC++;
        FilterP++;
    }

    DarkP = DarkChannel;
    FilterP = Filter;

    for (Y = 0; Y < Height * Width; Y++)
    {
        Min = *FilterP * P / 100;
        if (*DarkP > Min) 
            *FilterP = Min;                                // 获得满足约束条件的大气光幕
        else
            *FilterP = *DarkP;
        DarkP++;
        FilterP++;
    }

    FilterP = Filter;
    for (Y = 0;Y < Height; Y++)
    {
        Pointer = Scan0 + Y * Stride;
        for (X = 0; X < Width; X++)
        {
            F = *FilterP++;
            if (AtomB != F) 
                Value = AtomB *(*Pointer - F) /( AtomB - F);
            else
                Value=*Pointer;
            *Pointer++ = Clamp(Value);
            if (AtomG != F) 
                Value =  AtomG * (*Pointer - F) /( AtomG-F);
            else
                Value =  *Pointer;
            *Pointer++ = Clamp(Value);
            if (AtomR != F) 
                Value =  AtomR *(*Pointer - F) /( AtomR-F);
            else
                Value =  *Pointer;
            *Pointer++ = Clamp(Value);
        }
    }
    free(Histgram);
    free(Filter);
    free(DarkChannel);
    free(FilterClone);
}

   关于中值滤波或者两者滤波的飞算法,可以当自我博客中找到大量之相干音讯。

   
 在次的耗时达到,重要仍然2次中值处理及,借助于C++的片优化(比如内嵌SSE代码,C#开不交)中值的速吗一定快了,我之所以1024*768的灰度图测试耗时大致为60ms(未考虑用多线程,因为好程序用几近线程编码上会复杂不少),对彩色图用这种艺术去雾,I3CPU上1024*768底总耗时盖为140ms,想只要实时,换换I7的CPU试试吧(传说被我的这篇实时错过雾的篇章的算法在I3上20ms,I7上起测试声明只设3到4ms)。

   
 由于算法的尾声一步的公式问题,在一些参数境况下图像会产出黑快或者白块,如今欠问题绝非解决。
有趣味对改算法举办更加测试的同班可协调研讨下。

     相关测试代码下载:

   
  http://files.cnblogs.com/Imageshop/HazeRemovalBasedOnMedianBlur.rar

     美学原理 25

 美学原理 26

*********************************作者:
laviewpbt   时间: 2013.12.5   联系QQ:  33184777
 转载请保留本行音信*************************