A resposta de frequência para o filtro projetado usando a
função de manteiga é:
Mas não há razão para limitar o filtro a um design de filtro monotônico constante. Se você deseja uma atenuação mais alta na faixa de parada e na faixa de transição mais íngreme, existem outras opções. Para obter mais informações sobre a especificação de um filtro usando iirdesing, consulte isso . Como mostra os gráficos de resposta em frequência para o design da manteiga , a frequência de corte (ponto de -3dB) está longe do objetivo. Isso pode ser atenuado pela amostragem reduzida antes da filtragem (as funções de design terão um tempo difícil com um filtro tão estreito, 2% da largura de banda). Vamos analisar a taxa de amostragem original com o limite especificado.
import numpy as np
from scipy import signal
from matplotlib import pyplot as plt
from scipy.signal import fir_filter_design as ffd
from scipy.signal import filter_design as ifd
# setup some of the required parameters
Fs = 1e9 # sample-rate defined in the question, down-sampled
# remez (fir) design arguements
Fpass = 10e6 # passband edge
Fstop = 11.1e6 # stopband edge, transition band 100kHz
Wp = Fpass/(Fs) # pass normalized frequency
Ws = Fstop/(Fs) # stop normalized frequency
# iirdesign agruements
Wip = (Fpass)/(Fs/2)
Wis = (Fstop+1e6)/(Fs/2)
Rp = 1 # passband ripple
As = 42 # stopband attenuation
# Create a FIR filter, the remez function takes a list of
# "bands" and the amplitude for each band.
taps = 4096
br = ffd.remez(taps, [0, Wp, Ws, .5], [1,0], maxiter=10000)
# The iirdesign takes passband, stopband, passband ripple,
# and stop attenuation.
bc, ac = ifd.iirdesign(Wip, Wis, Rp, As, ftype='ellip')
bb, ab = ifd.iirdesign(Wip, Wis, Rp, As, ftype='cheby2')
Como mencionado, como estamos tentando filtrar uma porcentagem tão pequena da largura de banda, o filtro não terá um corte agudo. Nesse caso, filtro lowpass, podemos reduzir a largura de banda para obter um filtro com melhor aparência. A função de reamostragem python / scipy.signal pode ser usada para reduzir a largura de banda.
Observe que a função de reamostragem realizará a filtragem para evitar aliases. A pré-filtragem também pode ser realizada (para reduzir o aliasing) e, nesse caso, poderíamos simplesmente re-amostrar em 100 e pronto , mas a pergunta foi feita sobre a criação de filtros. Neste exemplo, reduziremos a amostra em 25 e criaremos um novo filtro
R = 25; # how much to down sample by
Fsr = Fs/25. # down-sampled sample rate
xs = signal.resample(x, len(x)/25.)
Se atualizarmos os parâmetros de design para o filtro FIR, a nova resposta será.
# Down sampled version, create new filter and plot spectrum
R = 25. # how much to down sample by
Fsr = Fs/R # down-sampled sample rate
Fstop = 11.1e6 # modified stopband
Wp = Fpass/(Fsr) # pass normalized frequency
Ws = Fstop/(Fsr) # stop normalized frequency
taps = 256
br = ffd.remez(taps, [0, Wp, Ws, .5], [1,0], maxiter=10000)
O filtro que opera nos dados de amostragem reduzida tem uma resposta melhor. Outro benefício do uso de um filtro FIR é que você terá resposta de fase linear.
filtfilt
deseja para oa
parâmetro.Isto funciona?
Você está certo, porém, a documentação não é muito completa. Parece que
butter
é um invólucro paraiirfilter
, que está melhor documentado :Porém, a maioria dessas coisas é clonada do matlab, para que você possa ver também a documentação deles :
Atualizar:
Eu adicionei documentação para essas funções. :) O Github facilita isso.
fonte
Não sabe ao certo qual é o seu aplicativo, mas você pode conferir o Gnuradio: http://gnuradio.org/doc/doxygen/classgr__firdes.html
Os blocos de processamento de sinal são escritos em C ++ (embora os gráficos de fluxo do Gnuradio estejam em Python), mas você disse que o alto desempenho é importante.
fonte
Estou tendo bons resultados com este filtro FIR. Observa que aplica o filtro duas vezes, avançando e retrocedendo, de modo a compensar o deslocamento do sinal (a
filtfilt
função não funcionou, não sei por quê):Um ótimo recurso para filtrar o design e o uso, de onde peguei esse código e de onde exemplos de filtros passa-banda e passe-hi podem ser obtidos, é ISTO .
fonte
Não tenho direitos de comentário ...
@ endolith: Eu uso o mesmo que você, exceto usando o scipy.signal.filtfilt (B, A, x) onde x é o vetor de entrada a ser filtrado - por exemplo, numpy.random.normal (size = (N)) . filtfilt faz uma passagem para frente e para trás do sinal. Por uma questão de integridade (a maioria é igual a @endolith):
filtfilt, como também sugerido por @heltonbiker, exige matrizes de coeficientes, acredito. Caso você precise executar a filtragem de banda em banda básica complexa, é necessária uma configuração mais envolvida, mas isso não parece ser um problema aqui.
fonte