web-dev-qa-db-ja.com

MATLABでプロットを平滑化する方法は?

グラフにプロットされるいくつかの9000ポイントがあります。

[ フル解像度 ]

alt text

実際、プロットは思ったほど滑らかではありません。 グラフを必要な程度に滑らかにする方法はありますか?

または、あまりにもでこぼこしている部分を選択的に平滑化できるように、何らかのしきい値を設定しますか?

確かではありませんが、 fast-fourier-transform 助けてもいいですか?

20
Lazer

簡単な(アドホックな)方法は、隣接する各ポイントで加重平均(alphaで調整可能)を取るだけです。

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

またはそのバリエーション。はい。より洗練するには、まずデータをフーリエ変換してから、高周波をカットします。何かのようなもの:

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

これにより、最も高い20の周波数がカットされます。それらを対称的に切り取るように注意してください。そうしないと、逆変換はもはや実在しません。適切なレベルの平滑化のために、カットオフ周波数を慎重に選択する必要があります。これは非常に単純な種類のフィルタリング(周波数領域でのボックスフィルタリング)であるため、歪みが許容できない場合は、高次の周波数を緩やかに減衰してみてください。

17
Victor Liu

Curve Fitting Toolboxがある場合は、 smooth 関数を使用できます。デフォルトの方法は、サイズ5の移動平均です(方法は変更できます)。例:

% 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])

そうでない場合は、コアMATLABの filter 関数を使用して独自のウィンドウ関数を使用できます。

% 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

FFTは悪い考えではありませんが、おそらくここではやり過ぎです。移動平均または移動平均の結果は一般に悪いため、宿題の遅れ(およびホワイトノイズ)以外は避けてください。

Savitzky-Golayフィルタリングを使用します(Matlab sgolayfilt(...)で)。これにより、探しているものに最適な結果が得られます-曲線の形状を維持しながら、局所的なスムージングを行います。

-ポール

5
Paul

外れ値に対してロバストではないため、モバイル平均の使用を避ける必要がある場合があります。これらの場合、モバイル中央値が望ましいです。

3
Thrax

最初に、5または10などの複数のポイントで移動平均を表示しようとします。この方法では、値の単一の不一致はグラフにほとんど影響を与えません。もちろん、グラフの正確性に依存します。

1
driis