西安科技大学
《MATLAB 遥感图像处理》课程设计报告
报告题目 图像去雾
姓 名
学 号
班 级
指导教师
日 期 2016 年 10 月 28 日
一、实习目的及意义
生活中,我们常常会遇到一些由于噪声影响的图像,然而这些图像是有一定
的使用价值的,同时我们能找到这些影响图像因素的规律,在摄影测量行业,我
们的数据绝大部分是直接来自遥感获取的影像,有的是无人机影像,有的是大飞
机的航空影像,也有更大的来自大气层以外的卫星影像。数据获取的结果有时候
是来之不易的,但是噪声比如云雾的影响是不可避免的。为了正常的使用资源,
同时更合理的运用有效资源,对存在有质量为题的影像进行处理达到可以利用的
结果是非常有必要的。这就是本次实习的目的:将实际观测图像还原为没有雾的
理想场景图像,并利用雾的浓度来估计物体的距离。
实验的主要内容:
(1)雾霭图像模型与暗通道先验
(2)透射率估计
(3)大气光值估计。
二、 算法原理
1、暗通道先验:Dark Channel Prior 认为每一个局部区域总有一些很暗的东
西, 这是图像去雾问题的本质规律,对于任意图 J, Dark Channel Prior 通过
下式描述:
其中,
表示暗通道,是 J 的颜色通道;
是以 x 为中心的图像
块,该式包含了提取 R、G、B 三个通道最小值与最小值滤波两层计算。实验表明,
对于绝大多数户外无雾的自然场景图像 J,除去天空区域外,非常低且接近于 0
值,而对于有雾的原始图像,即可从暗通道先验处理后的结果估计透射图和天空
亮度值 A。
由于雾总是灰白色的,因此一旦图像受到雾的影响,那么这些本来应该很暗
的东西就会变得灰白。不仅如此,根据雾霭的形成模型,还能根据这些东西的灰
白程度来判断雾的浓度。Dark Channel Prior 能很有效的去除雾的影响,同时
利用雾的浓度来估计物体的距离。
2、透射率估计:假设大气光亮度 A 已知,对于无雾图像出去天空外,
趋于零,因此可得到透射率计算公式:
)))((()(minmin},,{)(darkykJJcbgrxyJdark)(xJdark
式中设置常数 w,目的是使估计值接近于自然,考虑水汽的影响。如果直接利用
这里估计的透射率图像,那么在恢复图像中会产生“光晕”,为此需对透射率进
行优化已消除恢复图像中的光晕。
3、大气光值估计:对于天空区域,暗通道这一信息不成立,而实际上有雾图
像的天空区域像素值强度与大气光值 A 非常接近,此时透过率趋于零,因此可根
据下式恢复图像:
其中, 是一个较小的值。
三、 算法流程图及 MATLAB 源代码
1、算法流程图:
图二. 图像去雾算法流程图
))(min(min1)()(AIcccxyywxt)),(max()()(0tAIJxtxxccct0输入图像计算暗通道大气光值估计透射率估计透射率优化无雾图像恢复开始结束
基于暗通道先验的图像去雾算法流程如图二所示。算法主要由 3 部分组成:暗
通道计算、透射率估计和大气光值估计。首先利用暗通道原理计算暗通道,即提
取 R、G、B 三个通道最小值并进行最小值滤波;然后利用无雾图像的暗通道趋于
零计算透射率;最后利用有雾图像的天空区域像素值强度与大气光值 A 接近这一
特性,估计出大气光值,进而恢复图像。
2、MATLAB 源代码:
(1)调用
close all;clc;clear all; %创建图像去雾命令文件
addpath(genpath('guided-filter-code-v1')); %添加透射率优化工具包
I=imread('canon7.jpg'); %读取原影像
%估算出透射率 t
%调用基于暗通道先验的图像去雾函数
[Jim,transm,depth]=darkpriordhaze(I,15,0.99,0.1);
hsv_image=rgb2hsv(mat2gray(Jim));
%对比度拉伸
hsv_image(:,:,3)= imadjust(hsv_image(:,:,3),stretchlim(hsv_image(:,:,3)));
J = hsv2rgb(hsv_image);
figure,imshow(J); %显示原影像
%为原影像命标题
title('linear streched dehazed image');
imwrite(mat2gray(transm),'canon7_transmissionmap.jpg');
imwrite(mat2gray(Jim),'canon7_dehazed.jpg');
imwrite(J,'canon7_streched_dehazed.jpg');
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
(2)基于暗通道先验的图像去雾函数
%创建基于暗通道先验的图像去雾函数
function [Jim,transm,depth]=darkpriordhaze(I,blocksize,w0,t0,r,eps);
% single image dehaze
[rows,columns,L]=size(I);
r=round(blocksize/2);
dark_channel=zeros(rows,columns);
minRc=zeros(rows,columns);
%寻找原图像中每行每列的最小值像素
for i=1:rows
for j=1:columns
minRc(i,j)=min(I(i,j,:));
end
end
%对每行每列的最小值像素进行填充,填充后矩阵行列数变为 rows+2r、columns+2r
IminRc=padarray(minRc,[r r],'symmetric');
for i=(r+1):(rows+r)
waitbar((i-r)/rows);
for j=(r+1):(columns+r)
In=IminRc(i-r:i+r,j-r:j+r);
dark_channel(i-r,j-r)=min(In(:)); %暗通道计算,对上部结果进行修正,获得暗通道坐标信息
end
end
clear IminRc;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%大气透射率估计
%gray histogram statistic,To verify how good the dark channel prior is
n_elements = histc(dark_channel(:),[0:1:255]);%提取暗通道直方图
p_elements = cumsum(n_elements)/sum(n_elements);%计算累计百分比
%估计大气光亮度,通过 dark_chanel 中的那 0.1%最亮的值来确定
%寻找暗通道图像中最亮像素的 0.1%
ivp_elements=1-p_elements;
idx=find(ivp_elements<0.001);
Max_dark_channel=idx-1;
[ix,iy]=find(dark_channel>=Max_dark_channel(1));
max_ixsize=length(ix);
max_ixrgb=zeros(max_ixsize,3);
max_ixv=zeros(max_ixsize,1);
%为每一波段的最亮像素赋予位置信息
for i=1:max_ixsize;
max_ixrgb(i,1)=I(ix(i),iy(i),1);
max_ixrgb(i,2)=I(ix(i),iy(i),2);
max_ixrgb(i,3)=I(ix(i),iy(i),3);
%进行归一化
max_ixv(i)=norm(max_ixrgb(i,:));
end
[~,ixm]= max(max_ixv);
%将 0.1 中像素中对应原图像中灰度值最高的像素作为大气光亮度
A=max_ixrgb(ixm,:);
%显示原影像
figure;
imshow(I);
%为影像命标题
title('origin image and A area');
hold on
%在图像左上角加边框
line([iy(ixm)-20,iy(ixm)+20 iy(ixm)+20 iy(ixm)-20,iy(ixm)-20],[ix(ixm) ix(ixm) ix(ixm)+10 ix(ixm)+10 ix(ixm)-
10 ],'Color','r');
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%利用公式计算透射率
Ic=zeros(size(I));
for c=1:3,
Ic(:,:,c)=double(I(:,:,c))/A(c);
end
%寻找影像中像素最小值
for i=1:rows,
for j=1:columns,
minRc(i,j)=min(Ic(i,j,:));
end
end
%填充
IminRc=padarray(minRc,[r r],'symmetric');%
%dark channel
dark_channel2=zeros(rows,columns);
for i=(r+1):(rows+r)
waitbar((i-r)/rows);
for j=(r+1):(columns+r),
In=IminRc(i-r:i+r,j-r:j+r);
dark_channel2(i-r,j-r)=min(In(:));
end
end
figure;
imshow(mat2gray(dark_channel2));%显示暗通道
title('dark channel');%命标题
%%%transmission map 初始的透射率图像
transm=1-w0*dark_channel2;%根据公式计算透射率
clear IminRc dark_channel minRc IminRc
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%透射率优化
% soft matting 用 guided image filtering 工具包
maxRc=zeros(rows,columns);
for i=1:rows,
for j=1:columns,
maxRc(i,j)=max(I(i,j,:));
end
end
r = 11; % try r=2, 4, or 8
eps = 0.2^2; % try eps=0.1^2, 0.2^2, 0.4^2
transm = guidedfilter(maxRc, transm, r, eps);
figure
imshow(mat2gray(transm)); %显示优化后的透射率影像
title('transmission map');
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Jim=zeros(rows,columns,3);%根据雾霭模型恢复
%根据公式恢复理想图像
for i=1:rows,
for j=1:columns,
Jim(i,j,1)=(double(I(i,j,1))-A(1))/max([t0,transm(i,j)])+A(1);
Jim(i,j,2)=(double(I(i,j,2))-A(2))/max([t0,transm(i,j)])+A(2);
Jim(i,j,3)=(double(I(i,j,3))-A(3))/max([t0,transm(i,j)])+A(3);
end
end
figure;
imshow(mat2gray(Jim));%显示去雾后图像
title('dehazed image');%命标题
depth=-log(transm);
figure
imshow(depth);
title('depth image');
end
五、实验结果
为了验证基于暗通道图像去雾算法,本实验给出了基于此法的处理结果。利用
常见的自然景象进行测试,根据暗通道原理估计图像的暗通道、大气透过率以及
无雾图像的恢复。
图 1 原始雾霭图像 图 2 暗通道计算结果
图 3 优化后的透射率影像 图 4 去雾后影像
由图可知,借助何凯明、孙建等人在 CVPR2009 提出的暗通道算法进行图像
去雾技术,对烟雾影响的图像具有良好的图像去雾效果。综上所述,基于暗通道
的图像去雾算法是一种具有良好的图像去雾方法,该方法不但能达到去雾的效果
而且能利用雾的浓度估计物体距离,是一种值得借鉴的图像处理方法,很有实用
价值。