我在SO 线程中看到一个建议使用filtfilt
它执行向后/向前过滤而不是lfilter
.
使用一种技术对抗另一种技术的动机是什么?
我在SO 线程中看到一个建议使用filtfilt
它执行向后/向前过滤而不是lfilter
.
使用一种技术对抗另一种技术的动机是什么?
filtfilt
是零相位滤波,它在滤波时不会改变信号。由于相位在所有频率下都为零,因此它也是线性相位。及时向后过滤需要您预测未来,因此它不能用于“在线”现实生活中的应用程序,只能用于信号记录的离线处理。
lfilter
只是因果前向过滤,类似于现实生活中的电子过滤器。它不能是零相位。它可以是线性相位(对称 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")
@endolith 的回答是完整且正确的!请先阅读他的帖子,然后再阅读这篇文章。由于我的声誉较低,我无法回复@Thomas Arildsen和@endolith争论过滤器的有效顺序的评论filtfilt
:
lfilter
确实应用了给定的滤波器,并且在傅立叶空间中,这就像应用滤波器传递函数 ONCE。
filtfilt
应用相同的过滤器两次,效果就像应用过滤器传递函数 SQUARED。scipy.signal.butter
在具有传递函数的巴特沃斯滤波器 ( ) 的情况下
有效增益将是
这不能解释为或阶巴特沃斯滤波器