同步挤压变换(Synchrosqueezing Transform, SST)是一种高效的时频分析手段,其核心思想是将连续小波变换后的时频能量沿瞬时频率脊线进行“挤压”,从而显著提升时频平面的分辨率。在此基础上发展出的同步提取变换(Synchroextracting Transform, SET),进一步优化了信息提取方式,能够直接从变换结果中精准捕获脊线成分,获得更为清晰的时频表示。
[此处为图片1]
这些改进共同作用,使得新方法在复杂信号环境下仍能保持良好的时频聚焦性和解析精度。
clear; clc; close all;
% ==================== 参数设置 ====================
fs = 1000; % 采样频率 (Hz)
T = 2; % 信号持续时间 (s)
t = 0:1/fs:T-1/fs; % 时间序列
N = length(t); % 总采样点数
% 构造复合测试信号:线性调频信号叠加正弦调制项
f0 = 5; % 起始频率 (Hz)
f1 = 80; % 终止频率 (Hz)
chirp_sig = chirp(t, f0, T, f1, 'linear'); % 线性扫频信号
mod_sig = sin(2*pi*15*t); % 15Hz正弦调制分量
sig = chirp_sig .* (1 + 0.3*mod_sig); % 幅度调制合成信号
% 添加高斯白噪声以模拟实际环境
SNR = 15; % 设定信噪比 (dB)
sig_noisy = awgn(sig, SNR, 'measured');
% 原始与含噪信号可视化展示
figure;
subplot(2,1,1);
plot(t, sig);
title('原始信号(无噪声)');
xlabel('时间 (s)'); ylabel('幅度');
xlim([0, 0.5]);
subplot(2,1,2);
plot(t, sig_noisy);
title(['含噪信号 (SNR = ' num2str(SNR) 'dB)']);
xlabel('时间 (s)'); ylabel('幅度');
xlim([0, 0.5]);
% ==================== 改进SET算法函数 ==================== function [tfr, f, tf] = improved_set(signal, fs, wavelet_name, scales) % 输入参数说明: % signal - 待分析信号 % fs - 采样频率 % wavelet_name - 所用小波基名称(如'morl', 'mexh', 'gaus') % scales - 尺度向量 % % 输出参数说明: % tfr - 最终输出的高分辨率时频表示矩阵 % f - 对应频率轴向量 % tf - 时间轴向量 %% 步骤一:执行连续小波变换(CWT) [wt, f] = cwt(signal, scales, wavelet_name, 'SamplingPeriod', 1/fs); %% 步骤二:应用小波阈值去噪进行预处理 wt_denoised = wdenoise(wt, 3, 'Wavelet', wavelet_name, 'DenoisingMethod', 'Bayes'); %% 步骤三:计算瞬时频率和相位信息 [inst_freq, phase] = compute_inst_freq(wt_denoised, scales, fs); %% 步骤四:实施自适应频率重排 [tfr, f_new] = adaptive_reassignment(wt_denoised, inst_freq, scales, f, fs); %% 步骤五:多尺度脊线融合处理 tfr_fused = multi_scale_fusion(tfr, wt_denoised, inst_freq, scales); %% 步骤六:能量集中度优化 tfr_final = energy_concentration(tfr_fused); %% 返回最终结果 tf = t; f = f_new; tfr = tfr_final; end
% ==================== 子函数:瞬时频率估算 ====================
function [inst_freq, phase] = compute_inst_freq(wt, scales, fs)
[na, nt] = size(wt);
phase = angle(wt);
inst_freq = zeros(na, nt);
for k = 1:nt
for j = 2:na-1
% 利用相邻尺度间的相位差估计瞬时频率
dphi_ds = (phase(j+1,k) - phase(j-1,k)) / (2 * diff(log(scales([j,j+1]))));
inst_freq(j,k) = -dphi_ds * fs / (2*pi*scales(j));
end
end
end
该部分通过解析小波系数的相位变化率,在尺度方向上估算每个时刻对应的瞬时频率值,为后续重排与脊线提取提供基础数据支持。
[此处为图片1]
% 相位导数计算(采用中心差分法)
dphase = phase(j+1, k) - phase(j-1, k);
% 执行相位展开:处理相位跳变
if abs(dphase) > pi
dphase = dphase - sign(dphase)*2*pi;
end
% 计算瞬时频率
inst_freq(j, k) = (1/(2*pi)) * (dphase / (scales(j)/fs)) * fs;
end
% 对边界点进行处理,防止越界
inst_freq(1, k) = inst_freq(2, k);
inst_freq(end, k) = inst_freq(end-1, k);
end
end
% ==================== 子函数:自适应频率重排 ====================
function [tfr, f_new] = adaptive_reassignment(wt, inst_freq, scales, f_orig, fs)
[na, nt] = size(wt);
tfr = zeros(na, nt);
f_new = linspace(min(f_orig), max(f_orig), na);
for k = 1:nt
for j = 1:na
if abs(wt(j, k)) > 0.01*max(abs(wt(:, k))) % 设定阈值筛选有效成分
% 确定目标频率对应的索引位置
target_bin = round(inst_freq(j, k) * na / max(f_orig));
target_bin = max(1, min(na, target_bin));
% 定义权重参数:主权重与邻域权重
alpha = 0.7; % 主要贡献权重
beta = 0.3; % 周边扩散权重
% 将主要能量累加至目标频点
tfr(target_bin, k) = tfr(target_bin, k) + alpha * abs(wt(j, k));
% 向相邻频点分配部分能量
for offset = -1:1
nb = target_bin + offset;
if nb >= 1 && nb <= na
tfr(nb, k) = tfr(nb, k) + beta * abs(wt(j, k)) / 3;
end
end
end
end
end
end
% ==================== 子函数:多尺度脊线融合 ====================
function tfr_fused = multi_scale_fusion(tfr, wt, inst_freq, scales)
[na, nt] = size(tfr);
tfr_fused = zeros(na, nt);
% 根据尺度生成权重:小尺度更具可靠性
scale_weights = 1./sqrt(scales);
scale_weights = scale_weights / max(scale_weights); % 归一化处理
for k = 1:nt
for j = 1:na
if abs(wt(j, k)) > 0.01*max(abs(wt(:, k)))
% 初始化投票数组
votes = zeros(1, na);
% 多尺度投票机制
for s = 1:na
if abs(wt(s, k)) > 0.01*max(abs(wt(:, k)))
target_bin = round(inst_freq(s, k) * na / max(inst_freq(:)));
target_bin = max(1, min(na, target_bin));
votes(target_bin) = votes(target_bin) + scale_weights(s);
end
end
% 选取得票最多的频率bin
[~, best_bin] = max(votes);
tfr_fused(best_bin, k) = tfr_fused(best_bin, k) + abs(wt(j, k));
end
end
end
end
% ==================== 子函数:能量集中优化 ====================
function tfr_final = energy_concentration(tfr)
[na, nt] = size(tfr);
tfr_final = zeros(na, nt);
% 统计每行的总能量分布
energy_dist = sum(tfr, 2);
energy_total = sum(energy_dist);
% 检测主要能量聚集区域(提取显著峰)
[~, main_bands] = findpeaks(energy_dist, 'MinPeakHeight', 0.05*max(energy_dist));
% 逐时间点执行能量优化重分配
for k = 1:nt
% ==================== 主程序调用与参数设置 ====================
% 定义小波类型及尺度范围
wavelet_name = 'morl'; % 选用Morlet小波
min_scale = 1; % 起始尺度
max_scale = 128; % 最大尺度值
num_scales = 64; % 尺度总数
scales = linspace(min_scale, max_scale, num_scales);
% 执行改进的SET方法进行时频分析
[tfr, f, t] = improved_set(sig_noisy, fs, wavelet_name, scales);
% 同时计算传统SST结果用于对比
[sst_tfr, sst_f, sst_t] = wsst(sig_noisy, wavelet_name, scales, fs);
[此处为图片1]
% ==================== 时频图可视化展示 ====================
% 绘制改进SET方法的时频分布
figure;
imagesc(t, f, abs(tfr));
axis xy; colorbar;
title('改进SET时频分析');
xlabel('时间 (s)'); ylabel('频率 (Hz)');
colormap jet;
[此处为图片2]
% 显示传统SST方法的时频表示
figure;
imagesc(sst_t, sst_f, abs(sst_tfr));
axis xy; colorbar;
title('传统SST时频分析');
xlabel('时间 (s)'); ylabel('频率 (Hz)');
colormap jet;
[此处为图片3]
% 提取主能量轨迹:瞬时频率估计
[~, ridge_idx] = max(abs(tfr), [], 1);
ridge_freq = f(ridge_idx);
% 对比提取频率与理论真实频率曲线
figure;
subplot(2,1,1);
plot(t, sig_noisy);
title('含噪信号');
xlabel('时间 (s)'); ylabel('幅度');
subplot(2,1,2);
plot(t, ridge_freq);
hold on;
plot(t, f0 + (f1-f0)*(t/T), 'r--', 'LineWidth', 1.5); % 理论瞬时频率
title('提取的瞬时频率');
xlabel('时间 (s)'); ylabel('频率 (Hz)');
legend('SET提取', '理论频率');
grid on;
[此处为图片4]
% ==================== 性能指标评估与比较 ====================
% 计算Renyi熵以评估时频聚焦性(数值越小表示效果越好)
entropy_set = renyi_entropy(abs(tfr));
entropy_sst = renyi_entropy(abs(sst_tfr));
fprintf('改进SET Renyi熵: %.4f\n', entropy_set);
fprintf('传统SST Renyi熵: %.4f\n', entropy_sst);
% 计算能量集中度(越高代表能量越集中)
concentration_set = concentration_measure(abs(tfr));
concentration_sst = concentration_measure(abs(sst_tfr));
fprintf('改进SET集中度: %.4f\n', concentration_set);
fprintf('传统SST集中度: %.4f\n', concentration_sst);
% Renyi熵函数定义
function e = renyi_entropy(spec)
spec_norm = spec / sum(spec(:));
e = -log(sum(spec_norm(:).^2));
end
% 能量集中度计算函数
function c = concentration_measure(spec)
max_val = max(spec(:));
total_energy = sum(spec(:));
% ==================== 噪声鲁棒性测试 ====================
% 进行不同信噪比条件下的性能评估
snr_levels = 0:5:30; % 设置多个信噪比水平(dB)
errors = zeros(size(snr_levels)); % 初始化误差存储矩阵
for i = 1:length(snr_levels)
% 添加高斯白噪声至原始信号,生成含噪信号
noisy_sig = awgn(sig, snr_levels(i), 'measured');
% 应用改进的同步化提取变换(SET)方法
[tfr_set, ~, ~] = improved_set(noisy_sig, fs, wavelet_name, scales);
% 使用传统同步小波变换(SST)进行对比
[tfr_sst, ~, ~] = wsst(noisy_sig, wavelet_name, scales, fs);
% 获取纯净信号下的参考时频表示
[tfr_ref, ~, ~] = improved_set(sig, fs, wavelet_name, scales);
% 计算两种方法相对于参考结果的相对误差(Frobenius范数)
errors(i,1) = norm(tfr_set - tfr_ref, 'fro') / norm(tfr_ref, 'fro');
errors(i,2) = norm(tfr_sst - tfr_ref, 'fro') / norm(tfr_ref, 'fro');
end
% 绘制对数坐标下的噪声鲁棒性曲线
figure;
semilogy(snr_levels, errors(:,1), 'b-o', 'LineWidth', 1.5);
hold on;
semilogy(snr_levels, errors(:,2), 'r--s', 'LineWidth', 1.5);
xlabel('信噪比 (dB)');
ylabel('相对误差');
title('噪声鲁棒性对比');
legend('改进SET', '传统SST');
grid on;
[此处为图片1]
% ==================== 轴承故障诊断应用 ====================
% 实际工程案例:机械系统中轴承缺陷识别
load('bearing_data.mat'); % 导入振动数据文件(含故障信息)
% 参数设定
fs = 12000; % 采样频率为12 kHz
fault_freq = 80.2; % 外圈故障特征频率(Hz)
scales = 1:1:128; % 小波尺度范围
% 对振动信号执行改进SET变换
[tfr, f, t] = improved_set(vibration_signal, fs, 'morl', scales);
% 提取目标频带内能量(围绕故障频率±5 Hz)
freq_band = [fault_freq - 5, fault_freq + 5];
band_idx = find(f >= freq_band(1) & f <= freq_band(2));
energy_profile = sum(abs(tfr(band_idx, :)), 1);
% 检测能量包络中的显著峰值以定位故障脉冲
[pks, locs] = findpeaks(energy_profile, ...
'MinPeakHeight', 0.5 * max(energy_profile), ...
'MinPeakDistance', 0.1 * fs);
% 结果可视化
figure;
subplot(3,1,1);
plot(t, vibration_signal);
title('轴承振动信号');
xlabel('时间 (s)');
subplot(3,1,2);
imagesc(t, f, abs(tfr));
axis xy;
title('改进SET时频图');
xlabel('时间 (s)'); ylabel('频率 (Hz)');
ylim([0, 200]);
subplot(3,1,3);
plot(t, energy_profile);
hold on;
plot(t(locs), energy_profile(locs), 'ro');
title('故障特征频率能量包络');
xlabel('时间 (s)'); ylabel('能量');
[此处为图片2]
% ==================== 癫痫脑电检测应用 ====================
% 生物医学应用:癫痫发作期脑电信号分析
load('eeg_data.mat'); % 加载包含正常与异常状态的EEG数据
% 配置分析参数
fs = 256; % 采样率:256 Hz
seizure_freq = [4, 7]; % 癫痫相关Theta频段(4–7 Hz)
scales = 1:1:64; % 设定尺度向量用于时频分析
% 对脑电信号采用改进SET方法进行处理
[tfr, f, t] = improved_set(eeg_signal, fs, 'morl', scales);
% 使用改进的SET方法对癫痫发作期与正常期EEG信号进行时频分析
[tfr_seizure, f, t] = improved_set(eeg_seizure, fs, 'mexh', scales);
[tfr_normal, ~, ~] = improved_set(eeg_normal, fs, 'mexh', scales);
% 提取特征频段(如theta频段)的能量信息
theta_idx = find(f >= seizure_freq(1) & f <= seizure_freq(2));
theta_energy_seizure = sum(abs(tfr_seizure(theta_idx, :)), 1);
theta_energy_normal = sum(abs(tfr_normal(theta_idx, :)), 1);
% 结果可视化处理
figure;
subplot(2,2,1);
plot(t, eeg_seizure);
title('癫痫发作期EEG');
xlabel('时间 (s)');
subplot(2,2,2);
imagesc(t, f, abs(tfr_seizure));
axis xy;
title('癫痫发作期SET时频图');
xlabel('时间 (s)');
ylabel('频率 (Hz)');
ylim([0, 30]);
[此处为图片1]
subplot(2,2,3);
plot(t, theta_energy_seizure);
title('癫痫特征频段能量');
xlabel('时间 (s)');
subplot(2,2,4);
boxplot([theta_energy_normal, theta_energy_seizure], 'Labels', {'正常', '发作'});
title('特征频段能量对比');
ylabel('能量');
该方法采用自适应重排与多尺度融合策略,显著提升对非平稳信号的解析能力,适用于生物医学、机械振动及电磁信号等复杂场景下的精细频域分析。
| 特性 | 改进SET | 传统SST | STFT | 小波变换 |
|---|---|---|---|---|
| 时频分辨率 | ★★★★★ | ★★★★☆ | ★★☆☆☆ | ★★★☆☆ |
| 噪声鲁棒性 | ★★★★☆ | ★★★☆☆ | ★★☆☆☆ | ★★★☆☆ |
| 计算效率 | ★★★☆☆ | ★★★★☆ | ★★★★★ | ★★★★☆ |
| 参数敏感性 | ★★★☆☆ | ★★☆☆☆ | ★★★★☆ | ★★☆☆☆ |
| 多分量分离能力 | ★★★★★ | ★★★★☆ | ★★☆☆☆ | ★★★☆☆ |
| 实现复杂度 | ★★★☆☆ | ★★★☆☆ | ★★☆☆☆ | ★★☆☆☆ |
根据不同应用场景推荐如下配置:
扫码加好友,拉您进群



收藏
