È corretto sottrarre un segnale filtrato passa-basso dal segnale originale e utilizzare il risultato come "passa-alto"?


8

Non riesco a trovare la documentazione per implementare il filtro passa-banda o passa-alto con python / scipy / numpy.

Tuttavia, posso facilmente creare e applicare un filtro passa-basso, quindi chiedo:

Sarebbe concettualmente corretto filtrare un segnale passa-basso, quindi sottrarre il risultato dal segnale originale, al fine di ottenere solo le alte frequenze?

Inoltre, se qualcuno ha un semplice esempio di un ingenuo filtro passa-banda in Python (preferibilmente usando le librerie intorpidite e scipy), sarei molto grato.

Quello che cerco è qualcosa di simile:

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

Grazie per qualsiasi aiuto!

EDIT: con scipy, sto usando questo come passa-basso, con buoni risultati:

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

La documentazione per scipy.signal.firwinspiega come realizzare filtri passa-basso, passa-alto, passa-banda, passa-banda e multi-banda. Ci hai provato firwin(taps, cutoff=nfreq, pass_zero=False)?
endolith,

Vedi sound.whsites.net/articles/derived-xovers.htm per l'uso di questa tecnica negli altoparlanti
endolith,

Risposte:


7

In teoria puoi farlo, ma in pratica è difficile perché l'allineamento di tempo e fase deve essere abbastanza buono perché funzioni. Se l'allineamento è buono otterrai l' interferenza distruttiva che stai cercando. Se non lo sono, otterrai alcune interferenze costruttive. Ancora peggio, se interferiscono in modo distruttivo o costruttivo dipenderà dalla frequenza, ovvero è possibile ottenere contemporaneamente interferenze sia costruttive che distruttive. Può funzionare, tuttavia, se si filtrano solo frequenze abbastanza basse, poiché i loro requisiti di temporizzazione sono i più lenti perché cambiano così lentamente.

Breve storia: è possibile farlo, ma è abbastanza difficile che in genere ha senso fare un filtro passa-alto.

Un modo relativamente semplice per creare un filtro passa-banda consiste nel creare un filtro passa-basso, quindi modularlo sulla frequenza centrale desiderata moltiplicandolo con una sinusoide di quella frequenza.


Tendo a passare due volte il filtro, uno di questi al contrario, per compensare lo sfasamento.
heltonbiker,

@heltonbiker Quindi dovresti essere in grado di farlo in questo modo, purché i tempi siano allineati correttamente e assicurati che il guadagno del filtro passa-basso sia 1.
Jim Clay

4

È possibile progettare i diversi tipi di filtro direttamente con le funzioni scipy.signal. Esistono tre funzioni principali per la creazione di filtri di risposta agli impulsi finiti con il pacchetto scipy.signal.

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

La funzione remez , come argomenti, accetta il numero di tocchi (ordine + 1), le "bande" e il guadagno "desiderato". Le "bande" sono in Hz. Questa funzione è un po 'strana che il parametro "Hz" definisce la frequenza di campionamento in Hz. Un esempio potrebbe essere:

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).)))

Risposta in frequenza

Nota: ho barato un po 'e ho usato un FFT di ordine superiore per rendere la trama un po' più bella (interpolato i punti solo per la visualizzazione).

Esempi di passa-basso e passa-alto:

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

La funzione firwin prende di nuovo il numero di tocchi e il cutoff come argomenti. Il cutoff può essere più valori come un elenco per definire i filtri passa-banda e stopband. Le unità predefinite per il cutoff sono la frequenza normalizzata in cui il cutoff di nyquist è 1 e la frequenza di campionamento sarebbe 2. Questo può essere modificato impostando / nyq /. Usando gli esempi sopra il firwin sarebbe chiamato come:

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

Il firwin2 è più vicino al funcion remez. Ma invece di passare guadagni per le bande si passano guadagni ai cutoff.

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

Altri esempi disponibili qui


firwine il suo wrapper buttersono quello che sto usando ora. Grazie!
heltonbiker,

2
il burro non è un involucro per Firwin. Il burro è un metodo di progettazione del filtro IIR. La funzione iirdesign è uno strumento di progettazione di filtri IIR per uso generico. Dove burro, cheby, ecc. Sono funzioni di Matlab. Maggiori informazioni sulle funzioni del filtro IIR qui, bit.ly/JPS4Zs
Christopher Felton,

Immagino di aver frainteso quello che stavo facendo. Lo vedrò, grazie (dal momento che voglio sicuramente un filtro FIR).
heltonbiker,

3

Hai indicato che stai riscontrando problemi nel capire come progettare un filtro passa-alto adatto. Un metodo consiste innanzitutto nel progettare un prototipo di filtro passa-basso, quindi applicare una trasformazione che deformi la risposta del filtro in un filtro di un altro tipo (come un filtro passa-alto o passa-banda). Questo viene fatto sostituendo un'espressione perz1nella funzione di trasferimento del filtro passa-basso prototipo. Ecco alcuni link alle informazioni sull'argomento:

In particolare, per una trasformazione passa-basso-passa-alto, è possibile applicare la seguente sostituzione:

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

dove ωc è la frequenza di taglio del prototipo di filtro passa-basso e ωcè la frequenza di taglio risultante nel filtro passa-alto trasformato. Ci sono alcuni esempi forniti nella documentazione MATLAB mostrata nel primo link .; potrebbero esserci funzioni simili disponibili in SciPy. Detto questo, gran parte delle funzioni di progettazione dei filtri in quella libreria seguono da vicino l'esempio di MATLAB e sono in grado di progettare filtri di tutti i tipi principali (passa-basso, passa-alto, ecc.) Con il minimo sforzo.


Grazie per la tua attenzione, ma devo ammettere che non ho abbastanza background per digerire le informazioni eccessivamente tecnico / matematiche che hai pubblicato, vengo dal campo delle scienze biologiche e mi aspettavo una risposta più semplice. Se lo sforzo di creare un passa-alto è relativamente piccolo, sarebbe possibile pubblicare un piccolo codice funzionante o collegarsi a un esempio?
heltonbiker,

Quali tipi di filtri hai utilizzato? Li hai progettati usando una funzione di libreria SciPy?
Jason R,


1
Vedi il commento di endolith sopra sulla tua domanda. Come ha indicato, la funzione che stai utilizzando per rendere il tuo filtro sembra essere in grado di progettare anche filtri passa-alto.
Jason R,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.