Apakah benar untuk mengurangi sinyal low-pass filter dari sinyal asli dan menggunakan hasilnya sebagai "high-pass"?

8

Saya kesulitan menemukan dokumentasi untuk mengimplementasikan filter band-pass atau high-pass dengan python / scipy / numpy.

Saya dapat dengan mudah membuat dan menerapkan filter low-pass, jadi saya bertanya:

Apakah secara konseptual benar untuk menyaring sinyal low-pass, lalu kurangi hasil dari sinyal asli, untuk mendapatkan frekuensi tinggi saja?

Juga, jika ada orang yang memiliki contoh sederhana dari filter bandpass naif di Python (lebih disukai menggunakan perpustakaan numpy dan scipy), saya akan sangat berterima kasih.

Apa yang saya cari adalah sesuatu seperti:

filtered_signal = band_pass(original_signal, rate, low=20, high=500)

Terima kasih atas bantuannya!

EDIT: dengan scipy, saya menggunakan ini sebagai low-pass, dengan hasil yang baik:

import numpy, scipy.signal

def firfilt(interval, freq, sampling_rate):
    nfreq = freq/(0.5*sampling_rate)
    taps =  sampling_rate + 1
    a = 1
    b = scipy.signal.firwin(taps, cutoff=nfreq)
    firstpass = scipy.signal.lfilter(b, a, interval)
    ## second pass to compensate phase delay
    secondpass = scipy.signal.lfilter(b, a, firstpass[::-1])[::-1]
    return secondpass
heltonbiker
sumber
Dokumentasi untuk scipy.signal.firwinmemberi tahu cara membuat filter low-pass, high-pass, band-pass, band-stop, dan multi-band. Apakah kamu sudah mencoba firwin(taps, cutoff=nfreq, pass_zero=False)?
endolith
Lihat sound.whsites.net/articles/derived-xovers.htm untuk penggunaan teknik ini di speaker
endolith

Jawaban:

7

Secara teori Anda bisa melakukan ini, tetapi dalam praktiknya itu sulit dilakukan karena penyelarasan waktu dan fase harus cukup baik agar bisa bekerja. Jika penyelarasannya bagus Anda akan mendapatkan gangguan destruktif yang Anda cari. Jika tidak, Anda akan mendapat gangguan konstruktif. Lebih buruk lagi, apakah mereka mengganggu secara konstruktif atau konstruktif akan tergantung pada frekuensi - yaitu Anda bisa mendapatkan interferensi konstruktif dan destruktif secara bersamaan. Ini dapat bekerja, jika Anda hanya menyaring frekuensi yang cukup rendah, karena persyaratan waktu mereka yang paling longgar karena mereka berubah sangat lambat.

Cerita pendek - itu mungkin dilakukan tetapi cukup sulit sehingga umumnya masuk akal untuk hanya melakukan filter pass-tinggi.

Cara yang relatif mudah untuk membuat filter bandpass adalah membuat filter low-pass, dan kemudian memodulasinya ke frekuensi tengah yang Anda inginkan dengan mengalikannya dengan sinusoid frekuensi tersebut.

Jim Clay
sumber
Saya cenderung melewatkan filter dua kali, salah satunya secara terbalik, untuk mengkompensasi pergeseran fase.
heltonbiker
@heltonbiker Maka Anda harus dapat melakukannya dengan cara itu, asalkan Anda mendapatkan waktu yang tepat dan memastikan low-pass filter gain adalah 1.
Jim Clay
4

Anda dapat merancang berbagai jenis filter secara langsung dengan fungsi scipy.signal. Ada tiga fungsi utama untuk membuat filter respon impuls terbatas dengan paket scipy.signal.

  1. signal.remez
  2. signal.firwin
  3. signal.firwin2

Fungsi remez , sebagai argumen, mengambil jumlah ketukan (urutan +1), "band", dan keuntungan "yang diinginkan". "Band" ada di Hz. Fungsi ini agak aneh bahwa parameter "Hz" menentukan laju sampel dalam Hz. Contohnya adalah:

from scipy import signal
b = signal.remez(64, [0, 80, 100, 200, 220, 500], [0, 1, 0], Hz=1000)
plot(20*log10(abs(fft.fft(b, 4096).)))

Respon Frekuensi

Catatan: Saya sedikit curang dan menggunakan urutan FFT yang lebih tinggi untuk membuat plot terlihat lebih bagus (diinterpolasi poin untuk visualisasi saja).

Contoh lowpass dan highpass:

bl = signal.remez(64, [0, 248, 252, 500], [1, 0], Hz=1000) #lowpass
bh = signal.remez(64, [0, 248, 252, 500], [0, 1], Hz=1000) #highpass

Fungsi firwin mengambil jumlah tap lagi dan cutoff sebagai argumen. Cutoff dapat berupa beberapa nilai sebagai daftar untuk menentukan bandpass dan filter stopband. Unit default untuk cutoff adalah frekuensi dinormalisasi di mana cutoff nyquist adalah 1 dan laju sampel akan 2. Ini dapat dimodifikasi dengan menetapkan / nyq /. Menggunakan contoh-contoh di atas firwin akan disebut sebagai:

b = signal.firwin(64, [100, 200], pass_zero=False, nyq=500)

The firwin2 lebih dekat dengan funcion remez. Tetapi alih-alih memberikan keuntungan untuk band Anda memberikan keuntungan pada cutoffs.

b = signal.firwin2(64, [0, 100, 200, 500], [0, 1, 1, 0], nyq=500)

Lebih banyak contoh tersedia di sini

Christopher Felton
sumber
firwin, dan pembungkusnya butteradalah apa yang saya gunakan sekarang. Terima kasih!
heltonbiker
2
mentega bukanlah pembungkus untuk firwin. Mentega adalah metode desain filter IIR. Fungsi iirdesign adalah alat desain filter IIR tujuan umum. Dimana mentega, cheby, dll adalah fungsi Matlab'ish. Info lebih lanjut tentang fungsi filter IIR di sini, bit.ly/JPS4Zs
Christopher Felton
Saya kira saya salah mengerti apa yang saya lakukan. Akan memeriksanya, terima kasih (karena saya pasti ingin filter FIR).
heltonbiker
3

Anda mengindikasikan bahwa Anda mengalami kesulitan mencari tahu bagaimana merancang filter jalan pintas yang sesuai. Salah satu metode adalah pertama-tama merancang prototipe filter lowpass, kemudian menerapkan transformasi yang membelokkan respons filter ke dalam filter jenis lain (seperti filter highpass atau bandpass). Ini dilakukan dengan mengganti ekspresi untukz1ke dalam fungsi transfer filter lowpass prototipe. Berikut ini beberapa tautan ke informasi tentang topik tersebut:

Khususnya, untuk transformasi lowpass-to-highpass, Anda dapat menerapkan subtitusi berikut:

z1=α+z11+αz1,
α=cos(12(ωcωc))cos(12(ωc+ωc))

dimana ωc adalah frekuensi cutoff dari prototipe dan filter lowpass ωcadalah frekuensi cutoff yang dihasilkan dalam filter highpass yang ditransformasikan. Ada beberapa contoh yang diberikan dalam dokumentasi MATLAB yang ditunjukkan pada tautan pertama .; mungkin ada fungsi serupa yang tersedia di SciPy. Dengan demikian, banyak fungsi desain filter di perpustakaan yang mengikuti contoh MATLAB dengan cermat, dan mereka mampu mendesain filter dari semua tipe utama (lowpass, highpass, dll.) Dengan sedikit usaha.

Jason R
sumber
Terima kasih atas perhatian Anda, tetapi saya harus mengakui bahwa saya tidak memiliki latar belakang yang cukup untuk mencerna informasi teknis / matematika yang Anda posting, saya dari bidang bio-sains dan mengharapkan jawaban yang lebih mudah. Jika upaya untuk membuat jalan pintas relatif sedikit, apakah mungkin untuk memposting beberapa kode kerja kecil, atau tautan ke sebuah contoh?
heltonbiker
Jenis filter apa yang telah Anda gunakan? Apakah Anda mendesainnya menggunakan fungsi pustaka SciPy?
Jason R
Saya akan mengedit pertanyaan dengan low-pass yang saya gunakan
heltonbiker
1
Lihat komentar endolith di atas pada pertanyaan Anda. Seperti yang ditunjukkannya, fungsi yang Anda gunakan untuk membuat filter Anda tampaknya mampu merancang filter jalan pintas juga.
Jason R