スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

Scilabで移動平均

Scilabで移動平均処理をしてみましょう。

移動平均をする専用の関数はありませんが、フィルター用の関数を用いれば簡単に実現できます。
移動平均は、方形のデジタルフィルターと等価です。

ここでは、Convol関数という畳み込み積分を実行する関数を利用します。
Forを用いるよりも高速に処理することができます。

下記は移動平均を行う関数です。

ret = moving_average(data,len)
 data: 元のデータ
 len: 移動平均長さ
 ret: 移動平均後のデータ

function [ret] = moving_average(data,len)
data=data(:);len_d=length(data);
tmp=[ones(len-1,1)*data(1);data;ones(len-1,1)*data($)];

h = ones(1,len)/len;
ret = convol(h,tmp);

side=(length(ret)-length(data))/2;
ret = ret(floor(side)+1:$-ceil(side));

endfunction



上記プログラムの特徴は
 ・Convol関数で高速な処理
 ・平均値が変化しない
 ・(lenが奇数の場合)ピーク位置が変化しない
 ・データ長が変化しない
です。
データ長が変化しないように、両端にデータを付け加えています。

テストプログラムは下記になります。

exec('moving_average.sci');
a=ones(11,1);a(6)=2;
b=moving_average(a,3); //3点移動平均
scf();
plot(a);
plot(b,'r');

scf();
t=linspace(0,1,1000);
sig=sin(2*%pi*1*t);
sig=sig+0.2*rand(1,length(t));
plot(sig)
plot(moving_average(sig,32),'r');
p=get("hdl");
p.children.thickness=5


test_moving_average.pngピーク位置が変化していないことがわかります。
test_moving_average2.pngノイズ除去に有効です。


スポンサーサイト

コメントの投稿

非公開コメント

No title

この内容どこかのサイトで前にも見たけど、この端の処理だと一番端っこのデータの重みが端にいくほど重くなるので、端の方は平均に見えなくなるのだが・・・

確かに

>この端の処理だと一番端っこのデータの重みが端にいくほど重くなるので

これは仰る通りですね。
端点処理は

 ・ミラー
 ・ループ
 ・0点挿入
 ・端点挿入

くらいが一般的だと思いますが、信号の特性を理解した上でベストの方法を選ぶしかないでしょう。

他にも端点処理で良い方法があれば教えてくださいますと幸いです。
全記事表示リンク

全ての記事を表示する

最新記事
最新コメント
最新トラックバック
カテゴリ
検索フォーム
RSSリンクの表示
リンク
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。