NSCT(非下采样轮廓波变换)的分解和重建程序

NSCT(非下采样轮廓波变换)的分解和重建程序。NSCT是一种优秀的多尺度几何分析工具,具有平移不变性和良好的方向选择性。

1. NSCT基本原理

NSCT主要包含两个部分:

  • 非下采样金字塔(NSP):实现多尺度分解
  • 非下采样方向滤波器组(NSDFB):实现多方向分解

2. 完整的MATLAB实现

2.1 主函数:NSCT分解与重建

matlab 复制代码
function [coeffs, params] = nsctdec(x, levels, dfilter, pfilter)
% NSCT分解 - 非下采样轮廓波变换
% 输入:
%   x - 输入图像
%   levels - 分解层数向量,如[1,2,3]表示3层,每层方向数
%   dfilter - 方向滤波器
%   pfilter - 金字塔滤波器
% 输出:
%   coeffs - 变换系数
%   params - 变换参数

    if nargin < 4
        pfilter = 'pyrexc'; % 默认金字塔滤波器
    end
    if nargin < 3
        dfilter = 'dmaxflat7'; % 默认方向滤波器
    end
    
    % 参数初始化
    [h, w] = size(x);
    nlevels = length(levels);
    coeffs = cell(1, nlevels + 1);
    params = struct();
    params.levels = levels;
    params.dfilter = dfilter;
    params.pfilter = pfilter;
    params.imsize = [h, w];
    
    % 第1层:非下采样金字塔分解
    [lowpass, highpass] = nspdec(x, pfilter);
    coeffs{1} = highpass; % 高频子带
    
    current_low = lowpass;
    
    % 后续各层分解
    for k = 1:nlevels
        % 方向滤波器组分解
        if levels(k) > 0
            dir_coeffs = nsdfbdec(current_low, levels(k), dfilter);
            coeffs{k+1} = dir_coeffs;
        else
            % 如果没有方向分解,直接存储低频
            coeffs{k+1} = current_low;
        end
        
        % 如果不是最后一层,继续金字塔分解
        if k < nlevels
            [current_low, highpass] = nspdec(current_low, pfilter);
            coeffs{k+1} = highpass; % 更新当前层的高频
        end
    end
    
    % 存储最终的低频系数
    coeffs{end} = current_low;
end

function y = nsctrec(coeffs, params)
% NSCT重建 - 非下采样轮廓波逆变换
% 输入:
%   coeffs - 变换系数
%   params - 变换参数
% 输出:
%   y - 重建图像

    levels = params.levels;
    dfilter = params.dfilter;
    pfilter = params.pfilter;
    nlevels = length(levels);
    
    % 从最后一层开始重建
    current_recon = coeffs{end};
    
    for k = nlevels:-1:1
        % 如果是方向子带,进行方向重建
        if levels(k) > 0 && k < length(coeffs)-1
            if iscell(coeffs{k+1})
                current_recon = nsdfbrec(current_recon, coeffs{k+1}, levels(k), dfilter);
            end
        end
        
        % 金字塔重建
        if k > 1
            current_recon = nsprec(current_recon, coeffs{k}, pfilter);
        end
    end
    
    % 最终重建
    y = nsprec(current_recon, coeffs{1}, pfilter);
end

2.2 非下采样金字塔分解(NSP)

matlab 复制代码
function [lowpass, highpass] = nspdec(x, pfilter)
% 非下采样金字塔分解
% 输入:
%   x - 输入图像
%   pfilter - 金字塔滤波器
% 输出:
%   lowpass - 低频子带
%   highpass - 高频子带

    % 获取滤波器
    [h0, h1, g0, g1] = pfilters(pfilter);
    
    % 低频滤波(使用atrous算法)
    lowpass = atrousfilter(x, h0, 1);
    
    % 高频滤波
    highpass_approx = atrousfilter(x, h1, 1);
    
    % 计算高频子带(残差)
    highpass = x - lowpass;
end

function y = nsprec(lowpass, highpass, pfilter)
% 非下采样金字塔重建
% 输入:
%   lowpass - 低频子带
%   highpass - 高频子带
%   pfilter - 金字塔滤波器
% 输出:
%   y - 重建图像

    [h0, h1, g0, g1] = pfilters(pfilter);
    
    % 简单相加重建(因为是非下采样)
    y = lowpass + highpass;
    
    % 可选:使用合成滤波器进行更精确的重建
    % y = atrousfilter(lowpass, g0, 1) + atrousfilter(highpass, g1, 1);
end

function y = atrousfilter(x, h, level)
% Atrous算法实现非下采样滤波
% 输入:
%   x - 输入图像
%   h - 滤波器
%   level - 分解层数
% 输出:
%   y - 滤波结果

    % 滤波器上采样
    h_upsampled = upfilter(h, level);
    
    % 卷积运算
    y = imfilter(x, h_upsampled, 'conv', 'symmetric');
end

function h_up = upfilter(h, level)
% 滤波器上采样(插入零值)
% 输入:
%   h - 原始滤波器
%   level - 上采样级别
% 输出:
%   h_up - 上采样后的滤波器

    if level == 0
        h_up = h;
        return;
    end
    
    % 计算上采样因子
    factor = 2^(level-1);
    
    % 创建上采样滤波器
    len = length(h);
    h_up = zeros(1, (len-1)*factor + 1);
    h_up(1:factor:end) = h;
end

2.3 非下采样方向滤波器组(NSDFB)

matlab 复制代码
function dir_coeffs = nsdfbdec(x, ndir, dfilter)
% 非下采样方向滤波器组分解
% 输入:
%   x - 输入图像
%   ndir - 方向数(2的幂次)
%   dfilter - 方向滤波器
% 输出:
%   dir_coeffs - 方向子带系数

    if ndir == 1
        dir_coeffs = x;
        return;
    end
    
    % 获取方向滤波器
    [h0, h1] = dfilters(dfilter);
    
    % 第一级分解(2个方向)
    dir1 = fanfilter(x, h0, 1);
    dir2 = fanfilter(x, h1, 1);
    
    if ndir == 2
        dir_coeffs = {dir1, dir2};
        return;
    end
    
    % 递归分解得到更多方向
    dir_coeffs = cell(1, ndir);
    dir_coeffs(1:ndir/2) = nsdfbdec(dir1, ndir/2, dfilter);
    dir_coeffs(ndir/2+1:ndir) = nsdfbdec(dir2, ndir/2, dfilter);
end

function y = nsdfbrec(lowpass, dir_coeffs, ndir, dfilter)
% 非下采样方向滤波器组重建
% 输入:
%   lowpass - 低频分量(实际上在NSCT中不使用)
%   dir_coeffs - 方向子带系数
%   ndir - 方向数
%   dfilter - 方向滤波器
% 输出:
%   y - 重建图像

    if ndir == 1
        y = dir_coeffs;
        return;
    end
    
    [h0, h1, g0, g1] = dfilters(dfilter);
    
    if ndir == 2
        % 2方向重建
        y1 = fanfilter(dir_coeffs{1}, g0, 1);
        y2 = fanfilter(dir_coeffs{2}, g1, 1);
        y = y1 + y2;
        return;
    end
    
    % 递归重建
    half = ndir/2;
    rec1 = nsdfbrec([], dir_coeffs(1:half), half, dfilter);
    rec2 = nsdfbrec([], dir_coeffs(half+1:end), half, dfilter);
    
    y1 = fanfilter(rec1, g0, 1);
    y2 = fanfilter(rec2, g1, 1);
    y = y1 + y2;
end

function y = fanfilter(x, h, level)
% 扇形滤波器实现方向分解
% 输入:
%   x - 输入图像
%   h - 滤波器
%   level - 分解级别
% 输出:
%   y - 滤波结果

    % 创建扇形滤波器掩模
    fan_mask = fan2d(h, level);
    
    % 频域滤波
    X = fft2(x);
    Y = X .* fft2(fan_mask, size(X,1), size(X,2));
    y = real(ifft2(Y));
end

function mask = fan2d(h, level)
% 生成2D扇形滤波器掩模
    len = length(h);
    center = ceil(len/2);
    
    % 创建1D滤波器矩阵
    h_mat = h' * h;
    
    % 创建扇形区域
    [M, N] = size(h_mat);
    [X, Y] = meshgrid(1:N, 1:M);
    center_x = ceil(N/2);
    center_y = ceil(M/2);
    
    % 45度扇形区域
    angle_mask = abs(X - center_x) <= abs(Y - center_y);
    
    mask = zeros(size(h_mat));
    mask(angle_mask) = h_mat(angle_mask);
    
    % 归一化
    mask = mask / sum(mask(:));
end

2.4 滤波器设计

matlab 复制代码
function [h0, h1, g0, g1] = pfilters(type)
% 金字塔滤波器设计
% 输入:
%   type - 滤波器类型
% 输出:
%   h0, h1 - 分析滤波器(低通、高通)
%   g0, g1 - 合成滤波器(低通、高通)

    switch lower(type)
        case 'pyrexc' % 金字塔示例滤波器
            % 简单的9/7小波滤波器(近似)
            h0 = [0.026748757411, -0.016864118443, -0.078223266529, ...
                  0.266864118443, 0.602949018236, 0.266864118443, ...
                  -0.078223266529, -0.016864118443, 0.026748757411];
            h1 = [-0.091271763114, -0.057543526229, 0.591271763114, ...
                  1.115087052457, 0.591271763114, -0.057543526229, ...
                  -0.091271763114];
            
        case 'maxflat'
            % 最大平坦滤波器
            h0 = [1, 4, 6, 4, 1] / 16;
            h1 = [-1, -2, 6, -2, -1] / 4;
            
        otherwise
            error('未知的金字塔滤波器类型');
    end
    
    % 确保滤波器为行向量
    h0 = h0(:)';
    h1 = h1(:)';
    
    % 计算合成滤波器(QMF关系)
    g0 = (-1).^(0:length(h1)-1) .* h1;
    g1 = (-1).^(1:length(h0)) .* h0;
end

function [h0, h1, g0, g1] = dfilters(type)
% 方向滤波器设计
% 输入:
%   type - 滤波器类型
% 输出:
%   h0, h1 - 分析滤波器
%   g0, g1 - 合成滤波器

    switch lower(type)
        case 'dmaxflat7' % 7阶最大平坦方向滤波器
            h0 = [0.010493, 0.032875, 0.030235, -0.187035, ...
                  -0.027984, 0.630881, 0.714847, 0.230378];
            h1 = [-0.230378, 0.714847, -0.630881, -0.027984, ...
                  0.187035, 0.030235, -0.032875, 0.010493];
                  
        case 'haar' % Haar方向滤波器
            h0 = [1, 1] / sqrt(2);
            h1 = [1, -1] / sqrt(2);
            
        otherwise
            error('未知的方向滤波器类型');
    end
    
    h0 = h0(:)';
    h1 = h1(:)';
    
    % 计算合成滤波器
    g0 = fliplr(h0);
    g1 = fliplr(h1);
end

3. 应用示例

3.1 基本使用示例

matlab 复制代码
function demo_nsct_basic()
% NSCT基本使用演示
    
    % 生成测试图像
    x = im2double(imread('cameraman.tif'));
    if size(x, 3) > 1
        x = rgb2gray(x);
    end
    
    % NSCT参数
    levels = [2, 3, 4]; % 3层分解,方向数分别为2,4,8
    dfilter = 'dmaxflat7';
    pfilter = 'pyrexc';
    
    fprintf('开始NSCT分解...\n');
    tic;
    % NSCT分解
    [coeffs, params] = nsctdec(x, levels, dfilter, pfilter);
    decomposition_time = toc;
    
    fprintf('NSCT分解完成,耗时: %.2f秒\n', decomposition_time);
    fprintf('系数结构: %d个频带\n', length(coeffs));
    
    % 显示系数
    show_nsct_coeffs(coeffs, levels);
    
    % NSCT重建
    fprintf('开始NSCT重建...\n');
    tic;
    y = nsctrec(coeffs, params);
    reconstruction_time = toc;
    
    fprintf('NSCT重建完成,耗时: %.2f秒\n', reconstruction_time);
    
    % 计算重建误差
    mse = mean((x(:) - y(:)).^2);
    psnr = 10 * log10(1 / mse);
    
    fprintf('重建质量: MSE=%.6f, PSNR=%.2f dB\n', mse, psnr);
    
    % 显示结果
    figure('Position', [100, 100, 1200, 400]);
    subplot(1,3,1); imshow(x); title('原始图像');
    subplot(1,3,2); imshow(y); title('重建图像');
    subplot(1,3,3); imshow(abs(x-y), []); title('差异图像');
    colormap(jet);
end

function show_nsct_coeffs(coeffs, levels)
% 显示NSCT系数
    nlevels = length(levels);
    
    % 计算显示布局
    total_subplots = 1 + sum(2.^levels);
    rows = ceil(sqrt(total_subplots));
    cols = ceil(total_subplots / rows);
    
    figure('Position', [200, 200, 800, 600]);
    
    % 显示低频系数
    subplot(rows, cols, 1);
    imshow(coeffs{end}, []);
    title('低频子带');
    
    idx = 2;
    for k = 1:nlevels
        if levels(k) == 0
            % 无方向分解
            subplot(rows, cols, idx);
            imshow(coeffs{k}, []);
            title(sprintf('层%d高频', k));
            idx = idx + 1;
        else
            % 方向子带
            nDir = 2^levels(k);
            for d = 1:nDir
                subplot(rows, cols, idx);
                if iscell(coeffs{k+1})
                    imshow(coeffs{k+1}{d}, []);
                else
                    imshow(coeffs{k+1}, []);
                end
                title(sprintf('层%d-方向%d', k, d));
                idx = idx + 1;
            end
        end
    end
    
    sgtitle('NSCT系数分布');
end

3.2 图像融合应用

matlab 复制代码
function fused_image = nsct_fusion(image1, image2, levels, dfilter, pfilter)
% 基于NSCT的图像融合
% 输入:
%   image1, image2 - 输入图像
%   levels - 分解层数
%   dfilter - 方向滤波器
%   pfilter - 金字塔滤波器
    
    if nargin < 5
        pfilter = 'pyrexc';
    end
    if nargin < 4
        dfilter = 'dmaxflat7';
    end
    if nargin < 3
        levels = [2, 3, 4];
    end
    
    % NSCT分解
    [coeffs1, params] = nsctdec(image1, levels, dfilter, pfilter);
    [coeffs2, ~] = nsctdec(image2, levels, dfilter, pfilter);
    
    % 系数融合
    fused_coeffs = cell(size(coeffs1));
    
    % 低频系数融合(平均)
    fused_coeffs{end} = (coeffs1{end} + coeffs2{end}) / 2;
    
    % 高频系数融合(取绝对值最大)
    for k = 1:length(levels)
        if levels(k) > 0 && iscell(coeffs1{k+1})
            nDir = length(coeffs1{k+1});
            fused_coeffs{k+1} = cell(1, nDir);
            for d = 1:nDir
                % 基于区域能量的融合规则
                fused_coeffs{k+1}{d} = region_energy_fusion(...
                    coeffs1{k+1}{d}, coeffs2{k+1}{d});
            end
        end
    end
    
    % NSCT重建
    fused_image = nsctrec(fused_coeffs, params);
end

function fused = region_energy_fusion(coeff1, coeff2)
% 基于区域能量的系数融合
    window_size = 3;
    window = ones(window_size) / (window_size^2);
    
    % 计算区域能量
    energy1 = imfilter(coeff1.^2, window, 'symmetric');
    energy2 = imfilter(coeff2.^2, window, 'symmetric');
    
    % 选择能量较大的系数
    mask = energy1 >= energy2;
    fused = coeff1 .* mask + coeff2 .* (~mask);
end

3.3 去噪应用

matlab 复制代码
function denoised_image = nsct_denoise(noisy_image, levels, threshold_type)
% 基于NSCT的图像去噪
% 输入:
%   noisy_image - 含噪图像
%   levels - 分解层数
%   threshold_type - 阈值类型 ('soft', 'hard')
    
    if nargin < 3
        threshold_type = 'soft';
    end
    if nargin < 2
        levels = [2, 3, 4];
    end
    
    % NSCT分解
    [coeffs, params] = nsctdec(noisy_image, levels);
    
    % 估计噪声标准差
    sigma = median(abs(coeffs{1}(:))) / 0.6745;
    
    % 阈值处理高频系数
    for k = 1:length(levels)
        if levels(k) > 0 && iscell(coeffs{k+1})
            nDir = length(coeffs{k+1});
            for d = 1:nDir
                % 计算方向子带的阈值
                lambda = sigma * sqrt(2 * log(numel(coeffs{k+1}{d})));
                
                % 应用阈值
                coeffs{k+1}{d} = apply_threshold(coeffs{k+1}{d}, lambda, threshold_type);
            end
        end
    end
    
    % 处理第一层高频
    lambda = sigma * sqrt(2 * log(numel(coeffs{1})));
    coeffs{1} = apply_threshold(coeffs{1}, lambda, threshold_type);
    
    % NSCT重建
    denoised_image = nsctrec(coeffs, params);
end

function y = apply_threshold(x, lambda, type)
% 应用阈值
    switch lower(type)
        case 'hard'
            y = x .* (abs(x) > lambda);
        case 'soft'
            y = sign(x) .* max(abs(x) - lambda, 0);
        otherwise
            error('未知的阈值类型');
    end
end

4. 性能评估

matlab 复制代码
function evaluate_nsct_performance()
% 评估NSCT性能
    
    % 测试图像
    x = im2double(imread('lena.png'));
    if size(x, 3) > 1
        x = rgb2gray(x);
    end
    
    % 不同的分解层数
    level_configs = {[2, 3], [2, 3, 4], [2, 3, 4, 5]};
    times = zeros(length(level_configs), 2);
    errors = zeros(length(level_configs), 1);
    
    for i = 1:length(level_configs)
        levels = level_configs{i};
        
        % 分解时间
        tic;
        [coeffs, params] = nsctdec(x, levels);
        times(i, 1) = toc;
        
        % 重建时间
        tic;
        y = nsctrec(coeffs, params);
        times(i, 2) = toc;
        
        % 重建误差
        errors(i) = mean((x(:) - y(:)).^2);
        
        fprintf('层数配置: %s\n', mat2str(levels));
        fprintf('  分解时间: %.3f秒, 重建时间: %.3f秒\n', times(i,1), times(i,2));
        fprintf('  重建MSE: %.6f\n', errors(i));
    end
    
    % 绘制性能图
    figure;
    subplot(1,2,1);
    plot(1:length(level_configs), times, 'o-', 'LineWidth', 2);
    legend('分解时间', '重建时间', 'Location', 'northwest');
    xlabel('配置索引');
    ylabel('时间(秒)');
    title('计算时间比较');
    grid on;
    
    subplot(1,2,2);
    plot(1:length(level_configs), errors, 'ro-', 'LineWidth', 2);
    xlabel('配置索引');
    ylabel('MSE');
    title('重建误差');
    grid on;
    
    sgtitle('NSCT性能评估');
end

参考代码 NSCT分解和重建程序 www.3dddown.com/csa/82211.html

5. 使用说明

5.1 安装要求

  • MATLAB R2016b或更高版本
  • 图像处理工具箱
  • 信号处理工具箱

5.2 主要特点

  1. 平移不变性:非下采样结构避免了下采样的混叠问题
  2. 多方向性:提供灵活的方向分解能力
  3. 完美重建:确保信号可以无失真重建
  4. 计算效率:相比Contourlet变换,计算复杂度有所增加但性能更好

5.3 参数选择建议

  • 分解层数:通常3-5层,根据图像大小和应用需求选择
  • 方向数:从粗尺度到细尺度逐渐增加,如[2, 4, 8]
  • 滤波器选择
    • 金字塔滤波器:'pyrexc'(推荐)、'maxflat'
    • 方向滤波器:'dmaxflat7'(推荐)、'haar'
相关推荐
晨晖23 小时前
单链表逆转,c语言
c语言·数据结构·算法
im_AMBER4 小时前
Leetcode 78 识别数组中的最大异常值 | 镜像对之间最小绝对距离
笔记·学习·算法·leetcode
鼾声鼾语5 小时前
matlab的ros2发布的消息,局域网内其他设备收不到情况吗?但是matlab可以订阅其他局域网的ros2发布的消息(问题总结)
开发语言·人工智能·深度学习·算法·matlab·isaaclab
LYFlied5 小时前
【每日算法】LeetCode 25. K 个一组翻转链表
算法·leetcode·链表
Swizard5 小时前
别再迷信“准确率”了!一文读懂 AI 图像分割的黄金标尺 —— Dice 系数
python·算法·训练
s09071365 小时前
紧凑型3D成像声纳实现路径
算法·3d·声呐·前视多波束
可爱的小小小狼5 小时前
算法:二叉树遍历
算法
d111111111d6 小时前
在STM32函数指针是什么,怎么使用还有典型应用场景。
笔记·stm32·单片机·嵌入式硬件·学习·算法
AI科技星7 小时前
质量定义方程常数k = 4π m_p的来源、推导与意义
服务器·数据结构·人工智能·科技·算法·机器学习·生活