为了理解ffts的用法,我在python中为离散信号实现了一个低通滤波器。
得到的滤波信号几乎就是我想要的,但不幸的是,光谱并不是我所期望的。第一眼看上去还行,但正如你所看到的,振幅和频率都不正确。
频率应为0Hz,220Hz,660Hz,幅度为3,2,1;但它出来如下图所示。请注意,由于我在plot命令中写了abs(F)/N
而不是2*abs(F)/N
,因此该图中的幅度不正确。但是当我这样做时,DC值加倍到6,我认为这是错误的。
而谱图的绘制对我来说似乎有些奇怪,请看一下:
我不知道我做错了什么,非常感谢你的帮助。
import numpy as np
import matplotlib.pyplot as plt
from math import pi
N = 2048
w0 = 2*pi*220
t = np.linspace(0, 0.1, N)
signal = lambda x: 3 + 2*np.sin(w0*x) + np.sin(3*w0*x)
f = np.array(signal(t))
F = np.fft.fft(f)
Fo = F.copy() # just for printing the unfiltered spectrum
freq = np.fft.fftfreq(len(f), 1/N)
# That's the filter, all parts over the frequency of fg should be damped.
fg = 50
for i in range(0, len(f)):
F[i] *= (1 if abs(freq[i]) < fg else 0)
ff = np.fft.ifft(F)
plt.subplot(3, 1, 1)
plt.plot(t, f, label='f original')
plt.plot(t, ff, label='f filtered')
plt.axis(xmin=0, xmax=16e-3)
plt.legend()
plt.subplot(3, 1, 2)
plt.plot(freq, abs(Fo)/N, label='spec original')
plt.axis(xmin=-200, xmax=200)
plt.legend()
plt.subplot(3, 1, 3)
plt.plot(freq, abs(F)/N, label='spec filtered')
plt.axis(xmin=-200, xmax=200)
plt.legend()
plt.show()
答案 0 :(得分:0)
这里有两个问题:
1)由于freq
想要样本间距(例如,以秒为单位),fftfreq
轴偏离了10倍,应为{{1} (或者,在您的情况下为total_time/N
),而不是0.1/N
,因为您正在使用。
2)看起来很滑稽的情节是因为来自fft的返回值不是通过增加频率值来排序的,并且发生返回值中的最后一个频率处于图中的中间频率,因此该行就在那里结束。请尝试:只绘制点(而不是通过线连接的点),它看起来合理;或使用fftshift
。