C言語で書かれているFFTやフーリエ変換のプログラムのあるお勧めのサイトがあればおしえていただけないでしょうか?

よろしくお願いいたします。

A 回答 (3件)

No1のepistemeさんが紹介してくださっているライブラリは、それなりに有名だと思うので、


検索すれば情報が得られると思います。

ちなみにライブラリ本体は、
http://www.fftw.org/

http://www.fftw.org/download.html
からダウンロードできます…。


参考:
http://www32.atwiki.jp/amaeda/

参考URL:http://www32.atwiki.jp/amaeda/
    • good
    • 0
この回答へのお礼

ありがとうございます。

お礼日時:2011/04/29 00:25

> わかる範囲で良いので教えていただけないでしょうか?



まず読んで。お願いだから。
    • good
    • 1
この回答へのお礼

わかりました。

お礼日時:2011/04/29 00:25

下記URL参照



参考URL:http://www.fftw.org/
    • good
    • 0
この回答へのお礼

ありがとうございます。
ここでFFTのプログラムはどちらにありますか?

また、それをどのように利用したら良いのですか?

わかる範囲で良いので教えていただけないでしょうか?
よろしくお願いします。

お礼日時:2011/04/27 08:18

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Qc言語でDFTのプログラムを作成したのですが

c言語でDFTのプログラムを作成しました。
以下にソースを載せます。
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
#include<time.h>
#define PI 3.141592653589793
#define N 64 //データ数


DFT(double result[]){
int i,k;
double A[N],B[N],T=0; //A[N]:実数部,B[N]:虚数部
double a,b;
for(k=0;k<N;++k){
a=b=0;
for(i=0;i<N;++i){
a=a+result[i]*cos(2*PI*i*k/N);     
b=b+(-1.0)*result[i]*sin(2*PI*i*k/N);
}
A[k]=a/N;
B[k]=b/N;
}

for(i=0;i<N;++i){
printf("[%f秒]:Re:%f,Im:%f\n",T,A[i],B[i]); //変換後の値を表示
T=T+(0.1/N);
}

}

main(){
int i;
double T=0;
double Sampdata;
double result[N];

for(i=0;i<N;++i){
Sampdata=5*sin(20*PI*T);      //0~0.1秒間をN個にサンプリング
result[i]=Sampdata; //サンプリングデータを代入
T=T+(0.1/N);
}
clock_t start,end; //処理時間計測開始
start=clock();
DFT(result);
end=clock();
printf("%.2f秒かかりました\n",(double)(end-start)/CLOCKS_PER_SEC); //処理時間表示
}

元信号には5sin(20πt)の値を入れています。この信号は周期は0.1secです。
これでフーリエ変換を行うとデータ数N/2を中心に対称なデータが出てくるのですが、処理が終わるのが早い気がするんです。
例えば2^15個のデータで実行しても2分もかからずに処理が終わってしまいます。一応、対称性が出てるとはいえ、終わるのが早すぎる気がするのですが、おかしい所があれば教えていただけると嬉しいです。
よろしくお願いします。

c言語でDFTのプログラムを作成しました。
以下にソースを載せます。
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
#include<time.h>
#define PI 3.141592653589793
#define N 64 //データ数


DFT(double result[]){
int i,k;
double A[N],B[N],T=0; //A[N]:実数部,B[N]:虚数部
double a,b;
for(k=0;k<N;++k){
a=b=0;
for(i=0;i<N;++i){
a=a+result[i]*cos(2*PI*i*k/N);     
b=b+(-1.0)*result[i]*sin(2*PI*i*k/N);
}
A[k]=a/N;
B[k]...続きを読む

Aベストアンサー

計算に使っているコンピュータの性能はどれくらいなのでしょう?

このプログラムで一番時間がかかると思われるのは
> for(i=0;i<N;++i){
> printf("[%f秒]:Re:%f,Im:%f\n",T,A[i],B[i]); //変換後の値を表示>
> T=T+(0.1/N);
> }

この出力の部分です。

手許のcore i7 2.66GHz
gcc -O0 (最適化無し)
DFT(result); を2^15回ループ
結果出力部分をコメントアウト
で22秒程でした。

CPUの速度、コンパイラの最適化等でもっと速くなります。
2分かからないくらいなら、別に変では無いと思います。

心配なら、この計算結果を、別の方法で計算したもの(実績のあるDFT計算ライブラリ、Excel等の別ソフト等)と比較してみては?

Q一次元IFFTとFFTにおけるプログラムをください。

プログラミング経験1年くらいの者です。
通信シュミレーションのプログラムを書かなくてはいけないことになりました。しかし、私は、IDFTやDFTは作れるのですが、IFFTとFFTのアルゴリズムが難しく、また、プログラミングがまだまだということもあり、なかなかIFFT、FFTのプログラムがかけません。参照となるようなプログラムが欲しいと思っています。どうかよろしくお願いします。

Aベストアンサー

 参考 URL の,大浦氏のプログラムを使用させていただいてはいかがでしょうか。

参考URL:http://www.kurims.kyoto-u.ac.jp/~ooura/fftman/

QFFTとパワースペクトルの違いについて教えてください。

FFTとパワースペクトルの違いについて教えてください。
勉強不足で申し訳ありません。よろしくお願いします。

Aベストアンサー

信号をFFTで出したスペクトルというのは、
単にある信号をフーリエ展開した係数をプロットしたものに過ぎません。
ですので、位相によっては値がプラスにもマイナスにもなることがあります。

これに対してパワースペクトルというのは、信ある信号について
ある周波数における信号強度そのものをプロットしたものです。
ですので、位相にかかわらずかならず値がプラスになります。

確かFFTスペクトルを2乗したものがパワースペクトルになったと思います。
間違ってるかもしれないので、一応教科書も調べてみてください。

Qフーリエスペクトルの振幅について

ある時間関数を離散フーリエ変換して得られるフーリエスペクトルの
振幅値について教えて下さい。

今想定している離散フーリエ変換の式は一般的なもので
Σ(k=0~N-1) f(k)exp(-2πkni/N)
を考えています。
また、離散フーリエ変換して得られるスペクトルは
√(Re^2+Im^2)
で計算します。

離散フーリエ変換を適用する関数を、
振幅1の直流、及び振幅1で周波数5[Hz]の正弦波とします。
(この2つの信号は別々の信号で合成されていません。)
サンプリング周波数を20[Hz]とした場合、
サンプリングして得られるデータ列はそれぞれ、
直流: 「1, 1, 1, 1」
正弦波: 「0, 1, 0, -1」
となると想定されます。
(正弦波をサンプリングする場合は位相が関わってきますが、
今回は気にしないで下さい。)

このデータ列に対して上記の離散フーリエ変換を適用した場合、
得られるフーリエスペクトルの振幅値はそれぞれ、
直流: 「4」(直流のフーリエスペクトルの振幅値値)
正弦波: 「2」(5[Hz]のフーリエスペクトルの振幅値)
となります。
(データ点数は上の通り4点)

ここで質問なのですが、
離散フーリエ変換して得られるスペクトルの振幅値から
元の関数の振幅値を求める場合、
フーリエスペクトルをサンプリングの総データ点数で割ることは
数学的に納得できます。
しかしこの例の場合、フーリエスペクトルを総データ点数で割ると、
直流: 「4 -> 1」
正弦波: 「2 -> 0.5」
となってしまい、直流は正しいのですが、
正弦波の元の振幅値を正確に求めることは出来ません。
フーリエスペクトルの振幅値から正弦波の振幅値を正しく求めるには、
「フーリエスペクトルの振幅値*2/データ点数」
としてやらなければいけません。

上記のことに関して、
なぜこのようになるのかを(2をかける理由を)教えて頂けないでしょうか。

ある時間関数を離散フーリエ変換して得られるフーリエスペクトルの
振幅値について教えて下さい。

今想定している離散フーリエ変換の式は一般的なもので
Σ(k=0~N-1) f(k)exp(-2πkni/N)
を考えています。
また、離散フーリエ変換して得られるスペクトルは
√(Re^2+Im^2)
で計算します。

離散フーリエ変換を適用する関数を、
振幅1の直流、及び振幅1で周波数5[Hz]の正弦波とします。
(この2つの信号は別々の信号で合成されていません。)
サンプリング周波数を20[Hz]とした場合、
サンプリングし...続きを読む

Aベストアンサー

離散フーリエ変換というのは、実質離散フーリエ級数展開なので、
フーリエ級数展開を考えます。

f(t) = a0/2 + Σ[n=1→∞] { an cos (nωt) + bn sin (nωt) }

f(t)の周期をTとして、ω=2π/Tです。

直流成分の振幅といっているのはこの第1項a0/2のことで、
サイン成分の振幅はbnのことです。

問題文の離散フーリエ変換の式

>Σ(k=0~N-1) f(k)exp(-2πkni/N)

は複素フーリエ級数展開なのでオイラーの公式

cos nωt = [e^{inωt}+e^{-inωt}]/2
sin nωt = [e^{inωt}-e^{-inωt}]/2i = = -i [e^{inωt}-e^{-inωt}]/2

を使って書き直すと、

f(t) = a0/2 + Σ[n=1→∞] { ([an -i bn]/2) e^{nωt} + ([an +i bn]/2) e^{-inωt} }

an = a(-n), bn = -b(-n)の関係があるので、

cn = ([an -i bn]/2), c(-n) = ([an +i bn]/2)

と置くことができ、a0/2をc0と定義し直せば、

f(t) = Σ[n=-∞→∞] cn e^{nωt}

したがって、複素フーリエ係数が求めているのはcn = (an-ibn)/2で、その実数部はan/2、虚数部は-bn/2です。

こうなる理由は、サイン、コサインのときは正の整数だったnを複素数で取り扱うときにマイナス側に拡張したことで、同じ係数が+側と-側にわかれたためです。

離散的な場合は和が-N/2~N/2の範囲の有限項で打ち切られ、
-N/2~0の範囲が一周期ずらされてN/2~Nになっています。

離散フーリエ変換というのは、実質離散フーリエ級数展開なので、
フーリエ級数展開を考えます。

f(t) = a0/2 + Σ[n=1→∞] { an cos (nωt) + bn sin (nωt) }

f(t)の周期をTとして、ω=2π/Tです。

直流成分の振幅といっているのはこの第1項a0/2のことで、
サイン成分の振幅はbnのことです。

問題文の離散フーリエ変換の式

>Σ(k=0~N-1) f(k)exp(-2πkni/N)

は複素フーリエ級数展開なのでオイラーの公式

cos nωt = [e^{inωt}+e^{-inωt}]/2
sin nωt = [e^{inωt}-e^{-inωt}]/2i = = -i [e^{inωt}...続きを読む

QFFT(高速フーリエ変換)のプログラム

お世話になります。

仕事でFFTのプログラムを内製しようとしています。

初心者なので、他の人(今は退社していません)が昔作ったFFTのプログラムを参考にしようと思いそれを解読中です。

そのプログラムはC言語で書かれていますが、「ガウスの消去法を使って連立方程式を解く」というプロセスが含まれています。

私の認識では、FFTではガウスの消去法を使う事はないので、私が見たプログラムはFFTではなくDFTのプログラムではないかと思っています。

FFTのプログラムでガウスの消去法を使う事はあるのでしょうか?勉強中なのと、周りに知っている人がいないため、どなたか教えて下さい。

よろしくお願いします。

Aベストアンサー

http://ja.wikipedia.org/wiki/%E9%9B%A2%E6%95%A3%E3%83%95%E3%83%BC%E3%83%AA%E3%82%A8%E5%A4%89%E6%8F%9B
ここで、
e^ix=cos(x)+i * sin(x) を使って
f_real(j) + i*f_imag(j)
= Σ((x_real(k) + i * x_imag(k))*(cos(-2*π*(j^k)/n) + i*sin(-2*π*(j^k)/n))
※ -2*π*(j^k)/n=θとして、上記式を展開
= Σ(x_real(k)*cosθ + i * x_imag(k)*cosθ + i*x_real(k)*sinθ - x_imag(k)*sinθ )
∴ 実数部と虚数部に分けて
f_real(j)= Σ(x_real(k)*cosθ- x_imag(k)*sinθ )
f_imag(j) = Σ( x_imag(k)*cosθ + x_real(k)*sinθ )

つまり、DFTは、ひたすら「θを計算→sinθ,cosθを計算→掛けて足す」 を繰り返すだけです。
(三角関数の性質(周期等)を利用して、先に使用するcos,sinを計算しておく、等といった工夫を加えることもできますが)

FFTは、DFTの特殊なケース(xの数 n が2のべき乗個のとき)に、対称性等を利用して計算を減らしたものです。

どちらにも、多元連立方程式を解くようなものは出てきません。


もう一度、処理の流れを確かめてください。
・その消去法は、実際にプログラムで使用されているのでしょうか?
定義されているだけで、呼び出されていない(実行されていない)、ということは無いでしょうか?
・そのプログラムは、純粋にFFTを計算するだけのものでしょうか?
一連の処理の中にFFTがある、というものではありませんか?
生のデータ→前処理→FFT→後処理→欲しいデータ
という流れで、前処理や後処理に使われているだけではないでしょうか?


○VBA
プログラムを作ること自体は問題ありません。
http://ja.wikipedia.org/wiki/%E9%AB%98%E9%80%9F%E3%83%95%E3%83%BC%E3%83%AA%E3%82%A8%E5%A4%89%E6%8F%9B
にVisual Basicの例が載っていますが、ほぼここままでVBAでも動作すると思います。

ただし、メモリ量や計算速度が実用的なレベルになるかどうかまではわかりません。

http://ja.wikipedia.org/wiki/%E9%9B%A2%E6%95%A3%E3%83%95%E3%83%BC%E3%83%AA%E3%82%A8%E5%A4%89%E6%8F%9B
ここで、
e^ix=cos(x)+i * sin(x) を使って
f_real(j) + i*f_imag(j)
= Σ((x_real(k) + i * x_imag(k))*(cos(-2*π*(j^k)/n) + i*sin(-2*π*(j^k)/n))
※ -2*π*(j^k)/n=θとして、上記式を展開
= Σ(x_real(k)*cosθ + i * x_imag(k)*cosθ + i*x_real(k)*sinθ - x_imag(k)*sinθ )
∴ 実数部と虚数部に分けて
f_real(j)= Σ(x_real(k)*cosθ- x_imag(k)*sinθ )
f_imag(j) = Σ( x_imag(k)*cosθ + x_real(k)*sinθ...続きを読む

QFFT・PSDの縦軸は何を意味するのでしょう?

加速度計測の結果について、PSD(パワースペクトラムデンシティ)をかけた場合、その縦軸の意味を教えてください。
また、FFTとPSDはどういう違いが有るのでしょうか?
これまでは、周波数の分布のみに着目していました。
どなたか、わかりやすく教えてください。
よろしくお願いします。

Aベストアンサー

一般に加速度センサー信号の出力は電圧です。

縦軸は係数をかけていない状態では#1さんがおっしゃるように計測した電圧の値を示しています。

よって、縦軸に物理的な意味を持たせるのには、電圧と加速度の間の換算係数をかけてやる必要があります。

フーリエ解析は時刻歴波形は正弦波の組み合わせで構成されるという仮定の下で計算を行っています。FFTの結果は横軸で示される周波数の正弦波の振幅を示しています。
電圧と加速度の換算係数をかけてやると、FFTの縦軸はその周波数成分を持つ加速度振幅を示しています。

ここで1つ問題があります。FFTはサンプリング周波数により分解能が変わります。FFTによる周波数分析は正確にいうと、離散値なので、ジャストの周波数のもをだけを表しているのではなく、ある範囲の周波数範囲にある成分を表しています。
このため分解能が変わると周波数範囲が変わり、同じ波形を分析しても振幅が変わります。
これでは分解能が異なるデータ同士は比較できないなどの問題が生じます。
そのため、周波数幅で振幅を基準化して、1Hzあたりの振幅としたものがPSDです。
PSDならサンプリング周波数が異なるデータ同士の比較ができます。

要はフーリエ振幅(FFT)はサンプリング周波数・分解能により変わる値であり、PSDはそのようなことのないように周波数幅で基準化した値という差があります。

なお、2乗表示したものをパワースペクトルと呼び、それを周波数で基準化したものをPSDと呼びますが、PSDは表示方法によって2乗した状態のあたいを表示(パワー表示)するときと、2乗した値の平方根を計算して表示することがありますので、使用する際には縦軸の表示方法については要注意です。

一般に加速度センサー信号の出力は電圧です。

縦軸は係数をかけていない状態では#1さんがおっしゃるように計測した電圧の値を示しています。

よって、縦軸に物理的な意味を持たせるのには、電圧と加速度の間の換算係数をかけてやる必要があります。

フーリエ解析は時刻歴波形は正弦波の組み合わせで構成されるという仮定の下で計算を行っています。FFTの結果は横軸で示される周波数の正弦波の振幅を示しています。
電圧と加速度の換算係数をかけてやると、FFTの縦軸はその周波数成分を持つ加速...続きを読む

Qフーリエ変換について教えてください

フーリエ変換をすると横軸が時間から周波数になるのはわかったのですが、縦軸が何になるのかわかりません。

一般的に縦軸はなにになるのでしょうか?

また横軸が時間で、縦軸が距離をフーリエ変換したら縦軸は何になるのでしょうか?

よろしくお願いします。

Aベストアンサー

時間関数をフーリエ変換すると結果は、その時間関数の周波数成分が
得られます。スペクトルとも言います。従って、縦軸は、周波数成分です。一般に複素数です。
大きさと偏角による表現もできます。
大きさの方は振幅特性、位相角の方は位相特性と呼ばれます。
画像のように空間座標の上の関数の場合には、フーリエ変換すると
空間周波数成分が得られます。横軸は、空間周波数(2次元)となります。
対象とする関数により結果はそれぞれ意味が異なります。
「一般に何になる」とは言えません。

>横軸が時間で縦軸が距離の場合・・・
フーリエ変換の結果は、距離を表す時間関数の周波数成分です。

フーリエ変換の対象の関数は別に時間関数でなければならないということは
ありません。従って、フーリエ変換の結果は適用する人が解釈(定義)すれば
よいと思います。
たとえば、
時間関数をフーリエ変換し、その結果の絶対値の対数のフーリエ変換を
することもあります。これの結果には、発明者らがケプストラムという名前
をつけています。Cepstrum は Spectrum から作った造語です。

時間関数をフーリエ変換すると結果は、その時間関数の周波数成分が
得られます。スペクトルとも言います。従って、縦軸は、周波数成分です。一般に複素数です。
大きさと偏角による表現もできます。
大きさの方は振幅特性、位相角の方は位相特性と呼ばれます。
画像のように空間座標の上の関数の場合には、フーリエ変換すると
空間周波数成分が得られます。横軸は、空間周波数(2次元)となります。
対象とする関数により結果はそれぞれ意味が異なります。
「一般に何になる」とは言えません。

>横軸が...続きを読む

QFFTプログラム(1次元)を使って高次元のFFTを計算するプログラム

以下、長文になりますがご容赦。
 1次元のFFTのフォートランソースプログラムはネットにも本の付録にもあります。高次元のソースプログラム(2次元、3次元)を作りたいと思っています。私は以前にもこの質問をしており、1次元のプログラムを何度も繰り返して作成できる、ということが分かりました。
 添付した画像はこのような方向かなと思って式を調べたものです。画像のようにx方向への変換(赤字)とその後y方向への変換(そのあとの黒字式3行目)(都合2回)ということだろうと思います。これによりますと確かにできることがわかります。(このような理解でもいいでしょうか?)
 それでも少し疑問が残ります。赤字の変換は変換対象 f(x,y) が実数であり、その後の黒字の変換はg(kx,y)を変換していることになりますが、こちらは複素数ですね。また、たとえば、X方向に64個のデータでFFTをかけると波数kxの数は32個で位相情報(sin, cos)が32個づつ出るから系列の個数は64にはなるということではないかと思います。
 ということなので、1次元の計算を2回する、ということですが、1回目と2回目で若干様子が違うということになります。ただし、f(x,y)は実数ですが、複素数の変数の実部(虚部はゼロ)に代入してFFTルーチンに入れたようでもあります。だんだんあやふやになります。またkx, kyの定義についても2π(パイ)をかけるものがあったり、出てきたフーリエ成分はデータ数Nが掛けられているとかプログラムの作り方が作成者に依存するところがあったりするので正しく動作するかどうか不明です。
 フーリエ変換のプログラムが正しく動作しているかどうかは、すぐさま逆変換して比較するわけですが、フーリエ変換と逆変換は言わば同じものであり、片方が正しく動作すれば逆もほぼ正しいでしょうし、間違い(変換)と間違い(逆変換)が相殺して正しく見せてしまっているかも知れません。
 ということで、私の希望としては、これで正しく動作するというセットがあると安心して使えるのに、ということです。ネットを探してみると、2次元はあるかもな、というところです。画像処理として利用されている例があるからですね。3次元はどうでしょうか。ある、と聞いていますが、見つかりません。もしあるということであれば、ダウンロード情報を教えて頂きたいのですが。
 ソースプログラムはフォートランだとありがたいですが、Cでも解読できると思います。
実験して試行錯誤して解決するというよりも、先達に指定して頂くとありがたいです。また、人それぞれ自分のプログラムを持つ必要がなく、動作確認がされているソースを1つ持ちたいと思っているのです。あるいは1次元のFFTを複数回使って間違いなく計算する方法を教えて戴きたいのですが。
長文で申し訳ありませんが、よろしくお願いします。

以下、長文になりますがご容赦。
 1次元のFFTのフォートランソースプログラムはネットにも本の付録にもあります。高次元のソースプログラム(2次元、3次元)を作りたいと思っています。私は以前にもこの質問をしており、1次元のプログラムを何度も繰り返して作成できる、ということが分かりました。
 添付した画像はこのような方向かなと思って式を調べたものです。画像のようにx方向への変換(赤字)とその後y方向への変換(そのあとの黒字式3行目)(都合2回)ということだろうと思います。これによります...続きを読む

Aベストアンサー

No.3の回答へのお礼を受けて

>まず、j=1に固定してi=1~64を1DのFFTにかけます。結果,i=1~64の成分が複素数で出力されます。それをg(i,1) (i=1~64)に保存し、j=2,3,4...64と行くと、g(i,j),(64x64)ができます(図の赤字部)。次に、i=1に固定してg(1,j),j=1~64を1DのFFTにかけ、s(1,j),j=1~64に格納し、i=2,3,4..64と進めると、s(i,j) (64x64)が算出され、2次元フーリエ変換となる、という考え方です。
はい、この考え方で合っています

ソースコードは多分、前半部分がbit逆順配列への並べ替え、後半部分がFFTだと思います
コメントがないので解りづらいですが、頭のなかで計算する限りあっていると思います

Q高速フーリエ変換とフーリエ変換の違い

高速フーリエ変換とフーリエ変換の違いについて教えて下さい。
高速フーリエ変換は何か近似を行うことによって、計算速度を速くしているのでしょうか?
もし、何かの極限で出てくる結果が違う場合などがあれば教えて下さい。

Aベストアンサー

>出てくる結果は全く同じだということなのでしょうか?
その通りです。

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

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

わかりにくい説明ではありますが、分かる人がいましたらアドバイスください。

Aベストアンサー

No.2です。

画面全体がノイズだらけになるとしたらデータの処理だけで
ノイズを除去する事は難しいかもしれません。
データの再取得が可能であるならば再取得してください。
その際、あらかじめアナログ回路部分でノイズを除去しておいてデータを取得するようにしてください。
データのサンプリング時にエイリアシングが発生して信号にかぶさった場合には後処理でノイズを除去する事は不可能です。


フィルタについてはアナログ回路で実現するもの、AD変換後にデジタル回路で実現するもの、データ取得後にソフトウエアで行うものなどが有ります。

>多少信号のでている時間、大きさに誤差が出てきてしまう
とのことですが、フィルタを通した場合一般的には時間遅れが生じます。
どれだけ遅れるかはフィルタが決まれば決定されるのでその分補正すれば良いです。
大きさについては適切に設計されていれば大きくずれる事はありませんが
フィルタの種類によっては通過域でゲインが変化しないものと多少の変化があるものとが有るので用途によって使い分けします。

フィルタ処理の具体例を挙げます。
No.3さんの計算と同じものです。
/* FIRフィルタのサンプル */
#define DATA_SZ1000 /* データの個数 */
#define KN2
#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で置き換える)データを持ってくるか、無いものとするしかありません。

係数の数を増やせばより高性能なフィルタとすることが出来ます。
係数を決める、つまりはフィルタを設計する方法の説明はここでは難しいです。
次数がそれほど大きくなけれはエクセルでも計算できます。

No.2です。

画面全体がノイズだらけになるとしたらデータの処理だけで
ノイズを除去する事は難しいかもしれません。
データの再取得が可能であるならば再取得してください。
その際、あらかじめアナログ回路部分でノイズを除去しておいてデータを取得するようにしてください。
データのサンプリング時にエイリアシングが発生して信号にかぶさった場合には後処理でノイズを除去する事は不可能です。


フィルタについてはアナログ回路で実現するもの、AD変換後にデジタル回路で実現するもの、データ取得...続きを読む


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング

おすすめ情報