web-dev-qa-db-fra.com

Filtrage passe-haut dans MATLAB

Quelqu'un sait-il comment utiliser les filtres dans MATLAB? Je ne suis pas un aficionado, donc je ne suis pas préoccupé par les caractéristiques de décroissance, etc. ) pour supprimer la dérive de la ligne de base.

Il existe des filtres Butterworth, Elliptical et Chebychev décrits dans l'aide, mais aucune explication simple sur la façon de les mettre en œuvre.

25
user391339

Il existe plusieurs filtres qui peuvent être utilisés, et le choix réel du filtre dépendra de ce que vous essayez d'atteindre. Puisque vous avez mentionné les filtres Butterworth, Chebyschev et Elliptical, je suppose que vous recherchez des filtres IIR en général.

Wikipedia est un bon endroit pour commencer à lire sur les différents filtres et ce qu'ils font. Par exemple, Butterworth est au maximum plat dans la bande passante et la réponse se déroule dans la bande d'arrêt. Dans Chebyschev , vous avez une réponse fluide dans la bande passante (type 2) ou la bande d'arrêt (type 1) et des ondulations plus grandes et irrégulières dans l'autre et enfin, dans Elliptique = filtres, il y a des ondulations dans les deux bandes. L'image suivante est tirée de wikipedia .

enter image description here

Donc, dans les trois cas, vous devez échanger quelque chose contre autre chose. À Butterworth, vous n'obtenez aucune ondulation, mais le ralentissement de la réponse en fréquence est plus lent. Dans la figure ci-dessus, il faut de 0.4 À environ 0.55 Pour atteindre la moitié de la puissance. Dans Chebyschev, vous obtenez un roulement plus raide, mais vous devez autoriser des ondulations irrégulières et plus grandes dans l'une des bandes, et dans Elliptical, vous obtenez une coupure quasi instantanée, mais vous avez des ondulations dans les deux bandes.

Le choix du filtre dépendra entièrement de votre application. Essayez-vous d'obtenir un signal propre avec peu ou pas de pertes? Ensuite, vous avez besoin de quelque chose qui vous donne une réponse fluide dans la bande passante (Butterworth/Cheby2). Essayez-vous de tuer les fréquences dans la bande d'arrêt, et cela ne vous dérangera pas une perte mineure de la réponse dans la bande passante? Ensuite, vous aurez besoin de quelque chose de lisse dans la bande d'arrêt (Cheby1). Avez-vous besoin de coins de coupure extrêmement nets, c'est-à-dire que quelque chose un peu au-delà de la bande passante est préjudiciable à votre analyse? Si c'est le cas, vous devez utiliser des filtres elliptiques.

La chose à retenir sur les filtres IIR est qu'ils ont des pôles. Contrairement aux filtres FIR où vous pouvez augmenter l'ordre du filtre avec la seule ramification étant le retard du filtre, l'augmentation de l'ordre des filtres IIR rendra le filtre instable. Par instable, je veux dire que vous aurez des pôles qui se trouvent en dehors du cercle unitaire. Pour voir pourquoi il en est ainsi, vous pouvez lire les articles wiki sur filtres IIR , en particulier la partie sur la stabilité.

Pour illustrer davantage mon propos, considérons le filtre passe-bande suivant.

fpass=[0.05 0.2];%# passband
fstop=[0.045 0.205]; %# frequency where it rolls off to half power
Rpass=1;%# max permissible ripples in stopband (dB)
Astop=40;%# min 40dB attenuation
n=cheb2ord(fpass,fstop,Rpass,Astop);%# calculate minimum filter order to achieve these design requirements

[b,a]=cheby2(n,Astop,fstop);

Maintenant, si vous regardez le diagramme à pôles zéro en utilisant zplane(b,a), vous verrez qu'il y a plusieurs pôles (x) situés à l'extérieur du cercle unitaire, ce qui rend cette approche instable.

enter image description here

et cela est évident du fait que la réponse en fréquence est entièrement détraquée. Utilisez freqz(b,a) pour obtenir les éléments suivants

enter image description here

Pour obtenir un filtre plus stable avec vos exigences de conception exactes, vous devrez utiliser des filtres de second ordre en utilisant la méthode z-p-k Au lieu de b-a, Dans MATLAB. Voici comment pour le même filtre que ci-dessus:

[z,p,k]=cheby2(n,Astop,fstop);
[s,g]=zp2sos(z,p,k);%# create second order sections
Hd=dfilt.df2sos(s,g);%# create a dfilt object.

Maintenant, si vous regardez les caractéristiques de ce filtre, vous verrez que tous les pôles se trouvent à l'intérieur du cercle unitaire (donc stables) et correspondent aux exigences de conception

enter image description here

enter image description here

L'approche est similaire pour butter et ellip, avec l'équivalent buttord et ellipord. La documentation MATLAB contient également de bons exemples sur la conception de filtres. Vous pouvez vous appuyer sur ces exemples et exploiter le mien pour concevoir un filtre en fonction de ce que vous voulez.

Pour utiliser le filtre sur vos données, vous pouvez faire filter(b,a,data) ou filter(Hd,data) selon le filtre que vous utilisez finalement. Si vous voulez une distorsion de phase nulle, utilisez filtfilt. Cependant, cela n'accepte pas les objets dfilt. Pour filtrer en phase nulle avec Hd, utilisez le fichier filtfilthd disponible sur le site d'échange de fichiers Mathworks

[~ # ~] modifier [~ # ~]

C'est en réponse au commentaire de @ DarenW. Le lissage et le filtrage sont deux opérations différentes, et bien qu'ils soient similaires à certains égards (la moyenne mobile est un filtre passe-bas), vous ne pouvez pas simplement substituer l'un à l'autre sauf si vous pouvez être sûr qu'il ne sera pas de dans l'application spécifique.

Par exemple, en mettant en œuvre la suggestion de Daren sur un signal de chirp linéaire de 0 à 25 kHz, échantillonné à 100 kHz, ce spectre de fréquences après lissage avec un filtre gaussien

enter image description here

Bien sûr, la dérive proche de 10Hz est presque nulle. Cependant, l'opération a complètement changé la nature des composantes de fréquence du signal d'origine. Cet écart provient du fait qu'ils ont complètement ignoré le déroulement de l'opération de lissage (voir ligne rouge) et ont supposé qu'il serait égal à zéro. Si c'était vrai, la soustraction aurait fonctionné. Mais hélas, ce n'est pas le cas, c'est pourquoi un champ entier sur la conception de filtres existe.

48
abcd

Créez votre filtre - par exemple en utilisant [B,A] = butter(N,Wn,'high') où N est l'ordre du filtre - si vous n'êtes pas sûr de ce que c'est, réglez-le simplement sur 10. Wn est la fréquence de coupure normalisée entre 0 et 1, avec 1 correspondant à la moitié de la fréquence d'échantillonnage du signal. Si votre fréquence d'échantillonnage est fs et que vous souhaitez une fréquence de coupure de 10 Hz, vous devez définir Wn = (10/(fs/2)).

Vous pouvez ensuite appliquer le filtre en utilisant Y = filter(B,A,X) où X est votre signal. Vous pouvez également consulter la fonction filtfilt.

7
Andreass

Une façon bon marché de faire ce type de filtrage qui n'implique pas de forcer les cellules du cerveau sur la conception, les zéros et les pôles et l'ondulation et tout cela, est:

* Make a copy of the signal
* Smooth it.   For a 100KHz signal and wanting to eliminate about 10Hz on down, you'll need to smooth over about 10,000 points.   Use a Gaussian smoother, or a box smoother maybe 1/2 that width twice, or whatever is handy.  (A simple box smoother of total width 10,000 used once may produce unwanted Edge effects)
* Subtract the smoothed version from the original.  Baseline drift will be gone.

Si le signal d'origine est spikey, vous pouvez utiliser un court filtre médian avant le gros lisseur.

Cela se généralise facilement aux images 2D, aux données de volume 3D, peu importe.

0
DarenW