Menerapkan filter dalam scipy.signal: Gunakan lfilter atau filtfilt?

21

Saya melihat di thread SO saran untuk menggunakan filtfiltyang melakukan penyaringan mundur / maju bukan lfilter.

Apa motivasi untuk menggunakan satu terhadap teknik lainnya?

Bar
sumber
Filtfilt lebih lambat
Aaron
kemungkinan duplikat Apa keuntungan dari filtfilt MATLAB
Matt L.
1
@ Harun filtfiltmelakukan filter yang sama dua kali, dalam arah yang berlawanan, jadi itu tidak lebih lambat daripada melakukan lfilterdua kali dalam satu arah, yang adalah bagaimana Anda akan mendapatkan respons frekuensi yang sama.
endolith
Ya itu yang saya maksudkan. Ini dua kali lebih lambat.
Aaron
Saya baru dengan ini dan sedang mencari-cari menggunakan filtfilt. @endolith mengatakan bahwa scipy.signal menggunakan sinyal asli. Saya tidak yakin apa arti sinyal asli dan bagaimana kami mendapatkannya. Saya memiliki file wav yang saya muat ke sistem saya, tetapi saya tidak berpikir itu adalah sinyal asli karena dipecah menjadi array yang numpy dan jumlah sampel. Tolong jika seseorang bisa membantu. Terima kasih!
Arunima Pathania

Jawaban:

30
  • filtfiltadalah penyaringan fase nol, yang tidak menggeser sinyal saat disaring. Karena fase adalah nol pada semua frekuensi, itu juga fase linier. Penyaringan mundur dalam waktu mengharuskan Anda untuk memprediksi masa depan, sehingga tidak dapat digunakan dalam aplikasi kehidupan nyata "online", hanya untuk pemrosesan rekaman sinyal secara offline.

  • lfilteradalah penyaringan forward-in-time kausal saja, mirip dengan filter elektronik kehidupan nyata. Tidak mungkin fase-nol. Itu bisa fase linear (FIR simetris), tetapi biasanya tidak. Biasanya itu menambah jumlah penundaan yang berbeda pada frekuensi yang berbeda.

Contoh dan gambar harus membuatnya jelas. Meskipun besarnya respon frekuensi dari filter adalah identik (kiri atas dan kanan atas), lowpass fase-nol sejajar dengan sinyal asli, hanya tanpa frekuensi tinggi, sedangkan penyaringan fase minimum menunda sinyal dengan cara yang disebabkan oleh sebab-akibat. :

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")
endolith
sumber
4
lfilterbelum tentu fase minimum, bisa berupa apa saja tergantung pada koefisien filter, tetapi dalam kasus apa pun itu adalah kausal , yang filtfiltbukan. Jadi hasil perbandingan yang filtfiltmemiliki zero delay, dan lfilterselalu menambahkan beberapa delay adalah tidak sepenuhnya benar, karena filtfiltnon-kausal di tempat pertama. Yang penting adalah hal itu filtfilttidak menyebabkan distorsi fase apa pun, sedangkan lfiltertidak (kecuali jika digunakan sebagai filter FIR fase linier, yaitu dengan penyebut = 1).
Matt L.
Perlu dicatat juga bahwa penyaringan urutan filtfiltke- N sesuai dengan penyaringan dengan urutan ke-2 (-2) dengan lfilter.
Thomas Arildsen
@ThomasArildsen Bukan hanya 2N? Itulah yang saya tunjukkan dalam naskah
endolith
@ArunimaPathania Anda harus mengomentari jawaban saya, bukan di bawah pertanyaan. "Sinyal asli" hanya berarti sinyal yang Anda filter. Anda dapat memfilter dengan salah satu lfilteratau filtfilt. Mereka berperilaku berbeda, seperti yang ditunjukkan
endolith
7

Jawaban oleh @endolith sudah lengkap dan benar! Silakan baca postingnya terlebih dahulu, dan kemudian yang ini sebagai tambahan. Karena reputasi saya rendah saya tidak mampu untuk merespon komentar mana @Thomas Arildsen dan @endolith berdebat tentang pesanan yang efektif filter diperoleh dengan filtfilt:

  • lfilter tidak menerapkan filter yang diberikan dan dalam ruang Fourier ini seperti menerapkan fungsi transfer filter SEKALI.

  • filtfiltterapkan filter yang sama dua kali dan efeknya seperti menerapkan fungsi transfer filter SQUARED. Dalam hal filter Butterworth ( scipy.signal.butter) dengan fungsi transfer

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

keuntungan yang efektif adalah

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

2n2n1

G(n)filtfiltG(2n).
drgujic
sumber
1
Cobalah untuk tidak menambahkan komentar sebagai jawaban. Namun, selamat datang di SE.DSP, dan dapatkan +1 dari saya. Saya pikir ini menambah jawaban ... setidaknya mencoba untuk mendapatkan rep cukup untuk berkomentar! :-)
Peter K.
Saya pikir ini tidak benar. G (n) adalah gain amplitudo dari filter. Jika Anda mengalirkan fungsi transfer yang kompleks, saya pikir itu akan berhasil ke 2n.
Mike
Saya mengkonfirmasi dengan simulasi cepat bahwa urutan ke-6 Butterworth memberikan G (ω) yang sama dengan 2 x (urutan ke-3 Butterworth) mengalir tetapi dengan frekuensi cutoff dari urutan ke-3 diskalakan dengan 1,6. Hasilnya identik kecuali untuk penskalaan frekuensi cutoff. Jadi, urutannya berskala 2n, tetapi perhatikan bahwa passband akan berkurang saat Anda mengalir dan perlu diberi kompensasi. Seseorang merasa bebas untuk menjelaskan teori tetapi saya tidak benar-benar ingin melewati semua matematika.
Mike