采用暗通道算法和导向滤波以及改进的最小值滤波器进行去雾处理
基于暗通道先验与改进最小值滤波的图像去雾算法
实现图像去雾,结合暗通道先验、导向滤波和改进的最小值滤波器,提供高效的雾霾去除效果
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号