Python:计算信号的最大傅里叶系数

时间:2015-07-16 12:38:31

标签: python numpy signal-processing fft frequency-analysis

我正在尝试确定信号的最主要频率。然而,当人工创建50 Hz信号并应用足够的零点添加来增强fft分辨率时,我得到的最高频率为49,997 Hz。对于我的应用,这是一个显着的差异。我在这里做错了吗?

import numpy as np
import matplotlib.pyplot as plt

fs = 2**12

x = np.linspace(0,1,fs+1)

signal = np.sin(50*2*np.pi*x)
spect = abs(np.fft.fft(np.append(signal,np.zeros(999*fs))))

plt.figure('Four Coef')
plt.plot(spect)
plt.axis([49995,49999,2048.01,2048.05])

plt.show()

注意,由于零填充,系数49997对应于49,997 Hz的频率。

编辑:数组恰好代表50 Hz信号的1秒。最后999秒是零,以增加fft"分辨率"到1 mHz。我只有1秒的可用信号,我需要最高频率,精确到mHz

更改采样率fs = 2**8最多可以得到49.999,所以我认为采样方式在这里至关重要...

2 个答案:

答案 0 :(得分:2)

你没有采用50 Hz波的1000 s的FFT:传递给np.fft.fft的数组是1秒的信号,然后是999秒的静音零。因此,您的限幅信号FFT会变成一个时髦的,多峰值的东西。

当我使用连续信号执行以下操作时,我会看到指数50000处的峰值符合预期:

import numpy as np
import matplotlib.pyplot as plt

fs = 2**12

x = np.linspace(0,1000,fs*1000)

signal = np.sin(50*2*np.pi*x)
spect = abs(np.fft.fft(signal))

plt.figure('Four Coef')
plt.plot(spect)
print np.argmax(spect), np.max(spect)

plt.show()

输出:

50000 2047497.79244

NB1 /只是重复你的数组也不会正常工作,因为两端不会“匹配”(信号将从一个1 s数组的末尾跳到下一个数组的开头)。

NB2 /您可以考虑使用rfftrfftfreq来获取频率。

答案 1 :(得分:0)

如果FFT的长度是该信号频率周期的精确整数倍,则峰值幅度FFT结果仓的频率将指示信号的频率。对于任何其他频率,尝试使用频率估计算法(例如FFT结果的抛物线或Sinc插值,但还有许多其他估算方法),而不仅仅是原始单峰值幅度频率。