MATLAB, Come filtrare un segnale discreto?


8

Ho una matrice 1 per 10000 di double`s memorizzata in un file chiamato "fecg.mat". La matrice rappresenta l'entità di un segnale FECG registrato.

L'ho tracciato contro il tempo (da 0 a 9999):

inserisci qui la descrizione dell'immagine

Per rimuovere la linea di base mi chiedo se posso usare un filtro passa-alto. Come posso progettare un filtro adeguato?

L'elaborazione del segnale PS non è il mio campo di studio. Non ho idea di come filtrare un segnale discreto nel dominio del tempo.


1
Noterei che per alcune forme d'onda complesse (come i segnali video) è più efficace "bloccare" alcune funzionalità della forma d'onda piuttosto che provare a "filtrare" il segnale per rimuovere il rumore a bassa frequenza. Tuttavia, in questo caso non c'è alcuna caratteristica ovvia a cui aggrapparsi.
Daniel R Hicks,

1
Quindi vuoi filtrare un ECG fetale dall'ECG della madre e l'ECG fetale è ad alta frequenza. Trasferirei il segnale nel dominio della frequenza (FFT) usando un filtro per finestre per ottenere la frequenza in diversi intervalli di tempo, quindi guarderei le frequenze risultanti nelle diverse finestre temporali per dire a quale frequenza filtrare. Se vuoi conoscere i valori numerici del tempo e delle frequenze, avrai comunque bisogno della frequenza di campionamento. Se vuoi solo vedere che è costante, potresti non averne bisogno.
Danny Varod,

Risposte:


6

Il modo più semplice per rimuovere la linea di base è rimuovere la media:

filtered = original - mean(original);

In realtà, la media è il primo coefficiente della trasformata di Fourier, quindi in realtà è un filtro molto nitido: stai eliminando il coefficiente CC.

Se si desidera un filtro più classico, quindi controllare funzioni come buttere amici, che sintetizzeranno un filtro IIR, quindi utilizzare filterper filtrare il segnale.

Matlab include anche uno strumento di progettazione del filtro.


3

MATLAB ha uno strumento di progettazione del filtro chiamato fdatool. Esegui fdatool in MATLAB, ti dà una GUI visiva, in cui puoi cambiare i parametri del filtro. Scegli un filtro passa-alto da lì e scegli una frequenza cut0ff. quando sei soddisfatto della forma del filtro, esportalo nell'area di lavoro MATLAB. Supponiamo che il nome del filtro sia myFilter e il nome del segnale sia mySignal. Quindi per filtrare il segnale nel tipo MATLAB: filteredSignal = conv (mySignal, myFilter).


3

Se si conosce il contenuto di frequenza del segnale desiderato, è possibile passare in alto leggermente al di sotto di tale frequenza. Diciamo che sei interessato solo al segnale sopra 2 Hz e che la frequenza di campionamento è 100 Hz, quindi puoi farlo come segue:

[b,a] = butter(3,2/(100/2),'high');
outputData = filter(b,a,inputData);

Questo esempio specifico utilizza un highpass butterworth di terzo ordine.


Grazie. Non ho la frequenza e la frequenza di campionamento, ma penso che dovrei stimarli, perché la frequenza dei segnali ECG è per lo più nell'intervallo da 0,1 a 250 Hz.
hoo_man,

1
@hoo_man Se non si conosce la frequenza di campionamento, le informazioni non hanno senso. Dovrai chiedere a chiunque ti abbia dato la misurazione. PS La frequenza di campionamento dovrebbe essere almeno 2 * la frequenza massima del segnale.
Danny Varod,

@DannyVarod: Quindi in questa circostanza l'unico modo è trovare la frequenza di campionamento attraverso tentativi ed errori ...
Comincio

Non deve essere un numero tondo. Cosa vuoi fare con i dati?
Danny Varod,

@DannyVarod: principalmente la frequenza di campionamento per la registrazione dell'ECG è di circa 400Hz-500Hz. Voglio estrarre l'ECG fetale dall'ECG materno. Per prima cosa devo rimuovere il vagabondo della linea di base.
hoo_man,

1

Quale filtro usare dipende davvero dall'applicazione specifica. - Un filtro troppo approssimativo potrebbe rimuovere le informazioni che stai cercando!

L' algoritmo Pan-Tompkins ampiamente utilizzato (per il rilevamento QRS) specifica un filtro per la rimozione della linea di base nei dati ECG. Ma è difficile determinare se questo filtro è adatto alla tua applicazione dalle informazioni limitate fornite. Si prega di elaborare una risposta più precisa.


4
Passa basso per riconoscere la linea di base. Per rimuoverlo dovresti sottrarre il risultato del passa-basso dal segnale originale, creando così un filtro passa-alto, non è vero?
Castilho,

Hai ragione - ho la parte capovolta. Grazie per averlo corretto.
mola,

Ho passato il segnale attraverso un LPFcome ha detto Castilho . ma la linea di base che ho ottenuto è stata ritardata. Per abbinare la linea di base e il segnale originale per sottrarli, dovrei spostarne uno o esiste un modo migliore?
hoo_man,

1

Ti suggerirei di utilizzare un filtro adattivo per rimuovere il rumore di base a 50Hz. un filtro adattivo lms andrebbe benissimo:

xk = sin(2*pi*50*t1);
dk = ecg1; 
bk = [0 0 0];                       %Gewichteter Vektor (FIR Koefizienten mit Anfangswert 0)
                                    %Die Werte ändern sich ständig bis sich
                                    %das System adaptiert hat

mu = .1;                            %Konvergenzgeschwindigkeit des Algorithmes.
                                    %( 0 < mu < 1/(20*(L+1)*Potenz_xk); L Filterorder)                                
Pot_x=mean(xk.*xk);
%mu=1/(100*(L+1)*Pot_x);            % Konvergenzgeschwindigkeit des Algorithmus.
                                    % Bei den Prädiktiven Adaptiven filter
                                    % gilt die Potenz nicht




yk=zeros(size(xk));                 % Ausgangssignal zum Zeitpunkt t=0 von der FIR.
ek=zeros(size(xk));                 % Fehlersignal zum ZEitpunkt t=0.

%Algorithmus für FIR Adaptiven Filter:
for n = 3:(punkte - 1)                          %Arranca en 3 porque tiene que almacenar las dos muestras anteriores y la actual (FIR de 2 coeficientes)
    xkn = [xk( n ) xk( n - 1 ) xk( n - 2 )];    %Vector niésimo (2 posiciones porque son dos coeficientes).
    yk(n) = xkn * bk';                          %Resultado parcial de la salida por el vector bk traspuesto.
    ek(n) = dk(n) - yk(n);                      %Señal de error parcial.
    bk = bk + 2*mu*ek(n)*xkn;                   %Actualización instante a instante del vector de pesos.  
end                                             %Ende des adaptiven Algorithmes.

Eje1 = figure(1);
set(Eje1,'name','Übung 1: FIR Adaptive Filter','position',[10 10 900 650]);
subplot( 2, 1, 1 );
plot( t1, xk, 'r');
xlabel('n');
ylabel('EKG mit Rauschen');
title('Eingangssignal: Bewegungsartifakt zu filtern');
subplot( 2, 1, 2 );
plot( t1, ek, '-k');
xlabel('n');
ylabel('d[k] - y[k]');
title('Ausgangssignal: EKG ohne Rauschen');
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.