图像去雾

-
-
2016-10-22

刷博客的时候,无意中看到一篇介绍图像去雾的博客,讲到何凯明的《Single Image Haze Removal Using Dark Channel Prior》这篇文章,2009年CVPR的最佳论文,简单看了下介绍,瞬间就对作者佩服的五体投地,感叹这才叫做研究。 论文《Single Image Haze Removal Using Dark Channel Prior》可以在这里下载到,并且里面还有论文相关的幻灯片和其他参考论文等信息。

1. 论文的主要介绍

1.1 暗通道先验

暗通道先验是基于户外无雾图像的观察,在大部分不包含天空的图像中,在r,g,b三个通道中,至少有一个通道的最小灰度值非常小。用公式表示为,图像的暗通道J定义为:

\(J^{dark}(x)=\min_{y\in{r,g,b}}(\min_{y\in\Omega(x)}(J^c(y))\)

其中,$J^c$表示J的颜色通道,$\Omega(x)$表示以x为中心的窗口。 观察发现,对于户外无雾图片,$J^{dark}$值是非常小的,由此,称这个统计规律为暗通道先验。

1.2 图像去雾

在计算机视觉和计算机图形学中,通常使用下面的模型描述有雾图像:

 $$ I(x)=J(x)t(x) + A(1-t(x)) $$ 

其中,I(x)就是观察到的含雾图像,J(x)是不包含雾的图像,A是全球大气光成分系数,t(x)表示透射率。图像去雾的问题实际上是根据已知的I(x)来求J(x)。

1.3 计算透射率

首先,假设大气光成分系数A是已知的,进一步的,假设在图像的一个小窗口内$\Omega(x)$,透射率t(x)是一个常数,对有雾图像模型的窗口内,使用min操作,得到: 

$$ \min_{y\in\Omega(x)}(I^c(y)) = \tilde{t}(x)\min_{y\in\Omega(x)}(J^c(y))+(1-\tilde{t}(x))A^c $$

min操作是在三个色彩通道上独立进行的,所以等式可以化简为: 

$$ \min_{y\in\Omega(x)}(\frac{I^c(y)}{A^c}) = \tilde{t}(x)\min_{y\in\Omega(x)}(\frac{J^c(y)}{A^c})+(1-\tilde{t}(x)) $$

对上面等式中三个色彩通道使用min操作,得到 

$$ \min_c(\min_{y\in\Omega(x)}(\frac{I^c(y)}{A^c})) = \tilde{t} \min_c( (x)\min_{y\in\Omega(x)}(\frac{J^c(y)}{A^c})) + (1-\tilde{t}(x)) \tag{公式8} $$

根据暗通道先验,无雾图像J的暗通道$J^{dark}$趋向于0: 

$$ J^{dark}(x) = \min_c( \min_{y\in\Omega(x)}(J^c(y))) = 0 $$

$A^c$一直是一个正数,可得:

 $$ \min_c(\min_{y\in\Omega(x)}(\frac{I^c(y)}{A^c})) = 0 \tag{公式10} $$

\(\min_c(\min_{y\in\Omega(x)}(\frac{I^c(y)}{A^c})) = 0 \)

将公式10代入公式8中,得到: 

$$ \tilde{t}(x) = 1 - \min_c(\min_{y\in\Omega(x)}(\frac{I^c(y)}{A^c})) \tag{公式11} $$ 由此,得到透射率$\tilde{t}(x)$。

前面有说道,暗通道先验在天空的区域效果不好,不过幸运的是,有雾图像中天空的颜色通常都跟大气光成分A非常相似,由此,在天空区域有: $$ \min_c(\min_{y\in\Omega(x)}(\frac{I^c(y)}{A^c})) \rightarrow 1 \text{, and } \tilde{t}(x) \rightarrow 0, $$

在天空区域,图像的透射率趋向于0,这样,公式11就很好的概况了没有天空区域和有天空区域。

在现实生活中,图像中少量的雾能够反映物体的深度信息,所以,我们可以保留一点雾来让图像更加自然一些。 $$ \tilde{t}(x) = 1 - \omega\min_c(\min_{y\in\Omega(x)}(\frac{I^c(y)}{A^c})) $$ $\omega$一般取0.95。

1.4 大气光成分系数

大气光成分系数一般是借助暗通道图获得的,首先在暗通道图中找出前0.1%的像素位置,再在这些位置中找出最高亮度的点作为大气光成分系数A。

1.5 恢复无雾图像

现在,I、A、T都已知,则无雾图像为: $$ J(x) = \frac{I(x) - A}{max(t(x), t_0)} + A $$ 其中,$max(t(x), t_0)$主要是防止t值很小时,J值偏大,使得图像过白,一般设置$t_0$为0.1。

2. 我的一个实现

看我文章后,我自己用Python写了一个程序简单实现下。程序放在Github了。同时,我用Flask搭了一个简单的服务,可以直接上传有雾图片得到去雾后的图片,感兴趣的可以去http://tools.pfchai.com看看。

“您的支持是我持续分享的动力”

微信收款码
微信
支付宝收款码
支付宝

目录