【问题标题】:Understanding FFT output in python了解python中的FFT输出
【发布时间】:2015-12-16 18:18:36
【问题描述】:

我正在尝试了解 scipy.fftpack.fft 的输出。我创建了一个信号并做了一个 fft。这是fft的代码:

import numpy as np
from scipy.fftpack import fft
import matplotlib.pyplot as plt

# Number of samplepoints
N = 600
# sample spacing
T = 1.0 / 800.0
x = np.linspace(0.0, N*T, N)
y = 5.0 * np.sin(50.0 * 2.0*np.pi*x) + 1.0*np.sin(80.0 * 2.0*np.pi*x) #unit is V
yf = fft(y)
xf = np.linspace(0.0, 1.0/(2.0*T), N/2)

plt.close()
plt.plot(xf, 2.0/N * np.abs(yf[0:N/2]))
plt.grid()
plt.show()

创建这个:

我知道信号强度大小的单位与从 (V) 创建的波形上的信号单位相同。我不明白 fft 频率的幅度与原始信号的幅度之间的关系。比如50Hz正弦部分的幅度是5.0V,那为什么fft上50Hz的幅度在3.6V左右呢?

【问题讨论】:

    标签: python fft


    【解决方案1】:

    如果音调的频率是 FFT 频率间隔1.0/(N*T) 的整数倍,则频域中的峰值幅度通常只会与时域中的音调幅度匹配。当音调频率不是频率间隔的整数倍时,音调的能量会出现在称为Spectral leakage 的多个 bin 中。

    根据您的具体情况,频率间隔为800/600 = 1.333Hz。相应地,80Hz 音调恰好是频率间隔的 60 倍,FFT 显示的峰值与相关时域分量 1.0*np.sin(80.0 * 2.0*np.pi*x) 的幅度相同。

    另一方面,50Hz 音调对应于频率间隔的 37.5 倍。在这种情况下,能量分布在多个 bin 中,峰值相应降低,在 3.6 处显示最大峰值,而不是 5.0 * np.sin(50.0 * 2.0*np.pi*x) 时域分量的完整 5.0 幅度。

    【讨论】:

    • 我认为这是有道理的。有没有办法从频域中的峰值幅度中计算出时域中信号的幅度?例如,如果我使用的信号我不知道分量及其幅度并想弄清楚它们。
    • 在假设音调足够分散并且没有太多干扰的假设下,您可以估计组件的幅度、频率和相位(参见this other answer of mine)。否则,当您有单音时,Parseval's theorem 可以派上用场。
    猜你喜欢
    • 1970-01-01
    • 2015-03-24
    • 1970-01-01
    • 2020-01-16
    • 1970-01-01
    • 2017-08-30
    • 2023-03-21
    • 2012-06-01
    • 2010-11-30
    相关资源
    最近更新 更多