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);
相关推荐
亚马逊云开发者6 分钟前
Amazon OpenSearch 助力高效 RAG 系统落地
人工智能
suke8 分钟前
听说前端又死了?
前端·人工智能·程序员
小小小怪兽24 分钟前
关于氛围编程(Vibe Coding)的一切
人工智能·全栈
Sɪʟᴇɴᴛ໊ོ23527 分钟前
Anyview数据结构第一章(按需自取)
c语言·开发语言·数据结构·算法
付玉祥31 分钟前
从谷歌白皮书看 Prompt 工程
人工智能
松岛雾奈.23032 分钟前
机器学习--数据集的标准化和归一化算法;随机森林
人工智能·算法·机器学习
黑仔要睡觉34 分钟前
Anaconda和Pycharm的卸载
开发语言·python
阿明Drift34 分钟前
用 RAG 搭建一个 AI 小说问答系统
前端·人工智能
朱龙凯39 分钟前
LangChain学习笔记
人工智能
橘颂TA40 分钟前
【剑斩OFFER】算法的暴力美学——丢失的数字
数据结构·算法·leetcode·结构与算法