【图像增强】基于matlab暗通道先验图像去雾【含Matlab源码 1367期】

一、获取代码方式

获取代码方式1: 完整代码已上传我的资源:【图像增强】基于matlab暗通道先验图像去雾【含Matlab源码 1367期】

获取代码方式2: 通过紫极神光博客主页开通CSDN会员,凭支付凭证,私信博主,可获得此代码。

获取代码方式3: 通过订阅紫极神光博客付费专栏,凭支付凭证,私信博主,可获得此代码。

备注:开通CSDN会员,仅只能免费获得1份代码(有效期为开通日起,三天内有效); 订阅紫极神光博客付费专栏,可免费获得2份代码(有效期为订阅日起,三天内有效);

二、简介

1 暗通道先验图像去雾方法 1.1 光线透射率模型 光在传播中由于散射使得从光源发出的辐射只有部分能到达接收传感器,其他则被散射到传播介质中。假设距离较小时散射光强与距离是线性关系,当光源距离传感器无限接近时,光的衰减值可近似为:Br,其中β为空气的散射系数;r为光源与传感器间的距离。大气密度均匀时,光线透射率的数学模型为: 在这里插入图片描述 式中:D为场景深度;t为光线透射率,用于量化传感器接收光强与光源表面光强间的比例关系,即没有被散射的辐射与光源辐射间的比例关系。

1.2 暗通道先验理论 基于统计大量清晰图像得到的暗通道先验理论是指大部分不含天空的优质图像的所有像素在R,G,B这3个通道中最少存在一个颜色通道灰度值相当低以至趋近于0[5],也就是在一定的微小区域里最小辐射强度值极低。一幅图像J可定义为: 在这里插入图片描述 式中:J dark为图像J的暗通道值; J为图像J的c通道灰度值; Q(x) 为以像素x为中心的局部微小区域; y为区域内任一像素。

1.3 暗通道先验图像去雾处理 图像去雾的目标是将传感器接收到的有雾图像利用获得的有用信息通过去雾还原出清晰图像。暗通道先验图像去雾处理是根据暗通道原理获取先验知识,再利用有雾图像退化模型实现图像去雾效果。

1.3.1 图像退化模型 在计算机视觉图形学领域,有雾图像的退化模型为[6]: 在这里插入图片描述 式中:l(x)为传感器接收到的场景信号,即输入的有雾影像;场景辐射J(x)为信号处理后的清晰图像;A为环境光照强度;t(x)为大气透射率。J(x)t(x)称为直接衰减项,用来量化场景辐射和传播中的信号损失。A(1-t(x))表示图像接收到的大气散射光强,它是引起色彩偏移和云雾效果的直接原因。

1.3.2 估算环境光照强度 暗通道图像中灰度值越高的区域云雾越厚,在输入图像中位于这部分区域的]像素灰度值越接近于环境光照强度。估算环境光照强度首先需要找到暗通道图像中灰度值最高并占图像总像素数量01%的像素点,记录它们对应的坐标索引,然后根据坐标索引在输入的有雾图像中找到对应像素点,计算有雾图像中对应像素点的灰度平均值作为环境光照强度A。

1.3.3估算大气透射率 使用t'(x)表示以像素x为中心的滤波窗口内的大气透射率,假设它局部不变对式(3)最小值运算,分别计算R,G,B这3个颜色通道中的最小值,即 在这里插入图片描述 将3个颜色通道的最小值进行运算,可得出以像素x为中心的滤波窗口内的灰度最小值,即 在这里插入图片描述 根据暗通道先验原理和式(2)可以得出: 在这里插入图片描述 于是,由式(5)和式(6)计算出大气透射率为: 在这里插入图片描述 1.3.4 去雾处理 暗通道先验条件可用来量化云雾厚度和全部像素的辐射还原量,然后恢复出清晰优质的图像。通过式(3)的有雾图像退化模型和环境光照强度A、大气透射率t(x),可进行单幅图像去雾处理,即 在这里插入图片描述 2 暗通道先验算法去雾效果优化 本文优化流程如图1所示。当输入图像云雾不均时,其大气透射率图层的灰度信息仅处于有限范围内,而整张图像的辐射还原量将被限制在一定区间里,不能分别准确还原云雾厚薄区域的辐射强度,从而影响图像去雾效果,考虑利用拉伸大气透射率图层对比度的方法来改善云雾厚薄不均时基于暗通道先验得出的无雾图像质量。 在这里插入图片描述 图1 基于暗通道先验的图像去雾处理效果优化流程

三、部分源代码

clc;
clear all;
close all;
J = imread('tree2.jpg');
[q,v,~] = size(J);
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
R1 = J(:,:,1);         %提取全部RGB分量                       
L=1; R=1; 
for i=1:2:q;            %0.5倍减采样 
    
    for j=1:2:v;
        R11(L,R)=R1(i,j);
        R=R+1;%取原图像i列下一行的元素赋给新图像的对应位置 ? ??
    end
    L=L+1;%换列 ? ??
    R=1;%从换列后的列里的第一个元素开始取元素?
end
G1 = J(:,:,2);
L=1; R=1; 
for i=1:2:q;            %0.5倍减采样 
    
    for j=1:2:v;
        G11(L,R)=G1(i,j);
        R=R+1;%取原图像i列下一行的元素赋给新图像的对应位置 ? ??
    end
    L=L+1;%换列 ? ??
    R=1;%从换列后的列里的第一个元素开始取元素?
end
B1 = J(:,:,3); 
L=1; R=1; 
for i=1:2:q;            %0.5倍减采样 
    
    for j=1:2:v;
        B11(L,R)=B1(i,j);
        R=R+1;%取原图像i列下一行的元素赋给新图像的对应位置
    end
    L=L+1;%换列 
    R=1;%从换列后的列里的第一个元素开始取元素?
end
OutImg(:,:,1) = R11;     %合成RGB分量
OutImg(:,:,2) = G11;  
OutImg(:,:,3) = B11;  
J=OutImg;
figure(5);
imshow(OutImg);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
J = double(J); %读进来是unot8类型,且后面的滤波等操作都要用到浮点运算
J = J ./255 ;               %归一化
figure(1); imshow(J);title('原图')       %显示原图


%求暗通道图像 Jdark = min(min());三个分量中的最小值并标记
Jdark = Idark(J);
figure(2);imshow(Jdark);title('暗通道图')    %显示暗通道图
 
% 采用梯度导向滤波方法对得到的粗透射率Jdark进行细化,可以加快运算速度,增加透射图细节
Jdark = gradient_guidedfilter(Jdark,Jdark, 0.04);   %图片导向滤波后得到新的图片
figure(3);imshow(Jdark);title('细化粗透射率后图')

% 大气物理模型 J = I*t + A*(1-t)  【直接衰减项】+【大气光照】
% 透射率 t与深度的关系 t=exp(-a*depth)
w = 0.95;           %去雾系数,例如w为0.95时保留0.05的雾,构造景深效果
Jt = 1 - w*Jdark;   %求解透射率

% 求解全局大气光照
% 1.首先对输入的有雾图像I求解其暗通道图像Jdark。
% 2.选择Jdark总像素点个数千分之一(N/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.
[m,n,~] = size(J);
N = floor( m*n./1000 );  %向下取整得到千分之一像素点的个数,最亮的一般就是天空
MaxPos = [0,0];          % 初始化
for i=1:1:N 
    MaxValue = max(max(Jdark));      %寻找暗通道图里全局最大值,第一次是每行,第二次是每列
    [x,y] = find(Jdark==MaxValue);   %寻找最大值的点
    Jdark(Jdark==MaxValue) = 0;      %最大值置零,寻找下一个次大值
    %检查长度
    MaxPos = vertcat(MaxPos,[x,y]);  %垂直串联矩阵,MaxPos就是N*2的矩阵
    Cnt = length(MaxPos(1));         %计数
    if Cnt > N
        break;
    end
end
MaxPosN = MaxPos(2:N+1,:); %这里多加一是因为初始化的[0,0]在最上面
 
%提取rgb分量
%根据点的坐标分别在原图像J的三个通道(r,g,b)内找到这些像素点并加和得到(sum_r,sum_g,sum_b).
Rsum = 0;  Jr = J(:,:,1);  
Gsum = 0;  Jg = J(:,:,2);
Bsum = 0;  Jb = J(:,:,3);
for j=1:1:N   %对三个分量加和
    Rsum = Rsum + Jr(MaxPosN(j,1),MaxPosN(j,2));  
    Gsum = Gsum + Jg(MaxPosN(j,1),MaxPosN(j,2));
    Bsum = Bsum + Jb(MaxPosN(j,1),MaxPosN(j,2));
end
 
Ac = [Rsum/N, Gsum/N, Bsum/N];  %求平均值
 

% 求解清晰的图像
% 根据 J = I*t + A*(1-t)   I = (J-A)/Jt + A
Iorg = zeros(m,n,3);
for i = 1:1:m
    for j = 1:1:n
        for k = 1:1:3
        Iorg(i,j,k) = (J(i,j,k)-Ac(k)) ./ Jt(i,j) + Ac(k);%J为原图,Jt为透射率
        end
    end
end
figure(4); imshow(Iorg,[]);title('去雾处理图')


复制代码

四、运行结果

在这里插入图片描述 在这里插入图片描述

五、matlab版本及参考文献

1 matlab版本 2014a

2 参考文献 [1] 蔡利梅.MATLAB图像处理——理论、算法与实例分析[M].清华大学出版社,2020. [2]杨丹,赵海滨,龙哲.MATLAB图像处理实例详解[M].清华大学出版社,2013. [3]周品.MATLAB图像处理与图形用户界面设计[M].清华大学出版社,2013. [4]刘成龙.精通MATLAB图像处理[M].清华大学出版社,2015.

猜你喜欢

转载自juejin.im/post/7015972615827226631