6.14. FFT¶
การแปลงฟูเรียร์ (Fourier transform) จะแยกสัญญาณในโดเมนเวลาออกเป็นความถี่ส่วนประกอบต่าง ๆ การแปลงฟูเรียร์แบบเร็ว (FFT) คืออัลกอริทึมมาตรฐานสำหรับการคำนวณนี้อย่างมีประสิทธิภาพ ซึ่งเป็นเหตุผลที่โมดูลนี้มีอยู่ และเป็นเหตุผลที่การแปลงที่มีความยาวเพียงพอสำหรับการใช้งานจริง (1024 จุด, 4096 จุด) สามารถทำได้บนไมโครคอนโทรลเลอร์
สำหรับกล้อง อินพุตมักจะเป็นบัฟเฟอร์ของตัวอย่างที่เว้นระยะห่างเท่ากันจากไมโครโฟน แกนของมาตรวัดความเร่ง เซนเซอร์กระแสไฟ หรืออุปกรณ์ตรวจจับการสั่นสะเทือน ส่วนเอาต์พุตคือสเปกตรัมที่แอปพลิเคชันตรวจสอบหาจุดสูงสุด พลังงาน หรือลักษณะเด่นสำหรับตัวจำแนกประเภท
numpy.fft ให้การแปลงฟูเรียร์แบบแยกส่วนหนึ่งมิติ ฟังก์ชันทั้งสองคือ fft() (ไปข้างหน้า) และ ifft() (ผกผัน ทำให้เป็นมาตรฐานโดย N)
ความยาวของการแปลงต้องเป็นกำลังของสอง ความยาวอื่น ๆ จะทำให้เกิด ValueError โดย N = 256 และ N = 1024 เป็นตัวเลือกทั่วไป ยาวพอสำหรับความละเอียดความถี่ที่ใช้งานได้ในอัตราการสุ่มตัวอย่างแบบฝังตัวส่วนใหญ่ และสั้นพอที่จะพอดีกับ RAM และเสร็จสิ้นภายในเวลาหนึ่งช่วงเฟรม
fft() รับส่วนจริงของอินพุตเป็นอาร์กิวเมนต์เชิงตำแหน่งแรก และส่วนจินตภาพเป็นตัวเลือกที่สอง แล้วคืนค่าเป็น 2-tuple (real, imag) ของอาร์เรย์จริง
6.14.1. อินพุตจริง เอาต์พุตขนาด¶
เมื่อแอปพลิเคชันป้อนอินพุตจริงเท่านั้นและต้องการเฉพาะสเปกตรัมขนาด:
real, imag = np.fft.fft(x)
magnitude = np.sqrt(real * real + imag * imag)
ผลลัพธ์คือ ndarray จริงที่มีความยาวเท่ากับอินพุต ฟังก์ชันช่วยเหลือ spectrogram() ทำสิ่งนี้โดยไม่มีการจัดสรรหน่วยความจำกลาง ซึ่งเป็นการเรียกที่ถูกต้องภายในลูปการสตรีม
6.14.2. การแปลงผกผัน¶
ifft() ถูกทำให้เป็นมาตรฐานเพื่อให้การเดินทางไปกลับคืนอินพุตเดิมภายในข้อผิดพลาดทศนิยม ทั้งสองการเรียกรับและคืนค่าคู่ของอาร์เรย์จริง:
real, imag = np.fft.fft(y)
re_back, im_back = np.fft.ifft(real, imag)
6.14.3. การหาความถี่ที่โดดเด่น¶
รูปแบบทั่วไปคือการหาจุดสูงสุดที่ใหญ่ที่สุดในบัฟเฟอร์ของตัวอย่าง ไม่ว่าจะเป็นเสียง การสั่นสะเทือน หรือ IR แบบมอดูเลต สูตร:
จับตัวอย่าง
Nรายการ โดยที่Nเป็นกำลังของสองทำ FFT
หาถังที่มีขนาดใหญ่ที่สุด
แปลงดัชนีถังเป็น Hz โดยใช้อัตราการสุ่มตัวอย่าง
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")