在Python中平滑FFT图

时间:2017-06-24 20:10:05

标签: python python-3.x scipy signal-processing fft

我想平滑我在200Hz获得的FFT图(我此刻捕获500点),以便代表峰显示接近THIS

这是我的代码:

N = 500
T = 5/1000
y1 = np.array(data_Ax)
yf1 = scipy.fftpack.fft(y1)
xf1 = np.linspace(0.0, 1.0/(2.0*T), N/2)
yfft1 = 2.0/N * np.abs(yf1[:N//2])

plt.figure(figsize=(20, 3), dpi= 100, facecolor='w', edgecolor='k')
plt.plot(xf1, yfft1, 'g-', label ="FFT for Ax")
plt.xlabel('Frequency [Hz]')
plt.legend(loc=1)

为了平滑,我尝试使用它:

rft = np.fft.rfft(yfft1)
y_smooth = np.fft.irfft(rft)

但它没有任何效果。

我很清楚200Hz是一个低采样频率,500次测量不是很多,但它只是为了得到程序的悬念。这是获得的图表: enter image description here

我想知道:

  1. 如何平滑图表?
  2. 如何去除0Hz处的峰值(高通滤波器)?
  3. 从理论的角度来看,代表性的FFT图是否存在最小数量的测量要求?
  4. 感谢您的任何帮助!

3 个答案:

答案 0 :(得分:2)

平滑图表

我认为你真正关心的是增加分数。因此,只需指定要使其看起来更平滑的点数。

例如,这里的FFT与测量的点数相同:

n = 500
nfft = n

t = np.linspace(0, 0.1, n)
y = 0.5 + np.sin(2*np.pi*60*t)
yf = fftshift(fft(y, nfft))

f = fftshift(fftfreq(nfft, np.mean(np.diff(t))))

pyplot.plot(f, abs(yf))
pyplot.grid()
pyplot.xlim([-100, 100])

enter image description here

如果您将fft点的数量更改为4096,即nfft=2**12,那么您将获得更平滑的图形。 enter image description here

删除0 Hz处的峰值

如果你关心的是DC值,那么只需减去均值即可。根据上面的示例,您可以将第5行更改为

yf = fftshift(fft(y - np.mean(y), nfft))

你得到没有基带的FFT。 enter image description here

最低分数

从理论的角度来看,你只需要满足奈奎斯特率。然而,对于视觉效果,FFT中的频率间隔是Fs / N.因此,如果您的采样率为500 Hz和500点,则点之间的间距为1 Hz,如果您的带宽为5 Hz,这可能还不够,因此您可以通过零填充信号来增加FFT的点数,或者降低采样率(只要它高于奈奎斯特)......

答案 1 :(得分:1)

首先,我建议您获得超过500个样本。那只是2.5个周期

使用Welch的方法应该有助于获得更平滑的图表。

doc scipy

答案 2 :(得分:0)

您是否尝试过使用scipy模块的高斯滤波器?试一试:https://docs.scipy.org/doc/scipy-0.16.1/reference/generated/scipy.ndimage.filters.gaussian_filter.html