在计算机视觉领域,图像去雾是一项重要的预处理任务,尤其是在自动驾驶、遥感图像分析以及监控系统中,去雾能够有效提升图像质量,使目标更加清晰可见。本项目采用 Retinex 算法进行图像去雾,并结合 GPU 加速以提高计算效率。
Retinex 算法原理:
Retinex (Retina + Cortex) 是 Land 和 McCann 提出的图像增强算法,主要基于人眼视觉系统对亮度变化的适应性。Retinex 算法的核心思想是:
教程链接:https://go.openbayes.com/vaEyL
使用云平台:OpenBayes
https://openbayes.com/console/signup?r=Dennis9801_1ohB
登录 OpenBayes.com,在「公共教程」页面,选择键部署 「使用 MATLAB 进行图像去雾处理」教程。

页面跳转后,点击右上角「克隆」,将该教程克隆至自己的容器中。

选择「NVIDIA GeForce RTX 4090」以及「MATLAB」镜像,OpenBayes 平台提供了 4 种计费方式,大家可以按照需求选择「按量付费」或「包日/周/月」,点击「继续执行」。可以使用文章开头的邀请链接,获得 RTX 4090 使用时长!


待系统分配好资源,当状态变为「运行中」后,点击「打开工作空间」。


在「工作空间」的「控制台」处找到「Matlab」,运行以下代码:
代码块
JavaScript
自动换行
复制代码
123
f = imread('1.png');
imshow(f);
title('原始图像');
复制成功

代码实现(此处已将 RemoveFogByRetinex.m 代码文件准备完毕,已保存在 home 目录下,可以直接在下一步使用运行)
代码块
JavaScript
自动换行
复制代码
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
function In = RemoveFogByRetinex_GPU(f, flag)
% 启用CUDA前向兼容性
parallel.gpu.enableCUDAForwardCompatibility(true);
if nargin < 2
flag = 1;
end
% 转换到 GPU
f = gpuArray(im2double(f));
% 拆分颜色通道
fr = f(:, :, 1);
fg = f(:, :, 2);
fb = f(:, :, 3);
% 归一化
mr = mat2gray(fr);
mg = mat2gray(fg);
mb = mat2gray(fb);
% 设置滤波参数
alpha = 200;
n = floor(min([size(f, 1) size(f, 2)]) * 0.5);
n1 = floor((n + 1) / 2);
% 创建滤波核
[X, Y] = meshgrid(1:n, 1:n);
b = exp(-((X - n1).^2 + (Y - n1).^2) / (4 * alpha)) / (pi * alpha);
b = gpuArray(b);
% 进行滤波
nr1 = imfilter(mr, b, 'conv', 'replicate');
ng1 = imfilter(mg, b, 'conv', 'replicate');
nb1 = imfilter(mb, b, 'conv', 'replicate');
% 计算 Retinex 公式(避免 log(0) 问题)
ur1 = log(max(nr1, 0.01));
ug1 = log(max(ng1, 0.01));
ub1 = log(max(nb1, 0.01));
tr1 = log(max(mr, 0.01));
tg1 = log(max(mg, 0.01));
tb1 = log(max(mb, 0.01));
% 计算 Retinex 输出
yr1 = tr1 - ur1;
yg1 = tg1 - ug1;
yb1 = tb1 - ub1;
% 归一化(手动调整范围)
min_val = min([min(yr1(:)), min(yg1(:)), min(yb1(:))]);
max_val = max([max(yr1(:)), max(yg1(:)), max(yb1(:))]);
yr1 = (yr1 - min_val) / (max_val - min_val);
yg1 = (yg1 - min_val) / (max_val - min_val);
yb1 = (yb1 - min_val) / (max_val - min_val);
% 转换到 uint8
cr = gather(im2uint8(yr1));
cg = gather(im2uint8(yg1));
cb = gather(im2uint8(yb1));
% 合并通道
In = cat(3, cr, cg, cb);
% 显示结果
if flag
figure;
subplot(2, 2, 1);
imshow(gather(f)); title('原图像', 'FontWeight', 'Bold');
subplot(2, 2, 2);
imshow(In); title('处理后的图像', 'FontWeight', 'Bold');
Q = rgb2gray(gather(f));
M = rgb2gray(In);
subplot(2, 2, 3);
imhist(Q, 64); title('原灰度直方图', 'FontWeight', 'Bold');
subplot(2, 2, 4);
imhist(M, 64); title('处理后的灰度直方图', 'FontWeight', 'Bold');
end
end
复制成功

继续在「Matlab」控制台中输入以下命令运行去雾处理:
代码块
JavaScript
自动换行
复制代码
1
In = RemoveFogByRetinex(f, 1);
复制成功

继续在「Matlab」控制台中输入以下命令进一步增强对比度:
代码块
JavaScript
自动换行
复制代码
123456789
lab = rgb2lab(In);
L = lab(:, :, 1) / 100;
L = adapthisteq(L, 'ClipLimit', 0.02, 'Distribution', 'rayleigh');
lab(:, :, 1) = L * 100;
In = lab2rgb(lab);
In = imadjust(In, stretchlim(In, [0.01, 0.99]), []);
In = imsharpen(In, 'Radius', 2, 'Amount', 1.5);
imshow(In);
复制成功
免责声明:本文系网络转载或改编,未找到原创作者,版权归原作者所有。如涉及版权,请联系删