Respons frekuensi untuk filter yang dirancang menggunakan
fungsi mentega adalah:
Tetapi tidak ada alasan untuk membatasi filter ke desain filter monotonik konstan. Jika Anda menginginkan atenuasi yang lebih tinggi di pita transisi stopband dan curam, ada opsi lain. Untuk informasi lebih lanjut tentang menentukan filter menggunakan iirdesing lihat ini . Seperti yang ditunjukkan oleh plot respons frekuensi untuk desain mentega frekuensi cutoff (-3dB point) jauh dari tujuan. Ini dapat dikurangi dengan pengambilan sampel sebelum disaring (fungsi desain akan mengalami kesulitan dengan filter yang sempit, 2% dari bandwidth). Mari kita lihat penyaringan laju sampel asli dengan cutoff yang ditentukan.
import numpy as np
from scipy import signal
from matplotlib import pyplot as plt
from scipy.signal import fir_filter_design as ffd
from scipy.signal import filter_design as ifd
# setup some of the required parameters
Fs = 1e9 # sample-rate defined in the question, down-sampled
# remez (fir) design arguements
Fpass = 10e6 # passband edge
Fstop = 11.1e6 # stopband edge, transition band 100kHz
Wp = Fpass/(Fs) # pass normalized frequency
Ws = Fstop/(Fs) # stop normalized frequency
# iirdesign agruements
Wip = (Fpass)/(Fs/2)
Wis = (Fstop+1e6)/(Fs/2)
Rp = 1 # passband ripple
As = 42 # stopband attenuation
# Create a FIR filter, the remez function takes a list of
# "bands" and the amplitude for each band.
taps = 4096
br = ffd.remez(taps, [0, Wp, Ws, .5], [1,0], maxiter=10000)
# The iirdesign takes passband, stopband, passband ripple,
# and stop attenuation.
bc, ac = ifd.iirdesign(Wip, Wis, Rp, As, ftype='ellip')
bb, ab = ifd.iirdesign(Wip, Wis, Rp, As, ftype='cheby2')
Seperti yang disebutkan, karena kami mencoba memfilter persentase kecil dari bandwidth, filter tidak akan memiliki cutoff yang tajam. Dalam hal ini, filter lowpass, kita dapat mengurangi bandwidth untuk mendapatkan filter yang terlihat lebih baik. Fungsi resample python / scipy.signal dapat digunakan untuk mengurangi bandwidth.
Perhatikan fungsi resample akan melakukan penyaringan untuk mencegah alias. Prefilter juga dapat dibuat (untuk mengurangi alias) dan dalam hal ini kita bisa dengan sederhana melakukan resample sebanyak 100 dan dilakukan , tetapi pertanyaannya adalah tentang membuat filter. Untuk contoh ini, kami akan menurunkan sampel sebanyak 25 dan membuat filter baru
R = 25; # how much to down sample by
Fsr = Fs/25. # down-sampled sample rate
xs = signal.resample(x, len(x)/25.)
Jika kami memperbarui parameter desain untuk filter FIR, respons yang baru adalah.
# Down sampled version, create new filter and plot spectrum
R = 25. # how much to down sample by
Fsr = Fs/R # down-sampled sample rate
Fstop = 11.1e6 # modified stopband
Wp = Fpass/(Fsr) # pass normalized frequency
Ws = Fstop/(Fsr) # stop normalized frequency
taps = 256
br = ffd.remez(taps, [0, Wp, Ws, .5], [1,0], maxiter=10000)
Filter yang beroperasi pada data downsampled memiliki respons yang lebih baik. Manfaat lain menggunakan filter FIR adalah bahwa Anda akan memiliki respons fase linier.
filtfilt
diinginkan untuka
parameter.Apakah ini berhasil?
Namun, Anda benar, dokumentasinya tidak lengkap. Sepertinya
butter
ini adalah pembungkus untukiirfilter
, yang lebih baik didokumentasikan :Namun, sebagian besar barang ini diklon dari matlab, jadi Anda dapat melihat dokumentasi mereka juga:
Memperbarui:
Saya menambahkan dokumentasi untuk fungsi-fungsi ini. :) Github membuatnya mudah.
sumber
Tidak yakin apa aplikasi Anda, tetapi Anda mungkin ingin memeriksa Gnuradio: http://gnuradio.org/doc/doxygen/classgr__firdes.html
Blok pemrosesan sinyal ditulis dalam C ++ (walaupun grafik aliran Gnuradio menggunakan Python), tetapi Anda mengatakan kinerja tinggi itu penting.
sumber
Saya mendapatkan hasil yang baik dengan filter FIR ini. Pemberitahuan itu menerapkan filter dua kali, maju "maju" dan "mundur", sehingga untuk mengimbangi offset sinyal (
filtfilt
fungsi tidak bekerja, tidak tahu mengapa):Sumber yang bagus untuk memfilter desain dan penggunaan, dari mana saya mengambil kode ini, dan dari mana contoh band-pass dan hi-pass filter dapat diambil, adalah INI .
sumber
Saya tidak punya hak komentar ...
@endolith: Saya menggunakan yang sama seperti Anda kecuali menggunakan scipy.signal.filtfilt (B, A, x) di mana x adalah vektor input untuk disaring - misalnya numpy.random.normal (size = (N)) . filtfilt membuat sinyal maju dan mundur. Demi kelengkapan (sebagian besar sama dengan @endolith):
filtfilt seperti juga disarankan oleh @heltonbiker membutuhkan array koefisien yang saya percaya. Jika Anda perlu melakukan pemfilteran bandpass di baseband kompleks, konfigurasi yang lebih diperlukan diperlukan tetapi ini tampaknya tidak menjadi masalah di sini.
sumber