6.14. FFT

Biến đổi Fourier phân tích một tín hiệu trong miền thời gian thành các tần số cấu thành. Biến đổi Fourier nhanh (FFT) là thuật toán tiêu chuẩn để tính toán hiệu quả -- đó là lý do module này tồn tại, và lý do các phép biến đổi đủ dài để hữu ích (1024 điểm, 4096 điểm) có thể thực hiện được trên vi điều khiển.

Trên camera, đầu vào thường là một bộ đệm các mẫu cách đều nhau từ microphone, một trục gia tốc kế, một cảm biến dòng điện, hoặc một đầu dò rung động; đầu ra là phổ tần số mà ứng dụng kiểm tra để tìm đỉnh, năng lượng, hoặc các đặc trưng của bộ phân loại.

numpy.fft cung cấp biến đổi Fourier rời rạc một chiều. Hai hàm là fft() (thuận) và ifft() (nghịch, chuẩn hóa theo N).

Độ dài biến đổi phải là lũy thừa của hai. Các độ dài khác sẽ phát sinh ValueError. N = 256N = 1024 là các lựa chọn phổ biến: đủ dài để có độ phân giải tần số sử dụng được ở hầu hết các tốc độ lấy mẫu nhúng, đủ ngắn để vừa trong RAM và hoàn thành trong một chu kỳ khung hình.

fft() nhận phần thực của đầu vào làm đối số vị trí đầu tiên và phần ảo tùy chọn làm đối số thứ hai, và trả về một tuple 2 phần tử (real, imag) gồm các mảng thực.

6.14.1. Đầu vào thực, đầu ra biên độ

Khi ứng dụng chỉ cung cấp đầu vào thực và chỉ cần phổ biên độ:

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

Kết quả là một ndarray thực có cùng độ dài với đầu vào. Hàm trợ giúp spectrogram() thực hiện đúng điều này mà không cần cấp phát trung gian -- đây là lệnh gọi đúng đắn trong một vòng lặp truyền phát.

6.14.2. Biến đổi nghịch

ifft() được chuẩn hóa sao cho vòng khứ hồi trả về đầu vào ban đầu trong phạm vi sai số dấu phẩy động. Cả hai lệnh gọi đều nhận và trả về một cặp mảng thực:

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

6.14.3. Tìm tần số chiếm ưu thế

Một mẫu phổ biến là xác định đỉnh lớn nhất trong một bộ đệm các mẫu -- âm thanh, rung động, hồng ngoại điều chế. Công thức:

  1. Thu thập N mẫu, với N là lũy thừa của hai.

  2. Thực hiện FFT.

  3. Tìm bin có biên độ lớn nhất.

  4. Chuyển đổi chỉ số bin sang Hz sử dụng tốc độ lấy mẫu.

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