MATLAB 做 FFT 频谱分析:峰值泄漏从哪来?窗函数与补零的工程取舍

举报
yd_223794387 发表于 2026/10/26 06:39:29 2026/10/26
【摘要】 做信号处理实验时,很多人都遇到过这个现象:一个明明是单频正弦的信号,用 MATLAB 的 fft 一算,频谱主峰两边拖出一串“裙摆”,峰值也不正好落在某个频点上。换一台示波器看时域波形又很干净——问题不在信号,而在我们对一段有限长数据做 FFT 的方式本身。本文把泄漏的成因、窗函数的取舍和补零的真实作用一次讲清。一、泄漏的根源:截断等于加了矩形窗FFT 默认我们给的 N 个采样点就是信号的全...

做信号处理实验时,很多人都遇到过这个现象:一个明明是单频正弦的信号,用 MATLAB 的 fft 一算,频谱主峰两边拖出一串“裙摆”,峰值也不正好落在某个频点上。换一台示波器看时域波形又很干净——问题不在信号,而在我们对一段有限长数据做 FFT 的方式本身。本文把泄漏的成因、窗函数的取舍和补零的真实作用一次讲清。

一、泄漏的根源:截断等于加了矩形窗

FFT 默认我们给的 N 个采样点就是信号的全部。但只要信号频率不是采样频率除以 N 的整数倍(即非整周期截断),这段数据在 FFT 眼里就相当于被周期延拓后首尾不连续。时域上的一次跳变,对应频域上 sinc 形的旁瓣扩散,这就是频谱泄漏。

举个具体例子:采样率 fs=1000 Hz,取 N=1000 个点,信号频率 50.5 Hz。50.5 不是 1 Hz 频率分辨率的整数倍,FFT 的能量必然分散到 50 Hz、51 Hz 及周边多个频点上,峰值读数也因此偏低。反过来,若信号恰好是 50 Hz 整周期截断,频谱就只有一根干净的谱线。所以“泄漏”不是噪声,而是截断方式与信号频率不匹配的必然结果。

二、窗函数:用主瓣换旁瓣

加窗就是在做 FFT 之前先给数据乘一个两端渐变到零的权重,压住首尾跳变。代价是主瓣变宽、频率分辨率下降,换来的是旁瓣大幅压低,弱信号不再被强信号的裙摆淹没。

常用选择可以这样记:矩形窗分辨率最高、旁瓣最差(约 -13 dB),只适合整周期或信噪比极高的场合;汉宁窗(Hann)旁瓣约 -31 dB,是通用折中;布莱克曼窗旁瓣约 -58 dB,适合在强干扰旁边找弱信号,但主瓣最宽;平顶窗(Flattop)幅值精度最好,适合只关心幅值、不关心分辨两个邻近频率的场合。没有“最好”的窗,只有与任务匹配的窗:测两个邻近频率用矩形或汉宁,测弱信号用布莱克曼,标定幅值用平顶窗。

三、补零不是提高分辨率

很多人以为 fft(x, 4*N) 把频率分辨率提高了 4 倍。其实补零只是在频域做插值:它让谱线画得更密、峰值位置读得更准,但并不能把两个原本靠得太近的频率分开。真正的频率分辨率只由观测时长 T=N/fs 决定,约等于 1/T。想分辨 2 Hz 的两个频率,至少需要约 0.5 秒的数据,再怎么补零也变不出来。

但补零并非无用:配合窗函数与抛物线插值,它能把峰值频率的估计误差从半个频点压到百分之几个频点,对测频、标定幅值很有帮助。关键是分清“谱线变密”与“分辨率提高”是两回事。

四、MATLAB 实操:一段可直接跑的代码

fs = 1000; N = 1000; t = (0:N-1)/fs;
x = sin(2*pi*50.5*t) + 0.05*sin(2*pi*120*t); % 50.5 Hz 强信号 + 120 Hz 弱信号
% 矩形窗对照
X_rect = abs(fft(x));
% 汉宁窗 + 4 倍补零
win = hann(N).';
X_hann = abs(fft(x.*win, 4*N));
f = (0:4*N-1)*(fs/(4*N));
plot(f(1:200), 20*log10(X_hann(1:200)+eps));
xlabel('频率 (Hz)'); ylabel('幅值 (dB)');

跑这段代码可以直观对比:矩形窗下 120 Hz 的弱峰会被 50.5 Hz 的旁瓣抬高、甚至淹没;换汉宁窗后弱峰清晰出现,但 50.5 Hz 的主瓣变宽了。这就是工程取舍的现场演示。

五、工程 checklist

做 FFT 之前先问自己四件事:第一,信号是否整周期截断,不是就加窗;第二,任务是分辨频率还是找弱信号还是标定幅值,据此选窗;第三,观测时长够不够分辨目标频率差,不够就加长数据而不是补零;第四,读峰值时是否做了插值或补零修正,否则幅值与频率都会系统性偏低。按这个顺序排查,大多数“频谱不对”的问题在加窗这一步就解决了。

结论:泄漏不是玄学,是截断的数学后果。窗函数用分辨率换动态范围,补零用计算量换读数精度,观测时长才是分辨率的硬约束。理解这三条分工,FFT 频谱就不再是一张需要猜的图。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。