プログラムでローパスフィルタ(平滑化、ノイズ除去)

Pocket

 

 プログラム(ソフト)で簡単な平滑フィルタ(ローパスフィルタ?)を通して、計測値の平滑化(スムージング、ノイズ除去)をよく行うのですが、リアルタイムで処理する場合にはどうしても遅れや減衰などが、発生してしまいます。

 

 今回はあまり遅れが出ないように、ローパスフィルタを少し改造?して試してみました。

 

まずは何もしてない簡易的なローパスフィルタから

 サンプルデータは適当にEXCELで準備しました。

 

▼計測値サンプルデータ▼

 黒実線が真の値です。灰色のキザキザしているのが真値にノイズを乗せた「計測値」としてサンプルデータを準備してます。真値は徐々に「1」へ収束していくようにしてます

 

 このサンプル(計測値)にまずは普通?のローパスフィルタを通してみます。

 

 ▼ローパスフィルタは▼

  LPF = (1 - k) * lastLPF + k * raw;
  lastLPF = LPF;

  //lastLPF:前回のLPF値
  //raw :今回の計測値

 言語風に書くとこんな感じでしょうか。「前回の補正値」と「今回の計測値」を重み付け平均している感じです。「k」は適当な定数です。(k=1以下)

 

▼式を展開して纏め直すと▼

  LPF += k * (raw - lastLPF);

 こんな感じで速度から積分してるっぽい式?になります。ですので「k」(時間)の値を小さくすればするほど遅くなる・・(イメージです・・。)

 

 先ほどのサンプルデータ(計測値)に普通のローパスフィルタを通してみます。

 

 ▼ローパスフィルタ後グラフ▼
 ここでは定数「k」の値は「0.01」にしてます。結構小さな値にしてます。ですのでノイズっぽいギザギザ感はほとんど無くなり平滑化されますが、やはり真値に比べて、だいぶ遅れがでてしまいます。で今回はこの遅れをなるべく軽減したいと思います。

<スポンサーリンク>

 

 

ローパスフィルタを少し改造

 ここから一手間加えて、なるべくこの遅れを少しでも軽減してみたいと思います。

 

 方法としては、随時、「測定値」と「補正値」を比較し、差が大きいようであれば、定数「k」(速度)を変更するといった処理を加えてみます。

 

 ▼言語風に記述すると▼

  if (abs(raw - LPF) > 0.33) {
    k = 0.1;
  }
  else {
    k = 0.01;
  }
  LPF += k * (raw - LPF);

 このような感じです。「今回の測定値」と「前回の補正値」の差分が大きいようであれば、定数「k」の値を変えてます。差分の判定値は適当です。誤差の分散などをみて適宜調整が必要かと思います。

 

 この考え方で先ほどのグラフ(計測値)に、フィルタを通してみます。

 

 ▼フィルタ(改)後グラフ▼

 赤ラインが一手間加えたフィルタを通したものです。

 

 立ち上がりで少しガタツキが出てしまってますが、遅れはだいぶ解消しているのではないかと思います。なるべく平滑化したいけどあまり遅れるのは困るということきに使えるかも・・・。

 

 ここでは測定値と補正値の差分で単純に定数「kの値」を切り替えてるだけですが、定数「k」を「差分」の関数で置いたら、もう少し立ち上がりも滑らかになるかもしれませんね。

 

 また今回は、適当に作ったサンプルデータをEXCEL上で計算して試してみただけです。実際試したわけではないのでここまでうまくいくかどうかわかりませんが、そのうち機会(必要なとき)があったら試してみたいと思います。

 

Pocket

<スポンサーリンク>


この投稿へのコメント

コメントはありません。

コメントを残す

メールアドレスが公開されることはありません。

この投稿へのトラックバック

トラックバックはありません。

トラックバック URL