时频信号分析总结

1 引言

在现代信号处理领域,非平稳信号广泛存在于通信、机械振动、生物医学及地球物理等场景中,其频率成分随时间动态变化,传统傅里叶变换因仅能提供整体频谱信息而难以揭示信号的时变特性。时频分析 (Joint Time-Frequency Analysis, JTFA)作为一种同时刻画信号时域与频域联合特性的技术,通过构建时频分布函数,能够直观呈现信号能量在时间-频率平面上的演化规律,成为解析非平稳信号特征的核心工具。

时频分析的核心思想在于突破单一域分析的局限性,例如短时傅里叶变换(STFT)通过滑动窗函数实现局部频谱估计,但其固定的时频分辨率受限于测不准原理,难以兼顾瞬态与稳态信号分析;而小波变换通过多尺度分解提供自适应分辨率,但缺乏直接的相位信息。针对这些问题,Wigner-Ville分布(WVD)等双线性时频表示方法通过提升能量聚集性显著改善时频分辨率,但其固有的交叉项干扰问题促使研究者提出平滑伪WVD(SPWVD)等改进方案。此外,希尔伯特-黄变换(HHT)通过经验模态分解(EMD)与瞬时频率计算,为非线性信号分析提供了新范式。

2时频分析算法

2.1 短时傅里叶变换

2.1.1 STFT基本原理

短时傅里叶变换通过滑动窗口截取信号片段,对每个片段进行傅里叶变换,构建时频分布矩阵。其核心公式为:

分辨率权衡:

时间分辨率:由窗长决定,窗长越短,时间分辨率越高,但频率分辨率越低。

频率分辨率:由FFT点数(nfft)决定,nfft越大,频率分辨率越高,但计算量增加。

matlab 复制代码
%%
% 短时傅里叶变换时频分析
%%

% 生成测试信号(含两个频率分量)
fs = 1000; 
t = 0:1/fs:1-1/fs;
x = sin(2*pi*50*t) + 0.5*sin(2*pi*150*t);

% 参数设置
wlen = 256;    % 窗长
hop = 128;     % 重叠(50%)
nfft = 512;    % FFT点数
win = hamming(wlen); % 窗函数

% 计算STFT
[S, F, T] = spectrogram(x, win, hop, nfft, fs);

% 可视化时频图(dB尺度)
figure('name' , '短时傅里叶变换');
subplot(2 ,1,1);
plot(x);
title('原始信号');

subplot(2 ,1,2);
imagesc(T, F, 20*log10(abs(S)));
axis xy;
colormap(jet);
xlabel('时间 (s)');
ylabel('频率 (Hz)');
title('STFT时频图(dB)');
colorbar;

2.1.2关键参数影响分析

1. 窗长(wlen)

时间分辨率:窗长越短,时间分辨率越高(适合快速变化的信号)。

频率分辨率:窗长越长,频率分辨率越高(适合稳定频率成分)。

matlab 复制代码
figure('name' , '短时傅里叶变换:不同窗长');
% 窗长256(左) vs 1024(右)
subplot(2,1,1);
spectrogram(x, hamming(256), 128, 512, fs);
title('窗长256');
subplot(2,1,2);
spectrogram(x, hamming(512), 256, 512, fs);
title('窗长512');


2. 重叠步长(noverlap)

时间平滑:重叠比例越高(如75%),时频图时间轴更平滑,但计算量增加。

频谱泄漏抑制:适当重叠可减少频谱泄漏。
3. FFT点数(nfft)

频率刻度精度:nfft越大,频率轴分辨率越高(如nfft=2048可分辨1Hz间隔)。

频谱泄漏:增大nfft可降低频谱泄漏,但需权衡计算效率。

2.2 提取时频脊

提取时频脊(Instantaneous Frequency),跟踪信号频率随时间的变化

matlab 复制代码
%%
% 提取时频脊线进行时频分析
%%
close all;

% 生成线性调频信号(0Hz→250Hz)
fs = 1000; 
t = 0:1/fs:1-1/fs;
x1 = chirp(t, 0, 1, 250);%0~250HZ线性调频
%双频
is_two_signal = 0;
if is_two_signal == 0
    x2 = 0.3*randn(size(t)); % 噪声
else
    x2 = chirp(t, 200, 1, 300) + 0.3*randn(size(t)); % 200Hz→300Hz
end
x = x1 + x2;


% 计算短时傅里叶变换(STFT)
% 参数设置
wlen = 256; hop = 250; nfft = 512;
win = hamming(wlen); % 窗函数选择

% 计算STFT
%添加汉明窗
[stft, f, t_stft] = spectrogram(x, win, hop, nfft, fs);
%[stft, f, t_stft] = spectrogram(x, 256, 250, 512, fs);

% 提取时频脊线
penalty = 0.1;  % 低惩罚允许频率跳变,值越大脊线越平滑
if is_two_signal == 0
    [fridge, iridge] = tfridge(stft, f, penalty, 'NumRidges', 1);
else
    [fridge, iridge] = tfridge(stft, f, penalty, 'NumRidges', 2);
end

% 可视化
figure('name', '线性调频信号时频分析');
subplot(3,1,1);
plot(x);
title('原始信号');
subplot(3,1,2);
imagesc(t_stft, f, 20*log10(abs(stft))); axis xy;
colormap(jet); colorbar;
xlabel('时间 (s)'); ylabel('频率 (Hz)');
title('STFT时频图');

subplot(3,1,3);
hold on;
plot(t_stft, fridge, 'LineWidth', 2);
xlabel('时间 (s)');
ylabel('频率 (Hz)');
legend('脊线');
title('瞬时频率提取结果');

2.3 WVD时频分析

计算Wigner-Ville分布(WVD),显示信号的时频能量分布

matlab 复制代码
%单分量正弦信号的WVD分析

% 参数设置
fs = 1000;          % 采样频率
t = 0:1/fs:1-1/fs;  % 时间向量(1秒)
f = 50;             % 信号频率
x = sin(2*pi*f*t) + 0.3*randn(size(t));  % 正弦信号
figure('name' ,'原始信号');
subplot(3,1,1)
plot(x);
title('原始信号');
%傅里叶变换
Y = fft(x);
L = length(x);
P2 = abs(Y/L);
P1 = P2(1:L/2+1);
P1(2:end-1) = 2*P1(2:end-1);
f = fs*(0:(L/2))/L;
subplot(3,1,2);
plot(f,P1) 
title('Single-Sided Amplitude Spectrum of X(t)')
xlabel('f (Hz)')
ylabel('|P1(f)|')

% 计算WVD
[wvd_matrix, t_axis, f_axis] = wvd(x, fs);
subplot(3,1,3);
% 绘制时频图
imagesc(t_axis./(fs/2), f_axis.*(fs/2), abs(wvd_matrix));
axis xy;
colormap(jet);
colorbar;
xlabel('时间 (s)');
ylabel('频率 (Hz)');
title('单分量正弦信号的WVD时频图');

2.4 hht 希尔伯特-黄变换

希尔伯特-黄变换(HHT),包括经验模态分解(EMD)和希尔伯特谱

matlab 复制代码
%%
% 希尔伯特-黄变换(HHT)的完整示例
%%
close all;
% 参数设置
load('sinusoidalSignalExampleData.mat','X','fs');
t = (0:length(X)-1)/fs;

% 执行EMD分解
[imf,residual,info] = emd(X,'Interpolation','pchip');

len = size(imf ,2);
figure('name' ,'emd分解');
subplot(len+1,1,1);
plot(t,X);
xlabel('Time(s)');
title('原始信号');

for i = 2:len+1
    subplot(len+1,1,i);
    plot(imf(:,i-1));
    str = sprintf('第%d个imf分类' ,i-1);
    title(str);
end


%Hilbert变换与时频分析
% 计算Hilbert谱
figure('name' ,'hht分析');
subplot(2,1,1);
hht(imf, fs);
title('hht默认时频图');


[hs, f, t] = hht(imf, fs);
hs_log = log10(hs);                  % 对数变换
hs_norm = hs_log / max(hs_log(:));   % 归一化到0~1

% 绘制一致的时频图
subplot(2,1,2);
imagesc(t, f, hs_log);
colormap(jet);
colorbar;          % 设置颜色条范围与默认一致
xlabel('时间 (s)'); 
ylabel('频率 (Hz)');
title('Hilbert时频谱');

2.5 pspectrum 综合时频分析

pspectrum

综合时频分析函数,支持STFT、CWT等多种变换,输出时频功率谱

matlab 复制代码
%%
% pspectrum功率谱分析
%%
close all;
% 生成测试信号(含200Hz和500Hz正弦波)
fs = 1000; t = 0:1/fs:1-1/fs;
x = sin(2*pi*200*t) + 0.5*sin(2*pi*500*t) + 0.2*randn(size(t));

% 计算功率谱
p = pspectrum(x, fs, 'Leakage', 0.85);

% 绘制频谱图(dB尺度)
figure('name' ,'功率谱分析');
subplot(2,2,1);
plot(x);
title('原始信号');

subplot(2,2,2);
plot(p);
title('功率谱(dB)');
xlabel('频率 (Hz)');
ylabel('功率 (dB)');

% 生成调频信号(0Hz→1kHz)
fs = 2000; t = 0:1/fs:2-1/fs;
x = chirp(t, 0, 2, 1000);

% 计算时频谱
[p, f, t_stft] = pspectrum(x, fs, 'spectrogram', ...
    'TimeResolution', 0.05, 'OverlapPercent', 75, 'MinThreshold', -40);

% 可视化时频图
subplot(2,2,3);
plot(x);
title('0~1kHZ调频原始信号');

subplot(2,2,4);
imagesc(t_stft, f, 10*log10(p));
axis xy;
colormap(jet);
xlabel('时间 (s)');
ylabel('频率 (Hz)');
title('STFT时频图');


% 生成含间歇干扰的信号
fs = 1000; t = 0:1/fs:5-1/fs;
carrier = sin(2*pi*100*t);
interference = 0.3*sin(2*pi*300*t).*(t>1 & t<2);
x = carrier + interference + 0.1*randn(size(t));

% 计算持久谱
[p, f, t_persist] = pspectrum(x, fs, 'persistence', ...
    'FrequencyLimits', [50, 400], 'TimeResolution', 0.1);

% 绘制持久谱(热力图)
figure('name' ,'热力图分析');
subplot(2,2,1);
plot(x);
title('原始信号');

subplot(2,2,2);
imagesc(t_persist, f, p);
axis xy;
colormap(hot);
xlabel('时间 (s)');
ylabel('频率 (Hz)');
title('持久谱(出现时间百分比)');

% 生成含强噪声的信号
fs = 1000; t = 0:1/fs:1-1/fs;
x_clean = sin(2*pi*200*t);
x_noisy = x_clean + 1.5*randn(size(t)); % SNR≈3dB

% 设置最小阈值过滤噪声
[p, f] = pspectrum(x_noisy, fs, 'MinThreshold', -20);

% 绘制带噪声抑制的频谱
subplot(2,2,3);
plot(x);
title('200HZ+随机噪声原始信号');

subplot(2,2,4);
plot(f, 10*log10(p));
title('噪声抑制后频谱');
xlabel('频率 (Hz)');
ylabel('功率 (dB)');
相关推荐
CoovallyAIHub2 小时前
让Qwen-VL的检测能力像YOLO一样强,VLM-FO1如何打通大模型的视觉任督二脉
深度学习·算法·计算机视觉
2401_841495642 小时前
【自然语言处理】基于统计基的句子边界检测算法
人工智能·python·算法·机器学习·自然语言处理·统计学习·句子边界检测算法
CoovallyAIHub2 小时前
突破跨模态识别瓶颈!火箭军工程大学提出MFENet:让AI在白天黑夜都能准确识人
深度学习·算法·计算机视觉
CoovallyAIHub2 小时前
TypeScript超越Python,以66%增速跃升第一,Python稳居AI领域王座
深度学习·算法·计算机视觉
User_芊芊君子3 小时前
【LeetCode经典题解】递归破解对称二叉树之谜
算法·leetcode·职场和发展
Rock_yzh3 小时前
LeetCode算法刷题——49. 字母异位词分组
数据结构·c++·学习·算法·leetcode·职场和发展·哈希算法
小欣加油3 小时前
leetcode 2654 使数组所有元素变成1的最少操作次数
数据结构·c++·算法·leetcode·职场和发展
Kt&Rs3 小时前
11.12 LeetCode 题目汇总与解题思路
算法·leetcode
m0_565611133 小时前
Java Stream流操作全解析
java·开发语言·算法