6.14. FFT¶
Fourierova transformace rozkládá signál v časové oblasti na jeho jednotlivé frekvenční složky. Rychlá Fourierova transformace (FFT) je standardní algoritmus pro její efektivní výpočet – důvod, proč tento modul existuje, a důvod, proč jsou na mikrokontroléru vůbec zvládnutelné transformace dostatečně dlouhé na to, aby byly užitečné (1024 bodů, 4096 bodů).
Na kameře je vstupem obvykle buffer rovnoměrně rozložených vzorků z mikrofonu, z osy akcelerometru, z proudového senzoru nebo z vibrační sondy; výstupem je spektrum, které aplikace následně zkoumá kvůli vrcholům, energii nebo příznakům pro klasifikátor.
numpy.fft poskytuje jednorozměrnou diskrétní Fourierovu transformaci. Tyto dvě funkce jsou fft() (dopředná) a ifft() (zpětná, normalizovaná hodnotou N).
Délka transformace musí být mocninou dvou. Jiné délky vyvolají ValueError. N = 256 a N = 1024 jsou běžné volby: dostatečně dlouhé pro použitelné frekvenční rozlišení při většině vestavěných vzorkovacích frekvencí, dostatečně krátké, aby se vešly do RAM a dokončily se s rezervou během jedné periody snímku.
fft() přijímá reálnou část vstupu jako svůj první poziční argument a volitelnou imaginární část jako druhý a vrací 2-tici (real, imag) reálných polí.
6.14.1. Reálný vstup, výstup velikosti (magnitudy)¶
Když aplikace předává pouze reálný vstup a potřebuje pouze spektrum velikostí (magnitud):
real, imag = np.fft.fft(x)
magnitude = np.sqrt(real * real + imag * imag)
Výsledkem je reálné ndarray o stejné délce jako vstup. Pomocná funkce spectrogram() dělá přesně toto bez mezilehlých alokací – správná volba uvnitř streamovací smyčky.
6.14.2. Zpětná transformace¶
ifft() je normalizována tak, aby celý cyklus vrátil původní vstup v rámci chyby pohyblivé řádové čárky. Oba volání přijímají a vracejí dvojici reálných polí:
real, imag = np.fft.fft(y)
re_back, im_back = np.fft.ifft(real, imag)
6.14.3. Nalezení dominantní frekvence¶
Běžným vzorem je nalezení největšího vrcholu v bufferu vzorků – zvuk, vibrace, modulované IR. Postup:
Zachyťte
Nvzorků, kdeNje mocnina dvou.Proveďte FFT.
Najděte bin s největší velikostí (magnitudou).
Převeďte index binu na Hz pomocí vzorkovací frekvence.
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")