Python中的FFT滤波器与lfilter的比较
我在用Python给信号加带通滤波器的时候遇到了一些麻烦。我尝试了以下两种方法:
- 手动做一个方框窗口,也就是先对信号进行快速傅里叶变换(FFT),然后用方框窗口来滤波,最后再用逆快速傅里叶变换(IFFT)把结果转换回时间域。
- 使用scipy.signal模块,利用firwin2来构建滤波器,然后用lfilter来进行滤波。
此外,我还在音频处理软件Cool Edit中做了同样的滤波,并把上面两种测试的结果进行了比较。
从结果来看(我还是新手,所以不能发我的png图),FFT和scipy.signal的结果差别很大。与Cool Edit的结果相比,FFT的结果比较接近,但并不完全相同。代码如下:
# imports
from pylab import *
import os
import scipy.signal as signal
# load data
tr=loadtxt('tr6516.txt',skiprows=1)
sr = 500 # [samples/s]
nf = sr/2.0 # Nyquist frequence
W = 512 # Window widht for filtering
N=float(8192) # Fourier settings
Ns = len(tr[:,0]) # Total number of samples
# Create inpulse responce from the filter
fv=12.25
w =0.5
r =0.5*w
Hz=[0, fv-w-r, fv-w, fv+w, fv+w+r, nf]
ff=[0, 0, 1, 1, 0, 0]
b = signal.firwin2(W,Hz,ff,nfreqs=N+1,nyq=nf)
SigFilter = signal.lfilter(b, 1, tr[:,1])
# Fourier transform
X1 = fft(tr[:,1],n=int(N))
X1 = fftshift(X1)
F1 = arange(-N/2.0,N/2.0)/N*sr
# Filter data
ff=[0,1,1,0]
fv=12.25
w =0.5
r =0.5*w
Hz=[fv-w-r,fv-w,fv+w,fv+w+r]
k1=interp(-F1,Hz,ff)+interp(F1,Hz,ff)
X1_f=X1*k1
X1_f=ifftshift(X1_f)
x1_f=ifft(X1_f,n=int(N))
有没有人能告诉我为什么会有这样的差异?在Cool Edit中进行的滤波和在scipy.signal中的设置是一样的(汉宁窗口,窗口宽度512)。还是说我完全搞错了。
最好的祝福,
Anders
上面的代码:
与Cool Edit的比较:
1 个回答
0
小的差异可以用不同的库使用不同的算法来解释,这些算法在累积误差时略有不同。
举个例子,如果你用三种不同的方法来计算离散傅里叶变换(DFT),分别是基于2的快速傅里叶变换(FFT)、分裂基快速傅里叶变换和普通的DFT,结果都会有一点点不同。实际上,普通的DFT准确度比所有不错的FFT实现都要差,因为它使用了更多的浮点运算,因此累积的误差也更多。
这是否能解释你看到的结果接近(但不完全相同)的情况呢?