6.14. FFT

Uma transformada de Fourier decompõe um sinal no domínio do tempo em suas frequências constituintes. A transformada rápida de Fourier (FFT) é o algoritmo padrão para computá-la de forma eficiente – a razão de existir deste módulo e o motivo pelo qual transformadas longas o suficiente para serem úteis (1024 pontos, 4096 pontos) são tratáveis em um microcontrolador.

Em uma câmera, a entrada é tipicamente um buffer de amostras igualmente espaçadas vindas de um microfone, de um eixo de acelerômetro, de um sensor de corrente ou de uma sonda de vibração; a saída é um espectro que a aplicação então inspeciona em busca de picos, energia ou características para um classificador.

numpy.fft fornece a transformada discreta de Fourier unidimensional. As duas funções são fft() (direta) e ifft() (inversa, normalizada por N).

O comprimento da transformada deve ser uma potência de dois. Outros comprimentos lançam ValueError. N = 256 e N = 1024 são escolhas comuns: longas o suficiente para uma resolução de frequência utilizável na maioria das taxas de amostragem embarcadas, curtas o suficiente para caber na RAM e terminar bem dentro de um único período de quadro.

fft() recebe a parte real da entrada como seu primeiro argumento posicional e uma parte imaginária opcional como o segundo, e retorna uma 2-tupla (real, imag) de arrays reais.

6.14.1. Entrada real, saída de magnitude

Quando a aplicação só fornece entrada real e só precisa do espectro de magnitude:

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

O resultado é um ndarray real do mesmo comprimento da entrada. O auxiliar spectrogram() faz exatamente isso sem as alocações intermediárias – a chamada certa dentro de um laço de streaming.

6.14.2. Transformada inversa

ifft() é normalizada de modo que a ida e volta retorne a entrada original dentro do erro de ponto flutuante. Ambas as chamadas recebem e retornam um par de arrays reais:

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

6.14.3. Encontrando a frequência dominante

Um padrão comum é localizar o maior pico em um buffer de amostras – áudio, vibração, IR modulado. A receita:

  1. Capture N amostras, com N sendo uma potência de dois.

  2. Calcule a FFT.

  3. Encontre o bin com a maior magnitude.

  4. Converta o índice do bin para Hz usando a taxa de amostragem.

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