Filter in scipy.signal anwenden: lfilter oder filtfilt verwenden?


21

Ich habe in einem SO-Thread einen Vorschlag gesehen, filtfiltder eine Rückwärts- / Vorwärtsfilterung anstelle von ausführt lfilter.

Was ist die Motivation, eine gegen die andere Technik einzusetzen?


Filtfilt ist langsamer
Aaron


1
@Aaron filtfiltmacht den gleichen Filter zweimal in entgegengesetzte Richtungen, also nicht langsamer als lfilterzweimal in eine Richtung. Auf diese Weise erhalten Sie den gleichen Frequenzgang.
Endolith

Ja das ist alles was ich meinte. Es ist doppelt so langsam.
Aaron

Ich bin neu in diesem Bereich und habe mich umgesehen, um filtfilt zu verwenden. @endolith sagte, dass das scipy.signal das ursprüngliche Signal verwendet. Ich bin nicht sicher, was das ursprüngliche Signal bedeutet und wie wir es bekommen. Ich habe eine WAV-Datei, die ich auf mein System lade, aber ich glaube nicht, dass es das Originalsignal ist, da es in ein numpy-Array und eine Anzahl von Samples aufgeteilt ist. Bitte wenn jemand helfen könnte. Vielen Dank!
Arunima Pathania

Antworten:


30
  • filtfiltist eine Nullphasenfilterung, die das Signal beim Filtern nicht verschiebt. Da die Phase bei allen Frequenzen Null ist, ist sie auch linear. Wenn Sie in der Zeit rückwärts filtern, müssen Sie die Zukunft vorhersagen. Daher kann es nicht in "Online" -Anwendungen im echten Leben verwendet werden, sondern nur für die Offline-Verarbeitung von Signalaufzeichnungen.

  • lfilterist nur eine kausale Vorwärts-in-Zeit-Filterung, ähnlich einem realen elektronischen Filter. Es kann nicht nullphasig sein. Sie kann linearphasig sein (symmetrische FIR), ist es aber normalerweise nicht. Normalerweise werden unterschiedliche Verzögerungswerte bei verschiedenen Frequenzen hinzugefügt.

Ein Beispiel und ein Bild sollten es deutlich machen. Obwohl die Größe des Frequenzgangs der Filter identisch ist (oben links und oben rechts), stimmt der Nullphasentiefpass mit dem Originalsignal überein, nur ohne Hochfrequenzanteil, während die Minimalphasenfilterung das Signal auf kausale Weise verzögert :

filtfilt vs 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
lfilterist nicht unbedingt die Minimalphase, es kann alles in Abhängigkeit von den Filterkoeffizienten sein, aber in jedem Fall ist es kausal , was filtfiltnicht ist. Das Ergebnis des Vergleichs, filtfiltdas eine Verzögerung von Null aufweist und lfilterimmer eine Verzögerung hinzufügt, ist also nicht genau richtig, da filtfiltes in erster Linie nicht kausal ist. Was tatsächlich zählt, ist, filtfiltdass keine Phasenverzerrungen verursacht werden, wohingegen dies der lfilterFall ist (es sei denn, es wird als lineares Phasen-FIR-Filter verwendet, dh mit Nenner = 1).
Matt L.

Es ist auch anzumerken, dass das Filtern der N-ten Ordnung mit filtfiltdem Filtern mit (2N-1) -ter Ordnung mit entspricht lfilter.
Thomas Arildsen

@ThomasArildsen Ist es nicht nur 2N? Das habe ich im Drehbuch demonstriert
Endolith

@ArunimaPathania Du solltest unter meiner Antwort, nicht unter der Frage kommentieren. "Originalsignal" bedeutet nur das Signal, das Sie filtern. Sie können entweder mit lfilteroder filtern filtfilt. Sie verhalten sich anders, wie gezeigt
Endolith

7

Antwort von @endolith ist vollständig und richtig! Bitte lesen Sie zuerst seinen Beitrag und dann diesen zusätzlich dazu. Aufgrund meines schlechten Rufs konnte ich nicht auf Kommentare antworten, in denen @Thomas Arildsen und @endolith über die effektive Reihenfolge der Filter streiten, die erhalten wurden durch filtfilt:

  • lfilter Wendet ein gegebenes Filter an und im Fourier-Raum ist dies wie das EINMALIGE Anwenden der Filterübertragungsfunktion.

  • filtfiltWenden Sie denselben Filter zweimal an, und der Effekt entspricht der Anwendung der Filterübertragungsfunktion SQUARED. Bei Butterworth-Filter ( scipy.signal.butter) mit Übertragungsfunktion

G(n)=11-ω2nwoher n ist die Reihenfolge der Filter

der effektive Gewinn wird sein

G(n)fichltfichlt=G(n)2=11-ω2n

2n2n-1

G(n)fichltfichltG(2n).

1
Bitte versuchen Sie nicht, Kommentare als Antworten hinzuzufügen. Willkommen jedoch bei SE.DSP und habe eine +1 von mir. Ich denke, dies trägt zur Antwort bei ... versuche wenigstens, genug Wiederholungen zu bekommen, um Kommentare abzugeben! :-)
Peter K.

Ich denke nicht, dass das wahr ist. G (n) ist die Amplitudenverstärkung des Filters. Wenn Sie die komplexe Übertragungsfunktion kaskadieren, wird es meiner Meinung nach auf 2n funktionieren.
Mike

Ich bestätigte mit einer schnellen Simulation, dass ein Butterworth 6. Ordnung dasselbe G (ω) ergibt wie 2 x (Butterworth 3. Ordnung) in Kaskade, aber mit der Grenzfrequenz 3. Ordnung, skaliert um 1,6. Die Ergebnisse sind bis auf die Skalierung der Grenzfrequenz identisch. Die Reihenfolge skaliert also mit 2n, aber beachten Sie, dass sich das Durchlassband verringert, wenn Sie kaskadieren, und kompensiert werden muss. Jemand kann gerne die Theorie erklären, aber ich möchte nicht wirklich die ganze Mathematik durchgehen.
Mike
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.