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 主要特点
- 平移不变性:非下采样结构避免了下采样的混叠问题
- 多方向性:提供灵活的方向分解能力
- 完美重建:确保信号可以无失真重建
- 计算效率:相比Contourlet变换,计算复杂度有所增加但性能更好
5.3 参数选择建议
- 分解层数:通常3-5层,根据图像大小和应用需求选择
- 方向数:从粗尺度到细尺度逐渐增加,如[2, 4, 8]
- 滤波器选择 :
- 金字塔滤波器:'pyrexc'(推荐)、'maxflat'
- 方向滤波器:'dmaxflat7'(推荐)、'haar'