É correto subtrair um sinal filtrado passa-baixo do sinal original e usar o resultado como um "passe passa-alto"?

8

Estou com dificuldade para encontrar documentação para implementar o filtro passa-banda ou passa-alto com python / scipy / numpy.

Porém, posso criar e aplicar facilmente um filtro passa-baixo, então pergunto:

Seria conceitualmente correto filtrar um sinal com passa-baixo e subtrair o resultado do sinal original, para obter apenas as altas frequências?

Além disso, se alguém tiver um exemplo simples de um filtro passa-banda ingênuo em Python (preferencialmente usando as bibliotecas numpy e scipy), ficaria muito grato.

O que eu procuro é algo como:

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

Obrigado por qualquer ajuda!

EDIT: com scipy, estou usando isso como passa-baixo, com bons 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
fonte
A documentação para scipy.signal.firwinmostra como criar filtros passa-baixo, passa-alto, passa-banda, pára-banda e multibanda. Você tentou firwin(taps, cutoff=nfreq, pass_zero=False)?
endolith 23/08/12
Veja sound.whsites.net/articles/derived-xovers.htm para usar esta técnica em alto
endolith

Respostas:

7

Em teoria, você pode fazer isso, mas na prática é difícil, porque o alinhamento de tempo e fase deve ser muito bom para que funcione. Se o alinhamento for bom, você receberá a interferência destrutiva que está buscando. Caso contrário, você obterá alguma interferência construtiva. Pior ainda, se eles são interferentes de maneira destrutiva ou construtiva, dependerá da frequência - ou seja, você pode obter interferência construtiva e destrutiva ao mesmo tempo. Pode funcionar, no entanto, se você estiver filtrando apenas frequências razoavelmente baixas, pois os requisitos de tempo são os mais fracos, porque mudam muito lentamente.

Breve história - é possível, mas é difícil o suficiente para que geralmente faça sentido apenas fazer um filtro passa-alto.

Uma maneira relativamente simples de criar um filtro passa-banda é criar um filtro passa-baixo e modulá-lo para a frequência central desejada, multiplicando-o por um sinusóide dessa frequência.

Jim Clay
fonte
Tendo a passar o filtro duas vezes, um deles ao contrário, para compensar a mudança de fase.
precisa saber é o seguinte
@heltonbiker Então você deve ser capaz de fazê-lo dessa maneira, desde que você obter o calendário alinhado à direita e certifique-se o ganho de filtro passa-baixa é 1.
Jim Clay
4

Você pode projetar os diferentes tipos de filtro diretamente com as funções scipy.signal. Existem três funções principais para criar filtros de resposta de impulso finito com o pacote scipy.signal.

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

A função remez , como argumentos, recebe o número de toques (ordem + 1), as "bandas" e o ganho "desejado". As "bandas" estão em Hz. Essa função é um pouco estranha porque o parâmetro "Hz" define a taxa de amostragem em Hz. Um exemplo seria:

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

Resposta de Freqüência

Nota: Eu trapacei um pouco e usei uma FFT de ordem superior para fazer o gráfico parecer um pouco melhor (interpolou os pontos apenas para visualização).

Exemplos de passa-baixo 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

A função firwin pega novamente o número de torneiras e o ponto de corte como argumentos. O ponto de corte pode ter vários valores como uma lista para definir filtros de passagem de banda e parada de banda. As unidades padrão para o corte são a frequência normalizada, em que o corte nyquist é 1 e a taxa de amostragem seria 2. Isso pode ser modificado pela configuração / nyq /. Usando os exemplos acima, o firwin seria chamado como:

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

O firwin2 está mais próximo da função remez. Mas, em vez de passar ganhos para as bandas, você passa ganhos nos pontos de corte.

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

Mais exemplos disponíveis aqui

Christopher Felton
fonte
firwin, e seu invólucro butteré o que estou usando agora. Obrigado!
Heltonbiker 28/08/12
2
manteiga não é um invólucro para firwin. A manteiga é um método de design de filtro IIR. A função iirdesign é uma ferramenta de design de filtro IIR de uso geral. Onde manteiga, cheby, etc. são funções do Matlab. Mais informações sobre as funções de filtro IIR aqui, bit.ly/JPS4Zs
Christopher Felton
Acho que não entendi o que estava fazendo. Vou dar uma olhada, obrigado (já que eu definitivamente quero um filtro FIR).
precisa saber é o seguinte
3

Você indicou que está tendo problemas para descobrir como projetar um filtro passa-alto adequado. Um método é primeiro projetar um protótipo de filtro passa-baixo e depois aplicar uma transformação que deforma a resposta do filtro em um filtro de outro tipo (como um filtro passa-alto ou passa-banda). Isso é feito substituindo uma expressão por na função de transferência do filtro lowpass do protótipo. Aqui estão alguns links para informações sobre o tópico:z1

Especificamente, para uma transformação de passagem baixa para passagem alta, você pode aplicar a seguinte substituição:

α=cos ( 1

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

whereωcωc

Jason R
fonte
Obrigado pela atenção, mas tenho que admitir que não tenho experiência suficiente para digerir as informações excessivamente técnicas / matemáticas que você postou; sou do campo das biociências e esperava uma resposta mais direta. Se o esforço para criar um passe alto for relativamente pequeno, seria possível publicar algum código de trabalho pequeno ou vincular a um exemplo?
heltonbiker
Que tipos de filtros você está usando? Você os projetou usando uma função da biblioteca SciPy?
Jason R
Vou editar a questão com o baixo-pass eu estou usando
heltonbiker
11
Veja o comentário do endólito acima em sua pergunta. Como ele indicou, a função que você está usando para fazer seu filtro também parece ser capaz de projetar filtros passa-altos.
Jason R