帮做我改进hsv_svd_clahe函数文件
代码如下:
% ===================== 主程序 =====================
clear, clc, close all;
% 加载测试图像
low_light = imread('D:\SVD\实验素材\LOLdataset\our485\low\101.png');
reference = imread('D:\SVD\实验素材\LOLdataset\our485\high\101.png'); % 正常光照参考图像
% 初始化结果表
methods = {'HE', 'BIMEF', 'LIME', 'MSRCR', 'HSV-SVD-CLAHE'};
results = zeros(5, 6); % 5种方法 x 6个指标 (PSNR, SSIM, Avg Gradient, Entropy, NIQE, VIF)
% 评估每种方法
disp('评估HE方法...');
enhanced_he = he_method(low_light);
[results(1,1), results(1,2), results(1,3), results(1,4), results(1,5), results(1,6)] = ...
evaluate_image(enhanced_he, reference);
disp('评估BIMEF方法...');
enhanced_bimef = bimef(low_light);
[results(2,1), results(2,2), results(2,3), results(2,4), results(2,5), results(2,6)] = ...
evaluate_image(enhanced_bimef, reference);
disp('评估LIME方法...');
enhanced_lime = lime_method(low_light);
[results(3,1), results(3,2), results(3,3), results(3,4), results(3,5), results(3,6)] = ...
evaluate_image(enhanced_lime, reference);
disp('评估MSRCR方法...');
enhanced_msrcr = msrcr_method(low_light);
[results(4,1), results(4,2), results(4,3), results(4,4), results(4,5), results(4,6)] = ...
evaluate_image(enhanced_msrcr, reference);
disp('评估HSV-SVD-CLAHE方法...');
enhanced_proposed = hsv_svd_clahe(low_light);
[results(5,1), results(5,2), results(5,3), results(5,4), results(5,5), results(5,6)] = ...
evaluate_image(enhanced_proposed, reference);
% 显示结果
fprintf('\n%-25s %8s %8s %12s %10s %10s %10s\n', ...
'Method', 'PSNR', 'SSIM', 'Avg Gradient', 'Entropy', 'NIQE', 'VIF');
fprintf('--------------------------------------------------------------------------------------------\n');
for i = 1:5
fprintf('%-25s %8.2f %8.4f %12.4f %10.4f %10.4f %10.4f\n', ...
methods{i}, results(i,1), results(i,2), results(i,3), results(i,4), results(i,5), results(i,6));
end
% 可视化结果
figure('Position', [100, 50, 1200, 800], 'Name', '增强结果对比');
subplot(2,3,1); imshow(low_light); title('原始低照度图像');
subplot(2,3,2); imshow(enhanced_he); title('HE');
subplot(2,3,3); imshow(enhanced_bimef); title('BIMEF');
subplot(2,3,4); imshow(enhanced_lime); title('LIME');
subplot(2,3,5); imshow(enhanced_msrcr); title('MSRCR');
subplot(2,3,6); imshow(enhanced_proposed); title('HSV-SVD-CLAHE');
% 梯度可视化验证
figure('Position', [200, 100, 1200, 800], 'Name', '梯度分布验证');
subplot(2,3,1); plot_gradient(low_light, '原始图像梯度');
subplot(2,3,2); plot_gradient(enhanced_he, 'HE梯度');
subplot(2,3,3); plot_gradient(enhanced_bimef, 'BIMEF梯度');
subplot(2,3,4); plot_gradient(enhanced_lime, 'LIME梯度');
subplot(2,3,5); plot_gradient(enhanced_msrcr, 'MSRCR梯度');
subplot(2,3,6); plot_gradient(enhanced_proposed, '本文方法梯度');
% ===================== 梯度可视化函数 =====================
function plot_gradient(img, title_str)
img_double = im2double(img);
if size(img_double, 3) == 3
gray = rgb2gray(img_double);
else
gray = img_double;
end
% 计算梯度
[Gx, Gy] = imgradientxy(gray, 'sobel');
G_mag = sqrt(Gx.^2 + Gy.^2);
% 排除边界
[h, w] = size(G_mag);
border_cut = round(0.05*min(h, w));
if border_cut > 0
valid_region = G_mag(border_cut:end-border_cut, border_cut:end-border_cut);
else
valid_region = G_mag;
end
% 显示梯度幅值
imshow(valid_region, [0, 0.5]);
colorbar;
title(sprintf('%s\n平均梯度: %.4f', title_str, mean(valid_region(:))));
end
% ===================== 评估函数 =====================
% 指标 理想范围 说明
% PSNR >25 dB 值越高表示失真越小
% SSIM 0.8-1.0 值越接近1结构相似度越高
% Avg Gradient 0.1-0.3 值越高表示边缘越清晰
% Entropy >7 值越高表示信息越丰富
% NIQE <5 值越低表示感知质量越好
% VIF >0.6 值越高表示视觉信息保留越好
function [psnr_val, ssim_val, avg_grad, entropy_val, niqe_val, vif_val] = ...
evaluate_image(enhanced, reference)
% 输入验证
if nargin < 2, reference = []; end
% 转换为double类型
enhanced_double = im2double(enhanced);
% PSNR和SSIM计算
if ~isempty(reference) && isequal(size(enhanced), size(reference))
reference_double = im2double(reference);
psnr_val = psnr(enhanced_double, reference_double);
ssim_val = ssim(enhanced_double, reference_double);
% VIF计算(仅在有参考图像时)
vif_val = calculate_vif(enhanced, reference);
else
psnr_val = NaN;
ssim_val = NaN;
vif_val = NaN;
end
% 平均梯度
if size(enhanced_double, 3) == 3
gray_img = rgb2gray(enhanced_double);
else
gray_img = enhanced_double;
end
% 使用Sobel算子计算梯度
[Gx, Gy] = imgradientxy(gray_img, 'sobel');
% 计算梯度幅值
G_mag = sqrt(Gx.^2 + Gy.^2);
% 排除5%边界像素
[h, w] = size(G_mag);
border_cut = round(0.05*min(h, w));
if border_cut > 0
valid_region = G_mag(border_cut:end-border_cut, border_cut:end-border_cut);
else
valid_region = G_mag; % 小图像不排除边界
end
% 计算平均梯度
avg_grad = mean(valid_region(:));
% 信息熵
entropy_val = entropy(gray_img);
% NIQE指标
niqe_val = niqe(enhanced);
end
% ===================== VIF计算函数 =====================
function vif_val = calculate_vif(enhanced, reference)
% 计算视觉信息保真度(VIF)指标
% 转换为double类型并提取亮度通道(Y)
enhanced_y = rgb2ycbcr(im2double(enhanced));
reference_y = rgb2ycbcr(im2double(reference));
enhanced_y = enhanced_y(:,:,1);
reference_y = reference_y(:,:,1);
% 设置VIF参数
sigma_nsq = 0.1; % 噪声方差估计
num_scales = 4; % 多尺度分析层数
% 初始化VIF值
vif_val = 0;
% 多尺度VIF计算
for scale = 1:num_scales
% 下采样
if scale > 1
enhanced_y = imresize(enhanced_y, 0.5, 'bicubic');
reference_y = imresize(reference_y, 0.5, 'bicubic');
end
% 计算小波系数(使用db2滤波器)
[ref_coeff, ~] = dwt2(reference_y, 'db2');
[enh_coeff, ~] = dwt2(enhanced_y, 'db2');
% 计算子带信息
ref_var = imfilter(ref_coeff.^2, ones(3)/9, 'symmetric');
enh_var = imfilter(enh_coeff.^2, ones(3)/9, 'symmetric');
cross_var = imfilter(ref_coeff.*enh_coeff, ones(3)/9, 'symmetric');
% 计算互信息
g = cross_var ./ (ref_var + eps);
sv = enh_var - g.*cross_var;
% 计算信息量
ref_info = log2(1 + ref_var / sigma_nsq);
enh_info = log2(1 + (g.^2 .* ref_var) ./ (sv + sigma_nsq + eps));
% 累加VIF值
vif_val = vif_val + sum(enh_info(:)) / sum(ref_info(:));
end
% 平均多尺度结果
vif_val = vif_val / num_scales;
end
% ===================== 改进的本文方法 =====================
function enhanced_img = hsv_svd_clahe(img, beta, gamma, tau)
% 转换为HSV并计算平均亮度
img_double = im2double(img);
hsv_img = rgb2hsv(img_double);
V = hsv_img(:,:,3);
mean_brightness = mean(V(:));
% 参数自适应调整
if nargin < 2 || isempty(beta)
if mean_brightness < 0.2 % 极暗图像
beta = 3.2;
gamma = 0.6;
tau = 0.999; % 高阈值避免块状伪影
disp('参数模式: 极暗图像 (beta=3.2, gamma=0.6, tau=0.999)');
elseif mean_brightness < 0.5 % 低照度图像
beta = 2.5;
gamma = 0.7;
tau = 0.99; % 中等阈值
disp('参数模式: 低照度图像 (beta=2.5, gamma=0.7, tau=0.99)');
else % 正常图像
beta = 1.6;
gamma = 0.85;
tau = 0.95; % 较低阈值保留细节
disp('参数模式: 正常图像 (beta=1.6, gamma=0.85, tau=0.95)');
end
end
if nargin < 3 || isempty(gamma), gamma = 0.8; end
if nargin < 4 || isempty(tau), tau = 0.999; end % 默认高阈值
% 奇异值分解
[U, S, V_svd] = svd(V, 'econ');
sigma = diag(S);
total_energy = sum(sigma.^2);
% 确定主次成分分界点
cum_energy_ratio = cumsum(sigma.^2) / total_energy;
idx = find(cum_energy_ratio >= tau, 1);
if isempty(idx), idx = numel(sigma); end
% 主次成分差异化处理
sigma_enhanced = zeros(size(sigma));
sigma_enhanced(1:idx) = sigma(1:idx) * beta; % 主成分增强
sigma_enhanced(idx+1:end) = sigma(idx+1:end) * gamma; % 次成分抑制
% 重构亮度通道
V_enhanced = U * diag(sigma_enhanced) * V_svd';
V_enhanced = min(max(V_enhanced, 0), 1);
% 添加细节增强层
base_layer = imgaussfilt(V_enhanced, 1.5);
detail_layer = V_enhanced - base_layer;
V_enhanced = base_layer + 1.6 * detail_layer; % 增强细节
% 重组HSV并转RGB
hsv_enhanced = hsv_img;
hsv_enhanced(:,:,3) = V_enhanced;
rgb_enhanced = hsv2rgb(hsv_enhanced);
% CLAHE增强 (Lab空间)
lab_img = rgb2lab(rgb_enhanced);
L = lab_img(:,:,1) / 100;
L_clahe = adapthisteq(L, 'ClipLimit', 0.01, 'NumTiles', [8,8]);
lab_img(:,:,1) = L_clahe * 100;
enhanced_img = lab2rgb(lab_img, 'OutputType', 'double');
% 小波去噪(仅低照度图像)
if mean_brightness < 0.5
try
enhanced_img = wavelet_denoise(enhanced_img);
disp('应用小波去噪');
catch ME
warning('去噪步骤跳过: %s', ME.message);
end
end
% 转换为uint8
enhanced_img = im2uint8(enhanced_img);
end
% ===================== 小波去噪函数 =====================
function denoised_img = wavelet_denoise(img)
% 小波去噪处理泊松噪声
% 初始化输出
denoised_img = zeros(size(img));
% 小波去噪参数
wavelet = 'sym8';
level = 3;
% 对每个通道分别处理
for ch = 1:3
channel = img(:,:,ch);
% 使用Bayes方法去噪
denoised_channel = wdenoise2(channel, level, ...
'Wavelet', wavelet, ...
'DenoisingMethod', 'Bayes', ...
'ThresholdRule', 'median', ...
'NoiseEstimate', 'LevelDependent');
denoised_img(:,:,ch) = denoised_channel;
end
end
% ===================== 传统增强方法 =====================
% 直方图均衡化 (HE)
function enhanced = he_method(img)
enhanced = histeq(img);
end
% BIMEF方法
function enhanced = bimef(img)
% 读取彩色图像
img_double = im2double(img);
gray_img = rgb2gray(img_double);
log_img = log(1 + gray_img);
% BIMEF 算法参数
filter_size = 5;
step = 1;
enhanced_img = zeros(size(log_img));
for i = step:step:size(log_img, 1)-filter_size+1
for j = step:step:size(log_img, 2)-filter_size+1
h = ones(filter_size, filter_size) / (filter_size^2);
enhanced_img(i:i+filter_size-1, j:j+filter_size-1) = ...
exp(h * log_img(i:i+filter_size-1, j:j+filter_size-1));
end
end
enhanced_img = (enhanced_img - min(enhanced_img(:))) / ...
(max(enhanced_img(:)) - min(enhanced_img(:)));
enhanced_img = uint8(255 * enhanced_img);
% 转换为彩色
hsv_img = rgb2hsv(img_double);
hsv_img(:, :, 3) = mat2gray(enhanced_img);
enhanced = hsv2rgb(hsv_img);
enhanced = im2uint8(enhanced);
end
% LIME方法
function enhanced = lime_method(img)
img = im2double(img);
T = max(img, [], 3);
r = 16; eps = 0.01;
L = imguidedfilter(T, img, 'NeighborhoodSize', [r r], 'DegreeOfSmoothing', eps);
L = min(L, 1);
L_adjusted = imadjust(L, [min(L(:)) max(L(:))], [0.2 1]);
enhanced = zeros(size(img));
for ch = 1:3
enhanced(:,:,ch) = img(:,:,ch) ./ max(L_adjusted, 0.01);
end
enhanced = min(max(enhanced, 0), 1);
enhanced = im2uint8(enhanced);
end
% MSRCR方法
function enhanced_img = msrcr_method(img)
scales = [15, 80, 250];
alpha = 125; beta = 46; G = 5;
img = im2double(img);
msr = zeros(size(img));
for i = 1:numel(scales)
sigma = scales(i);
gaus_filter = fspecial('gaussian', 2*ceil(3*sigma)+1, sigma);
for ch = 1:3
log_img = log(img(:,:,ch) + 1e-6);
blurred = imfilter(img(:,:,ch), gaus_filter, 'symmetric');
log_blurred = log(blurred + 1e-6);
msr(:,:,ch) = msr(:,:,ch) + (log_img - log_blurred)/numel(scales);
end
end
color_restored = zeros(size(msr));
for ch = 1:3
I_ch = img(:,:,ch);
col_sum = sum(img,3);
color_restored(:,:,ch) = beta * (log(alpha*I_ch + 1) - log(col_sum + 1));
end
enhanced_img = G * (0.5*msr + 0.5*color_restored);
enhanced_img = (enhanced_img - min(enhanced_img(:))) / ...
(max(enhanced_img(:)) - min(enhanced_img(:)));
enhanced_img = im2uint8(enhanced_img);
end