本文参考何凯明大神的暗通道去雾算法《Single Image Haze Removal Using Dark Channel Prior》和一些相关的csdn上的博客,并附上自己编写的代码
采用暗通道先验去雾算法中模糊图像(有雾图像)模型被描述成:
I(x)是我们观察到的图像,即有雾的图像,J(x)是我们要恢复的图像,即去雾之后的图像,
A是全局大气光强,t是媒介传播系数。这个算法的目的就是从I、A、t中得到J。目前我们只知道I(x),需要求出A和t
在A和t之前,我们引入暗通道先验:
一个图像的暗通道可以表示为:
而无雾的图像,即我们要恢复的图像的暗通道数值趋于0
因此我们把这个先验条件带入模糊图像模型
我们可以得到:
由此我们得到了t,因为这样在视觉上看起来是不自然的,我们修正了这个公式:
其中w=0.95,最终在把t,带入模型,可以得到
以下是matlab代码:
求暗通道的部分:先求RGB三个通道的最小值,再进行最小值滤波
%% dark_channel
I1=zeros(m,n);
for i=1:m
for j=1:n
I1(i,j)=min(I(i,j,:));
end
end
Id = ordfilt2(I1,1,ones(wh,wh),'symmetric');
求大气光强A的部分:暗通道前0.1%最大值的值
%% A
dark_channel = Id;
A_temp = max(max(dark_channel))*0.999;
A=A_temp;
完整代码:
clc
clear all
close all
Im=imread('Ex_ColorEnhance.png');
I=double(Im)/255;
[m,n]=size(I,1,2);
subplot(1,2,1);
imshow(I,[]);title('Original image')
w0=0.95;
wh=3;
%% dark_channel
I1=zeros(m,n);
for i=1:m
for j=1:n
I1(i,j)=min(I(i,j,:));
end
end
Id = ordfilt2(I1,1,ones(wh,wh),'symmetric');
%% A
dark_channel = Id;
A_temp = max(max(dark_channel))*0.999;
A=A_temp;
tr= 1 - w0 * Id/ A;
%% out
t0=0.1;
t1 = max(t0,tr);
I_out=zeros(m,n,3);
for k=1:3
for i=1:m
for j=1:n
I_out(i,j,k)=(I(i,j,k)-A)/t1(i,j)+A;
end
end
end
subplot(1,2,2);
imshow(I_out,[]);title('Improved image')
效果图:
也可以用下面的链接,下载完整代码和图片
https://download.csdn.net/download/hongliyu_lvliyu/18592365