• ベストアンサー

原波形のノイズ除去方法(FFT、逆FFT)

始めに、僕は数値解析等にはかなりの未熟者です。 今、微量な電流を拾ってそれを200倍に増幅した原波形があるのですが、それには多くのノイズがはいってしまい見にくいんです。それでそのノイズを除去したいのです。 今考えているのはFFTをかけてでてきた周波数を逆FFTを行いノイズを除去しようと考えています。もし他に簡単にノイズを除去できる方法があれば教えていただきたいのですが。 今、自分のなりの考えで行うとしてもその処理の仕方がまったくわかりません。どのソフトを使うのが最適なのかがわかりません。こういう場合で使いやすいソフトってありますか? わかりにくい説明ではありますが、分かる人がいましたらアドバイスください。

質問者が選んだベストアンサー

  • ベストアンサー
  • tadys
  • ベストアンサー率40% (856/2135)
回答No.4

No.2です。 画面全体がノイズだらけになるとしたらデータの処理だけで ノイズを除去する事は難しいかもしれません。 データの再取得が可能であるならば再取得してください。 その際、あらかじめアナログ回路部分でノイズを除去しておいてデータを取得するようにしてください。 データのサンプリング時にエイリアシングが発生して信号にかぶさった場合には後処理でノイズを除去する事は不可能です。 フィルタについてはアナログ回路で実現するもの、AD変換後にデジタル回路で実現するもの、データ取得後にソフトウエアで行うものなどが有ります。 >多少信号のでている時間、大きさに誤差が出てきてしまう とのことですが、フィルタを通した場合一般的には時間遅れが生じます。 どれだけ遅れるかはフィルタが決まれば決定されるのでその分補正すれば良いです。 大きさについては適切に設計されていれば大きくずれる事はありませんが フィルタの種類によっては通過域でゲインが変化しないものと多少の変化があるものとが有るので用途によって使い分けします。 フィルタ処理の具体例を挙げます。 No.3さんの計算と同じものです。 /* FIRフィルタのサンプル */ #define DATA_SZ 1000 /* データの個数 */ #define KN 2 #define KEISU_SZ (2*KN+1) /* フィルタの係数の個数 */ float input[DATA_SZ]; /* 入力データ 適当な方法で初期化すること */ float output[DATA_SZ]; /* 出力データ */ float keisu[KEISU_SZ] = {1.0/KEISU_SZ} ; /* 移動平均フィルタの場合 */ void fir( float *in, float *out, float *ks ){ int i,j ; float x;   for( i=KN ; i<DATA_SZ-KN ; i++ )     {       x= 0 ;       for( j=-KN : j<=KN ; j++ )       {          x += in[i+j] * ks[j+KN] ;       }       out[i] = x ;    } } /* インデントを付けるため全角スペースを使用しています */ もっと具体的には 入力データ d0,d1,d2,d3,d4,d5,d6,d7 係数データ k0,k1,k2,k3,k4 出力データ ______x2______  上下をそれぞれ掛け算したものの合計 x2 = ( d0*k0 + d1*k1 + d2*k2 + d3*k3 + d4*k4 ) 出力のx3を求める場合は入力データを1個左にシフトします。 入力データ d1,d2,d3,d4,d5,d6,d7 係数データ k0,k1,k2,k3,k4 出力データ ______x3______  x3 = ( d1*k0 + d2*k1 + d3*k2 + d4*k3 + d5*k4 ) これから分かるように x0,x1 を求めるにはデータが足りません。 どこかから(例えばd0で置き換える)データを持ってくるか、無いものとするしかありません。 係数の数を増やせばより高性能なフィルタとすることが出来ます。 係数を決める、つまりはフィルタを設計する方法の説明はここでは難しいです。 次数がそれほど大きくなけれはエクセルでも計算できます。

その他の回答 (3)

  • foobar
  • ベストアンサー率44% (1423/3185)
回答No.3

実際の処理は、どんな処理プログラムを使っているかにも依存します。 (私の場合、一度限りの処理ならそれように簡単なプログラムを作ってしまうこともあります。) FFT、処理、逆FFT 一旦、元の信号をFFTのプログラムで横軸周波数のデータにします。 このデータで信号の含まれてい無い部分(ノイズと思われる部分)を0にします。(これで信号と思われる部分だけ抽出したことになる) このデータを逆FFTすれば、ノイズを除いた時間波形になります。 加重(移動)平均 これは#2さん回答にあるFIRフィルタと同じ処理になります。 希望の周波数帯だけ通すような、係数 c[k]をもってきて、 y[i]=Σ(c[k]*x[i-k]) (xはもとの信号、yが処理済みの信号、Σはkについて、0からkmまでの積算) みたいな計算処理をします。

  • tadys
  • ベストアンサー率40% (856/2135)
回答No.2

ノイズといっているものがほんとにノイズなんですか? 元々の信号にノイズと同じような信号が含まれている可能性はありませんか? ノイズを除去するということは信号とノイズの性質の違いを見定めてそれらを区別するフィルターを設計するという事になります。 元の信号が直流あるいは低い周波数でノイズが高い周波数なのであればローパスフィルタで除去できます。 信号とノイズの周波数が離れているのであれば簡単なローパスフィルタで除去できます。 例えば移動平均フィルタでも良いでしょう。これは注目点の前後のデータ(注目点を含む)を平均した値をその点の値とするものです。 信号が高い周波数で低い周波数のノイズが乗っている場合ではハイパスフィルタ又はバンドパスフィルタで除去します。 信号とノイズの周波数が離れている時には簡単なフィルタでいいのですが近い場合は高次なフィルターが必要となります。 高次なフィルターの設計は難しいのですが下記URLなどで計算してくれます。 デジタルフィルタには色々な形式がありますがFIRタイプのフィルターが良いでしょう。 デジタルフィルタについては書籍、インターネットなどに解説がありますので調べてください。

参考URL:
http://momiji.i.ishikawa-nct.ac.jp/dfdesign/
ryoji
質問者

お礼

ありがとうございます。でてくる原波形が画面真っ赤になるくらいノイズがはいっていて、とりあえず高い周波数をカットしてみないと元の信号がわからないんです。少し詳しい人に原波形をみてもらうと高い周波数と低い周波数をカットしたら見やすくなるといわれました。 今、僕はIgorというソフトを使ってその解析メニューにある移動平均でノイズを除去していたのですが、多少信号のでている時間、大きさに誤差が出てきてしまうので困っていたのです。 ハイパスフィルタ、バンドパスフィルタ、ローパスフィルタとは機械でしょうか?それともそういうソフトがあって、原波形のデータを取り込んでそういう処理ができるものなのでしょうか?

  • foobar
  • ベストアンサー率44% (1423/3185)
回答No.1

一旦FFTをかけて、信号とノイズで周波数が違うところにあるようなら、信号の部分だけ取り出して逆FFTによりノイズ除去(正しくは抑制)した信号が得られるかと思います。 また、ある程度信号の周波数がわかっていれば、重み付けした平均を原信号(FFTする前の信号)にかけることで、同様の処理も可能です。(重み付けした平均をとる=ある周波数成分を通過もしくはカットするフィルタを通す、ですので)

ryoji
質問者

お礼

ありがとうございます。信号の部分だけ取り出して逆FFTによりノイズ除去(正しくは抑制)した信号が得られるかと思います。というのは実際にどういう風に行えばいいのですか?。重み付けした平均をとる=ある周波数成分を通過もしくはカットするフィルタを通す)とういのもどういう風におこなえばよいのかわかりません。 簡単にできるそういうソフトがあるのでしょうか?

関連するQ&A