暗通道图像去雾matlab算法详解--学习笔记

1、什么是暗通道先验:在绝大多数非天空的局部区域里,某一些像素总会有至少一个颜色通道具有很低的值。

2、对于任意的输入图像J,其暗通道可以用下式表达:

Jc表示彩色图像的每个通道 ,Ω(x)表示以像素X为中心的一个窗口。(5)式的意义用代码表示:首先求出每个像素RGB分量中的最小值,存入一副和原始图像大小相同的灰度图中,然后再对这幅灰度图进行最小值滤波,滤波的半径由窗口大小决定,一般有WindowSize = 2 * Radius + 1; 若窗口大小为15*15,即最小值滤波的半径为7像素。         

以像素点x为中心,分别取三个通道内窗口Ω内的最小值,然后再取三个通道的最小值作为像素点x的暗通道的值,如下图所示:(图来自:https://www.cnblogs.com/changkaizhao/p/3266798.html)

3、暗通道先验的理论指出:

4、采用暗通道先验去雾算法中模糊图像(有雾图像)模型被描述成:

 I(x)是有雾图像,J(x)是去雾后图像,A是全局大气光强,t(x)为透射率。这个算法的目的就是从I、A、t中得到J。目前我们只知道I(x),需要求出A和t。

由此我们得到了t,因为这样在视觉上看起来是不自然的,我们修正了这个公式:

 其中w=0.95,最终在把t,带入模型,可以得到

在这里插入图片描述

5、上述推论中都是假设全球达气光A值时已知的,在实际中,我们可以借助于暗通道图来从有雾图像中获取该值。具体步骤如下:

        ① 从暗通道图中按照亮度的大小取前0.1%的像素。

        ② 在这些位置中,在原始有雾图像I中寻找对应的具有最高亮度的点的值,作为A值。

到这一步,我们就可以进行无雾图像的恢复了。由式(1)可知:  J = ( I - A)/t + A  

现在I,A,t都已经求得了,因此,完全可以进行J的计算。

注:当投射图t 的值很小时,会导致J的值偏大,从而使得图像整体向白场过度,因此一般可设置一阈值T0,当t值小于T0时,令t=T0,本文中所有效果图均以T0=0.1为标准计算。

6、主程序: imageprocessing.m

clc
clear all;

%导入原始图片并显示
figure(1)           %figure是建立图形的意思
subplot(1,2,1)           %将多个图画到一个平面,图排成1行2列,从左到右从上到下的第一个位置
I1=imread('迷雾1.png');      %读入图片,返回一个数组(矩阵),往往a*b*c unit8 类型         
imshow(I1)               %显示图像I1
title('有雾图像1')          %图像标题
impixelinfo;           %显示像素坐标以及像素值(鼠标移动位置)
 
figure(1)   
subplot(1,2,2)    %第二个位置
I2=imread('迷雾2.png');          
figure(1)
imshow(I2)
title('有雾图像2')
impixelinfo;         %显示像素坐标以及像素RGB值
    
%A=antongdao(a,m,n);  a为彩色图像矩阵;m,n为滤波窗口大小,滤波窗口自己设置一般是3*3,5*5,9*9,15*15,25*25
A1=antongdao(I1,25,25);   %计算暗通道函数
figure(2)      %创建第二个图窗
subplot(1,2,1)
imshow(A1)
title('暗通道图像1')
 
A2=antongdao(I2,5,5);
figure(2)
subplot(1,2,2)       %在第二个窗口显示暗通道图像
imshow(A2)            %显示暗通道图像
impixelinfo;             %显示像素坐标以及像素值
title('暗通道图像2')

[Ac1]=qjdqgz(A1,I1);     %调用qjdqgz()函数
[Ac2]=qjdqgz(A2,I2);     %调用qjdqgz()函数

[t1,R1,G1,B1]=tsl(I1,Ac1);    %调用函数ts1()
[t2,R2,G2,B2]=tsl(I2,Ac2);
I1=cat(3,R1,G1,B1);
I2=cat(3,R2,G2,B2);
figure(3)
subplot(1,2,1)
% I1=im2uint8(I1);
imshow(I1)
title('去雾图像1 ');
impixelinfo;
 
subplot(1,2,2)
% I2=im2uint8(I2);
imshow(I2)
title('去雾图像2 ');
impixelinfo;

7、求暗通道的部分:先求RGB三个通道的最小值,再进行最小值滤波

文件:antongdao.m---计算暗通道函数,c为彩色图像矩阵;m,n为滤波窗口大小,A为计算的暗通道

function  A=antongdao(c,m,n)
c=im2double(c);   %将图像数组转换为double型(c为主函数传过来的图像I1矩阵)
[a,b,~]=size(c); %行数(垂直辨率),列数(水平分辨率),层数
R1=c(:,:,1);  %读取图像R值 
G1=c(:,:,2);  %读取图像G值 
B1=c(:,:,3);  %读取图像B值 
A=zeros(a,b);  %生成一个a*b的零矩阵
d=A;
for i=1:a    %1~a的for循环
for j=1:b    %1~b的for循环
d(i,j)=min(R1(i,j),G1(i,j));  %R1和G1中取较小值赋值给d
A(i,j)=min(d(i,j),B1(i,j));   %在d和B1中取较小值
end
end
A=ordfilt2(A,1,ones(m,n));        %m*n的最小值滤波

8、文件:qjdqgz.m---求解全局大气光照函数,A为暗通道,I1为原彩色图像,Ac为全局大气光照

 求解全局大气光照过程如下:
1.首先对输入的有雾图像I求解其暗通道图像Jdark。

2.选择暗通道Jdark内图像总像素点个数(N_imagesize)千分之一(N=N_imagesize/1000)个最亮的像素点,并记录这些像素点(x,y)坐标。
3.根据点的坐标分别在原图像J的三个通道(r,g,b)内找到这些像素点并加和得到(sum_r,sum_g,sum_b)

 4.Ac=[Ar,Ag,Ab]. 其中Ar=sum_r/N; Ag=sum_g/N; Ab=sum_b/N

function  [Ac]=qjdqgz(A,I1)
I1=im2double(I1);  %将图像数组转换为double型(c为主函数传过来的图像I1矩阵)
R1=I1(:,:,1);
G1=I1(:,:,2);
B1=I1(:,:,3);
[a,b]=size(A);   %返回图片的尺寸信息, 并存储在a、b中,m中存储的是行数,n中存储的是列数。(要是数组就求出其m*n,要是照片的话就是求出其像素大小!)
c=ceil(a*b/1000);        %朝正无穷大方向取整
r1=zeros(c,1);     %返回一个c*1的零矩阵
g1=zeros(c,1);
b1=zeros(c,1);
m=0.9;
x=1;
d(1,1)=0;
q(1,1)=0;
while size(d,1)<=c
for i=1:a
for j=1:b
if A(i,j)>m && size(d,1)<=c
d(x,1)=i;
q(x,1)=j;
x=x+1;
end
if size(d,1)>c
     break 
end
end
end
if size(d,1)<=c
m=m-0.1;
end
end
for p=1:c
r1(p,1)=R1(d(p,1),q(p,1));
g1(p,1)=G1(d(p,1),q(p,1));
b1(p,1)=B1(d(p,1),q(p,1));
end
Ar=max(max(r1));
Ag=max(max(g1));
Ab=max(max(b1));
Ac=[Ar,Ag,Ab];

9、文件:tsl.m---求解透射率函数及去雾后RGB值。I1为原彩色图像,Ac为全局大气光照,t为透射率,R1,G1,B1为去雾后的值

function  [t,R1,G1,B1]=tsl(I1,Ac)
[a,b,~]=size(I1);
I1=im2double(I1);
R1=I1(:,:,1);
G1=I1(:,:,2);
B1=I1(:,:,3);
t=zeros(a,b);
d=t;
for i=1:a
     for j=1:b
   d(i,j)=min(R1(i,j)/Ac(1,1),G1(i,j)/Ac(1,2));
   t(i,j)=1-0.95*min(d(i,j),B1(i,j)/Ac(1,3));
     end
end
t=imguidedfilter(t);                      %导向滤波

for i=1:a
     for j=1:b
            R1(i,j)=(R1(i,j)-Ac(1,1))./(max(t(i,j),0.1))+Ac(1,1);
            G1(i,j)=(G1(i,j)-Ac(1,2))./(max(t(i,j),0.1))+Ac(1,2);
            B1(i,j)=(B1(i,j)-Ac(1,3))./(max(t(i,j),0.1))+Ac(1,3);
            
     end
end

10、 matlab

 运行结果:

本文若有不足之处,望指正,共同进步 ❤

文章参考:https://www.cnblogs.com/Imageshop/p/3281703.html

代码来自:e小白MATLAB图像去雾_哔哩哔哩_bilibili

  • 7
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值