让我们使用以下 Matlab 代码模拟两个频率的正弦曲线:
fs = 1000;
t = 0 : 1/fs : 1 - 1/fs;
f1 = 3; f2 = 3.5;
x1 = cos(2*pi*f1*t);
x2 = cos(2*pi*f2*t);
L1 = length(x1); L2 = length(x2);
如果我使用以下方法对第一个信号进行 FFT:
X1 = fft(x1);
并使用以下方法绘制生成的幅度谱:
figure; subplot(2, 1, 1); plot(t, x1)
subplot(2, 1, 2); plot([-L1/2 : (L1/2 -1)]*fs/L1, fftshift(abs(X1)))
我发现得到的幅度谱完全符合我的预期(即 3 Hz 的频率的高度为 500 - 这是 3 Hz 分量幅度的 0.5*L1 倍 - 所有其他频率都有一个高度0)。
当我为 x2 绘制相同的图时,我发现频谱能量已经分布在 3-4 Hz 左右的频率上,导致 3 Hz 处的峰值幅度从 500 降低到 320 左右:
X2 = fft(x2);
figure; subplot(2, 1, 1); plot(t, x2)
subplot(2, 1, 2); plot([-L2/2 : (L2/2 -1)]*fs/L2, fftshift(abs(X2)))
据我了解,这是由于 DFT 的操作方式:它将在信号长度上具有整数个周期的正弦曲线与信号相关联。由于 x2 在其 1000 个样本中有 3.5 个周期,因此 3 Hz 的正弦波和 4 Hz 的正弦波都不能与信号完全匹配,尽管这两个频率是所有频率中最接近的。因此,我们在这两个频率上都看到了很大的峰值。
但是,如果我用 1000 个额外的零对信号进行零填充,我能够找到一个 3.5 Hz 分量,因为在 2000 个样本中有 7 个周期的正弦曲线(每个样本对应于 1/1000 = 0.001 s)对应于3.5 Hz 正弦曲线(因为我们总是按 fs/L = 1000/2000 = 0.5 缩放 bin;所以 0.5*7 = 3.5 Hz),这与前 1 秒的信号完全匹配。此外,峰值的幅度现在为 500,这与在没有零填充的情况下为 3 Hz 信号找到的峰值幅度相匹配。
x2 = [x2 zeros(1, 1000)];
X2 = fft(x2);
L2 = length(x2);
t_zeropad = [0:L2-1]/fs;
figure; subplot(2, 1, 1); plot(t_zeropad, x2)
subplot(2, 1, 2); plot([-L2/2 : (L2/2 -1)]*fs/L2, fftshift(abs(X2)))
这导致了几个相关的问题:
- 是什么导致了第三个图中的旁瓣?这不是因为 t = 1 处的不连续性,因为当输入信号从余弦变为正弦时效果仍然存在,这使得信号在 t = 1 处连续。
- 当您对信号进行零填充时,您按什么因素缩放 FFT 的幅度?我知道对于一个没有被零填充的正弦信号,并且信号长度内正弦波的周期数是一个整数,你将幅度除以 L/2。因此,在第一个示例中,您将 500 除以 (1000/2) 得到 1,这与余弦波的幅度相匹配。补零后,信号的长度现在为 2000,因此 L/2 将为 1000,这意味着幅度图中的峰值幅度将为 0.5。当您进行零填充时,这个比例因子是否应该改变?
- 当正弦曲线不均匀地适合被分析的样本数量时,当您处理的是多个正弦曲线的线性组合的信号时,或者当您正在处理更复杂的信号时(例如 e(- t))?
- 如果有人只是给你一个信号而没有告诉你是否已经完成了零填充,你怎么能知道通过什么因素来缩放 FFT 的幅度来计算频率分量的幅度?
- 最后,我注意到,如果将频率为 3 Hz 的信号 x1 零填充 1000 个样本,并进行 FFT,我们再次看到在 3 Hz 的频率下,幅度为 500;光谱能量分布在 3 Hz 附近;并且存在旁瓣(见下图)。虽然使用原始信号(不是零填充),但我没有这些伪影。这使我相信,从某种意义上说,零填充会增加噪声,因为基于幅度谱,您正在引入实际不存在的频率分量。这是一种明智的思考方式吗?这是否意味着除非你“必须”,否则你不应该零填充,如果是这样,你怎么知道你是否必须?你应该零填充多少?