基于暗通道的图像去雾

该算法基于雾图像成像模型:雾图像成像模型
其中,I(X)就是待去雾的图像,J(x)是我们要恢复的无雾的图像,A是环境光, t(x)为透射率。现在的已知I(X),求目标值J(x)。其中环境光A的计算,参考暗通道去雾算法。定义F(x,y)为图像的雾浓度,对应于模型中的A(1-t(x))。

计算F(x,y)

  第一步:

function SD = MyCloud( IM )
%MYCLOUD Summary of this function goes here
%   Detailed explanation goes here

row=30;
line=30;
p=0.2;




[h, w, c] = size(IM);

%获取原图三通道
R= IM(:,:,1);
G= IM(:,:,2);
B= IM(:,:,3);
%获取原图三通道结束



%每个像素取三通道最小值
for i=1:h
    for j=1:w
        if R(i,j)<G(i,j)
            if R(i,j)<B(i,j)
                M(i,j)=R(i,j);
            else
                M(i,j)=B(i,j);
            end
        else
            if G(i,j)<B(i,j)
                M(i,j)=G(i,j);
            else
                M(i,j)=B(i,j);
            end
        end
    end
end

这里的IM为传入参数,即读取的原图,其中h,w,c分别为行数、列数和通道数。

用M记录每个点三通道的最小值

 

第二步:

%将M中值滤波
Am=medfilt2(M,[row,line]);
%Am=M;

将M中值滤波,Am为中值滤波以后的结果,平滑的同时保留M的边缘信息。

 

第三步:

for i=1:h
    for j=1:w
        if Am(i,j)>M(i,j)
         temp(i,j)=Am(i,j)-M(i,j);   
        else
         temp(i,j)=M(i,j)-Am(i,j);
        end
        %temp(i,j)=abs(Am(i,j)-M(i,j));
    end
end

计算|Am(x,y)-M(x,y)|,将结果存在temp里

 

median=medfilt2(temp,[row,line]);

将temp中值滤波,结果存在median。

%计算B(x,y)
for i=1:h
    for j=1:w
        B(i,j)=Am(i,j)-median(i,j);
    end
end
  • 计算B(x,y),B(x,y)=Am(x,y)-median(|Am(x,y)-M(x,y)|)。考虑到有较好对比度的纹理区域可能没有雾,这部分区域就不需要做去雾处理,因此用Am(x,y)减去M(x,y)的局部标准差;通过对|Am(x,y)-M(x,y)|执行中值滤波来估计M(x,y)的局部标准差,这样可以保证标准差估计的鲁棒性,比如在深度大致相当的区域中突然出现一个小的前景目标的情况下,使用这种方法估计雾浓度可以避免在小目标周围保留一定量的雾。

第四步:

%F=max(min(p*B,M),0);
for i=1:h
    for j=1:w
        F(i,j)=max(min(p*B(i,j),M(i,j)),0);
    end
end
  • 计算F(x,y)=max(min(p*B(x,y),M(x,y)),0),p是控制去雾能力的参数,介于0~1之间,值越大去雾能力越强。

这里用p*B与M之间的最小值跟0比是为了防止有负数的情况产生,如果结果比0小则取0.

 

第五步:

Dark=MyDark( IM ,h, w, c);

具体MyDark函数怎么运行我会在另一篇博客中详细介绍,这里只需要知道他是返回的暗通道图就可以了

获取IM的暗通道图存在Dark中

%countDark为0.1%的点的个数
countDark=floor(h*w/1000);

%IMtoGray为原图的灰度图像
IMtoGray=rgb2gray(IM);

CopyDark=Dark;
%ic矩阵横坐标存的是亮点的序号, Dcoordinate存亮点的位置
Dcoordinate=zeros(floor(countDark/1),1);
for ic=1:countDark
    temp=find(CopyDark==max(max(CopyDark)));
    Dcoordinate(ic,1)=temp(1,1);
    CopyDark(temp(1,1))=0;
end

将暗通道图中最亮的0.1%的点的位置记录下来。

LuvIM=colorspace('Luv<-RGB',IM);

  LightIM=zeros(floor(countDark/1),1);
for ic=1:countDark
    x=ceil(Dcoordinate(ic,1)/w);
    y=rem(Dcoordinate(ic,1),w);
    if y<1
        y=w;
    end
   
    LightIM(ic,1)=LuvIM(x,y,1);
end

将原图转换成LUV图,记录这千分之一个点的亮度值,

J=LuvIM;
A=max(max(LightIM));

取这中间最大的亮度值为A

第六步:

根据公式:照片获得去雾后的图像。

 

posted @ 2015-05-09 01:32  PHPer_Wu  阅读(1209)  评论(0编辑  收藏  举报