Применение фильтра в scipy.signal: Использовать фильтр или фильтр?

21

Я видел в SO-потоке предложение использовать filtfiltвместо него обратную / прямую фильтрацию lfilter.

Какова мотивация использовать один метод против другого?

Бар
источник
Filtfilt медленнее
Аарон
Возможный дубликат В чем преимущество фильтфильта MATLAB
Мэтт Л.
1
@ Аарон filtfiltделает один и тот же фильтр дважды, в противоположных направлениях, так что он не медленнее, чем lfilterдважды в одном направлении, что позволяет получить одинаковую частотную характеристику.
эндолит
Да, это все, что я имел в виду. Это в два раза медленнее.
Аарон
Я новичок в этом и искал вокруг, чтобы использовать FilterFilt. @endolith сказал, что scipy.signal использует оригинальный сигнал. Я не уверен, что означает оригинальный сигнал и как мы его получаем. У меня есть файл WAV, который я загружаю в свою систему, но я не думаю, что это исходный сигнал, так как он разбит на массив и количество выборок. Пожалуйста, если кто-то может помочь. Спасибо!
Арунима Патания

Ответы:

30
  • filtfiltэто фильтрация нулевой фазы, которая не сдвигает сигнал при его фильтрации. Поскольку фаза равна нулю на всех частотах, она также является линейной фазой. Фильтрация во времени требует от вас предсказания будущего, поэтому его нельзя использовать в реальных онлайн-приложениях, только для автономной обработки записей сигналов.

  • lfilterтолько причинно-следственная фильтрация, аналогичная реальной электронной фильтрации. Это не может быть нулевой фазой. Это может быть линейно-фазовая (симметричная КИХ), но обычно это не так. Обычно это добавляет разные величины задержки на разных частотах.

Пример и изображение должны сделать это очевидным. Хотя величина частотной характеристики фильтров одинакова (вверху слева и вверху справа), низкочастотный диапазон нижних частот совпадает с исходным сигналом, только без высокочастотного содержимого, в то время как минимальная фазовая фильтрация задерживает сигнал причинно-следственной связью. :

фильтрфильт против фильтра

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")
эндолиты
источник
4
lfilterне обязательно минимальная фаза, это может быть что угодно в зависимости от коэффициентов фильтра, но в любом случае это причинно-следственная связь , а filtfiltэто не так. Таким образом, результат сравнения, который filtfiltимеет нулевую задержку и lfilterвсегда добавляет некоторую задержку, не совсем верен, поскольку не filtfiltявляется причинно-следственной, во-первых. Что на самом деле имеет значение, так это то, filtfiltчто не вызывает никаких фазовых искажений, тогда как lfilterделает (если только он не используется в качестве линейного фазового КИХ-фильтра, т.е. с знаменателем = 1).
Мэтт Л.
Также стоит отметить, что фильтрация N-го порядка с filtfiltсоответствует фильтрации с (2N-1) -го порядка с lfilter.
Томас Арилдсен
@ThomasArildsen Разве это не просто 2N? Это то, что я продемонстрировал в сценарии
эндолит
@ArunimaPathania Вы должны комментировать под моим ответом, а не под вопросом. «Исходный сигнал» означает только сигнал, который вы фильтруете. Вы можете выбирать либо lfilterили filtfilt. Они ведут себя по-разному, как показано
эндолит
7

Ответ @endolith полный и правильный! Пожалуйста, сначала прочитайте его пост, а затем этот в дополнение к нему. Из-за моей низкой репутации я не смог ответить на комментарии, в которых @Thomas Arildsen и @endolith утверждают об эффективном порядке фильтра, полученного filtfilt:

  • lfilter действительно применяет данный фильтр, и в пространстве Фурье это похоже на применение функции передачи фильтра ONCE.

  • filtfiltпримените один и тот же фильтр дважды, и эффект будет аналогичен применению передаточной функции фильтра SQUARED. В случае фильтра Баттерворта ( scipy.signal.butter) с передаточной функцией

G(n)=11ω2nwhere n is order of filter

эффективный выигрыш будет

G(n)filtfilt=G(n)2=11ω2n

и это не может быть истолковано как фильтр Баттерворта или порядка2 n - 12n2n1

G(n)filtfiltG(2n).
drgrujic
источник
1
Пожалуйста, постарайтесь не добавлять комментарии в качестве ответов. Тем не менее, добро пожаловать в SE.DSP и получите +1 от меня. Я думаю, что это добавляет к ответу ... по крайней мере, попытайтесь получить достаточно репутации, чтобы комментировать! :-)
Питер К.
Я не думаю, что это правда. G (n) - усиление амплитуды фильтра. Если вы каскадируете сложную передаточную функцию, я думаю, что она сработает до 2n.
Майк
Я быстро подтвердил, что Баттерворт 6-го порядка дает тот же самый G (ω), что и 2х (Баттеруорт 3-го порядка), но с частотой отсечки 3-го порядка, масштабированной на 1,6. Результаты идентичны, за исключением масштабирования частоты среза. Таким образом, порядок масштабируется с 2n, но учтите, что полоса пропускания будет уменьшаться, когда вы каскадируете, и должна быть скомпенсирована. Кто-то не стесняется объяснять теорию, но я не очень хочу разбираться в математике.
Майк