La réponse en fréquence du filtre conçu à l'aide de la
fonction beurre est:
Mais il n'y a aucune raison de limiter le filtre à une conception de filtre monotone constante. Si vous souhaitez une atténuation plus élevée dans la bande d'arrêt et une bande de transition plus raide, d'autres options existent. Pour plus d'informations sur la spécification d'un filtre à l'aide d' iirdesing, consultez ceci . Comme le montrent les graphiques de réponse en fréquence pour la conception du beurre , la fréquence de coupure (point -3 dB) est loin de l'objectif. Cela peut être atténué par un sous-échantillonnage avant le filtrage (les fonctions de conception auront du mal avec un filtre aussi étroit, 2% de la bande passante). Permet de filtrer la fréquence d'échantillonnage d'origine avec la coupure spécifiée.
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')
Comme mentionné, parce que nous essayons de filtrer un si petit pourcentage de la bande passante, le filtre n'aura pas de coupure nette. Dans ce cas, filtre passe-bas, nous pouvons réduire la bande passante pour obtenir un meilleur filtre. La fonction de rééchantillonnage python / scipy.signal peut être utilisée pour réduire la bande passante.
Notez que la fonction de rééchantillonnage effectuera un filtrage pour empêcher l'aliasing. Le préfiltrage peut également être effectué (pour réduire l'aliasing) et dans ce cas, nous pourrions simplement rééchantillonner par 100 et être fait , mais la question posée sur la création de filtres. Pour cet exemple, nous allons sous-échantillonner de 25 et créer un nouveau filtre
R = 25; # how much to down sample by
Fsr = Fs/25. # down-sampled sample rate
xs = signal.resample(x, len(x)/25.)
Si nous mettons à jour les paramètres de conception du filtre FIR, la nouvelle réponse est.
# 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)
Le filtre opérant sur les données sous-échantillonnées a une meilleure réponse. Un autre avantage de l'utilisation d'un filtre FIR est que vous aurez une réponse de phase linéaire.
filtfilt
que l' on veut pour lea
paramètre.Est-ce que ça marche?
Vous avez raison, cependant, la documentation n'est pas très complète. Il ressemble à
butter
un wrapper pouriirfilter
, qui est mieux documenté :La plupart de ces éléments sont clonés depuis matlab, vous pouvez donc également consulter leur documentation :
Mise à jour:
J'ai ajouté de la documentation pour ces fonctions. :) Github vous facilite la tâche.
la source
Je ne sais pas quelle est votre application, mais vous voudrez peut-être consulter Gnuradio: http://gnuradio.org/doc/doxygen/classgr__firdes.html
Les blocs de traitement du signal sont écrits en C ++ (bien que les graphiques de flux Gnuradio soient en Python), mais vous avez dit que les hautes performances sont importantes.
la source
J'ai de bons résultats avec ce filtre FIR. Remarque qu'il applique le filtre deux fois, en "avant" et "en arrière", afin de compenser le décalage du signal (la
filtfilt
fonction ne fonctionnait pas, je ne sais pas pourquoi):CECI est une excellente ressource pour filtrer la conception et l'utilisation, d'où j'ai pris ce code, et d'où des exemples de filtres passe-bande et passe-haut .
la source
Je n'ai pas de droit de commentaire ...
@endolith: j'utilise la même chose que vous sauf en utilisant scipy.signal.filtfilt (B, A, x) où x est le vecteur d'entrée à filtrer - par exemple numpy.random.normal (taille = (N)) . filtfilt effectue une passe avant et arrière du signal. Par souci d'exhaustivité (la plupart étant identiques à @endolith):
filtfilt comme l'a également suggéré @heltonbiker nécessite des tableaux de coefficients, je crois. Si vous devez effectuer un filtrage passe-bande sur une bande de base complexe, une configuration plus complexe est nécessaire, mais cela ne semble pas être un problème ici.
la source