プログラムでフィルタ(平滑化、ノイズ除去)の遅れを無くす

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

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

スポンサーリンク

何もしてないフィルタで遅れの確認

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

スポンサーリンク
スポンサーリンク

コメント

  1. 匿名 より:

    FFT→閾値→Ifft 使うといけちゃうと思います。