¿Cómo aplico un filtro Chebishev?

7

Leí un artículo sobre una interfaz cerebro-computadora. En este artículo, los autores informaron que "cada señal se ha filtrado con un filtro Chebishev Tipo I de paso de banda de 8 órdenes cuyas frecuencias de corte son 0.1 y 10 Hz y se ha diezmado de acuerdo con la frecuencia de corte alta". Traté de diseñar este filtro con scipy:

import scipy.signal as signal
signal.cheby1(8,0.05,[0.1,10.0],btype='band',analog=0,output='ba')

El resultado fue:

Warning: invalid value encountered in sqrt
(array([ nan,  nan,  nan,  nan,  nan,  nan,  nan,  nan,  nan,  nan,  nan,
    nan,  nan,  nan,  nan,  nan,  nan]), array([ nan,  nan,  nan,  nan,  nan,  nan,  nan,  nan,  nan,  nan,  nan,
    nan,  nan,  nan,  nan,  nan,  nan]))

No tengo experiencia en el procesamiento de señales, por lo que en realidad no sé lo que estoy haciendo. No sé si usaron un filtro IIR o FIR o si tengo que escalar las frecuencias de corte o si estoy usando la ondulación incorrecta. Espero que puedas ayudarme.

esparto
fuente

Respuestas:

5

El problema principal con el ejemplo que dio es que la función de diseño del filtro cheby1está devolviendo todos los NaNs, lo que no va a ser un filtro muy bueno. El problema es cómo está especificando las frecuencias de borde de banda de paso / banda de detención. Esta función particular está destinada a emular la cheby1función de MATLAB ; las frecuencias que le das deben normalizarse, de modo que un valor de 1corresponda a la mitad de la frecuencia de muestreo.

import scipy.signal as signal
fs = whatever_the_sample_rate_of_the_filter_input_is_going_to_be
signal.cheby1(8,0.05,[0.1/(fs/2),10.0/(fs/2)],btype='band',analog=0,output='ba')

No tengo SciPy a mano, pero eso al menos debería diseñar correctamente el filtro que deseas.

Jason R
fuente
Gracias, lo intentaré por la noche. Mi frecuencia de muestreo es de 240 Hz. ¿Sabes cómo aplicar el filtro en los datos? Encontré una fórmula en wikipedia ( en.wikipedia.org/wiki/… ), pero esta me da resultados oscilantes extraños (números muy grandes ...). Así que supongo que implementé algo mal. Implemento esto en C ++, por lo que no puedo llamar a la función scipy.signal.lfilter. Por cierto. ¿Qué cambiará cuando cambie la onda?
alfa
2
Este es un filtro numéricamente desafiante, ya que tiene polos muy muy cerca del círculo unitario. Debe dividir el filtro en secciones de segundo orden y aplicarlas secuencialmente.
Hilmar
¿Y cómo dividiría el filtro en secciones de segundo orden? Creo que Matlab tiene una función para esto, pero no está disponible en scipy.
alfa
@alfa: no scipy no lo tiene, pero comencé a traducir el código de octava a python: gist.github.com/endolith/4525003
endolith
2

Dos frecuencias de corte generalmente significan que es un filtro de paso de banda con el paso alto a 0.1 Hz y el paso bajo a 10 Hz. El corte de paso bajo (que es la más alta de las dos frecuencias) determina cuánto puede reducir la muestra. Si su filtro de paso bajo era infinitamente empinado, podría salirse con una nueva frecuencia de muestreo de 20 Hz (el doble del límite). Dado que tiene una inclinación limitada, debe dejar una banda de protección entre la frecuencia de corte y la nueva frecuencia de Nyquist. Cuánto necesita depende del orden del filtro y cuánto ruido de alias puede tolerar.

En este ejemplo específico, parece que han reducido la muestra en un factor de 12 o más, lo que me parece demasiado agresivo y probablemente generará mucho ruido de alias.

Hilmar
fuente
Gracias por las explicaciones Creo que la disminución de resolución por un factor de 12 tiene sentido, porque hay mucho ruido con alta amplitud y frecuencia y la señal en la que estaban interesados ​​tenía una frecuencia muy baja. En realidad quería reproducir sus resultados. ¿Hay algún tutorial práctico (con código) sobre este tipo de filtros?
alfa