为什么在 FFT 中会出现频谱泄漏?

信息处理 fft 频谱
2022-01-08 01:20:11

我试过谷歌搜索和维基百科,但除了“这是因为输入信号的频率位于两个箱之间”之外,我没有得到任何答案。

我知道这是原因,但我无法理解的是为什么泄漏似乎延伸到几个相邻的垃圾箱,而不仅仅是一个相邻的垃圾箱。

为了说明我在说什么,这里有一些模拟数据(代码在帖子末尾): 频率_10

上图是频率为 10 的正弦波的 FFT 频谱(以对数刻度绘制)。采样率为 1,样本数为 100。该图已进行 FFT 移位。显然,在 bin 10 处只有一个峰值,其余的都在数值误差的数量级上,或者差不多。

频率_10_1

这是生成频率为 10.1 的频谱。显然,除了紧邻的垃圾箱之外,还有更多垃圾箱“泄漏”。

频率_10_5

这是频率为 10.5 的图。

问题:为什么会出现这种泄漏,为什么它会延伸到所有其他垃圾箱,而不是直接相邻的垃圾箱?


代码,任何有兴趣的人(Python代码)

import numpy as np
import matplotlib.pyplot as plt

xFreq = 10.5
xSize = 100.0
xPeriod = xSize/xFreq
x = np.linspace(1,xSize,xSize)

data = np.sin(2*np.pi*x/xPeriod)
fft = np.fft.fft(data)
fft = np.fft.fftshift(fft)

fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(abs(fft), "o")
ax.set_yscale('log')
plt.show()

我将xFreq值从更改10.010.5等。

2个回答

FFT 具有有限长度,因此构成数据流上的默认矩形窗口。时域中的窗口导致频域中的卷积与窗口的变换。请注意,矩形窗口的变换是一个 Sinc 函数 (sin(x)/x),它具有无限宽。这不仅仅是 2 个箱子的宽度。因此,Sinc 函数的波纹将显示为远离任何在 FFT 长度上不是完全周期性的光谱峰值的“泄漏”。

下图显示了 sinc 函数的部分频率响应。当音调以其中一个箱为中心时,所有其他点都与频率响应中的零点对齐。如果它不是以一个 bin 为中心,那么就像移动整个频率响应一样,这会导致其他 bin 落在频率响应的非零部分上。

在此处输入图像描述

另一种看待它的方式是,FFT 只是一个滤波器组,其中每个滤波器阻带底都有很多波纹,并且在远离中心频率超过 1 个 bin 的衰减中肯定不是无限的。矩形以外的一些窗口(von Hann 等)具有较低的阻带,这是它们广泛使用的原因之一。

hotpaw2的回答很好,但我想详细说明一下user5133的评论:

感谢您没有通过说“FFT 假定其输入序列是周期性的”来解释泄漏。可悲的是,在 DSP 的文献中,“假定的周期性”这个愚蠢的概念被重复得太频繁了

同时也回答了这个问题。请注意,我是该领域的专家——请随时发表评论、更正或确认。

离散时间傅里叶变换 (DTFT) 定义为Z(不仅仅是{1,2,,N}!) 经过

X(ω)=n=x[n]eiωn.

在实践中,测量信号是有限的;表示长度N. 有限信号可以扩展为N- 周期性超过Z. 离散傅里叶变换 (DFT) 定义为

Xk =def n=0N1xne2πikn/N,kZ
对应于离散频率X(2πk/N)DTFT 的,除非n在 不在{1,2,,N}. 换句话说,它对应于 DTFTx[n]w[n]在哪里w是一个矩形函数,当n{1,,N}和 0 其他地方。

但是乘积的傅里叶变换是傅里叶变换的卷积:

F{fg}=F{f}F{g}

因此原始信号的 DFT 是其“周期性”版本的 DTFT 与矩形窗口的傅里叶变换的卷积......这是一个sinc因为(在连续框架中并以 0 为中心以简化...):

w(f)ejωtdt=ττejωtdt=2τsinc(ωτ)

卷积与sinc产生观察到的旁瓣(某些特定情况除外)。