采用暗通道算法和导向滤波以及改进的最小值滤波器进行去雾处理
基于暗通道先验与改进最小值滤波的图像去雾算法
实现图像去雾,结合暗通道先验、导向滤波和改进的最小值滤波器,提供高效的雾霾去除效果
function dehazed_image = improved_dehazing(input_image, varargin)
    % 改进的图像去雾算法
    % 输入:
    %   input_image - 有雾图像 (RGB格式)
    %  可选参数:
    %   'window_size' - 暗通道窗口大小 (默认15)
    %   'omega' - 保留雾气的参数 (默认0.95)
    %   't0' - 透射率下限 (默认0.1)
    %   'guided_radius' - 导向滤波半径 (默认60)
    %   'guided_eps' - 导向滤波正则化参数 (默认0.001)
    %   'gamma' - 伽马校正参数 (默认1.0)
    %
    % 输出:
    %   dehazed_image - 去雾后的图像
    
    % 参数解析
    p = inputParser;
    addParameter(p, 'window_size', 15, @(x) isnumeric(x) && x>0);
    addParameter(p, 'omega', 0.95, @(x) isnumeric(x) && x>0 && x<=1);
    addParameter(p, 't0', 0.1, @(x) isnumeric(x) && x>0 && x<1);
    addParameter(p, 'guided_radius', 60, @(x) isnumeric(x) && x>0);
    addParameter(p, 'guided_eps', 0.001, @(x) isnumeric(x) && x>0);
    addParameter(p, 'gamma', 1.0, @(x) isnumeric(x) && x>0);
    parse(p, varargin{:});
    params = p.Results;
    
    % 转换为双精度浮点数并归一化
    I = im2double(input_image);
    
    % 步骤1: 计算改进的暗通道
    dark_channel = improved_min_dark_channel(I, params.window_size);
    
    % 步骤2: 估计大气光
    atmospheric_light = estimate_atmospheric_light(I, dark_channel);
    
    % 步骤3: 估计初始透射率
    normalized_I = bsxfun(@rdivide, I, atmospheric_light);
    normalized_dark = improved_min_dark_channel(normalized_I, params.window_size);
    t_initial = 1 - params.omega * normalized_dark;
    
    % 步骤4: 使用导向滤波优化透射率
    gray_I = rgb2gray(I);
    t_refined = guided_filter(gray_I, t_initial, params.guided_radius, params.guided_eps);
    
    % 步骤5: 恢复无雾图像
    t_clamped = max(t_refined, params.t0);
    dehazed = bsxfun(@minus, I, atmospheric_light) ./ t_clamped + atmospheric_light;
    
    % 步骤6: 应用伽马校正增强对比度
    dehazed_image = imadjust(dehazed, [], [], params.gamma);
end
function dark_channel = improved_min_dark_channel(rgb_img, window_size)
    % 改进的暗通道计算:结合最小值滤波与局部对比度增强
    % 输入:RGB图像和窗口大小
    % 输出:暗通道图像
    
    % 计算最小值通道
    min_channel = min(rgb_img, [], 3);
    
    % 使用形态学操作改进最小值滤波
    se = strel('square', window_size);
    
    % 方案1: 交替使用腐蚀和膨胀
    eroded = imerode(min_channel, se);
    dilated = imdilate(eroded, se);
    
    % 方案2: 局部自适应窗口大小
    local_contrast = stdfilt(min_channel, true(window_size));
    adaptive_window = round(window_size * (1 + 2*(local_contrast - 0.5)));
    adaptive_window = max(3, min(adaptive_window, 2*window_size));
    
    % 创建自适应暗通道
    adaptive_dark = zeros(size(min_channel));
    for i = 1:size(min_channel, 1)
        for j = 1:size(min_channel, 2)
            win = adaptive_window(i, j);
            r1 = max(1, i-win);
            r2 = min(size(min_channel,1), i+win);
            c1 = max(1, j-win);
            c2 = min(size(min_channel,2), j+win);
            adaptive_dark(i,j) = min(min(min_channel(r1:r2, c1:c2)));
        end
    end
    
    % 结合两种方法
    dark_channel = 0.7*dilated + 0.3*adaptive_dark;
end
function atmospheric_light = estimate_atmospheric_light(rgb_img, dark_channel)
    % 估计大气光
    % 输入:RGB图像和暗通道
    % 输出:大气光值 [R, G, B]
    
    % 选择暗通道中最亮的0.1%像素
    num_pixels = numel(dark_channel);
    [~, indices] = sort(dark_channel(:), 'descend');
    top_indices = indices(1:ceil(num_pixels*0.001));
    
    % 在这些像素位置找到原始图像中最亮的像素
    brightest_intensity = zeros(size(top_indices));
    for i = 1:numel(top_indices)
        [row, col] = ind2sub(size(dark_channel), top_indices(i));
        brightest_intensity(i) = max(rgb_img(row, col, :));
    end
    
    % 找到最亮像素的索引
    [~, max_idx] = max(brightest_intensity);
    [row, col] = ind2sub(size(dark_channel), top_indices(max_idx));
    
    % 获取大气光值
    atmospheric_light = squeeze(rgb_img(row, col, :))';
end
function q = guided_filter(I, p, r, eps)
    % 导向滤波实现
    % 输入:引导图像I,输入图像p,半径r,正则化参数eps
    % 输出:滤波后图像q
    
    % 转换为灰度图如果I是彩色
    if size(I, 3) == 3
        I = rgb2gray(I);
    end
    
    % 计算均值
    mean_I = imboxfilt(I, 2*r+1, 'Padding', 'symmetric');
    mean_p = imboxfilt(p, 2*r+1, 'Padding', 'symmetric');
    mean_Ip = imboxfilt(I.*p, 2*r+1, 'Padding', 'symmetric');
    
    % 计算方差和协方差
    cov_Ip = mean_Ip - mean_I .* mean_p;
    mean_II = imboxfilt(I.*I, 2*r+1, 'Padding', 'symmetric');
    var_I = mean_II - mean_I .* mean_I;
    
    % 计算线性系数
    a = cov_Ip ./ (var_I + eps);
    b = mean_p - a .* mean_I;
    
    % 计算系数均值
    mean_a = imboxfilt(a, 2*r+1, 'Padding', 'symmetric');
    mean_b = imboxfilt(b, 2*r+1, 'Padding', 'symmetric');
    
    % 输出结果
    q = mean_a .* I + mean_b;
end
function enhanced_img = adaptive_contrast_enhancement(img)
    % 自适应对比度增强
    % 输入:图像
    % 输出:增强后图像
    
    % CLAHE 对比度受限自适应直方图均衡化
    lab = rgb2lab(img);
    L = lab(:,:,1)/100;
    L = adapthisteq(L, 'NumTiles', [8 8], 'ClipLimit', 0.01);
    lab(:,:,1) = L*100;
    enhanced_img = lab2rgb(lab);
end
%% 主程序:去雾演示
clc;
clear;
close all;
% 读取有雾图像
foggy_img = imread('foggy_scene.jpg');
% 参数设置
params.window_size = 15;     % 暗通道窗口大小
params.omega = 0.95;         % 雾气保留参数
params.t0 = 0.1;             % 透射率下限
params.guided_radius = 60;   % 导向滤波半径
params.guided_eps = 0.001;   % 导向滤波正则化参数
params.gamma = 0.9;          % 伽马校正参数
% 执行去雾
tic;
dehazed_img = improved_dehazing(foggy_img, ...
    'window_size', params.window_size, ...
    'omega', params.omega, ...
    't0', params.t0, ...
    'guided_radius', params.guided_radius, ...
    'guided_eps', params.guided_eps, ...
    'gamma', params.gamma);
processing_time = toc;
% 自适应对比度增强
enhanced_img = adaptive_contrance_enhancement(dehazed_img);
% 显示结果
figure('Position', [100, 100, 1200, 600]);
% 原始雾图
subplot(1,3,1);
imshow(foggy_img);
title('原始雾图', 'FontSize', 12);
% 去雾结果
subplot(1,3,2);
imshow(dehazed_img);
title('去雾结果', 'FontSize', 12);
% 增强结果
subplot(1,3,3);
imshow(enhanced_img);
title('增强后结果', 'FontSize', 12);
% 保存结果
imwrite(dehazed_img, 'dehazed_result.jpg');
imwrite(enhanced_img, 'enhanced_result.jpg');
fprintf('去雾处理完成! 耗时: %.2f 秒\n', processing_time);
%% 性能评估
% 如果有无雾参考图像,可以计算质量指标
% ref_img = imread('clear_scene.jpg');
% 
% psnr_val = psnr(enhanced_img, im2double(ref_img));
% ssim_val = ssim(enhanced_img, im2double(ref_img));
% 
% fprintf('PSNR: %.2f dB\n', psnr_val);
% fprintf('SSIM: %.4f\n', ssim_val);
%% 透射率可视化
% 计算透射率用于可视化
[~, dark_channel] = improved_min_dark_channel(im2double(foggy_img), params.window_size);
atmospheric_light = estimate_atmospheric_light(im2double(foggy_img), dark_channel);
normalized_I = bsxfun(@rdivide, im2double(foggy_img), atmospheric_light);
normalized_dark = improved_min_dark_channel(normalized_I, params.window_size);
t_initial = 1 - params.omega * normalized_dark;
gray_I = rgb2gray(im2double(foggy_img));
t_refined = guided_filter(gray_I, t_initial, params.guided_radius, params.guided_eps);
% 可视化透射率图
figure('Position', [100, 100, 1000, 400]);
subplot(1,2,1);
imagesc(t_initial);
colormap jet;
colorbar;
title('初始透射率图', 'FontSize', 12);
axis image;
subplot(1,2,2);
imagesc(t_refined);
colormap jet;
colorbar;
title('优化后透射率图', 'FontSize', 12);
axis image;
算法创新点与技术细节
1. 改进的暗通道计算
传统暗通道算法使用固定大小的窗口进行最小值滤波,容易导致光晕效应和细节丢失。本算法采用创新性的混合方法:
function dark_channel = improved_min_dark_channel(rgb_img, window_size)
    % 方案1: 形态学操作 (腐蚀+膨胀)
    eroded = imerode(min_channel, se);
    dilated = imdilate(eroded, se);
    
    % 方案2: 局部自适应窗口
    local_contrast = stdfilt(min_channel, true(window_size));
    adaptive_window = round(window_size * (1 + 2*(local_contrast - 0.5)));
    
    % 结合两种方法
    dark_channel = 0.7*dilated + 0.3*adaptive_dark;
end
创新点:
- 形态学优化:通过先腐蚀后膨胀的操作,有效减少光晕效应
- 自适应窗口:根据局部对比度动态调整窗口大小
- 高对比度区域使用较小窗口保留细节
- 低对比度区域使用较大窗口减少噪声
 
- 混合输出:结合两种方法的优势,平衡细节保留和噪声抑制
2. 大气光估计优化
传统方法直接取暗通道最亮像素,容易受白色物体干扰:
function atmospheric_light = estimate_atmospheric_light(rgb_img, dark_channel)
    % 1. 选择暗通道中最亮的0.1%像素
    % 2. 在这些位置找到原始图像中最亮的像素
    % 3. 取这些像素中最亮的值作为大气光
end
改进:
- 先选择暗通道中最亮的0.1%像素
- 在这些位置中寻找原始图像RGB通道的最大值
- 有效避免白色物体对大气光估计的干扰
3. 导向滤波优化透射率
使用导向滤波替代传统的软抠图方法,显著提高效率:
function q = guided_filter(I, p, r, eps)
    % 使用引导图像I优化透射率图p
    % 核心计算:
    mean_I = imboxfilt(I, 2*r+1, 'Padding', 'symmetric');
    % ... (计算线性系数)
    q = mean_a .* I + mean_b;
end
优势:
- 时间复杂度O(N) vs 软抠图的O(N²)
- 更好地保持边缘信息
- 参数可调性强(半径r和正则化参数eps)
4. 自适应对比度增强
去雾后应用自适应对比度增强:
function enhanced_img = adaptive_contrast_enhancement(img)
    % 在LAB颜色空间进行CLAHE
    lab = rgb2lab(img);
    L = lab(:,:,1)/100;
    L = adapthisteq(L, 'NumTiles', [8 8], 'ClipLimit', 0.01);
    % ... (转换回RGB)
end
特点:
- 在LAB空间处理亮度通道,避免颜色失真
- 自适应直方图均衡化(CLAHE)增强局部对比度
- 可调节的剪切限制防止过度增强
参考代码 采用暗通道算法和导向滤波以及改进的最小值滤波器进行去雾处理 youwenfan.com/contentcna/66038.html
算法流程
- 输入处理:读取有雾图像,转换为双精度格式
- 暗通道计算:使用改进的最小值滤波器
- 大气光估计:基于暗通道的优化方法
- 透射率估计:
- 初始透射率计算
- 导向滤波优化透射率
 
- 图像恢复:
- 使用大气散射模型恢复无雾图像
- 伽马校正调整整体亮度
 
- 后处理:
- 自适应对比度增强
- 结果可视化与保存
 
参数调优建议
- 
窗口大小 (window_size): - 雾浓度高:增大窗口(15-25)
- 雾浓度低:减小窗口(7-15)
- 影响细节保留和光晕抑制
 
- 
雾气保留 (omega): - 取值范围:0.85-0.95
- 较低值:去雾更彻底
- 较高值:保留更多大气透视效果
 
- 
导向滤波参数: - 半径 (guided_radius):影响平滑程度(通常30-80)
- 正则化 (guided_eps):影响边缘保持(通常0.001-0.01)
 
- 
伽马校正 (gamma): - 
<1.0:提亮图像 
- 
1.0:压暗图像 
- 
根据图像亮度调整(通常0.8-1.2) 
 
- 
此实现平衡了算法性能和效果,通过创新的暗通道计算和参数优化,在各种雾霾条件下都能获得自然清晰的结果。
 
                    
                
 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号