filter low pass dan FFT untuk pemula dengan Python

23

Saya baru untuk pemrosesan sinyal dan terutama untuk FFT, maka saya tidak yakin apakah saya melakukan hal yang benar di sini dan saya agak bingung dengan hasilnya.

Saya memiliki fungsi nyata diskrit (data pengukuran) dan ingin mengatur low pass filter. Alat pilihan adalah Python dengan paket numpy. Saya mengikuti prosedur ini:

  • hitung fft dari fungsi saya
  • memotong frekuensi tinggi
  • melakukan invers fft

Berikut adalah kode yang saya gunakan:

import numpy as np
sampling_length = 15.0*60.0 # measured every 15 minutes
Fs = 1.0/sampling_length
ls = range(len(data)) # data contains the function
freq = np.fft.fftfreq(len(data), d = sampling_length)
fft = np.fft.fft(data)
x = freq[:len(data)/2] 
for i in range(len(x)):
if x[i] > 0.005: # cut off all frequencies higher than 0.005
    fft[i] = 0.0
    fft[len(data)/2 + i] = 0.0
inverse = np.fft.ifft(fft)

Apakah ini prosedur yang benar? Hasilnya inverseberisi nilai-nilai kompleks, yang membingungkan saya.

Sampai b
sumber
1
Ketika saya belajar FFT, saya menemukan posting blog ini sangat membantu. glowingpython.blogspot.com/2011/08/...
David Poole

Jawaban:

23

Fakta bahwa hasilnya rumit harus diharapkan. Saya ingin menunjukkan beberapa hal:

Anda menerapkan filter domain frekuensi brick-wall untuk data, mencoba untuk nol semua output FFT yang sesuai dengan frekuensi lebih besar dari 0,005 Hz, kemudian mengubah terbalik untuk mendapatkan sinyal domain-waktu lagi. Agar hasilnya menjadi nyata, maka input ke FFT terbalik harus simetris konjugat . Ini berarti bahwa untuk panjang- FFT,N

X[k]=X[Nk],k=1,2,,N21(Neven)

X[k]=X[Nk],k=1,2,,N2(Nodd)
  • Perhatikan bahwa untuk genap, dan secara umum tidak sama, tetapi keduanya nyata. Untuk aneh , harus nyata.NX[0]NX[0]X[N2]NX[0]

Saya melihat bahwa Anda mencoba melakukan sesuatu seperti ini dalam kode Anda di atas, tetapi itu tidak sepenuhnya benar. Jika Anda menerapkan kondisi di atas pada sinyal yang Anda berikan ke FFT terbalik, maka Anda harus mengeluarkan sinyal nyata.

Poin kedua saya lebih bersifat filosofis: apa yang Anda lakukan akan berhasil, karena hal itu akan menekan konten domain frekuensi yang tidak Anda inginkan. Namun, ini biasanya bukan cara filter lowpass akan diterapkan dalam praktiknya. Seperti yang saya sebutkan sebelumnya, apa yang Anda lakukan pada dasarnya adalah menerapkan filter yang memiliki respon magnitudo dinding-bata (yaitu persegi panjang sempurna). Respons impuls filter semacam itu memiliki bentuk . Karena penggandaan dalam domain frekuensi setara dengan (dalam kasus menggunakan konvolusi DFT, bundar) dalam domain waktu, operasi ini sama dengan menggabungkan sinyal domain waktu dengan fungsi .s i n csinc(x)sinc

Mengapa ini menjadi masalah? Ingatlah seperti apa fungsi dalam domain waktu (di bawah gambar dipinjam tanpa malu-malu dari Wikipedia):sinc

plot fungsi sinc

Fungsi memiliki dukungan yang sangat luas dalam domain waktu; itu meluruh sangat lambat saat Anda bergerak menjauh dari lobus utamanya. Untuk banyak aplikasi, ini bukan properti yang diinginkan; ketika Anda memadukan sinyal dengan , efek dari sidelobes yang perlahan membusuk akan sering terlihat dalam bentuk domain waktu dari sinyal output yang difilter. Efek semacam ini sering disebut sebagai dering . Jika Anda tahu apa yang Anda lakukan, ada beberapa kasus di mana jenis penyaringan ini mungkin sesuai, tetapi dalam kasus umum, itu bukan yang Anda inginkan.s i n csincsinc

Ada cara yang lebih praktis untuk menerapkan filter lowpass, baik dalam domain waktu dan frekuensi. Respons impuls terbatas dan filter respons impuls tak terbatas dapat diterapkan langsung menggunakan representasi persamaan perbedaannya . Atau, jika filter Anda memiliki respons impuls yang cukup lama, Anda seringkali dapat memperoleh manfaat kinerja menggunakan teknik konvolusi cepat berdasarkan FFT (menerapkan filter dengan mengalikan dalam domain frekuensi alih-alih konvolusi dalam domain waktu), seperti tumpang tindih- simpan dan tumpang tindih-tambahkan metode.

Jason R
sumber
Fungsi sinc adalah pemfilteran yang ideal, bukan? Itulah tujuan semua filter lainnya, tetapi tidak tercapai. Ini buruk untuk pemrosesan gambar karena gambar tidak antialias terlebih dahulu, sehingga menghasilkan dering yang terlihat mengerikan, tetapi untuk audio atau sinyal lain yang antialiasnya disaring sebelum pengambilan sampel, bukankah itu filter terbaik yang bisa Anda dapatkan?
endolith
1
Ya, hasil saya tidak simetris konjugat. Saya memperbaiki kode, sekarang semuanya berfungsi dengan baik. Terima kasih!
Hingga B
3
@endolith - a Sinc adalah interpolator yang ideal untuk kepastian jenis interpolasi, tetapi bisa jauh dari ideal sebagai filter untuk sebagian besar jenis persyaratan filter umum, seperti kerataan respon band pass, penolakan stop band, dan lain
hotpaw2
+1 untuk penjelasan yang bagus tentang "mengapa orang tidak menerapkan filter seperti halnya PO"
Sibbs Gambling
Anda harus menggunakan sinc windowed. Jika Anda tidak dibatasi oleh waktu, ini adalah filter optimal, jauh lebih baik daripada Chebichev.