“暗通道”到底是个什么东西

对于图像去雾领域的研究者来说,何凯明博士的“暗通道先验(DCP)”可谓是奉若圭臬,接触这个概念一年了,但一直没有深挖,一直都是“拿来主义”,看大家粗略地一概而过,今天一时兴起,想着小搞一波,咱们就稍微深入一点,看看这个神奇的“暗通道”到底是个什么东西。

先来一段经典的代码吧,何博士的基于暗通道先验的单幅图像去雾中的部分代码,本人做了详细的注释,应该是可以看懂的:

clear all;
I=imread('xxxx\dehazing.png');  %读取图片
I=double(I);  %将读入图像I的uint8数据转换为double类型的数据
I=I./255;  %将像素值转换到0~1之间
dark=darkfunction(I);

subplot(1,2,1);imshow(I);
subplot(1,2,2);imshow(dark);  %展示雾图和对应的暗通道

function [dark] =darkfunction(I)
R=I(:,:,1);  %将I的第一层赋值给R,下面的G、B分别为I的第二、三层
G=I(:,:,2);  %三个参数分别代表行、列和层
B=I(:,:,3);
[m,n]=size(R); %size求取矩阵大小,返回其行列值,即m、n
a=zeros(m,n);  %zeros返回 m x n 大小的零矩阵
for i=1:m   %i从1开始一直循环到m
    for j=1:n
        a(i,j)=min(R(i,j),G(i,j));
        a(i,j)=min(a(i,j),B(i,j));
    end;
end;  
%整个for循环就是求取所有像素的RGB三通道(层)中的最小值,最后得到
%一副和原始图像同样大小的灰度图,即单通道图像
d=ones(15,15); %ones产生15x15的全1矩阵
fun=@(block_struct)min(min(block_struct.data))*d; %最小值滤波
%@(block_struct)为装饰器函数,block_struct.data表示传入的数据(图片或者矩阵)
dark=blockproc(a,[15,15],fun); %blockproc为分块矩阵处理函数
dark=dark(1:m,1:n); 
end

代码是基于matlab的,还是比较好理解的,最后的装饰器类似于python,具体的功能就是实现最小值滤波。

以下纯属个人理解,如有错误还望各位指点一二:

通常彩色图像都包括三个通道,即RGB三通道,也可以理解而成一张图片又三层同样大小的RGB(光学三原色:红绿蓝)三色堆叠而成,而图片实质上是由一个个像素组成的,对应于RGB三色来说,每一种颜色都是由这三原色组合而成,比如红色为(255,0,0),绿色为(0,255,0),粉红为(255,192,203),也就是说一张彩色图片中的每个像素都是以这种形式来表示的。

那么我们通常所说的暗通道,即清晰无雾的图片中除天空区域(因为天空区域或者白色区域和雾的特征较为接近)外的任一局部区域像素至少有一个通道值很低,几乎趋近于零。那如何求暗通道呢,我们在上面的代码中已经做了详细的说明,便是先求每个像素在三个通道中的最小值,然后得到一张与原始图像大小一致的灰度图,然后再使用最小值滤波进行平滑处理,即在得到的灰度图中,以每一个像素为中心取一定大小的矩形窗口(本文为15x15),取矩形窗口中灰度值的最小值代替中心像素的值,从而得到原始图像对应的暗通道图像。(求暗通道过程中要计算两次最小值)

为了更加直观地展示暗通道图像,我们先看一下上面代码的结果,即雾图和其对应的暗通道图:

“暗通道”到底是个什么东西_第1张图片

可以发现有雾的图片对应的暗通道整体偏灰白,即其灰度值较高(0代表纯黑,255代表纯白,可以理解成灰度值越高其看起来越亮),然后我们再看看暗通道图的真实面目,在matlab中输出一下dark:

“暗通道”到底是个什么东西_第2张图片

这是部分面貌,因为体量太大,无法完全显示出来,该图大小为413x550:

可以看出经过最小值滤波后的暗通道图比较平滑,局部区域内的像素值都是一致的(关于最小值滤波的过程大家可以查一下资料,我本来想画个图说一下其运行原理,发现要是详细地讲解一番工作量还是比较大的,这不是本文的重点哈~)

还有一个点大家应该也注意到了,便是我们一开始在求暗通道的雾图之前先是进行了“I=I./255;”的操作,这是因为imshow对unit8类型的数据识别范围为0~255,但我们为了增加图片的精度,通常会将其转换为double,而imshow对double精度的识别范围为0~1,大于1则显示白色,所以我们在进行显示图片前要将一开始的unit8类型转换为double类型之后再做 /255 的操作,这一点是不影响正常显示最终的暗通道图的。还有一点就是正常的清晰图像即使不做 /255 的操作,其局部像素的最小值也是很小的,经过最小值滤波后可以近似为零。

来看一下未做最小值滤波前的灰度图长什么样吧:

“暗通道”到底是个什么东西_第3张图片

这便是对每个像素的三通道取最小值所得的,为了更加直观,我们看一下对应的RGB三通道值:

“暗通道”到底是个什么东西_第4张图片   “暗通道”到底是个什么东西_第5张图片     “暗通道”到底是个什么东西_第6张图片

不难看出,每个像素点取三通道中的最小值便可得到其对应的灰度图。

我们再来看看一下清晰图像和其对应的暗通道图:

“暗通道”到底是个什么东西_第7张图片

可以发现其整体偏暗,再通过其灰度值更直观地感受一下:

“暗通道”到底是个什么东西_第8张图片

以上是截取的清晰图像求取三通道最小值后所得的灰度图,可以发现其灰度值普遍较小~~

大概就是这样子了,可能有些地方还比较模糊,继续努力吧~~

如果文章对您有一点点帮助,还请打赏一二,您的鼓励是我前进的不竭动力

微信公众号为:非著名IT表演艺术家

“暗通道”到底是个什么东西_第9张图片

你可能感兴趣的:(经典算法&图像处理)