web-dev-qa-db-fra.com

Comment lisser un tracé dans MATLAB?

J'ai environ 9000 points qui sont tracés sur un graphique:

[ pleine résolution ]

alt text

En fait, l'intrigue n'est pas aussi fluide que je le voulais. Existe-t-il un moyen de lisser le graphique au degré requis?

Ou une certaine forme de seuillage pour que je puisse lisser sélectivement les parties trop bosselées?

Je ne suis pas sûr mais peut fast-fourier-transform aider?

20
Lazer

Un moyen simple (ad hoc) consiste à simplement prendre une moyenne pondérée (ajustable par alpha) à chaque point avec ses voisins:

data(2:n-1) = alpha*data(2:n-1) + (1-alpha)*0.5*(data(1:n-2)+data(3:n))

ou une variante de celui-ci. Oui, pour être plus sophistiqué, vous pouvez d'abord transformer Fourier vos données, puis couper les hautes fréquences. Quelque chose comme:

f = fft(data)
f(n/2+1-20:n/2+20) = zeros(40,1)
smoothed = real(ifft(f))

Cela coupe les 20 fréquences les plus élevées. Attention à les couper symétriquement sinon la transformée inverse n'est plus réelle. Vous devez choisir soigneusement la fréquence de coupure pour le bon niveau de lissage. Il s'agit d'un type de filtrage très simple (filtrage en caisson dans le domaine fréquentiel), vous pouvez donc essayer d'atténuer doucement les fréquences d'ordre élevé si la distorsion est inacceptable.

17
Victor Liu

Si vous avez la boîte à outils d'ajustement de courbe , vous pouvez utiliser la fonction smooth . La méthode par défaut est une moyenne mobile de taille 5 (la méthode peut être modifiée). Un exemple:

% some noisy signal
Fs = 200; f = 5;
t = 0:1/Fs:1-1/Fs;
y = sin(2*pi*f*t) + 0.6*randn(size(t));
subplot(411)
plot(y), title('Noisy signal')

% smoothed signal
subplot(412)
plot( smooth(y, 5, 'moving') ), title('smooth')
ylim([-2 2])

Sinon, vous pouvez utiliser votre propre fonction de fenêtre en utilisant la fonction filter du noyau MATLAB:

% equivalent to a moving average window
wndwSize = 5;
h = ones(1,wndwSize)/wndwSize;
subplot(413)
plot( filter(h, 1, y) ), title('filter + square window')

% Guassian
h = pdf('Normal',-floor(wndwSize/2):floor(wndwSize/2),0,1);
subplot(414)
plot( filter(h, 1, y) ), title('filter + Guassian window')

screenshot

30
Amro

La FFT n'est pas une mauvaise idée, mais c'est probablement exagéré ici. Les moyennes courantes ou mobiles donnent généralement des résultats médiocres et doivent être évitées pour tout autre chose que les devoirs tardifs (et le bruit blanc).

J'utiliserais le filtrage Savitzky-Golay (dans Matlab sgolayfilt (...)). Cela vous donnera les meilleurs résultats pour ce que vous recherchez - un certain lissage local tout en conservant la forme de la courbe.

-Paul

5
Paul

Parfois, vous devriez éviter d'utiliser la moyenne mobile car elle n'est pas robuste aux valeurs aberrantes. La médiane mobile est préférable dans ces cas.

3
Thrax

J'essaierais d'abord d'afficher la moyenne mobile sur un certain nombre de points, comme 5 ou 10. De cette façon, une seule différence dans les valeurs n'a qu'un faible impact sur le graphique. Bien sûr, cela dépend de la précision dont vous avez besoin pour que le graphique soit.

1
driis