Retinex 算法 + MATLAB 软件,高效率完成图像去雾处理

在计算机视觉领域,图像去雾是一项重要的预处理任务,尤其是在自动驾驶、遥感图像分析以及监控系统中,去雾能够有效提升图像质量,使目标更加清晰可见。本项目采用 Retinex 算法进行图像去雾,并结合 GPU 加速以提高计算效率。

Retinex 算法原理:

Retinex (Retina + Cortex) 是 Land 和 McCann 提出的图像增强算法,主要基于人眼视觉系统对亮度变化的适应性。Retinex 算法的核心思想是:

  • 分解反射和光照:图像 I(x, y)由光照 L(x, y) 和反射率 R(x, y) 组成,即: I(x, y) = R(x, y) * L(x, y)
  • 对数变换:为了消除光照影响,取对数: log I(x, y) = log R(x, y) + log L(x, y)
  • 平滑光照:使用高斯滤波 G(x, y) 估计光照分量: L'(x, y) = G(x, y) * I(x, y)
  • 计算 Retinex 输出: R'(x, y) = log I(x, y) - log L'(x, y) 通过该方法,可以增强图像的对比度,同时减少光照影响。

教程链接:https://go.openbayes.com/vaEyL

使用云平台:OpenBayes
http://openbayes.com/console/signup?r=sony_0m6v

运行准备

登录 http://OpenBayes.com,在「公共教程」页面,选择键部署 「使用 MATLAB 进行图像去雾处理」教程。

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

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

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

加载图像

在「工作空间」的「控制台」处找到「Matlab」,运行以下代码:

复制代码
f = imread('1.png');
imshow(f);
title('原始图像');

运行去雾算法

代码实现(此处已将 RemoveFogByRetinex.m 代码文件准备完毕,已保存在 home 目录下,可以直接在下一步使用运行)

复制代码
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」控制台中输入以下命令运行去雾处理:

复制代码
In = RemoveFogByRetinex(f, 1);

进一步增强对比度

继续在「Matlab」控制台中输入以下命令进一步增强对比度:

复制代码
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);
相关推荐
双叶8363 分钟前
(C语言)单链表(1.0)(单链表教程)(数据结构,指针)
c语言·开发语言·数据结构·算法·游戏
想睡hhh6 分钟前
c++概念——入门基础概念
开发语言·c++
2301_7644413310 分钟前
基于神经网络的肾脏疾病预测模型
人工智能·深度学习·神经网络
肖永威14 分钟前
python列表常用方法大全
开发语言·python
子燕若水17 分钟前
用gpt-4o 生成图的教程和常用提示词
人工智能
愚润求学20 分钟前
【C++】vector的模拟实现
开发语言·c++·stl·语法
weixin_4424240321 分钟前
Opencv计算机视觉编程攻略-第七节 提取直线、轮廓和区域
人工智能·opencv·计算机视觉
x-cmd23 分钟前
[250401] OpenAI 向免费用户开放 GPT-4o 图像生成功能 | Neovim 0.11 新特性解读
人工智能·gpt·文生图·openai·命令行·neovim
uhakadotcom27 分钟前
OpenAI 的 PaperBench:AI 研究复现基准测试工具
算法·面试·github
HABuo32 分钟前
【YOLOv8】YOLOv8改进系列(12)----替换主干网络之StarNet
人工智能·深度学习·yolo·目标检测·计算机视觉