ตัวกรองความถี่ต่ำและ FFT สำหรับผู้เริ่มต้นด้วย Python


23

ฉันใหม่กับการประมวลผลสัญญาณและโดยเฉพาะอย่างยิ่งกับ FFT ดังนั้นฉันไม่แน่ใจว่าฉันกำลังทำสิ่งที่ถูกต้องที่นี่และฉันสับสนเล็กน้อยกับผลลัพธ์

ฉันมีฟังก์ชั่นจริงที่ไม่ต่อเนื่อง (ข้อมูลการวัด) และต้องการตั้งค่าตัวกรองความถี่ต่ำผ่านในนั้น เครื่องมือที่เลือกคือ Python พร้อมแพ็คเกจ numpy ฉันทำตามขั้นตอนนี้:

  • คำนวณค่า fft ของฟังก์ชั่นของฉัน
  • ตัดความถี่สูง
  • ดำเนินการ fft ผกผัน

นี่คือรหัสที่ฉันใช้:

import numpy as np
sampling_length = 15.0*60.0 # measured every 15 minutes
Fs = 1.0/sampling_length
ls = range(len(data)) # data contains the function
freq = np.fft.fftfreq(len(data), d = sampling_length)
fft = np.fft.fft(data)
x = freq[:len(data)/2] 
for i in range(len(x)):
if x[i] > 0.005: # cut off all frequencies higher than 0.005
    fft[i] = 0.0
    fft[len(data)/2 + i] = 0.0
inverse = np.fft.ifft(fft)

นี่เป็นขั้นตอนที่ถูกต้องหรือไม่? ผลลัพธ์inverseมีค่าที่ซับซ้อนซึ่งทำให้ฉันสับสน


1
เมื่อฉันเรียนรู้ FFT ฉันพบว่าการโพสต์บล็อกนี้มีประโยชน์มาก glowingpython.blogspot.com/2011/08/…
David Poole

คำตอบ:


23

ความจริงที่ว่าผลลัพธ์มีความซับซ้อนเป็นที่คาดหวัง ฉันต้องการชี้ให้เห็นสองสิ่ง:

คุณกำลังใช้ตัวกรองโดเมนความถี่กำแพงอิฐกับข้อมูลพยายามเป็นศูนย์เอาท์พุท FFT ทั้งหมดที่สอดคล้องกับความถี่มากกว่า 0.005 Hz จากนั้นเปลี่ยนอินเวอร์สเพื่อรับสัญญาณโดเมนเวลาอีกครั้ง เพื่อให้ผลที่ตามมาจะเป็นจริงแล้วการป้อนข้อมูลเพื่อ FFT ผกผันต้องสมมาตรผัน ซึ่งหมายความว่าสำหรับความยาว - FFTยังไม่มีข้อความ

X[k]=X* * * *[ยังไม่มีข้อความ-k],k=1,2,...,ยังไม่มีข้อความ2-1(ยังไม่มีข้อความอีโวลต์อีn)

X[k]=X* * * *[ยังไม่มีข้อความ-k],k=1,2,...,ยังไม่มีข้อความ2(ยังไม่มีข้อความโอdd)
  • โปรดทราบว่าสำหรับสม่ำเสมอX [ 0 ]และX [ Nยังไม่มีข้อความX[0]ไม่เท่ากันโดยทั่วไป แต่มีทั้งจริง สำหรับคี่N,X[0]ต้องเป็นของจริงX[ยังไม่มีข้อความ2]ยังไม่มีข้อความX[0]

ฉันเห็นว่าคุณพยายามทำสิ่งนี้ในรหัสของคุณด้านบน แต่ก็ไม่ถูกต้องนัก หากคุณบังคับใช้เงื่อนไขข้างต้นกับสัญญาณที่คุณส่งไปยัง FFT ผกผันคุณควรได้รับสัญญาณจริง

sผมn(x)sผมn

sผมn

พล็อตของฟังก์ชัน sinc

sผมnsผมn

มีวิธีปฏิบัติที่เป็นประโยชน์มากกว่าสำหรับการใช้ตัวกรอง lowpass ทั้งในโดเมนเวลาและความถี่ การตอบสนองแบบอิมพัลส์แบบ จำกัดและฟิลเตอร์การตอบสนองแบบอิมพัลส์แบบไม่ จำกัดสามารถใช้โดยตรงโดยใช้การแทนสมการผลต่าง หรือหากตัวกรองของคุณมีการตอบสนองต่อแรงกระตุ้นอย่างเพียงพอคุณมักจะได้รับประโยชน์ด้านประสิทธิภาพโดยใช้เทคนิคการแปลงอย่างรวดเร็วตาม FFT (ใช้ตัวกรองโดยการคูณในโดเมนความถี่แทนที่จะเป็นข้อตกลงในโดเมนเวลา) เช่นการทับซ้อน ประหยัดและทับซ้อนกันเพิ่มวิธีการ


ฟังก์ชั่น sinc เป็นการกรองในอุดมคติใช่ไหม นั่นคือสิ่งที่ตัวกรองอื่น ๆ ทั้งหมดตั้งเป้าไว้ แต่ไม่ประสบความสำเร็จ มันไม่ดีสำหรับการประมวลผลภาพเพราะภาพนั้นไม่ได้ลดรอยหยักก่อนดังนั้นมันจึงสร้างเสียงเรียกเข้าซึ่งดูแย่มาก แต่สำหรับเสียงหรือสัญญาณอื่น ๆ ที่ถูกกรองก่อนที่จะทำการสุ่มตัวอย่างมันเป็นตัวกรองที่ดีที่สุดหรือไม่?
endolith

1
ใช่ผลลัพธ์ของฉันไม่ได้สมมาตรกัน ฉันแก้ไขรหัสตอนนี้ทุกอย่างทำงานได้ดี ขอขอบคุณ!
จนถึง

3
@endolith - a Sinc เป็น interpolator ในอุดมคติสำหรับการแก้ไขชนิดต่าง ๆ แต่สามารถอยู่ห่างจากอุดมคติในการเป็นตัวกรองสำหรับความต้องการตัวกรองทั่วไปส่วนใหญ่เช่นความเรียบของการตอบสนองผ่านแถบหยุดวงปฏิเสธและอื่น ๆ
hotpaw2

+1 สำหรับคำอธิบายที่ดีเกี่ยวกับ "ทำไมผู้คนไม่ใช้ตัวกรองตามที่สั่ง"
การพนัน Sibbs

คุณต้องใช้ sinc แบบมีหน้าต่าง หากคุณไม่มีเวลา จำกัด นี่คือตัวกรองที่ดีที่สุดซึ่งดีกว่า Chebichev
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.