如何在信号FFT中获取正确频率幅值?解决幅值偏差问题
FFT幅值偏差的原因与还原方法
你遇到的500倍幅值偏差,根源是离散傅里叶变换(DFT)的输出幅值和信号的采样总数直接挂钩,而你用的np.fft.rfft是针对实信号优化的DFT实现,规则更具体:
- 对于实信号里的普通频率分量(非直流DC、非奈奎斯特Nyquist频率),
rfft输出的幅值等于原始信号幅值 × 采样点数的一半 - 你的采样点数是
5*200=1000,一半就是500,刚好对应你看到的偏差倍数
还原原始幅值的方法
直接对FFT的幅值结果做归一化即可:
- 对于你的信号(无DC、无Nyquist分量),把
fft_spectrum_abs除以signal.size / 2就能得到原始幅值 - 如果信号包含DC或Nyquist分量,这两个位置的幅值需要单独除以
signal.size
修正后的代码
把你的FFT部分代码修改如下:
fft_spectrum = np.fft.rfft(signal) fft_spectrum_abs = np.abs(fft_spectrum) # 归一化还原原始幅值 n = signal.size fft_amplitude = fft_spectrum_abs / (n / 2) # 若存在DC分量,单独修正(当前信号无DC,可注释) # fft_amplitude[0] = fft_spectrum_abs[0] / n freq = np.fft.rfftfreq(n, d=1./sampling_frequency) plt.plot(freq, fft_amplitude) plt.xlabel("frequency, Hz") plt.ylabel("amplitude, units") plt.show()
运行后,1Hz处峰值会接近1,10Hz处接近0.5,和你预期的原始信号幅值一致。
内容的提问来源于stack exchange,提问作者user22369396
相关产品推荐
相关产品推荐

