基于暗通道去雾的图像处理

# ##西电的数字信号处理大作业 ##具体代码与PPT可前往此处下载:https://download.csdn.net/download/yifantan/72862665

图像处理:针对浓雾天气下拍摄,导致细节无法辨认的图像进行去雾处理,还原更清晰真实的图像。在实际生活中,对大雾天气下的监控系统、航拍、航海以及矿山烟雾等生活场景应用中有着重要意义。 国内外研究现状:图像去雾的研究算法有很多,主要分为两类:图像增强的去雾算法:直方图均衡化(HE)、小波变换、同态滤波;图像复原的去雾算法:暗通道去雾算法,导向滤波的暗通道去雾算法、单幅图像去雾算法、单一图像去雾算法、快速图像恢复算法、贝叶斯去雾算法 (研究现状这里多少有点瞎扯的成分了)

一、背景知识

1.大气散射物理模型 在计算机视觉中,描述有雾图像的模型可以表示为:

I\left( x \right) =J\left( x \right) t\left( x \right) +A\left( 1-t\left( x \right) \right) \,\,    \left( 1 \right) 

I(x)为观察到的有雾图像,J(x)为无雾图像,A是大气光值,为1常数,t(x)为透射率,表示能够到达计算机系统的没有被散射掉的一部分光。 去雾的目的是从有雾图像I(x)中恢复J(x)。 式中关于t(x):

t\left( x \right) =e^{-\beta d\left( x \right)}\,\,    \left( 2 \right) 

其中β表示散射系数,d(x)表示场景深度。 2.暗通道先验 暗通道先验是基于一个假设:在绝大多数非天空的局部区域里,某一些像素总会有至少一个颜色通道具有很低的值。而这个假设是作者基于大量图片的观察得到了。换句话说就是在清晰的无雾图像中,局部图像块至少有一个颜色通道的值非常低,甚至接近于0。 对于一幅无雾图像,其暗通道可以表示为:

J^{dark}=\min _{y\in \varOmega \left( x \right)}\left( \min _{c\in \left( r,g,b \right)}J^c\left( y \right) \right) \,\,    \left( 3 \right) 

其中Jc(y)表示J的任意一个颜色通道,𝛺(x)表示在像素点x的窗口。(注意Jc(y)的c的位置,懒嘿嘿) 根据暗通道先验理论得出:

J^{dark}\rightarrow 0     \left( 4 \right) 

上式(4)的含义是:以像素点x为中心,分别取三个通道窗口Ω内的最小值,然后再取三个通道的最小值作为像素点x的暗通道的值,如下图所示: 在这里插入图片描述 举个例子来看: 在这里插入图片描述 其中图(a)是原图,图(b)是每个像素三通道中的最小值,图(c)是在图(b)的基础上用15x15的最小滤波器滤过后的结果,也就是一张暗通道先验的图片。 实际生活中造成暗原色中低通道值主要有三个因素:a)汽车、建筑物和城市中玻璃窗户的阴影,或者是树叶、树与岩石等自然景观的投影;b)色彩鲜艳的物体或表面,在RGB的三个通道中有些通道的值很低; c)颜色较暗的物体或者表面,例如灰暗色的树干和石头。总之,自然景物中到处都是阴影或者彩色,这些景物的图像的暗原色总是很灰暗的。 举个无雾例子来看: 在这里插入图片描述举个有雾例子来看: 在这里插入图片描述

二、大气光与透射率的估计

1.大气光的估计 在图像中,雾浓度越低,其暗通道图越暗,像素点值越小;雾浓度越高,其暗通道图越亮,像素点值越大,因此,暗通道图可以较好的反映雾浓度信息。经过前人研究,把大气光取值定在图像中雾最不透明区域。 本文中具体对大气光的选取方法为: a)首先在暗通道图中按亮度选取前0.1%的像素。 b)然后在原有雾图像对应的位置上选择亮度最大的点,作为我们的A值 2.透射率的估计 透射率t(x)是一个与图像大小一样的矩阵,矩阵中的每个点都代表了在那处的透射率。 大气光已知,利用大气光对大气散射模型式(1)作归一化处理:

\frac{I_c\left( x \right)}{A^c}=t\left( x \right) \frac{J^c\left( x \right)}{A^c}+1-t\left( x \right) \,\,    \left( 5 \right) 

对(5)式进行两次求最小值运算,得到下式:

\underset{y\in \varOmega \left( x \right)}{\min}\left( \underset{c}{\min}\frac{I^c\left( y \right)}{A^c} \right) =t\left( x \right) \underset{y\in \varOmega \left( x \right)}{\min}\left( \underset{c}{\min}\frac{J^c\left( y \right)}{A^c} \right) +1-t\left( x \right) \,\,     \left( 6 \right) 

A为常数且无雾图像的暗通道先验图像接近于0,所以(6)式等号右边的第一个部分等于0,即:

\underset{y\in \varOmega \left( x \right)}{\min}\left( \underset{c}{\min}\frac{J^c\left( y \right)}{A^c} \right) =0      \left( 7 \right) 

由此(6)式可简化为:

t\left( x \right) =1-\underset{y\in \varOmega \left( x \right)}{\min}\left( \underset{c}{\min}\frac{I^c\left( y \right)}{A^c} \right) \,\,    \left( 8 \right) 

式(8)为透射率t(x)的预估值。然而在现实环境中,往远处眺望时极远处一定有薄雾的存在,所以为了图像的视觉效果,添加了另一个常数w,取值在[0,1],通常设为0.95,来保留一定程度的雾,给人判断远近的感觉。

t\left( x \right) =1-\omega \underset{y\in \varOmega \left( x \right)}{\min}\left( \underset{c}{\min}\frac{I^c\left( y \right)}{A^c} \right) \,\,    \left( 9 \right) 

求解大气光A值和的透射率t(x)后,已可以恢复无雾图像了。但在实际应用中发现,粗略的t(x)值有时会偏小,这会导致恢复的图像过白,整体失真。所以我们需要设置一个最小阈值t0,当t(x)过小时使用t0值来替代,避免失真问题,所以,最终的恢复公式如下:

J\left( x \right) =\frac{I\left( x \right) -A}{\max \left( t\left( x \right) ,t_0 \right)}+A\,\,    \left( 10 \right) 

三、代码仿真与结果

1.主函数计算流程图 在这里插入图片描述 2.暗通道函数

%计算暗通道函数
%c为彩色图像矩阵;m,n为滤波窗口大小
%A为计算的暗通道

function  A=antongdao(c,m,n)
c=im2double(c);
[a,b,~]=size(c);
R1=c(:,:,1);
G1=c(:,:,2);
B1=c(:,:,3);
A=zeros(a,b);
d=A;
for i=1:a
for j=1:b
d(i,j)=min(R1(i,j),G1(i,j));
A(i,j)=min(d(i,j),B1(i,j));
end
end
A=ordfilt2(A,1,ones(m,n));                     %最小值滤波

3.求解大气光照

%求解全局大气光照函数
%A为暗通道
%I1为原彩色图像
%Ac为全局大气光照

function  [Ac]=qjdqgz(A,I1)
I1=im2double(I1);
R1=I1(:,:,1);
G1=I1(:,:,2);
B1=I1(:,:,3);
[a,b]=size(A);
c=ceil(a*b/1000);        %朝正无穷大方向取整,即前1%的个数
r1=zeros(c,1);
g1=zeros(c,1);
b1=zeros(c,1);
m=0.9;
x=1;
d(1,1)=0;
q(1,1)=0;
while size(d,1)<=c
for i=1:a
for j=1:b
if A(i,j)>m && size(d,1)<=c
d(x,1)=i;
q(x,1)=j;
x=x+1;
end
if size(d,1)>c
     break 
end
end
end
if size(d,1)<=c
m=m-0.1;
end
end
for p=1:c
r1(p,1)=R1(d(p,1),q(p,1));
g1(p,1)=G1(d(p,1),q(p,1));
b1(p,1)=B1(d(p,1),q(p,1));
end
Ar=max(max(r1));
Ag=max(max(g1));
Ab=max(max(b1));
Ac=[Ar,Ag,Ab];

4.求解透射率并恢复图像函数

%求解透射率函数及去雾后RGB值
%I1为原彩色图像
%Ac为全局大气光照
%t为透射率
%R1,G1,B1为去雾后的值
function  [t,R1,G1,B1]=tsl(I1,Ac)
[a,b,~]=size(I1);
I1=im2double(I1);
R1=I1(:,:,1);
G1=I1(:,:,2);
B1=I1(:,:,3);
t=zeros(a,b);
d=t;
for i=1:a     %粗透射率
     for j=1:b
   d(i,j)=min(R1(i,j)/Ac(1,1),G1(i,j)/Ac(1,2));
   t(i,j)=1-0.95*min(d(i,j),B1(i,j)/Ac(1,3));      
     end
end
t=imguidedfilter(t);                      %导向滤波

for i=1:a
     for j=1:b
            R1(i,j)=(R1(i,j)-Ac(1,1))./(max(t(i,j),0.1))+Ac(1,1);
            G1(i,j)=(G1(i,j)-Ac(1,2))./(max(t(i,j),0.1))+Ac(1,2);        %求解恢复公式
            B1(i,j)=(B1(i,j)-Ac(1,3))./(max(t(i,j),0.1))+Ac(1,3);
            
     end
end

5.仿真结果 在这里插入图片描述 在这里插入图片描述

四、局限性分析与心得体会

1.局限性 ①暗通道先验是一种统计的结果,是对大量户外无雾照片的统计结果,如果目标场景本身就和大气光类似,比如雪地、白色背景墙、大海等,则由于前提条件就不正确,因此一般无法获得满意的效果,而对于一般的风景照片这个算法能处理的不错。 ②在细化透射率的方法上,何恺明博士提出的软抠图法对得到的粗透射率进行细化。但由于这个方法时间和内存花费比较大,所以后来作者又使用指导性滤波器进行细化粗透射图。效果上指导性滤波要稍差于软抠图法,但在时间和内存花费上具有明显优势,本算法使用指导性滤波器进行细化粗透射率。 2.心得体会 最初选题时想做的是图像的频域去噪,通过离散傅里叶变化到频域,再利用低通滤波器等去噪,后再逆变换回时域;在查询资料的过程中了解到数字图像的频率意义等,后来资料查的较多时发现图像的去噪方法较多,认为不适合作为选题,后来偶然间看到了何恺明博士的暗通道去雾,虽感觉与课程关联度并不太大,但其帮助理解数字图像处理,且算法较为新颖高效便将此作为选题。 在代码过程中,充分了解认识了彩色图像的内涵,也在做求解大气光照的函数部分遇到困难,通过查找资料与组员讨论得以解决,通过这次大作业认识到数字信号处理在数字图像方面的具体应用,增强了解决困难的能力。

五、参考文献

[1] He K , Jian S , Fellow, et al. Single Image Haze Removal Using Dark Channel Prior[J]. IEEE Transactions on Pattern Analysis & Machine Intelligence, 2011, 33(12):2341-2353. [2] 朱娜. 基于暗原色先验的图像去雾技术研究[D]. 电子科技大学, 2016.

##具体代码与PPT可前往此处下载:https://download.csdn.net/download/yifantan/72862665


本文章使用limfx的vscode插件快速发布