本文参靠何凯明博士,暗通道理论论文及网上大量代码.
暗通道原理可参考博文:
白马负金羁: 链接:https://blog.csdn.net/baimafujinji/article/details/27206237
和蔼的zhxing:链接:https://www.jianshu.com/p/df9c963a392a
- 暗通道
所谓暗通道是一个基本假设,这个假设认为,在绝大多数的非天空的局部区域中,某一些像素总会有至少一个颜色通道具有很低的值。这个其实很容易理解,实际生活中造成这个假设的原因有很多,比如汽车,建筑物或者城市中的阴影,或者说色彩鲜艳的物体或表面(比如绿色的树叶,各种鲜艳的花,或者蓝色绿色的睡眠),颜色较暗的物体或者表面,这些景物的暗通道总是变现为比较暗的状态。
所以暗通道是什么呢?其实比较简单,作者认为暗通道是:
暗通道先验指出:
暗通道实际上是在rgb三个通道中取最小值组成灰度图,然后再进行一个最小值滤波得到的。如下程序演示效果:
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
from skimage.morphology import disk #生成扁平的盘状结构元素,其主要参数是生成圆盘的半径
import skimage.filters.rank as sfr
def min_box(image,kernel_size=15):
min_image = sfr.minimum(image,disk(kernel_size)) #skimage.filters.rank.minimum()返回图像的局部最小值
return min_image
def calculate_dark(image):
if not isinstance(image,np.ndarray):
raise ValueError("input image is not numpy type") #手动抛出异常
dark = np.minimum(image[:,:,0],image[:,:,1],image[:,:,2]).astype(np.float32) #取三个通道的最小值来获取暗通道
dark = min_box(dark,kernel_size=15)
return dark/255
haze = np.array(Image.open("/path/1118.jpg"))[:,:,0:3]/255
clear = np.array(Image.open("/path/clear.png"))[:,:,0:3]/255
dark_haze = calculate_dark(haze)
dark_clear = calculate_dark(clear)
plt.figure()
plt.subplot(2,2,1)
plt.imshow(haze)
plt.subplot(2,2,2)
plt.imshow(dark_haze,cmap="gray")
plt.subplot(2,2,3)
plt.imshow(clear)
plt.subplot(2,2,4)
plt.imshow(dark_clear,cmap="gray")
plt.show()
以上程序基于Python3实现,运行效果如图所示:
上面部分为有雾图像,右边是该图像的暗通道分布.下面时无雾图像,右边是其暗通道分布.
可以发现,有雾的时候会呈现一定的灰色,而无雾的时候咋会呈现大量的黑色(像素为接近0),作者统计了5000多副图像的特征,基本都符合这样一条先验定理。
- 雾图模型
计算机视觉中,下面这个雾图形成模型是被广泛使用的:
其中I(x)是现有的图像(待去雾),J(x)是要恢复的原无雾图像,A是全球大气光成分,t(x)是透射率,现在的条件就是已知I(x),来求J(x),显然不加任何限制的话是有无穷多个解的。
但是现实生活中,即使是晴天白云,空气中也会存在一些颗粒,看远方的物体还是能够感觉到雾的影响,另外,雾的存在可以让人们感觉到景深的存在,所以我们保留一部分的雾,上式修正为:其中w是[0-1]之间的一个值,一般取0.95差不多。
上面的推导都是假设全球大气光是已知的,实际中,我们可以借助暗通道图来从有雾图像中来获取该值:
1.从暗通道图中按照亮度大小取前0.1%的像素。
2.在这些位置中,在原始图像中寻找对应具有最高亮度点的值,作为A值。
之后,我们就可以进行有雾图像的恢复了:
当投射图t很小时,会导致J的值偏大,会导致图片某些地方过爆,所以一般可以设置一个阈值来限制,我们设置一个阈值:一般设置较小,0.1即可。
但是这个去雾效果还是挺粗糙的,主要原因是由于透射率图过于粗糙了,何凯明在文章中提出了soft matting方法,然后其缺点是速度特别慢,不适用在实时场合,2011年,又提出可以使用导向滤波的方式来获得更细腻的结果,这个方法的运算主要集中在方框滤波(均值滤波),而这种操作在opencv或者其他的图像库中都有快速算法。可以考虑使用。
我的实现效果如下所示:
先上论文原图效果演示:
网上随机找的图片进行演示:
这幅时开车时拍的雨天,蓝色区域时挡风玻璃贴的膜,算法略微有改动,使远处天空区域失真效果减弱了!
原算法1,不可去除大片白色区域的图片.2,不可去除大片天空区域.3,对于处理结果会有失真现象.接近天空部分区域会出现过曝.4,使用soft matiing方法使算法速度慢,所以后来改进为引导滤波算法获得透射率图像,这个后面我会再出一篇博客进行讲解.至此,看过原论文的大概基本都理解了!以上效果是改进一些参数后得到的图像.
公式推导建议自己推一遍,该算法基本原理来源于何凯明大神的CVPR09的论文Single Image Haze Removal Using Dark Channel Prior,何凯明博士论文原文链接: https://pan.baidu.com/s/1OfsUvMdNLDHvEtjDVanPPw 提取码: dvpn 复制这段内容后打开百度网盘手机App,操作更方便哦!
(第一次写博客,慌得一P,还是上班溜号写的,哈哈哈,就这样吧,以后常更新!)
**注意:研究无雾图像暗通道是为了了解图像暗通道的分布情况,但是实际情况中,我们不可能对有雾图像进行除雾.**
来源:CSDN
作者:叫我李先生
链接:https://blog.csdn.net/qq_40216084/article/details/103819818