Python 中的 FFT 滤波器与 lfilter
在Python中将带通滤波器应用于信号时我遇到了一些麻烦。已尝试以下操作:
- “手动”执行框窗口,即对信号进行 FFT,应用 使用框窗进行过滤并进行 IFFT 以返回时间 领域。
- 使用 scipy.signal 模块,我使用 firwin2 来构造 filter 然后 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 中相同的设置完成的(hanning 窗口,窗口宽度 512)。或者我完全错了。
此致, Anders
上面的代码:
与 Cool Edit 相比:
I have some troubles when applying bandpass filter to signal in Python. Have tried the following to things:
- Do the box window "by hand", i.e. do the FFT on the signal, apply the
filter with a box window and the do the IFFT to get back to the time
domain. - Use the scipy.signal module where I use firwin2 to construct the
filter and then lfilter to to the filtering.
Futhermore I have done the same filtering in the audio program Cool Edit and compared the result from the above two tests.
As can be seen (I am a new user so I can not post my png fig), the results from the FFT and scipy.signal are very different. When compare to the result from Cool edit, the FFT is close, however not identical. Code as below:
# 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))
Can anyone explain to me why this difference? The filtering in Cool edit has been done using the same settings as in scipy.signal (hanning window, window width 512). Or have I got this all totaly wrong.
Best regards,
Anders
Above code:
Compared with Cool Edit:
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
微小的差异可以通过使用不同算法的库来解释,这些算法累积的误差略有不同。
例如,如果使用基 2 FFT、分割基 FFT 和普通 DFT 计算 DFT,结果都会略有不同。事实上,普通 DFT 的精度比 FFT 的所有不错的实现都要差,因为它使用更多的浮点运算,因此会积累更多的误差。
这可以解释您所看到的接近(但不相同)的结果吗?
Small differences can be explained by the libraries using different algorithms that accumulate error slightly differently.
For example, if you compute the DFT using a radix-2 FFT, a split-radix FFT and an ordinary DFT, the results will all be slightly different. In fact the ordinary DFT has worse accuracy than all decent implementations of an FFT because it uses many more floating point operations, and thus it accumulates more error.
Could this explain the close (but not identical) results you are seeing?