基于暗通道优先算法的去雾应用Matlab

理论见博客:

http://www.cnblogs.com/changkaizhao/p/3266798.html

http://www.cnblogs.com/Imageshop/p/3281703.html

由于课程作业的需要,仅仅进行简单研究。

1.主函数

clc;
clear all;
close all;
J = imread('4.jpg');
J = double(J);
J = J ./255 ;
figure(1); imshow(J); 
%% 求暗通道图像 Jdark = min(min());
Jdark = Idark(J);
figure(2);imshow(Jdark,[]);

%%
% 注意:何凯明使用了soft matting方法对得到的粗透射率Jt进行细化 
%       本代码采用梯度导向滤波实现
Jdark = gradient_guidedfilter(Jdark,Jdark, 0.04);
figure(3);imshow(Jdark,[]);
%% 大气物理模型 J = I*t + A*(1-t)  【直接衰减项】+【大气光照】
% 透射率 t与深度的关系 t=exp(-a*depth)
w = 0.95;         %雾的保留系数
Jt = 1 - w*Jdark; %求解透射率

%% 求解全局大气光照
% 1.首先对输入的有雾图像I求解其暗通道图像Jdark。
% 2.选择Jdark总像素点个数千分之一(N/1000)个最亮的像素点,记录像素点(x,y)坐标
% 3.根据点的坐标分别在原图像J的三个通道(r,g,b)内找到这些像素点并加和得到(sum_r,sum_g,sum_b).
% 4.Ac=[Ar,Ag,Ab]. 其中Ar=sum_r/N;   Ag=sum_g/N;   Ab=sum_b/N.
[m,n,~] = size(J);
N = floor( m*n./1000 );
MaxPos = [0,0]; % 初始化
for i=1:1:N
    MaxValue = max(max(Jdark));
    [x,y] = find(Jdark==MaxValue);
    Jdack(Jdark==MaxValue) = 0; %最大值置零,寻找下一次次大值
    %检查长度
    MaxPos = vertcat(MaxPos,[x,y]);
    Cnt = length(MaxPos(1));
    if Cnt > N
        break;
    end
end
MaxPosN = MaxPos(2:N+1,:);

Rsum = 0;  Jr = J(:,:,1);
Gsum = 0;  Jg = J(:,:,2);
Bsum = 0;  Jb = J(:,:,3);
for j=1:1:N
    Rsum = Rsum + Jr(MaxPosN(j,1),MaxPosN(j,2));
    Gsum = Gsum + Jg(MaxPosN(j,1),MaxPosN(j,2));
    Bsum = Bsum + Jb(MaxPosN(j,1),MaxPosN(j,2));
end

Ac = [Rsum/N, Gsum/N, Bsum/N];

%% 求解清晰的图像
% 根据 J = I*t + A*(1-t)   I = (J-A)/Jt + A
Iorg = zeros(m,n,3);
for i = 1:1:m
    for j = 1:1:n
        for k = 1:1:3
        Iorg(i,j,k) = (J(i,j,k)-Ac(k)) ./ Jt(i,j) + Ac(k);
        end
    end
end
figure(4); imshow(Iorg,[]);

2.暗通道函数

function Jdark = Idark( I )
% output: Jdark = min(min(r),min(g),min(b));
Wnd = 3;
Ir = I(:,:,1);
Ig = I(:,:,2);
Ib = I(:,:,3);
%% 图像拓展
[m,n,~] = size(I);
Irr = zeros(m+Wnd-1, n+Wnd-1); 
Irr((Wnd-1)/2 : m+(Wnd-1)/2-1 , (Wnd-1)/2 : n+(Wnd-1)/2-1 ) = Ir;
Igg = zeros(m+Wnd-1, n+Wnd-1); 
Igg((Wnd-1)/2 : m+(Wnd-1)/2-1 , (Wnd-1)/2 : n+(Wnd-1)/2-1 ) = Ig;
Ibb = zeros(m+Wnd-1, n+Wnd-1); 
Ibb((Wnd-1)/2 : m+(Wnd-1)/2-1, (Wnd-1)/2 : n+(Wnd-1)/2-1 ) = Ib;
%% 暗通道
for i=1:1:m
    for j=1:1:n
        Rmin = min(min ( Irr(i:i+Wnd-1, j:j+Wnd-1) ));
        Gmin = min(min ( Igg(i:i+Wnd-1, j:j+Wnd-1) ));
        Bmin = min(min ( Ibb(i:i+Wnd-1, j:j+Wnd-1) ));
        Jdark(i,j) = min(min(Rmin,Gmin),Bmin);
    end
end

end

3.基于梯度的指导滤波器

function q = gradient_guidedfilter(I, p, eps)  
%   GUIDEDFILTER   O(1) time implementation of guided filter.  
%  
%   - guidance image: I (should be a gray-scale/single channel image)  
%   - filtering input image: p (should be a gray-scale/single channel image)  
%   - regularization parameter: eps  
  
r=16;  
[hei, wid] = size(I);  
N = boxfilter(ones(hei, wid), r); % the size of each local patch; N=(2r+1)^2 except for boundary pixels.  
  
mean_I = boxfilter(I, r) ./ N;  
mean_p = boxfilter(p, r) ./ N;  
mean_Ip = boxfilter(I.*p, r) ./ N;  
cov_Ip = mean_Ip - mean_I .* mean_p; % this is the covariance of (I, p) in each local patch.  
  
mean_II = boxfilter(I.*I, r) ./ N;  
var_I = mean_II - mean_I .* mean_I;  
  
%weight  
epsilon=(0.001*(max(p(:))-min(p(:))))^2;  
r1=1;  
  
N1 = boxfilter(ones(hei, wid), r1); % the size of each local patch; N=(2r+1)^2 except for boundary pixels.  
mean_I1 = boxfilter(I, r1) ./ N1;  
mean_II1 = boxfilter(I.*I, r1) ./ N1;  
var_I1 = mean_II1 - mean_I1 .* mean_I1;  
  
chi_I=sqrt(abs(var_I1.*var_I));      
weight=(chi_I+epsilon)/(mean(chi_I(:))+epsilon);       
  
gamma = (4/(mean(chi_I(:))-min(chi_I(:))))*(chi_I-mean(chi_I(:)));  
gamma = 1 - 1./(1 + exp(gamma));  
  
%result  
a = (cov_Ip + (eps./weight).*gamma) ./ (var_I + (eps./weight));   
b = mean_p - a .* mean_I;   
  
mean_a = boxfilter(a, r) ./ N;  
mean_b = boxfilter(b, r) ./ N;  
  
q = mean_a .* I + mean_b;   
end  

function imDst = boxfilter(imSrc, r)  
  
%   BOXFILTER   O(1) time box filtering using cumulative sum  
%  
%   - Definition imDst(x, y)=sum(sum(imSrc(x-r:x+r,y-r:y+r)));  
%   - Running time independent of r;   
%   - Equivalent to the function: colfilt(imSrc, [2*r+1, 2*r+1], 'sliding', @sum);  
%   - But much faster.  
  
[hei, wid] = size(imSrc);  
imDst = zeros(size(imSrc));  
  
%cumulative sum over Y axis  
imCum = cumsum(imSrc, 1);  
%difference over Y axis  
imDst(1:r+1, :) = imCum(1+r:2*r+1, :);  
imDst(r+2:hei-r, :) = imCum(2*r+2:hei, :) - imCum(1:hei-2*r-1, :);  
imDst(hei-r+1:hei, :) = repmat(imCum(hei, :), [r, 1]) - imCum(hei-2*r:hei-r-1, :);  
  
%cumulative sum over X axis  
imCum = cumsum(imDst, 2);  
%difference over X axis  
imDst(:, 1:r+1) = imCum(:, 1+r:2*r+1);  
imDst(:, r+2:wid-r) = imCum(:, 2*r+2:wid) - imCum(:, 1:wid-2*r-1);  
imDst(:, wid-r+1:wid) = repmat(imCum(:, wid), [1, r]) - imCum(:, wid-2*r:wid-r-1);  
end  

4.输出结果

基于暗通道优先算法的去雾应用Matlab_第1张图片

5.参考文献

[1] He K, Sun J, Tang X. Single image haze removal using dark channel prior[C]// Computer Vision and Pattern Recognition, 2009. CVPR 2009. IEEE Conference on. IEEE, 2009:1956-1963.
[2] Kou F, Chen W, Wen C, et al. Gradient Domain Guided Image Filtering.[J]. Image Processing IEEE Transactions on, 2015, 24(11):4528-4539.

你可能感兴趣的:(图像处理,目标跟踪,OpenCV)