Hanning Window

Gast #1130068
Hallo @ all.

Ich habe eine FFT programmiert. Jedoch noch ohne Fensterung. Hierzu habe 
ich einige Fragen:

1. Muss ich die Fensterung z.B. Hanning Window mit dem abgetasteten 
diskreten Signal multiplizieren?

2. Wo bekomme ich die Koeffizienten für das Hamming Window her?

3. Wie rechne ich aus dem Ergebnis der FFT (Betrag aus Real und 
Imaginärteil )die Fensterung wieder raus.
Persönliche Seite #1130328
Johann wrote:
> 1. Muss ich die Fensterung z.B. Hanning Window mit dem abgetasteten
> diskreten Signal multiplizieren?

Du meinst das Hann-Fenster. Es gibt "Hamming", "(von) Hann" - aber nicht 
"Hanning". Ja, du multiplizierst die Abgetasteten Werte (den 
Signalausschnitt der Länge N) mit einer Gewichtungsfunktion der Länge N.

  weighted(n) = original(n) * window(n) (für n = 0..N-1)

> 2. Wo bekomme ich die Koeffizienten für das Hamming Window her?

Aus der Bildungsvorschrift:

  http://de.wikipedia.org/wiki/Fensterfunktion#von-Hann-Fenster_.28auch_bekannt_als_.E2.80.9ERaised-Cosinus-Fenster.E2.80.9C.29

> 3. Wie rechne ich aus dem Ergebnis der FFT (Betrag aus Real und
> Imaginärteil )die Fensterung wieder raus.

Wozu? Im Spektrum ist die Transformierte der Gewichtungsfunktion in das 
"ursprüngliche" Spektrum gefaltet (vgl. "Leck-Effekt"). Das ist genauso 
gewollt und je nachdem welche Gewichtungsfunktion man wählt hat man auf 
der einen Seite gewisse Vorteile die man sich durch Abstriche an anderen 
Stellen erkauft (z.B. amplitudengenaues vs. frequenzgenaues Spektrum).
Gast #2354500
T. H. schrieb:
> z.B. amplitudengenaues vs. frequenzgenaues Spektrum

Welche Möglichkeiten gäbe es, diese Aspekte zu kombinieren?

Also wie kann ich "fenstern" um z.B. sehr genaue Amplituden und 
andererseits sehr genau Frequenzen zu bekommen?

Und: Was bedeutet "frequenzgenau"?
Persönliche Seite #2361765
Johann schrieb:
> Wo bekomme ich die Koeffizienten für das Hamming Window her?

Hann ist eine einfache Sinus-Funktion, passend verschoben und als Glocke 
genutzt. Hamming ist ähnlich, leicht gestaucht und etwas angehoben- ein 
Kompromiss zwischen geringem Leckeffekt und Repräsentanz der 
Spektrallinien. Schau Dir auch mal die Gauss-Funktion an, sowie das 
blackman-Fenster.
Gast #2512915
...ich habe das mal eben aus einem uralten Programm meiner selbst 
rausge-
copy-pasted, ohne dass ich das Wochenende darauf verwenden will.

Du brauchst irgendwo
#define SQUARE 1
#define Parzen 2 usw...

Die Funktion erzeugt einen Buffer, dessen Inhalt mit dem Eingabevektor
der FFT multipliziert werden muss, Position für Position. Nach der
Vektor-Mul muss der Eingabepuffer für die FFT in der Mitte große
Zahlen haben & an Anfang & Ende kleine.
Der Buffer time_window muss natürlich genauso groß sein wie Deine
FFT-Daten.

Gruß, Gerhard



-----------------------------

/* Berechnen einer Fensterfunktion. Die Werte werden im Gleitkomma-Array
 * window[0..npoints-1] abgelegt.
 */

void mk_window(int wtype, int win_size) {
  double f;
  int j;
  switch(wtype){
    case SQUARE:
    /* statt 0.999 waere eigentlich 1.0 korrekt, so werden aber
     * eventuelle Rundungsfehler beim Uebergang zu Integers harmlos 
gemacht.
     */
    for(j=0; j<win_size; j++) time_window[j] = 0.999;
    break;

    case PARZEN:
    for(j=0; j<win_size; j++){
      time_window[j] =
          1.0 - ( fabs( (j - 0.5 * (win_size-1)) / ( 0.5 * 
(win_size+1))));
    }
    break;

    case WELCH:
    for(j=0; j<win_size; j++){
      f= j - 0.5 * (win_size-1);
      f = f / ( 0.5 * (win_size + 1));
      time_window[j] = 1 - f * f;
    }
    break;

    case HANN:
    for(j=0; j<win_size; j++){
      time_window[j] = 0.5 * ( 1 - cos( 2  pi  j / (win_size-1)));
    }
    break;

    case HAMMING:
    for(j=0; j<win_size; j++){
      time_window[j] = 0.54 -0.46 * cos( 2  pi  j / (win_size-1));
    }
    break;

    case BLACKMAN:
    for(j=0; j<win_size; j++){
      time_window[j] = 0.42
                 - 0.5  * cos( 2  pi  j / (win_size-1))
               + 0.08 * cos( 4  pi  j / (win_size-1));
    }
    break;
    case BLACKMAN_HARRIS:
    for(j=0; j<win_size; j++){
      time_window[j] = 0.35875
               - 0.48829 * cos( 2  pi  j / (win_size-1))
               + 0.14128 * cos( 4  pi  j / (win_size-1))
             - 0.01168 * cos( 6  pi  j / (win_size-1));
    }
    break;
  }
} /* mk_window() */
Gast #2512920
Ich hab' keine Ahnung wieso beim copy&paste aus "2 * pi *j" und so
die Sternchen entfernt wurden. Dafür wird PI fett angezeigt.
Abweichend vom Kommentar heißt der Buffer time_window und nicht window.

Gruß, Gerhard

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 17 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.