2012-02-26 13 views
32

मैं एक एफएफटी (scipy.fftpack.fftfreq के माध्यम से लिया गया) में आवृत्ति अक्ष को कैसे डिब्बे या आंशिक डिब्बे के बजाय हर्ट्ज में आवृत्ति में बदलना चाहता हूं।Scipy/Numpy FFT फ्रीक्वेंसी विश्लेषण

मैं FFT का परीक्षण करने के लिए नीचे दिए गए कोड करने के लिए करने की कोशिश की:

t = scipy.linspace(0,120,4000) 
acc = lambda t: 10*scipy.sin(2*pi*2.0*t) + 5*scipy.sin(2*pi*8.0*t) + 2*scipy.random.random(len(t)) 

signal = acc(t) 

FFT = abs(scipy.fft(signal)) 
FFT = scipy.fftpack.fftshift(FFT) 
freqs = scipy.fftpack.fftfreq(signal.size) 

pylab.plot(freqs,FFT,'x') 
pylab.show() 

नमूना दर 4000 नमूने/120 सेकंड = 33.34 नमूने/सेकंड होना चाहिए।

सिग्नल में 2.0 हर्ट्ज सिग्नल, एक 8.0 हर्ट्ज सिग्नल, और कुछ यादृच्छिक शोर है।

मैं एफएफटी लेता हूं, आवृत्तियों को पकड़ता हूं, और इसे साजिश देता हूं। संख्याएं सुंदर बकवास हैं। यदि मैं आवृत्तियों को 33.34 (नमूना आवृत्ति) से गुणा करता हूं, तो मुझे लगभग 8 हर्ट्ज और 15 हर्ट्ज पर चोटी मिलती है, जो गलत लगता है (भी, आवृत्तियों को 4 अलग-अलग कारक होना चाहिए, 2 नहीं!)।

क्या मैं यहां गलत क्या कर रहा हूं पर कोई विचार?

उत्तर

47

मुझे लगता है कि आप fftshift() करने की ज़रूरत नहीं है, और आप fftfreq लिए नमूना अवधि() पारित कर सकते हैं: ग्राफ से

import scipy 
import scipy.fftpack 
import pylab 
from scipy import pi 
t = scipy.linspace(0,120,4000) 
acc = lambda t: 10*scipy.sin(2*pi*2.0*t) + 5*scipy.sin(2*pi*8.0*t) + 2*scipy.random.random(len(t)) 

signal = acc(t) 

FFT = abs(scipy.fft(signal)) 
freqs = scipy.fftpack.fftfreq(signal.size, t[1]-t[0]) 

pylab.subplot(211) 
pylab.plot(t, signal) 
pylab.subplot(212) 
pylab.plot(freqs,20*scipy.log10(FFT),'x') 
pylab.show() 

आप 2 हर्ट्ज और 8Hz पर दो चोटी देखते हैं देख सकते हैं।

enter image description here

+1

इस तरह के एक पूर्ण उत्तर के लिए धन्यवाद। हाय, आपने एफएफटी के बजाय 20 * scipy.log10 (एफएफटी) प्लॉट क्यों चुना? – Archie1986

+0

एचवाईआरई ने आपको डीबी स्केल में वाई अक्ष के साथ एक साजिश प्रदान की, और 20log10 एक परिमाण स्पेक्ट्रम के लिए सही रूपांतरण प्रदान करता है। – OldTinfoil

6

प्रत्येक बिन की आवृत्ति चौड़ाई (sampling_freq/num_bins) है।

एक और मौलिक समस्या यह है कि आपकी नमूना दर ब्याज के संकेतों के लिए पर्याप्त नहीं है। आपकी नमूना दर 8.3 हर्ट्ज है; 8Hz इनपुट टोन कैप्चर करने के लिए आपको कम से कम 16 हर्ट्ज की आवश्यकता है।


सभी डीएसपी विशेषज्ञों के लिए 1.; मुझे पता है कि यह वास्तव में बीडब्ल्यू है जो प्रासंगिक है, अधिकतम आवृत्ति नहीं। लेकिन मुझे लगता है कि ओपी अंडरम्प्लेड डेटा अधिग्रहण नहीं करना चाहता है।

+0

मैं 120 सेकंड के लिए 4000 नमूने का उपयोग कर रहा हूं - क्या यह 33.3 हर्ट्ज नहीं है? यह इसके लिए पर्याप्त से अधिक होना चाहिए, और संख्याएं अभी भी बंद हैं ... –

+0

@asymptoticdesign: आह, ठीक है। आपके प्रश्न ने शुरुआत में 1000 कहा। हाँ, यह पर्याप्त होना चाहिए। कौन सी बिन इंडेक्स ऊर्जा दिखाई दे रही है? –

-2

आपका समीकरण गड़बड़ है।

fs = 33.33 
df1 = 2*pi * (2.0/fs) 
df2 = 2*pi * (5.0/fs) 
x = [10*sin(n*df1) + 5*sin(n*df2) + 2*random.random() for n in range(4000)] 

यह आपको अपनी समारोह के 4000 नमूने, 33.33 हर्ट्ज पर नमूना देता है, डेटा के 120 सेकंड का प्रतिनिधित्व।

अब अपना एफएफटी लें। बिन 0 डीसी परिणाम आयोजित करेगा। बिन 1 33.33 होगा, बिन 2 66.66 होगा, आदि ..

संपादित करें: मैं इसका उल्लेख करना भूल जाता हूं, क्योंकि आपकी नमूना दर 33.33 हर्ट्ज है, इसलिए अधिकतम आवृत्ति का प्रतिनिधित्व किया जा सकता है fs/2, या 16.665 हर्ट्ज।

+2

-1: नहीं। कुल बैंडविड्थ 33.33 हर्ट्ज है, प्रत्येक बिन की चौड़ाई नहीं। –

11

scipy.fftpack.fftfreq(n, d) आप आवृत्तियों सीधे देता है। यदि आप d=1/33.34 सेट करते हैं, तो यह आपको एफएफटी के प्रत्येक बिंदु के लिए Hz में आवृत्ति बताएगा।

संबंधित मुद्दे