基于形态学的权重自适应图像去噪的MATLAB实现
classdef MorphologicalAdaptiveDenoising
% 基于形态学的权重自适应图像去噪类
% 支持灰度图像和彩色图像的去噪
properties
structuring_elements
alpha
beta
iterations
end
methods
function obj = MorphologicalAdaptiveDenoising(varargin)
% 构造函数
p = inputParser;
addParameter(p, 'alpha', 0.7, @(x) x>0 && x<=1);
addParameter(p, 'beta', 0.3, @(x) x>0 && x<=1);
addParameter(p, 'iterations', 2, @(x) x>0);
parse(p, varargin{:});
obj.alpha = p.Results.alpha;
obj.beta = p.Results.beta;
obj.iterations = p.Results.iterations;
% 初始化结构元素
obj.structuring_elements.small = strel('square', 3);
obj.structuring_elements.medium = strel('square', 5);
obj.structuring_elements.large = strel('square', 7);
end
function denoised_image = denoise(obj, image, varargin)
% 主去噪函数
p = inputParser;
addParameter(p, 'method', 'adaptive', @ischar);
addParameter(p, 'noise_level', 'medium', @ischar);
parse(p, varargin{:});
if ndims(image) == 3
% 彩色图像处理 - 分别处理每个通道
denoised_image = zeros(size(image));
for channel = 1:3
switch p.Results.method
case 'adaptive'
denoised_image(:,:,channel) = ...
obj.weighted_morphological_denoising(...
image(:,:,channel));
case 'advanced'
denoised_image(:,:,channel) = ...
obj.advanced_morphological_denoising(...
image(:,:,channel), p.Results.noise_level);
end
end
else
% 灰度图像处理
switch p.Results.method
case 'adaptive'
denoised_image = obj.weighted_morphological_denoising(image);
case 'advanced'
denoised_image = obj.advanced_morphological_denoising(...
image, p.Results.noise_level);
end
end
denoised_image = uint8(denoised_image);
end
function local_variance = calculate_local_variance(obj, image, window_size)
% 计算局部方差
if nargin < 3
window_size = 5;
end
if ~isfloat(image)
image = im2double(image);
end
% 使用积分图像加速计算
padded_image = padarray(image, [window_size, window_size]/2, 'replicate');
squared_image = padded_image .^ 2;
% 计算均值和平方均值
mean_filter = ones(window_size) / (window_size^2);
local_mean = imfilter(padded_image, mean_filter, 'same');
local_mean_sq = imfilter(squared_image, mean_filter, 'same');
% 计算方差: Var = E[X^2] - (E[X])^2
local_variance = local_mean_sq - local_mean .^ 2;
% 去除填充
pad = floor(window_size/2);
local_variance = local_variance(pad+1:end-pad, pad+1:end-pad);
end
function gradient_mag = calculate_gradient_magnitude(obj, image)
% 计算梯度幅值
if ~isfloat(image)
image = im2double(image);
end
% Sobel算子
sobel_x = fspecial('sobel');
sobel_y = sobel_x';
grad_x = imfilter(image, sobel_x, 'replicate');
grad_y = imfilter(image, sobel_y, 'replicate');
gradient_mag = sqrt(grad_x.^2 + grad_y.^2);
% 归一化
if max(gradient_mag(:)) > 0
gradient_mag = gradient_mag / max(gradient_mag(:));
end
end
function weights = adaptive_weight_calculation(obj, image)
% 计算自适应权重
if ~isfloat(image)
image = im2double(image);
end
% 计算局部特征
local_var = obj.calculate_local_variance(image);
gradient_mag = obj.calculate_gradient_magnitude(image);
% 归一化
local_var_norm = (local_var - min(local_var(:))) / ...
(max(local_var(:)) - min(local_var(:)) + eps);
gradient_norm = (gradient_mag - min(gradient_mag(:))) / ...
(max(gradient_mag(:)) - min(gradient_mag(:)) + eps);
% 计算权重:细节区域权重小,平坦区域权重大
weights = 1.0 ./ (1.0 + obj.alpha * local_var_norm + obj.beta * gradient_norm);
end
function results = morphological_operations(obj, image, se_type)
% 执行多种形态学操作
switch se_type
case 'small'
se = obj.structuring_elements.small;
case 'medium'
se = obj.structuring_elements.medium;
case 'large'
se = obj.structuring_elements.large;
end
results.opening = imopen(image, se);
results.closing = imclose(image, se);
results.gradient = imdilate(image, se) - imerode(image, se);
results.top_hat = imtophat(image, se);
results.black_hat = imbothat(image, se);
end
function denoised_image = weighted_morphological_denoising(obj, image)
% 权重自适应形态学去噪
if ~isfloat(image)
image = im2double(image);
end
denoised = image;
for iter = 1:obj.iterations
% 计算自适应权重
weights = obj.adaptive_weight_calculation(denoised);
% 转换到uint8进行形态学操作
denoised_uint8 = im2uint8(denoised);
% 多尺度形态学操作
results_small = obj.morphological_operations(denoised_uint8, 'small');
results_medium = obj.morphological_operations(denoised_uint8, 'medium');
results_large = obj.morphological_operations(denoised_uint8, 'large');
% 转换回double
field_names = fieldnames(results_small);
for i = 1:length(field_names)
field = field_names{i};
results_small.(field) = im2double(results_small.(field));
results_medium.(field) = im2double(results_medium.(field));
results_large.(field) = im2double(results_large.(field));
end
% 权重融合
weighted_result = zeros(size(denoised));
% 根据权重分类区域
mask_high_weight = weights > 0.7; % 平坦区域
mask_medium_weight = weights >= 0.3 & weights <= 0.7; % 过渡区域
mask_low_weight = weights < 0.3; % 细节区域
% 平坦区域:使用大结构元素
weighted_result(mask_high_weight) = ...
0.6 * results_large.opening(mask_high_weight) + ...
0.4 * results_large.closing(mask_high_weight);
% 过渡区域:使用中等结构元素
weighted_result(mask_medium_weight) = ...
0.4 * results_medium.opening(mask_medium_weight) + ...
0.4 * results_medium.closing(mask_medium_weight) + ...
0.2 * results_small.gradient(mask_medium_weight);
% 细节区域:使用小结构元素,保留原始细节
weighted_result(mask_low_weight) = ...
0.5 * results_small.opening(mask_low_weight) + ...
0.3 * results_small.closing(mask_low_weight) + ...
0.2 * denoised(mask_low_weight);
denoised = weighted_result;
end
denoised_image = denoised;
end
function denoised_image = advanced_morphological_denoising(obj, image, noise_level)
% 增强版形态学去噪
if nargin < 3
noise_level = 'medium';
end
if ~isfloat(image)
image = im2double(image);
end
% 根据噪声水平调整参数
switch noise_level
case 'low'
iter = 1;
alpha_temp = 0.5;
beta_temp = 0.2;
case 'medium'
iter = 2;
alpha_temp = 0.7;
beta_temp = 0.3;
case 'high'
iter = 3;
alpha_temp = 0.9;
beta_temp = 0.4;
end
% 临时修改参数
original_alpha = obj.alpha;
original_beta = obj.beta;
obj.alpha = alpha_temp;
obj.beta = beta_temp;
% 形态学重建
reconstructed = obj.morphological_reconstruction_denoising(image, iter);
% 权重计算和最终融合
weights = obj.adaptive_weight_calculation(reconstructed);
denoised_image = obj.final_fusion(image, reconstructed, weights);
% 恢复原始参数
obj.alpha = original_alpha;
obj.beta = original_beta;
end
function reconstructed = morphological_reconstruction_denoising(obj, image, iterations)
% 形态学重建去噪
marker = image;
for i = 1:iterations
% 交替开闭运算
opening = imopen(marker, obj.structuring_elements.small);
closing = imclose(marker, obj.structuring_elements.small);
% 重建操作
marker = imclose(opening, obj.structuring_elements.medium);
marker = imopen(closing, obj.structuring_elements.medium);
end
reconstructed = marker;
end
function fused = final_fusion(obj, original, denoised, weights)
% 最终结果融合
if ~isfloat(original)
original = im2double(original);
end
if ~isfloat(denoised)
denoised = im2double(denoised);
end
% 计算边缘保护系数
gradient_original = obj.calculate_gradient_magnitude(original);
edge_preserve = exp(-gradient_original * 5);
% 融合
fused = edge_preserve .* original + (1 - edge_preserve) .* denoised;
end
end
methods (Static)
function noisy_image = add_noise(original_image, noise_type, varargin)
% 添加噪声
switch noise_type
case 'gaussian'
p = inputParser;
addOptional(p, 'sigma', 25, @isnumeric);
parse(p, varargin{:});
sigma = p.Results.sigma / 255;
noise = sigma * randn(size(original_image));
noisy_image = im2double(original_image) + noise;
noisy_image = im2uint8(noisy_image);
case 'salt_pepper'
p = inputParser;
addOptional(p, 'density', 0.05, @isnumeric);
parse(p, varargin{:});
noisy_image = imnoise(original_image, 'salt & pepper', p.Results.density);
case 'poisson'
noisy_image = imnoise(original_image, 'poisson');
end
end
function psnr_value = calculate_psnr(original, denoised)
% 计算PSNR
if ~isfloat(original)
original = im2double(original);
end
if ~isfloat(denoised)
denoised = im2double(denoised);
end
mse_value = mean((original(:) - denoised(:)) .^ 2);
if mse_value == 0
psnr_value = inf;
else
psnr_value = 20 * log10(1 / sqrt(mse_value));
end
end
function ssim_value = calculate_ssim(original, denoised)
% 计算SSIM
ssim_value = ssim(denoised, original);
end
end
end
% 演示函数
function demonstrate_morphological_denoising()
% 演示形态学去噪效果
% 创建测试图像
original = create_test_image();
% 添加噪声
noisy = MorphologicalAdaptiveDenoising.add_noise(original, 'gaussian', 30);
% 创建去噪器
denoiser = MorphologicalAdaptiveDenoising('alpha', 0.7, 'beta', 0.3, 'iterations', 2);
% 执行去噪
tic;
denoised_basic = denoiser.denoise(noisy, 'method', 'adaptive');
time_basic = toc;
tic;
denoised_advanced = denoiser.denoise(noisy, 'method', 'advanced', 'noise_level', 'medium');
time_advanced = toc;
% 计算指标
psnr_noisy = MorphologicalAdaptiveDenoising.calculate_psnr(original, noisy);
psnr_basic = MorphologicalAdaptiveDenoising.calculate_psnr(original, denoised_basic);
psnr_advanced = MorphologicalAdaptiveDenoising.calculate_psnr(original, denoised_advanced);
ssim_noisy = MorphologicalAdaptiveDenoising.calculate_ssim(original, noisy);
ssim_basic = MorphologicalAdaptiveDenoising.calculate_ssim(original, denoised_basic);
ssim_advanced = MorphologicalAdaptiveDenoising.calculate_ssim(original, denoised_advanced);
% 显示结果
figure('Position', [100, 100, 1200, 800]);
subplot(2, 3, 1);
imshow(original);
title('原始图像');
subplot(2, 3, 2);
imshow(noisy);
title(['加噪图像 - PSNR: ', num2str(psnr_noisy, '%.2f'), ' dB, SSIM: ', num2str(ssim_noisy, '%.3f')]);
subplot(2, 3, 3);
imshow(denoised_basic);
title(['基本去噪 - PSNR: ', num2str(psnr_basic, '%.2f'), ' dB, SSIM: ', num2str(ssim_basic, '%.3f'), ...
' (', num2str(time_basic, '%.2f'), 's)']);
subplot(2, 3, 4);
imshow(denoised_advanced);
title(['增强去噪 - PSNR: ', num2str(psnr_advanced, '%.2f'), ' dB, SSIM: ', num2str(ssim_advanced, '%.3f'), ...
' (', num2str(time_advanced, '%.2f'), 's)']);
% 显示权重图
weights = denoiser.adaptive_weight_calculation(noisy);
subplot(2, 3, 5);
imshow(weights, []);
title('自适应权重图');
colorbar;
% 显示局部方差
local_var = denoiser.calculate_local_variance(noisy);
subplot(2, 3, 6);
imshow(local_var, []);
title('局部方差图');
colorbar;
fprintf('去噪结果对比:\n');
fprintf('噪声图像 - PSNR: %.2f dB, SSIM: %.3f\n', psnr_noisy, ssim_noisy);
fprintf('基本去噪 - PSNR: %.2f dB, SSIM: %.3f, 时间: %.2fs\n', psnr_basic, ssim_basic, time_basic);
fprintf('增强去噪 - PSNR: %.2f dB, SSIM: %.3f, 时间: %.2fs\n', psnr_advanced, ssim_advanced, time_advanced);
end
function test_image = create_test_image()
% 创建测试图像
% 方法1: 使用内置图像
% test_image = imread('cameraman.tif');
% 方法2: 创建合成测试图像
test_image = 128 * ones(256, 256, 'uint8');
% 添加几何形状
test_image(50:100, 50:100) = 200; % 亮方块
test_image(150:200, 150:200) = 60; % 暗方块
% 添加纹理
[x, y] = meshgrid(1:256, 1:256);
texture = uint8(50 * sin(x/10) .* cos(y/10) + 128);
test_image = test_image + texture;
% 添加边缘
test_image(100:110, :) = 0; % 水平线
test_image(:, 100:110) = 0; % 垂直线
test_image = uint8(test_image);
end
% 批量处理函数
function batch_denoising_test()
% 批量测试不同噪声水平的去噪效果
original = create_test_image();
noise_levels = [15, 25, 50];
methods = {'adaptive', 'advanced'};
results = cell(length(noise_levels), length(methods));
figure('Position', [50, 50, 1500, 600]);
for i = 1:length(noise_levels)
noise_sigma = noise_levels(i);
noisy = MorphologicalAdaptiveDenoising.add_noise(original, 'gaussian', noise_sigma);
subplot(3, 4, (i-1)*4 + 1);
imshow(original);
title('原始图像');
subplot(3, 4, (i-1)*4 + 2);
imshow(noisy);
title(['噪声图像 (σ=', num2str(noise_sigma), ')']);
for j = 1:length(methods)
denoiser = MorphologicalAdaptiveDenoising();
denoised = denoiser.denoise(noisy, 'method', methods{j});
subplot(3, 4, (i-1)*4 + 2 + j);
imshow(denoised);
psnr_val = MorphologicalAdaptiveDenoising.calculate_psnr(original, denoised);
ssim_val = MorphologicalAdaptiveDenoising.calculate_ssim(original, denoised);
title([methods{j}, ' - PSNR: ', num2str(psnr_val, '%.2f'), ...
', SSIM: ', num2str(ssim_val, '%.3f')]);
results{i, j} = denoised;
end
end
end
% 使用示例
% demonstrate_morphological_denoising();
% batch_denoising_test();
这个MATLAB实现包含了以下主要特性:
功能
-
自适应权重计算
- 基于局部方差和梯度幅值
- 自动识别平坦区域和细节区域
-
多尺度形态学操作
- 小、中、大三种结构元素
- 开运算、闭运算、梯度等操作
-
权重融合策略
- 平坦区域:使用大结构元素
- 细节区域:使用小结构元素
- 过渡区域:中等结构元素
-
增强版算法
- 形态学重建
- 边缘保护融合
使用
% 基本使用
denoiser = MorphologicalAdaptiveDenoising();
denoised_image = denoiser.denoise(noisy_image);
% 高级选项
denoised_image = denoiser.denoise(noisy_image, 'method', 'advanced', 'noise_level', 'high');
% 彩色图像处理
denoised_color = denoiser.denoise(color_image);
参考代码 基于形态学的权重自适应图像去噪 www.youwenfan.com/contentcni/63976.html
优势
- 自适应性强:根据图像局部特征自动调整处理策略
- 细节保护:在去噪的同时有效保护图像边缘和纹理
- 多尺度处理:结合不同尺度的形态学操作
- 参数可调:支持灵活的参数调整以适应不同噪声水平