¿Es correcto restar una señal filtrada de paso bajo de la señal original y usar el resultado como un "paso alto"?

8

Me cuesta encontrar la documentación para implementar el filtro de paso de banda o paso alto con python / scipy / numpy.

Sin embargo, puedo crear y aplicar fácilmente un filtro de paso bajo, así que pregunto:

¿Sería correcto conceptualmente filtrar una señal de paso bajo y luego restar el resultado de la señal original para obtener solo las frecuencias altas?

Además, si alguien tiene un ejemplo simple de un filtro de paso de banda ingenuo en Python (preferiblemente usando las bibliotecas numpy y scipy), estaría muy agradecido.

Lo que busco es algo como:

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

¡Gracias por cualquier ayuda!

EDITAR: con scipy, estoy usando esto como paso bajo, con buenos resultados:

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
fuente
La documentación de scipy.signal.firwinle indica cómo hacer filtros de paso bajo, paso alto, paso de banda, parada de banda y multibanda. ¿Lo intentaste firwin(taps, cutoff=nfreq, pass_zero=False)?
endolito el
Ver sound.whsites.net/articles/derived-xovers.htm para el uso de esta técnica en altavoces
endolito

Respuestas:

7

En teoría, puede hacer esto, pero en la práctica es difícil porque la alineación de tiempo y fase debe ser bastante buena para que funcione. Si la alineación es buena, obtendrá la interferencia destructiva que está buscando. Si no lo son, obtendrá alguna interferencia constructiva. Peor aún, si interfieren destructiva o constructivamente dependerá de la frecuencia, es decir, puede obtener interferencia constructiva y destructiva al mismo tiempo. Sin embargo, puede funcionar si solo está filtrando frecuencias bastante bajas, ya que sus requisitos de tiempo son los más flexibles porque cambian muy lentamente.

Breve historia: es posible hacerlo, pero es lo suficientemente difícil como para que tenga sentido hacer un filtro de paso alto.

Una forma relativamente sencilla de crear un filtro de paso de banda es crear un filtro de paso bajo y luego modularlo a la frecuencia central que desee multiplicándolo con una sinusoide de esa frecuencia.

Jim Clay
fuente
Tiendo a pasar el filtro dos veces, uno de ellos en reversa, para compensar el cambio de fase.
heltonbiker
@heltonbiker Entonces deberías poder hacerlo de esa manera, siempre que tengas el tiempo alineado correctamente y te asegures de que la ganancia del filtro de paso bajo sea 1.
Jim Clay
4

Puede diseñar los diferentes tipos de filtro directamente con las funciones scipy.signal. Hay tres funciones principales para crear filtros de respuesta de impulso finito con el paquete scipy.signal.

  1. signal.remez
  2. señal.firwin
  3. signal.firwin2

La función remez , como argumentos, toma el número de tomas (orden + 1), las "bandas" y la ganancia "deseada". Las "bandas" están en Hz. Esta función es un poco extraña porque el parámetro "Hz" define la frecuencia de muestreo en Hz. Un ejemplo sería:

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

Respuesta frecuente

Nota: Hice trampa un poco y usé un FFT de orden superior para hacer que la trama se viera un poco mejor (interpolaba los puntos solo para visualización).

Ejemplos de paso bajo y paso 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 función firwin toma de nuevo el número de toques y el corte como argumentos. El límite puede ser múltiples valores como una lista para definir filtros de paso de banda y de banda de detención. Las unidades predeterminadas para el corte son la frecuencia normalizada donde el corte de nyquist es 1 y la frecuencia de muestreo sería 2. Esto puede modificarse configurando / nyq /. Usando los ejemplos anteriores, el firwin se llamaría así:

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

El firwin2 está más cerca de la función remezcla. Pero en lugar de pasar ganancias para las bandas, pasas ganancias en los puntos de corte.

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

Más ejemplos disponibles aquí

Christopher Felton
fuente
firwin, y su contenedor butterson lo que estoy usando ahora. ¡Gracias!
heltonbiker
2
la mantequilla no es una envoltura para firwin. La mantequilla es un método de diseño de filtro IIR. La función iirdesign es una herramienta de diseño de filtros IIR de uso general. Donde mantequilla, cheby, etc.son funciones matlabish. Más información sobre las funciones del filtro IIR aquí, bit.ly/JPS4Zs
Christopher Felton
Supongo que no entendí lo que estaba haciendo. Voy a echarle un vistazo, gracias (ya que definitivamente quiero un filtro FIR).
heltonbiker
3

Indicaste que tienes problemas para descubrir cómo diseñar un filtro de paso alto adecuado. Un método es diseñar primero un prototipo de filtro de paso bajo, luego aplicar una transformación que distorsione la respuesta del filtro en un filtro de otro tipo (como un filtro de paso alto o paso de banda). Esto se realiza mediante la sustitución de una expresión para en la función de transferencia del filtro prototipo de paso bajo. Aquí hay algunos enlaces a información sobre el tema:z1

Específicamente, para una transformación de paso bajo a paso alto, puede aplicar la siguiente sustitución:

α=cos ( 1

z1=α+z11+αz1,
α=cos(12(ωC-ωC))cos(12(ωC+ωC))

donde es la frecuencia de corte del prototipo del filtro de paso bajo y es la frecuencia de corte resultante en el filtro de paso alto transformado. Hay algunos ejemplos dados en la documentación de MATLAB que se muestra en el primer enlace .; Puede haber funciones similares disponibles en SciPy. Dicho esto, muchas de las funciones de diseño de filtros en esa biblioteca siguen de cerca el ejemplo de MATLAB, y son capaces de diseñar filtros de todos los tipos principales (paso bajo, paso alto, etc.) con muy poco esfuerzo.ω cωCωC

Jason R
fuente
Gracias por su atención, pero debo admitir que no tengo suficientes antecedentes para digerir la información demasiado técnica / matemática que publicó, soy del campo de las ciencias biológicas y esperaba una respuesta más directa. Si el esfuerzo para crear un paso alto es relativamente pequeño, ¿sería posible publicar un pequeño código de trabajo o un enlace a un ejemplo?
Heltonbiker
¿Qué tipos de filtros has estado usando? ¿Los diseñaste usando una función de biblioteca SciPy?
Jason R
Editaré
1
Vea el comentario de endolith arriba sobre su pregunta. Como indicó, la función que está utilizando para hacer que su filtro parezca capaz de diseñar filtros de paso alto también.
Jason R