Python 如何在scipy.signal中制作低通滤波器?
关于在python/scipy.signal中制作低通滤波器,我有几个问题。如有任何答案,我将不胜感激Python 如何在scipy.signal中制作低通滤波器?,python,scipy,signal-processing,lowpass-filter,Python,Scipy,Signal Processing,Lowpass Filter,关于在python/scipy.signal中制作低通滤波器,我有几个问题。如有任何答案,我将不胜感激 我在试着理解它是如何工作的。它是否将滤波器系数与数据值相乘,这样对于数据[500],就可以了 这样做和它正在做的有什么区别 我也不明白当它开始过滤时,抽头的数量是如何影响的。对于不同的抽头数,我看到它从数据上的不同值开始。我假设它只有在有了必要的系数后才会开始。在我的示例中,我有683个来自scipy.signal.firwin的系数,但滤波器从300-400开始,正如您在图像中看到的那样(滤
数据[500]
,就可以了scipy.signal.firwin
的系数,但滤波器从300-400开始,正如您在图像中看到的那样(滤波器为蓝色;正弦波为红色;x为0-1000)scipy.signal.lfilter(b,a,x)
实现,其中b
和a
表示IIR滤波器,x
是输入信号
b
arg是M+1
分子(前馈)滤波器系数的数组,a
是N+1
分母(反馈)滤波器系数的数组。按照惯例,a[0]
=1(否则可以对过滤器进行规范化,使其成为1),因此我假设a[0]
=1。第n个输出样本y[n]
计算为
y[n]=b[0]*x[n]+b[1]*x[n-1]+…+b[M]*x[n-M]
-a[1]*y[n-1]-…-a[N]*y[N-N]。
IIR过滤的特殊之处在于,y[n]
的公式取决于之前的n
输出值y[n-1]
,…,y[n]
;这个公式是递归的。因此,为了开始这个过程,通常通过假设y[n]
和x[n]
对于n<0为零,将过滤器“初始化为零”。默认情况下,scipy.signal.lfilter
就是这样做的
您还可以使用scipy.signal.lfilter
通过设置a=[1]
应用“有限脉冲响应”(FIR),就像您在问题2中所做的那样。然后,在过滤公式中没有递归反馈项,因此过滤变成了b
和x
的简单卷积
scipy.signal.lfilter
立即开始过滤。正如我上面提到的,它这样做(默认情况下)假设y[n]
和x[n]
在n<0时为零,这意味着它计算的第一个输出样本是y[0]
,计算如下
y[0]=b[0]*x[0]。
但是,根据您的过滤器,可能是b[0]
接近于零,这可以解释为什么在开始时似乎什么都没有发生
检查过滤器性能的一个好方法是计算其“脉冲响应”,即查看通过单位脉冲[1,0,0,…]
作为输入产生的输出:
plot(scipy.signal.lfilter(b, a, [1] + [0] * 800))
下面是我从b=firwin(683,cutoff=1/30,window=“hamming”)
,a=[1]
:
从这幅图中我们可以看到一些东西:脉冲响应起初非常小,然后上升和振荡,峰值在样本指数341,然后对称衰减到零。过滤器的延迟为341=683//2,即设计过滤器时指定给firwin
的抽头数的一半
scipy.ndimage.convolve1d(sig, firwin_filter, mode='constant')
scipy.signal
中,我建议将kaiserord
与firwin
或firwin2
一起使用,以获得波纹量和过渡宽度的目标值,其中65是以dB为单位的阻带纹波,宽度
是以Hz为单位的过渡宽度:
用于确定过滤器的长度和Kaiser窗口的参数
>>> numtaps, beta = kaiserord(65, width/(0.5*fs))
>>> numtaps
167
>>> beta
6.20426
用于创建FIR滤波器
>>> taps = firwin(numtaps, cutoff, window=('kaiser', beta),
scale=False, nyq=0.5*fs)
编辑:对于其他设计,
kaiserord
可能会达到正确的标准,但不必依赖于这一标准来实现目标波纹量或过渡宽度。因此,一个可能的总体策略可能是这样一个迭代过程:
kaiserord
获得抽头数量的初始估计值scipy.ndimage.convolve1d(sig, firwin_filter, mode='constant')
>>> numtaps, beta = kaiserord(65, width/(0.5*fs))
>>> numtaps
167
>>> beta
6.20426
>>> taps = firwin(numtaps, cutoff, window=('kaiser', beta),
scale=False, nyq=0.5*fs)