6.14. FFT

Uma transformada de Fourier decompõe um sinal no domínio do tempo nas suas frequências constituintes. A transformada rápida de Fourier (FFT) é o algoritmo padrão para a calcular de forma eficiente – a razão pela qual este módulo existe, e a razão pela qual transformadas suficientemente longas para serem úteis (1024 pontos, 4096 pontos) são viáveis num microcontrolador.

Numa câmara, a entrada é tipicamente um buffer de amostras igualmente espaçadas provenientes 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 inspeciona posteriormente em busca de picos, energia ou características para classificação.

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

O comprimento da transformada tem de ser uma potência de dois. Outros comprimentos levantam ValueError. N = 256 e N = 1024 são escolhas comuns: compridos o suficiente para uma resolução de frequência utilizável às taxas de amostragem embarcadas mais comuns, curtos o suficiente para caber na RAM e terminar bem dentro de um período de fotograma.

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

6.14.1. Entrada real, saída de magnitude

Quando a aplicação apenas fornece entrada real e apenas necessita do espectro de magnitude:

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

O resultado é um ndarray real com o mesmo comprimento que a entrada. O auxiliar spectrogram() faz exatamente isto sem as alocações intermédias – a chamada certa dentro de um ciclo de processamento contínuo.

6.14.2. Transformada inversa

ifft() é normalizada para que a ida e volta devolva a entrada original dentro do erro de vírgula flutuante. Ambas as chamadas recebem e devolvem um par de arrays reais:

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

6.14.3. Encontrar a frequência dominante

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

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

  2. Calcular a FFT.

  3. Encontrar o bin com a maior magnitude.

  4. Converter 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")