我在SO线程中看到了使用filtfilt的建议,该建议执行向后/向前过滤而不是lfilter

将一种技术与另一种技术结合使用的动机是什么?

评论

Filtfilt较慢

MATLAB的filtfilt的优点是什么的可能重复

@Aaron filtfilt在相同的方向上执行两次相同的滤波器,因此它并不比在一个方向上执行两次lfilter慢,这就是您获得相同频率响应的方式。

是的,这就是我的意思。慢一倍。

我对此并不陌生,一直在寻找使用filtfilt的方法。 @endolith表示scipy.signal使用原始信号。我不确定原始信号的含义以及如何获得它。我有一个wav文件,可以将其加载到系统上,但是我认为它不是原始信号,因为它被分解为一个numpy数组和样本数。请有人帮忙。谢谢!

#1 楼


filtfilt是零相位滤波,在滤波时不会偏移信号。由于在所有频率下相位均为零,因此它也是线性相位。向后过滤需要您预测未来,因此不能在“在线”现实应用中使用,只能用于信号记录的脱机处理。
,类似于现实生活中的电子滤波器。不能为零相。它可以是线性相位(对称FIR),但通常不是。通常,它会在不同的频率上增加不同的延迟量。

一个示例和图像应该使它显而易见。尽管滤波器的频率响应幅度相同(左上和右上),但零相位低通与原始信号对齐,只是没有高频成分,而最小相位滤波则以因果关系延迟了信号:



from __future__ import division, print_function
import numpy as np
from numpy.random import randn
from numpy.fft import rfft
from scipy import signal
import matplotlib.pyplot as plt

b, a = signal.butter(4, 0.03, analog=False)

# Show that frequency response is the same
impulse = np.zeros(1000)
impulse[500] = 1

# Applies filter forward and backward in time
imp_ff = signal.filtfilt(b, a, impulse)

# Applies filter forward in time twice (for same frequency response)
imp_lf = signal.lfilter(b, a, signal.lfilter(b, a, impulse))

plt.subplot(2, 2, 1)
plt.semilogx(20*np.log10(np.abs(rfft(imp_lf))))
plt.ylim(-100, 20)
plt.grid(True, which='both')
plt.title('lfilter')

plt.subplot(2, 2, 2)
plt.semilogx(20*np.log10(np.abs(rfft(imp_ff))))
plt.ylim(-100, 20)
plt.grid(True, which='both')
plt.title('filtfilt')

sig = np.cumsum(randn(800))  # Brownian noise
sig_ff = signal.filtfilt(b, a, sig)
sig_lf = signal.lfilter(b, a, signal.lfilter(b, a, sig))
plt.subplot(2, 1, 2)
plt.plot(sig, color='silver', label='Original')
plt.plot(sig_ff, color='#3465a4', label='filtfilt')
plt.plot(sig_lf, color='#cc0000', label='lfilter')
plt.grid(True, which='both')
plt.legend(loc="best")


评论


$ \ begingroup $
lfilter不一定是最小相位,它可以是任何东西,具体取决于滤波器系数,但在任何情况下都是因果关系,而filtfilt则不是。因此,比较结果表明filtfilt的延迟为零,而lfilter总是添加一些延迟,这并不是完全正确的,因为filtfilt首先是无因果的。实际上重要的是filtfilt不会引起任何相位失真,而lfilter会引起相位失真(除非它用作线性相位FIR滤波器,即分母= 1)。
$ \ endgroup $
– Matt L.
2014年11月10日17:52



$ \ begingroup $
还值得注意的是,使用filtfilt进行N阶过滤相当于使用lfilter进行(2N-1)阶过滤。
$ \ endgroup $
–托马斯·阿里森(Thomas Arildsen)
2014年11月21日10:30

$ \ begingroup $
@ThomasArildsen不只是2N吗?这就是我在脚本中展示的
$ \ endgroup $
– Endolith
2014年11月21日15:13



$ \ begingroup $
@ArunimaPathania您应该在我的回答下而不是在问题下发表评论。 “原始信号”仅表示您要过滤的信号。您可以使用lfilter或filtfilt进行过滤。它们的行为不同,如图所示
$ \ endgroup $
– Endolith
18年7月31日在13:57

#2 楼

@endolith的回答是完整而正确的!请先阅读他的文章,然后再阅读此文章。由于我的声誉低下,我无法回复@Thomas Arildsen和@endolith争论filtfilt获得的过滤器的有效顺序的问题:这就像应用过滤器传递函数ONCE。
lfilter两次应用相同的过滤器,效果类似于应用过滤器传递函数SQUARED。如果是Butterworth滤波器(filtfilt)具有传递函数

$$ G(n)= \ frac {1} {\ sqrt {1- \ omega ^ {2n}}} \ quad \ text {where} n \ text {是过滤器的顺序} $$

有效增益为

$$ G(n)_ {filtfilt} = G(n) ^ 2 = \ frac {1} {1- \ omega ^ {2n}} $$

,这不能解释为$ 2n $或$ 2n-1 $订单Butterworth过滤器

$$ G(n)_ {filtfilt} \ neq G(2n)。$$

评论


$ \ begingroup $
请不要添加评论作为答案。但是,欢迎来到SE.DSP,并向我+1。我认为这增加了答案...至少尝试使足够多的代表发表评论! :-)
$ \ endgroup $
– Peter K.♦
18-3-29在12:08



$ \ begingroup $
我认为这不是真的。 G(n)是滤波器的幅度增益。如果您级联复杂的传递函数,我认为它将达到2n。
$ \ endgroup $
–迈克
19-10-29在22:15

$ \ begingroup $
我通过快速仿真确认了一个6阶巴特沃斯给出的G(ω)与级联的2 x(3阶巴特沃斯)相同,但是3阶截止频率按1.6缩放。除了截止频率的缩放比例之外,结果是相同的。因此,阶数确实会以2n缩放,但请注意,级联时通带会减少,需要补偿。有人可以自由地解释理论,但我真的不希望学习所有数学。
$ \ endgroup $
–迈克
19-10-29在23:22