我正在尝试确定信号的最主要频率。然而,当人工创建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,所以我认为采样方式在这里至关重要...
答案 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数组的末尾跳到下一个数组的开头)。
答案 1 :(得分:0)
如果FFT的长度是该信号频率周期的精确整数倍,则峰值幅度FFT结果仓的频率将指示信号仅的频率。对于任何其他频率,尝试使用频率估计算法(例如FFT结果的抛物线或Sinc插值,但还有许多其他估算方法),而不仅仅是原始单峰值幅度频率。