暗通道先验
暗通道先验是基于如下观察,在户外的无雾图像中,在大部分非天空区域,至少有一个通道值是很小一个数或趋近于零。因此,对任意一幅图
J
J
J,给出暗通道
J
d
a
r
k
J^{dark}
Jdark的表示:
(1)
J
d
a
r
k
(
X
)
=
min
y
∈
Ω
(
x
)
(
min
c
∈
{
r
,
g
,
b
}
J
c
(
Y
)
)
,
J^{dark}(X)=\min _{y\in \Omega(x)}(\min _{c\in \{r, g, b\}}J^c(Y)),\tag 1
Jdark(X)=y∈Ω(x)min(c∈{r,g,b}minJc(Y)),(1)
其中两个最小是各通道最小,局部窗口最小。即首先对图像每个像素取三通道中最小值,得到一个单通道图,然后对这个单通道图作最小值滤波就可以得到暗通道图
J
d
a
r
k
J^{dark}
Jdark。
作者将造成这个现象的原因归结为以下三点:
- 各类物体的阴影,玻璃
- 彩色物体表面,如花草树木,蓝色的水面
- 黑色物体表面,如树干,石头等
正因为自然界总是充满了彩色和阴影,就导致了图像暗通道总是很暗。为了验证这个先验知识,作者统计了大量图片,发现基本都符合这个先验。以下是几幅680*1024的风景图在不同大小滤波窗口下的暗通道图:
以上图像基本都符合暗通道先验,由此可见暗通道的普遍性。在暗通道先验的基础上,就可以进行去雾算法的推导。
雾模型分析
在计算机视觉和计算机图形领域,一个常用来描述有雾图像的公式表达为:
(2)
I
(
x
)
=
J
(
x
)
t
(
x
)
+
A
(
1
−
t
(
x
)
)
,
I(x)=J(x)t(x)+A(1-t(x)),\tag2
I(x)=J(x)t(x)+A(1−t(x)),(2)其中,
I
I
I表示有雾图像,
J
J
J是要恢复的无雾的图像,
A
A
A是全球大气光成分,
t
(
x
)
t(x)
t(x)为透射率。
在这里主要剖析一下这个式子。对这个式子,本身的理解,大气光成分和图像中的景物本身就是真实存在的。晴天和雾天的区别只是大气光成分的多少,表达在这个式子里就是透射率。晴天的时候大气光成分少,物体反射光的透射率很高,几乎让人感受不到大气光成分的存在。雾天则相反。
放在PS中理解,该模型几乎就是两个图层在不同透明度下的叠加。可以设透明度为
α
\alpha
α。叠加后的图像为
I
=
α
I
1
+
(
1
−
α
)
I
2
I=\alpha I_1+(1-\alpha)I_2
I=αI1+(1−α)I2因此,我们假设最大大气光成分为255,可以通过设置不同的透射率来产生不同的有雾图像,同样用上述的图片作实验。
不过,由于人为选定的
t
(
x
)
t(x)
t(x)在每个像素上都是一致的,所以会丢失景深的感觉。但是已经足以说明雾的生成,和去雾的思路。我们已知雾图,由式(2)去求解无雾的图像。同时,我们用无雾图的暗通道和人为生成
t
(
x
)
=
0.5
t(x)=0.5
t(x)=0.5的雾图暗通道进行对比。
基于暗通道的去雾算法
首先假设大气光成分A已知。去雾模型(2)可以化为以下方程:
(3)
I
c
(
x
)
A
c
=
t
(
x
)
J
c
(
x
)
A
c
+
1
−
t
(
x
)
.
\frac{I^c(x)}{A^c}=t(x)\frac{J^c(x)}{A^c}+1-t(x).\tag3
AcIc(x)=t(x)AcJc(x)+1−t(x).(3)上标
c
c
c即表示r,g,b三通道。
进一步假设每个滤波窗口内的透射率
t
(
x
)
t(x)
t(x)是常数,记为
t
ˉ
(
x
)
.
\bar t(x).
tˉ(x).然后对方程两边同时计算暗通道,即作两次最小值运算,可得下式:
(4)
min
y
∈
Ω
(
x
)
(
min
c
I
c
(
y
)
A
c
)
=
t
ˉ
(
x
)
min
y
∈
Ω
(
x
)
(
min
c
J
c
(
y
)
A
c
)
+
1
−
t
ˉ
(
x
)
.
\min_{y\in \Omega(x)}(\min_c\frac{I^c(y)}{A^c})=\bar t(x)\min_{y\in \Omega (x)}(\min_c\frac{J^c(y)}{A^c})+1-\bar t(x).\tag4
y∈Ω(x)min(cminAcIc(y))=tˉ(x)y∈Ω(x)min(cminAcJc(y))+1−tˉ(x).(4)因为
t
ˉ
(
x
)
\bar t(x)
tˉ(x)是常量,因此放在最小运算外面。
根据暗通道先验,
J
J
J趋近于零:
(5)
J
d
a
r
k
(
x
)
=
min
y
∈
Ω
(
x
)
(
min
c
J
c
(
y
)
)
=
0
J^{dark}(x)=\min_{y\in\Omega (x)}(\min_cJ^c(y))=0\tag5
Jdark(x)=y∈Ω(x)min(cminJc(y))=0(5)因为
A
c
A^c
Ac总是正值,可得:
(6)
min
y
∈
Ω
(
x
)
(
min
c
J
c
(
y
)
A
c
)
=
0.
\min_{y\in \Omega (x)}(\min_c\frac{J^c(y)}{A^c})=0.\tag6
y∈Ω(x)min(cminAcJc(y))=0.(6)将式(6)代回式(4),即可简单地得到透射率估计值:
(7)
t
ˉ
(
x
)
=
1
−
min
y
∈
Ω
(
x
)
(
min
c
I
c
(
y
)
A
c
)
.
\bar t(x)=1-\min_{y\in \Omega(x)}(\min_c\frac{I^c(y)}{A^c}).\tag7
tˉ(x)=1−y∈Ω(x)min(cminAcIc(y)).(7)同时,即使是晴天,大气光成分还是存在的,尤其是在看远处的物体时给人的感觉更强。这种大气光成分会给人一种景深的层次感,去雾要有所保留。因此,引入一个常量参数
ω
(
0
<
ω
<
1
)
\omega (0<\omega<1)
ω(0<ω<1)用来控制去雾的程度:
(8)
t
ˉ
(
x
)
=
1
−
ω
min
y
∈
Ω
(
x
)
(
min
c
I
c
(
y
)
A
c
)
.
\bar t(x)=1-\omega\min_{y\in \Omega(x)}(\min_c\frac{I^c(y)}{A^c}).\tag8
tˉ(x)=1−ωy∈Ω(x)min(cminAcIc(y)).(8)作者在文中建议的
ω
\omega
ω为0.95。
在算法开始的地方就假设
A
A
A是已知,那么具体如何得到A的值。作者在文中给出的方法是,在暗通道中找出前0.1%最亮的点,即透射率最小的点。对于这些点,去雾图中找到对于的点,并取它们中的所有通道最大的值作为
A
A
A的近似。至此,透射率
t
(
x
)
t(x)
t(x),大气光成分
A
A
A,雾图
I
I
I,都是已知了,就可以求解无雾图:
(9)
J
(
x
)
=
I
(
x
)
−
A
max
(
t
(
x
)
,
t
0
)
+
A
J(x)=\frac{I(x)-A}{\max(t(x),t_0)}+A\tag9
J(x)=max(t(x),t0)I(x)−A+A(9)其中,
t
0
t_0
t0为一个透射率下界。由于直接恢复时,当透射率
t
(
x
)
t(x)
t(x)接近零的时候,由式(2)可知,
J
(
x
)
t
(
x
)
J(x)t(x)
J(x)t(x)也为零,这就会失去原图信息,容易引入噪声,因此设置一个下界,在雾密度很大的地方,保留一定数量的雾。
t
0
t_0
t0的值一般取0.1。作者还提到,去雾后的图像一般会显得比较暗淡,可以适当增加曝光以得到更好的效果。
导向滤波
以原图灰度图作为导向图,对透射率图进行导向滤波,可以得到非常精细的透射率图,从而得到高质量的去雾图。这里再以之前人为生成的“雾图”说明导向滤波的效果。