MATLAB을 이용한 이미지 디헤이징
이미지 디헤이징 – Retinex 알고리즘
1. 튜토리얼 소개
컴퓨터 비전 분야에서 이미지 디헤이징은 중요한 전처리 작업이며, 특히 자율 주행, 원격 감지 이미지 분석 및 모니터링 시스템에서 중요합니다. 디헤이징은 이미지 품질을 효과적으로 개선하고 대상을 더 선명하게 보이게 할 수 있습니다.이 프로젝트에서는 이미지 디헤이징을 위해 Retinex 알고리즘을 사용하고 이를 GPU 가속과 결합하여 계산 효율성을 개선합니다.
이 튜토리얼에서는 소프트웨어 이미지로 MATLAB를, 컴퓨팅 리소스로 RTX 4090을 사용합니다.
2. 이론적 근거
레티넥스 알고리즘 원리
레티넥스(Retina + Cortex)는 랜드와 맥캔이 제안한 이미지 향상 알고리즘으로, 주로 밝기 변화에 대한 인간 시각 시스템의 적응성에 기반을 두고 있습니다. 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)
- 레티넥스 출력 계산: R'(x, y) = log I(x, y) – log L'(x, y) 이 방법을 사용하면 조명의 영향을 줄이면서 이미지의 대비를 향상시킬 수 있습니다.
3. 작업 단계
1. 수술 준비
컨테이너를 복제하고 성공적으로 시작한 후 작업 공간을 엽니다.
- 소프트웨어 이미지는 MATLAB이고, 컴퓨팅 리소스는 RTX 4090이며, 액세스 방법은 "작업공간"입니다.

2. 이미지 로딩
"작업공간"의 "콘솔"에서 "Matlab"을 찾아 다음 코드를 입력하세요.
(이 튜토리얼에서는 홈 디렉토리에 샘플 이미지 "1.png"를 제공했으니, 코드만 입력하세요)
f = imread('1.png');
imshow(f);
title('原始图像');


3. 디헤이징 알고리즘을 실행하세요
코드 구현(RemoveFogByRetinex.m 코드 파일이 준비되고 홈 디렉토리에 저장되었으며 다음 단계에서 직접 사용하고 실행할 수 있음)
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
4. 디헤이징 프로세스를 실행합니다.
"Matlab" 콘솔에 다음 명령을 입력하여 안개 제거 프로세스를 실행합니다.
In = RemoveFogByRetinex(f, 1);

5. 대비를 더욱 강화합니다
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);
