6.14. FFT

Une transformée de Fourier décompose un signal du domaine temporel en ses fréquences constitutives. La transformée de Fourier rapide (FFT) est l’algorithme standard pour la calculer efficacement – la raison d’être de ce module, et la raison pour laquelle des transformées suffisamment longues pour être utiles (1024 points, 4096 points) sont en premier lieu réalisables sur un microcontrôleur.

Sur une caméra, l’entrée est généralement un tampon d’échantillons régulièrement espacés provenant d’un microphone, d’un axe d’accéléromètre, d’un capteur de courant ou d’une sonde de vibration ; la sortie est un spectre que l’application examine ensuite pour y trouver des pics, de l’énergie ou des caractéristiques pour un classificateur.

numpy.fft fournit la transformée de Fourier discrète à une dimension. Les deux fonctions sont fft() (directe) et ifft() (inverse, normalisée par N).

La longueur de la transformée doit être une puissance de deux. Les autres longueurs lèvent ValueError. N = 256 et N = 1024 sont des choix courants : assez longs pour offrir une résolution en fréquence utilisable à la plupart des fréquences d’échantillonnage embarquées, assez courts pour tenir en RAM et se terminer bien à l’intérieur d’une période de trame.

fft() prend la partie réelle de l’entrée comme premier argument positionnel et une partie imaginaire facultative comme second, et renvoie un 2-uplet (real, imag) de tableaux réels.

6.14.1. Entrée réelle, sortie en magnitude

Lorsque l’application ne fournit qu’une entrée réelle et n’a besoin que du spectre de magnitude

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

Le résultat est un ndarray réel de la même longueur que l’entrée. La fonction utilitaire spectrogram() fait exactement cela sans les allocations intermédiaires – le bon appel à l’intérieur d’une boucle de traitement en continu.

6.14.2. Transformée inverse

ifft() est normalisée de sorte que l’aller-retour restitue l’entrée d’origine à l’erreur de virgule flottante près. Les deux appels prennent et renvoient une paire de tableaux réels

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

6.14.3. Trouver la fréquence dominante

Un schéma courant consiste à localiser le plus grand pic dans un tampon d’échantillons – audio, vibration, infrarouge modulé. La recette :

  1. Capturer N échantillons, avec N une puissance de deux.

  2. Calculer la FFT.

  3. Trouver le bin de plus grande magnitude.

  4. Convertir l’indice du bin en Hz à l’aide de la fréquence d’échantillonnage.

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")