6.14. FFT

Fourierova transformacija rastavlja signal u vremenskoj domeni na njegove sastavne frekvencije. Brza Fourierova transformacija (FFT) standardni je algoritam za njezino učinkovito izračunavanje – razlog zbog kojeg ovaj modul postoji i razlog zbog kojeg su transformacije dovoljno duge da budu korisne (1024 točke, 4096 točaka) uopće izvedive na mikrokontroleru.

Na kameri je ulaz tipično međuspremnik jednoliko raspoređenih uzoraka iz mikrofona, osi akcelerometra, senzora struje ili vibracijske sonde; izlaz je spektar koji aplikacija potom ispituje radi vrhova, energije ili značajki za klasifikator.

numpy.fft pruža jednodimenzionalnu diskretnu Fourierovu transformaciju. Dvije su funkcije fft() (unaprijedna) i ifft() (inverzna, normalizirana s N).

Duljina transformacije mora biti potencija broja dva. Druge duljine izazivaju ValueError. N = 256 i N = 1024 česti su izbori: dovoljno dugi za upotrebljivu frekvencijsku razlučivost pri većini ugrađenih brzina uzorkovanja, a dovoljno kratki da stanu u RAM i završe znatno unutar jednog razdoblja sličice.

fft() uzima realni dio ulaza kao prvi pozicijski argument i neobavezni imaginarni dio kao drugi te vraća 2-torku (real, imag) realnih polja.

6.14.1. Realni ulaz, izlaz magnitude

Kada aplikacija dovodi samo realni ulaz i treba samo spektar magnitude:

real, imag = np.fft.fft(x)
magnitude  = np.sqrt(real * real + imag * imag)

Rezultat je realni ndarray iste duljine kao ulaz. Pomoćna funkcija spectrogram() radi upravo to bez međudodjela memorije – pravi poziv unutar petlje za tok podataka.

6.14.2. Inverzna transformacija

ifft() je normalizirana tako da povratni put vraća izvorni ulaz unutar pogreške aritmetike s pomičnim zarezom. Oba poziva uzimaju i vraćaju par realnih polja:

real, imag       = np.fft.fft(y)
re_back, im_back = np.fft.ifft(real, imag)

6.14.3. Pronalaženje dominantne frekvencije

Čest obrazac je lociranje najvećeg vrha u međuspremniku uzoraka – zvuk, vibracije, modulirano IR. Recept:

  1. Snimite N uzoraka, gdje je N potencija broja dva.

  2. Izračunajte FFT.

  3. Pronađite spremnik s najvećom magnitudom.

  4. Pretvorite indeks spremnika u Hz koristeći brzinu uzorkovanja.

from ulab import numpy as np

N  = 1024
fs = 8000.0                       # sample rate, Hz

# ... fill ``samples`` with N data points ...

real, imag = np.fft.fft(samples)
spectrum   = np.sqrt(real * real + imag * imag)

half      = spectrum[:N // 2]     # only first half is meaningful
peak_bin  = np.argmax(half)
peak_hz   = peak_bin * fs / N

print("peak at", peak_hz, "Hz")