Python滤波器设计

发布于:2022-11-11 ⋅ 阅读:(902) ⋅ 点赞:(0)

文章目录

lfilter

FIR,即有限脉冲响应(finite impulse response),特点是无反馈,其离散形式可表示为

y n = ∑ k = 0 M b k x n − k y_n=\sum^M_{k=0}b_kx_{n-k} yn=k=0Mbkxnk

IIR,即无限脉冲响应(infinite impulse response),可以写为

a 0 y n = ∑ k = 0 M b k x n − k − ∑ k = 1 N a k y n − k a_0y_n=\sum^M_{k=0}b_kx_{n-k}-\sum^N_{k=1}a_ky_{n-k} a0yn=k=0Mbkxnkk=1Nakynk

滤波器设计,就是对 a k , b k a_k, b_k ak,bk具体形式的求解,scipy.signal中内置了一些常用的FIR和IIR滤波器。

其中lfilter是最基础的脉冲响应滤波器,其形式为

lfilter(b, a, x, axis=-1, zi=None)

其中,a, b为滤波参数,x为待滤波数组,axix为作用的坐标轴,zi为默认延时,其Z变换形式的滤波函数为

Y ( z ) = ∑ i = 0 b i z − i ∑ i = 0 a i z − i X ( z ) Y(z)=\frac{\sum_{i=0} b_iz^{-i}}{\sum_{i=0} a_iz^{-i}}X(z) Y(z)=i=0aizii=0biziX(z)

下面通过butter函数生成3阶巴特沃斯滤波器对应的ab值,用以lfilter进行滤波

import scipy.signal as ss
import matplotlib.pyplot as plt
rng = np.random.default_rng()
t = np.linspace(-1, 1, 201)
PI = 2*np.pi
x = (np.sin(PI*0.75*t*(1-t) + 2.1) +
     0.1*np.sin(PI*1.25*t + 1) +
     0.18*np.cos(PI*3.85*t))
# 原始数据添加噪声
xn = x + rng.standard_normal(len(t)) * 0.08
b, a = ss.butter(3, 0.05)

z = ss.lfilter(b, a, xn)
z2 = ss.lfilter(b, a, z)

plt.plot(t, z, 'r--', t, z2, 'r')
plt.scatter(t, xn, marker='.', alpha=0.75)
plt.legend(('lfilter, once', 'lfilter, twice', 'noisy signal'), loc='best')
plt.show()

效果如下

在这里插入图片描述

可见,lfilter的确对原始信号的噪声进行了过滤,过滤之后的信号也的确较为平滑,而且显然进行二次滤波的效果比第一次更加平滑,但却产生了延时。

这就是lfilter的问题所在,即其为因果关系实时过滤,对于除了对称FIR之外的其他情况,都会产生延时。

filtfilt

相比之下,另一个滤波函数filtfilt对输入信号进行正反两个方向的滤波,从而消除了lfilter所产生的相位差。

y = ss.filtfilt(b, a, xn)
plt.plot(t, y, 'r')
plt.scatter(t, xn, marker='.', alpha=0.75)
plt.legend(('filtfilt', 'noisy signal'), loc='best')
plt.show()

效果为

在这里插入图片描述

filtfilt函数的调用方法如下

filtfilt(b, a, x, axis=-1, padtype='odd', padlen=None, method='pad', irlen=None)

除了在lfilter中已有的b, a, x, axis之外,另外三个参数表示:

  • padtype: 滤波器填充信号的扩展类型,为"odd", "even", "constant"或者None
  • padlen:在应用滤波器之前在轴两端延伸X的元素数目。此值必须小于要滤波元素个数- 1。(int型或None)
  • method:边缘处理方法,为"pad"时,填充信号,填充类型由padtypepadlen决定;为"gust"时,使用古斯塔夫森方法,填充方式由irlen决定。
  • irlen:指定滤波器的脉冲响应的长度。如果irlen是None,则脉冲响应的任何部分都被忽略。对于长信号,指定irlen可以显著改善滤波器的性能。
本文含有隐藏内容,请 开通VIP 后查看