基于形态学的权重自适应图像去噪的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实现包含了以下主要特性:

功能

  1. 自适应权重计算

    • 基于局部方差和梯度幅值
    • 自动识别平坦区域和细节区域
  2. 多尺度形态学操作

    • 小、中、大三种结构元素
    • 开运算、闭运算、梯度等操作
  3. 权重融合策略

    • 平坦区域:使用大结构元素
    • 细节区域:使用小结构元素
    • 过渡区域:中等结构元素
  4. 增强版算法

    • 形态学重建
    • 边缘保护融合

使用

% 基本使用
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

优势

  1. 自适应性强:根据图像局部特征自动调整处理策略
  2. 细节保护:在去噪的同时有效保护图像边缘和纹理
  3. 多尺度处理:结合不同尺度的形态学操作
  4. 参数可调:支持灵活的参数调整以适应不同噪声水平
posted @ 2025-10-11 11:42  令小飞  阅读(7)  评论(0)    收藏  举报