加窗对 FFT 幅度的影响

信息处理 fft matlab 窗函数
2021-12-21 11:49:18

我有 2 个罪波:

Fs = 1500;
N = 100;
t = (0:N-1)'/Fs;

sinwave = sin(2*pi*15*t);
sinwaveshifted = sin(2*pi*15*t + 1.3);

如果我使用 fft 获得 15Hz 的幅度(由于我无法控制的原因,需要使用 2 次方的 FFT):

fftsin = fft(sinwave,128);
fftsinshift = fft(sinwaveshifted,128);

% 2 corresponds to 15Hz 

abs(fftsin(2)) = 51.819;
abs(fftsinshift(2)) = 41.6151;

为什么有区别?我假设因为我的垃圾箱没有完美排列,所以发生了一些泄漏。另外,我没有做任何窗口。

如果我对信号进行窗口化(我使用平顶,因为我读到它在幅度精度方面是最好的),这些是我的结果:

w = window(@flattopwin, 100);
sinwin = sinwave .* w;
sinshiftwin = sinwaveshift .* w;

fftsin = fft(sinwin ,128);
fftsinshift = fft(sinshiftwin ,128);

% 2 corresponds to 15Hz 

abs(fftsin(2)) = 2.7283;
abs(fftsinshift(2)) = 17.822;

为什么会有巨大的差异?

3个回答

我认为您是正确的,因为原始信号 fft 的微小差异是由于泄漏造成的。但是,窗口化结果的巨大差异是因为您没有足够的数据。您的原始信号只有一个正弦周期的数据。当您将此窗口化时,您将信号的边缘钳制为零,实际上只剩下信号的中间部分。所以你得到的信号只有一个周期的一小部分信息,绝对不足以在提取的频率分析中获得任何准确性。为了说明这一点,以下是开窗前后原始函数的 matlab 图像:

在此处输入图像描述

并且您可以很容易地看到信号中许多有意义的频率信息的丢失。使用 10 个周期的正弦信号,一个更好的加窗候选者如下所示:

在此处输入图像描述

这证明了保留频率信息和钳位边缘以减少泄漏之间的平衡。如果您有兴趣,本文将更深入地了解不同的窗口函数及其在不同类别的信号上的性能

几件事:

  1. 使用 128 点的 FFT,您的频率分辨率为 11.71 Hz,因此您无法真正直接查看 15 Hz。你的断言fftsin(2)对应于 15 Hz 是错误的。
  2. 通过对 100 个时域样本进行 128 个点的 FFT,您基本上可以在波形上附加 28 个零。这会显着改变频谱。
  3. 窗口比单个波长短很多,因此窗口和正弦波之间的精确排列产生了巨大的差异。与过零相比,如果在正弦波的峰值附近开窗,您将获得更多的能量。对于更高的频率,该窗口会更好地工作。

时域中的开窗是频域中的卷积。因此,窗口函数将在频域中将单个频谱频率点与扩展函数进行卷积。对于非常低的频率,此窗口扩展函数可以将 FFT 频率仓及其对应的负频率仓扩展到整个 DC,以便 2 个频率(正和负)相互干扰甚至部分抵消。

正负 bin 之间的抵消量将取决于正弦曲线相对于 FFT 孔径中心的相位。甚至,余弦或实分量也会相加。奇数、正弦或虚数分量将抵消。(因为实时域输入在 FFT 结果中产生复共轭对称)。

因此,不应使用加窗(或非常小心地使用,考虑到相位)来测量非常接近 DC(在第一个或两个 FFT 结果箱附近)或非常接近 Fs/2 的频率幅度。