Wie erhalte ich die Frequenzen jedes Werts in einer FFT?

148

Ich habe ein FFT-Ergebnis. Diese werden in zwei doubleArrays gespeichert : einem Realteil-Array und einem Imaginärteil-Array. Wie bestimme ich die Frequenzen, die jedem Element in diesen Arrays entsprechen?

Mit anderen Worten, ich hätte gerne ein Array erstellt, in dem die Frequenzen für jede reale und imaginäre Komponente meiner FFT gespeichert sind.

Rango
quelle
Ich mache es in C # .net. Können Sie mir helfen?
Rango
9
Wenn Sie die Relevanz des Real- und Imaginärteils einer FFT nicht verstehen, erhalten Sie keine aussagekräftigen Ergebnisse. Suchen Sie daher nach TFT- und Signalverarbeitungs-Tutorials, um zu verstehen, wie die Ergebnisse zu interpretieren sind. Ich denke, es ist ziemlich wahrscheinlich, dass Sie für alles, wofür Sie es verwenden, die Größe der FFT oder der Leistungsspektraldichte wünschen.
the_mandrill
Danke dir! Ich möchte Spitzenfrequenzen für jeden Frame erhalten (Frame-Länge hängt von Fensterlänge und Shift-Länge ab)
Rango

Antworten:

350

Der erste Bin in der FFT ist DC (0 Hz), der zweite Bin ist Fs / N, wo Fsdie Abtastrate und Ndie Größe der FFT ist. Der nächste Behälter ist 2 * Fs / N. Um dies allgemein auszudrücken, ist der n-te Behälter n * Fs / N.

Wenn Ihre Abtastrate Fsbeispielsweise 44,1 kHz und Ihre FFT-Größe N1024 beträgt, befinden sich die FFT-Ausgangsfächer auf:

  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

Beachten Sie, dass für ein reales Eingangssignal (Imaginärteile alle Null) die zweite Hälfte der FFT (Bins von N / 2 + 1bis N - 1) keine nützlichen zusätzlichen Informationen enthält (sie haben eine komplexe konjugierte Symmetrie mit den ersten N / 2 - 1Bins). Der letzte nützliche Behälter (für praktische Anwendungen) befindet sich bei N / 2 - 1, was im obigen Beispiel 22006,9 Hz entspricht. Der Bin at N / 2repräsentiert Energie bei der Nyquist-Frequenz, dh Fs / 2(= 22050 Hz in diesem Beispiel), aber dies ist im Allgemeinen nicht von praktischem Nutzen, da Anti-Aliasing-Filter typischerweise alle Signale bei und darüber dämpfen Fs / 2.

Paul R.
quelle
8
Hinweis - die Antwort ist leicht falsch - der 512. Bucket enthält den Level für 22050, das Nyquist-Limit. Die Fächer 0 bis einschließlich N / 2 enthalten nützliche Werte.
David van Brink
4
Vielen Dank für die Bearbeitung und Klarstellung ... Ich denke, hier zeige ich einen Mangel an Praktikabilität. Ich: Aber Meister, FFT arbeitet bis zum Nyquist! Sie: Padawan, Sie sollten das wirklich herausfiltern.
David Van Brink
5
Ich wünschte, ich könnte Antworten mit Sternen versehen. Diese Antwort ist noch besser als die ursprüngliche Frage!
Skylion
14
@PaulR - Ich wollte mich bei Ihnen für diese wundervolle Antwort bedanken, die mir über die Jahre gedient hat. Ich würde diese Antwort besuchen, bevor ich ein StackOverflow-Konto hatte, und ich habe tatsächlich vergessen, mich bei Ihnen zu bedanken, sobald ich mich angemeldet habe. Ich habe mir kürzlich FFT-Sachen angesehen und mich an Ihre Antwort erinnert und sie gerade besucht. Als ich hier ankam, erinnerte ich mich daran, Ihnen zu danken ... also danke! Immer wenn ich mit jemandem über die Interpretation der einzelnen Punkte auf der horizontalen Achse der FFT diskutiere, verweise ich ihn einfach auf diesen Link.
Rayryeng
6
@rayryeng: Vielen Dank - ich denke, das ist die schönste Bestätigung, die ich je in ~ 5 Jahren der Beantwortung von Fragen hier auf SO erhalten habe!
Paul R
55

Schauen Sie sich hier meine Antwort an .

Antwort auf Kommentar:

Die FFT berechnet tatsächlich die Kreuzkorrelation des Eingangssignals mit Sinus- und Cosinusfunktionen (Basisfunktionen) in einem Bereich von gleich beabstandeten Frequenzen. Für einen bestimmten FFT-Ausgang gibt es eine entsprechende Frequenz (F), wie sie in der von mir geposteten Antwort angegeben ist. Der Realteil der Ausgangsabtastung ist die Kreuzkorrelation des Eingangssignals mit cos(2*pi*F*t)und der Imaginärteil ist die Kreuzkorrelation des Eingangssignals mit sin(2*pi*F*t). Der Grund, warum das Eingangssignal mit sinund cosFunktionen korreliert, besteht darin, Phasendifferenzen zwischen dem Eingangssignal und den Basisfunktionen zu berücksichtigen.

Indem Sie die Größe des komplexen FFT-Ausgangs nehmen, erhalten Sie ein Maß dafür, wie gut das Eingangssignal mit Sinuskurven bei einer Reihe von Frequenzen korreliert, unabhängig von der Eingangssignalphase. Wenn Sie nur den Frequenzinhalt eines Signals analysieren, nehmen Sie fast immer die Größe oder das Quadrat der Größe des komplexen Ausgangs der FFT.

Jason B.
quelle
Der Real- und Imaginärteil sind das Ergebnis von FFT, das für? Bitte erkläre es mir. Vielen Dank
Rango
5
Diese Antwort verdient mehr Liebe.
Heller Stern
1
Könnte es sein, dass die Größe der komplexen Ausgaben jeweils verdoppelt werden muss? (wenn ich meine Interpretation auf die untere Hälfte beschränke)
Wolf
18

Ich habe folgendes verwendet:

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));
}

Die Eingänge sind:

  • i: Bin zuzugreifen
  • samples: Abtastrate in Hertz (dh 8000 Hz, 44100 Hz usw.)
  • nFFT: Größe des FFT-Vektors
Roberto
quelle
7
Die Leute können nicht genau wissen, was Sie mit samplesoder darstellen nFFT. Bitte erläutern Sie dies.
Mostar
14
Die akzeptierte Antwort besagt, dass dies sein sollte i * samples / nFFT. Warum ist das Extra 2da? Vermisse ich etwas
Yati Sagade
13

Die FFT-Ausgangskoeffizienten (für komplexe Eingänge der Größe N) reichen von 0 bis N - 1 und sind als Frequenz [LOW, MID, HI, HI, MID, LOW] gruppiert.

Ich würde annehmen, dass das Element bei k die gleiche Frequenz wie das Element bei Nk hat, da für reale Daten FFT [Nk] = komplexes Konjugat von FFT [k] ist.

Die Reihenfolge des Scannens von LOW nach HIGH ist

0,

 1,
 N-1,

 2,
 N-2

 ...

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

 [N/2]

Es gibt [N / 2] +1 Frequenzgruppen vom Index i = 0 bis [N / 2], die jeweils die frequency = i * SamplingFrequency / N

Die Frequenz bei bin FFT [k] ist also:

if k <= [N/2] then k * SamplingFrequency / N
if k >= [N/2] then (N-k) * SamplingFrequency / N
robert.b
quelle
5

Die Frequenz Ihres k- ten FFT-Ergebnisses beträgt 2 * pi * k / N.

Neo
quelle
6
Ich denke, das wird im Bogenmaß sein
Barnaby