MATLAB, ¿Cómo filtrar una señal discreta?

8

Tengo una matriz de dobles de 1 por 10000 almacenada en un archivo llamado "fecg.mat". La matriz representa la magnitud de una señal FECG grabada.

Lo he trazado contra el tiempo (de 0 a 9999):

ingrese la descripción de la imagen aquí

Para eliminar la línea de base, me pregunto si puedo usar un filtro de paso alto. ¿Cómo diseño un filtro adecuado?

PD El procesamiento de señales no es mi campo de estudio. No tengo idea de cómo filtrar una señal de dominio de tiempo discreta.

hoo_man
fuente
1
Notaría que para algunas formas de onda complejas (como las señales de video) es más efectivo "sujetar" alguna característica de la forma de onda que tratar de "filtrar" la señal para eliminar el ruido de baja frecuencia. Sin embargo, en este caso no hay una característica obvia para sujetar.
Daniel R Hicks
1
Por lo tanto, desea filtrar un ECG fetal del ECG de la madre y el ECG fetal está en una frecuencia alta. Transferiría la señal al dominio de frecuencia (FFT) usando un filtro de ventana para obtener la frecuencia en diferentes marcos de tiempo, luego miraría las frecuencias resultantes en las diferentes ventanas de tiempo para saber a qué frecuencia filtrar. Si desea conocer los valores numéricos del tiempo y las frecuencias, aún necesitará la frecuencia de muestreo. Si solo quiere ver que es constante, es posible que no lo necesite.
Danny Varod

Respuestas:

6

La forma más fácil de eliminar la línea de base es eliminar el promedio:

filtered = original - mean(original);

En realidad, el promedio es el primer coeficiente de la transformada de Fourier, por lo que en realidad es un filtrado muy agudo: está eliminando el coeficiente DC.

Si desea un filtrado más clásico, verifique las funciones como buttery amigos, que sintetizarán un filtro IIR, luego use filterpara filtrar su señal.

Matlab también incluye una herramienta de diseño de filtros.

Juancho
fuente
3

MATLAB tiene una herramienta de diseño de filtros llamada fdatool. Ejecute fdatool en MATLAB, le ofrece una GUI visual, en la que puede cambiar los parámetros del filtro. Elija un filtro de paso alto desde allí y elija una frecuencia cut0ff. cuando esté satisfecho con la forma del filtro, expórtelo al espacio de trabajo de MATLAB. Digamos que su nombre de filtro es myFilter y su nombre de señal es mySignal. Luego, para filtrar la señal en MATLAB, escriba: filterSignal = conv (mySignal, myFilter).

TJ1
fuente
3

Si conoce el contenido de frecuencia de la señal deseada, puede pasar un poco por debajo de esa frecuencia. Digamos que solo le interesa la señal por encima de 2 Hz y su frecuencia de muestreo es de 100 Hz, entonces puede hacer esto de la siguiente manera:

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

Este es un ejemplo específico que utiliza un paso alto de mantequilla de tercer orden.

Hilmar
fuente
Gracias. No tengo la frecuencia y la frecuencia de muestreo, pero creo que debería estimarlas, porque la frecuencia de las señales de ECG en su mayoría está en el rango de 0.1 a 250 Hz.
hoo_man
1
@hoo_man Si no conoce la frecuencia de muestreo, la información no tiene sentido. Tendrás que preguntar a quien te dio la medida. PS La frecuencia de muestreo debe ser al menos 2 * la frecuencia de señal máxima.
Danny Varod
@DannyVarod: Entonces, bajo esta circunstancia, la única forma es encontrar la frecuencia de muestreo a través de prueba y error ... Comienzo con 500Hz
hoo_man
No tiene que ser un número redondo. ¿Qué quieres hacer con los datos?
Danny Varod el
@DannyVarod: la frecuencia de muestreo para la grabación de ECG es principalmente de 400Hz a 500Hz. Quiero extraer el ECG fetal del ECG materno. Primero tengo que eliminar la deambulación de línea de base.
hoo_man
1

Qué filtro usar realmente depende de la aplicación específica. - ¡Un filtro demasiado áspero podría eliminar la información que está buscando!

El algoritmo Pan-Tompkins ampliamente utilizado (para la detección de QRS) especifica un filtro para la eliminación de la línea base en los datos de ECG. Pero es difícil determinar si este filtro es adecuado para su aplicación a partir de la información limitada que proporcionó. Por favor, elabore una respuesta más precisa.

mola
fuente
44
Paso bajo para reconocer la línea de base. Para eliminarlo, debe restar el resultado del paso bajo de la señal original, creando así un filtro de paso alto, ¿no es así?
Castilho
Tienes razón, tengo esa parte al revés. Gracias por corregir eso.
mola
Pasé la señal a través de un LPFcomo Castilho dijo. pero la línea de base que obtuve se retrasó. Para hacer coincidir la línea de base y la señal original para restarlas, ¿debería cambiar una de ellas o hay una mejor manera?
hoo_man
1

Te sugiero que uses un filtro adaptativo para eliminar el ruido de referencia de 50Hz. un filtro adaptativo lms estaría bien:

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');
Harry
fuente