傅立叶重采样的意外结果(Python 3)

信息处理 fft Python 重采样
2022-02-11 09:46:30

我正在尝试使用 python 中的傅立叶方法对信号进行重新采样,使用np.fft.rfft()and np.fft.irfft()(我没有使用scipy.signal.resample(),因为在我的最终应用程序中,我需要对频域中的信号做更多的事情,而window不是scipy.signal.resample(). :

%pylab inline

N = 16
P = 8

S = [0.49, 1.68, 0.78, 0.05, 0.21, 0.29, 1.34, 1.17, 16.73,
     48.78, 16.90, 0.62, 0.40, 1.60, 0.86, 0.57]
assert len(S) == N

figure(figsize=(14, 5))
plot(np.arange(N), S, '.')

dft = np.fft.rfft(S)
plot(np.arange(N), np.fft.irfft(dft), '-')

dft *= P
dft.resize(P*N/2+1)
plot(np.arange(P*N)/P, np.fft.irfft(dft), '-')

xlim(6.5, 11.5)
ylim(-5, 55);

这是我回来的:

ipython notebook 制作的绘图

如您所见,结果看起来几乎是正确的,但还是有一点偏差。(重新采样的红色曲线不会经过原始采样点,即使在与原始信号相同的时间位置存在采样点。)

绿线表示在扩展和缩放dft数组之前一切正常。所以问题似乎出在实际的重采样中:

dft *= P
dft.resize(P*N/2+1)
plot(np.arange(P*N)/P, np.fft.irfft(dft), '-')

我看不出这个结果在数学上是如何可能的,因为除了时间和幅度轴的缩放之外,向阵列的高频端dft添加零只会向信号的傅立叶级数展开添加零项。所以信号应该仍然通过原始样本值。

但是我看到的小错误似乎与缩放无关:有时重新采样的波形落后于原始波形(t=8),有时更快(t=10),有时幅度更大(t=7, 9,11),有时它更小(t = 8,10)。

我已经玩了好几个小时了,但找不到我的代码有什么问题。也许我只是看不到它,因为我已经盯着它看了很长时间了。

(有关 python FFT 实现使用的定义,请参阅np.fft文档)

编辑(回应评论):当我用 t=9 的脉冲或快速脉冲序列替换 S 时,我得到以下信息:

在此处输入图像描述

在此处输入图像描述

1个回答

如果对具有奇数个样本的信号执行完整的 DFT,则频谱中的频率值为 DC 系数和 (N-1)/2 对正弦系数的共轭。

如果您对具有偶数个样本的信号执行完整的 DFT,则频谱中的频率值为 DC 系数、(N-1)/2 对正弦系数共轭,以及对应于频率 0.5 的单个系数。

rfft只保留频谱的正频率部分,而反向的irfft,大概是在执行逆 DFT 之前重新创建频谱的负部分。

例如,对于具有 的奇数大小信号rfft[0 1 2 3]全频谱将是[3 2 1 0 1 2 3]

对于一个偶数大小的信号rfft[0 1 2 3 4]它可能在代码中的某处设置了一个标志,表示一个偶数大小的信号,因此整个频谱将是[3 2 1 0 1 2 3 4]注意4只出现一次。

但是,当您填充rfft结果时,例如[0 1 2 3 4 0 0 0 0],它可能会将频谱重新创建为[0 0 0 4 3 2 1 0 1 2 3 4 0 0 0 0]也就是说,4现在重复两次,因此该频率分量强两倍。

rfft因此,在填充之前,如果信号具有偶数个样本,则必须将最后一个系数减半。