FFTの各値の周波数を取得するにはどうすればよいですか?


148

FFTの結果があります。これらは2つに保存されますdouble、実部配列と虚部配列の配列にます。これらの配列の各要素に対応する周波数をどのように決定しますか?

言い換えると、FFTの各実数成分と虚数成分の周波数を格納する配列を作成したいと思います。


C#.netで行います。手伝って頂けますか?
Rango

9
FFTの実数部と虚数部の関連性を理解していないと、意味のある結果が得られないため、FFTと信号処理のチュートリアルを探して、結果の解釈方法を理解する必要があります。私はあなたがそれを使用しているものは何でも、FFTまたはパワースペクトル密度の大きさを望んでいる可能性が高いと思います。
the_mandrill

ありがとうございました!各フレームのピーク周波数を取得したい(フレーム長はウィンドウ長とシフト長に依存)
Rango

回答:


350

FFTの最初のビンはDC(0 Hz)、2番目のビンはですFs / N。ここFsで、はサンプルレートで、NはFFTのサイズです。次のビンは2 * Fs / Nです。これを一般的に表すと、n番目のビンはn * Fs / Nです。

したがって、サンプルレートFsが44.1 kHzで、FFTサイズNが1024の場合、FFT出力ビンは次のようになります。

  0:   0 * 44100 / 1024 =     0.0 Hz
  1:   1 * 44100 / 1024 =    43.1 Hz
  2:   2 * 44100 / 1024 =    86.1 Hz
  3:   3 * 44100 / 1024 =   129.2 Hz
  4: ...
  5: ...
     ...
511: 511 * 44100 / 1024 = 22006.9 Hz

実際の入力信号(虚数部がすべてゼロ)の場合、FFTの後半(ビンからN / 2 + 1までN - 1)には有用な追加情報が含まれていないことに注意してください(最初のN / 2 - 1ビンとの複素共役対称性があります)。最後の有用なビン(実用的なアプリケーション)はN / 2 - 1にあり、上記の例の22006.9 Hzに対応します。ビンはN / 2、ナイキスト周波数Fs / 2(この例では= 22050 Hz)のエネルギーを表しますが、アンチエイリアスフィルターは通常、とそれ以上の信号を減衰させるため、これは一般に実用的ではありませんFs / 2


8
注-答えは少し間違っています-512番目のバケットには、ナイキスト制限である22050のレベルが含まれています。0からN / 2までのビンには、有用な値が含まれています。
david van brink

4
編集と説明に感謝します...これは私が実用性の欠如を明らかにする場所だと思います。私:でもマスター、FFTはナイキストまでの仕事です!あなた:パダワン、あなたは本当にそれを除外すべきです。
david van brink

5
回答にスターを付けたいです。この答えは元の質問よりも優れています!
Skylion 2013

14
@PaulR-長年にわたって役立ってきたこの素晴らしい答えに感謝したいと思います。StackOverflowアカウントを作成する前にこの回答にアクセスしましたが、実際にサインアップしたら、お礼を忘れていました。私は最近FFTのことを調べていて、あなたの答えを覚えていて、ちょうど今それを訪れました。ここに着いたら、ありがとうございました。ありがとうございました。FFTの横軸の各点が何であるかを解釈することについて誰かと議論するときはいつでも、私はそれらをこのリンクに向けるだけです。
rayryeng 2015年

6
@rayryeng:どうもありがとうございました。これが、SOでの質問に5年ほど答えてきた中で、これまでで最高の謝辞です。
Paul R

55

ここで私の答えを見てください

コメントへの回答:

FFTは実際には、等間隔の周波数の範囲で、入力信号と正弦関数および余弦関数(基底関数)との相互相関を計算します。与えられたFFT出力に対して、私が投稿した回答で示されているように、対応する周波数(F)があります。出力サンプルの実数部は入力信号との相互相関でcos(2*pi*F*t)あり、虚数部は入力信号との相互相関ですsin(2*pi*F*t)。入力信号sincos関数が相関している理由は、入力信号と基底関数の間の位相差を説明するためです。

複素FFT出力の大きさを取得することにより、入力信号の位相に関係なく、入力信号が一連の周波数で正弦波とどの程度相関しているかを測定できます。信号の周波数成分を分析するだけの場合、ほとんどの場合、FFTの複素出力の絶対値または絶対値の2乗を取得します。


実数部と虚数部は、FFTの結果に使用されましたか?説明してください。ありがとう
Rango

5
この答えはもっと愛に値する。
明るい星、

1
複雑な出力の大きさをそれぞれ2倍にする必要があるのでしょうか。(解釈を下半分に制限した場合)
Wolf

18

私は以下を使用しました:

public static double Index2Freq(int i, double samples, int nFFT) {
  return (double) i * (samples / nFFT / 2.);
}

public static int Freq2Index(double freq, double samples, int nFFT) {
  return (int) (freq / (samples / nFFT / 2.0));
}

入力は次のとおりです。

  • i:アクセスするビン
  • samples:ヘルツ単位のサンプリングレート(つまり、8000 Hz、44100Hzなど)
  • nFFT:FFTベクトルのサイズ

7
人々は正確にあなたが何を表しているかを知ることはできませんsamplesnFFT。ですから、より説明的にしてください。
モスタル2012

14
受け入れられた答えはこれはそうあるべきであると言いますi * samples / nFFT。なぜ2そこに余分があるのですか?何か不足していますか?
yati sagade 2014年

13

FFT出力係数(サイズNの複素数入力の場合)は、0〜N-1で、[LOW、MID、HI、HI、MID、LOW]周波数としてグループ化されます。

実データの場合、FFT [Nk] = FFT [k]の複素共役であるため、kの要素はNkの要素と同じ周波数であると考えます。

LOWからHIGHの頻度でスキャンする順序は次のとおりです。

0,

 1,
 N-1,

 2,
 N-2

 ...

 [N/2] - 1,
 N - ([N/2] - 1) = [N/2]+1,

 [N/2]

インデックスi = 0から[N / 2]までの[N / 2] +1グループの周波数があり、それぞれが frequency = i * SamplingFrequency / N

したがって、ビンFFT [k]での周波数は次のとおりです。

if k <= [N/2] then k * SamplingFrequency / N
if k >= [N/2] then (N-k) * SamplingFrequency / N

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.