سؤال

يعتمد هذا السؤال على أ سؤال مماثل سابق.

لدي المعادلة التالية ومعدل (بعض البيانات العشوائية): 0.44*sin (n*2*pi/30)

أحاول استخدام FFT للحصول على التردد من البيانات التي تم إنشاؤها. ومع ذلك ، ينتهي التردد بأنه قريب ولكن لا يساوي التردد (مما يجعل الموجة أكبر قليلاً من المقصود)

الترددات الموجودة في الحد الأقصى لـ FFT هي 7Hz ، ومع ذلك فإن التردد المتوقع هو (30/2PI) 4.77Hz.

لقد قمت بتضمين رسم بياني للقيم FFT والقيم المرسومة.

alt text

الرمز الذي أستخدمه هو:

[sampleFFTValues sFreq] = positiveFFT(sampledata, 1);
sampleFFTValues = abs(sampleFFTValues);
[v sFFTV]= max(sampleFFTValues)

يمكن أن يكون FFT الإيجابي وجدت هنا. في الأساس يركز الرسم البياني FFT ويقطع الإشارات السلبية.

سؤالي هو كيف يمكنني جعل FFT أكثر دقة دون الحاجة إلى اللجوء إلى المربعات الصغرى فقط من أجل التردد؟

هل كانت مفيدة؟

المحلول

لا أعتقد أن FFT مفيد لقياس التردد الدقيق للإشارات الدورية (شبه) - انظر أدناه.

انتشر كل FFT منفصل على ترددات بن غير eneger (أي على أي تردد لا يتوافق بالضبط مع واحدة من خطوات تردد FFT معينة) ؛ سيتم تلطيخ هذه الترددات "الوسيطة" حول أقرب صندوق عدد صحيح. يعتمد شكل انتشار هذا ("وظيفة الانتشار") على وظيفة الرياح المستخدمة في FFT. هذه وظيفة الانتشار - لتبسيط الأشياء وتعميمها - إما ضيقة للغاية ولكنها خشنة للغاية (قمم عالية جدًا/وديان منخفضة للغاية) ، أو أوسع ولكنها أقل خشونة. من الناحية النظرية ، يمكنك القيام بتكحف تردد جيد جدًا من موجات الجيب وحساب FFT لكل منها ، وبعد ذلك يمكنك "معايرة" شكل الوظيفة وسلوكها عن طريق حفظ مخرجات جميع FFT مع التردد الذي أدى إلى هذا الإخراج ، ثم بمقارنة إخراج FFT للإشارة المراد قياسها بالنتائج المحفوظة مسبقًا وإيجاد "الأقرب" الذي يجد ترددًا أكثر دقة.

الكثير من الجهد.

لكن لا تفعل هذا إذا كنت بحاجة فقط إلى قياس تردد إشارة واحدة.

بدلاً من ذلك ، حاول قياس الطول الموجي. يمكن أن يكون هذا بسيطًا مثل قياس المسافة بين الصلبان الصفر (ربما لدورات متعددة للحصول على مزيد من الدقة - heck ، وقياس 1000 دورة إذا كان لديك الكثير) في العينات ، وتقسيم معدل العينة على ذلك للوصول إلى التردد. أبسط بكثير وأسرع وأكثر دقة.

مثال: معدل العينة 48000 هرتز ، إشارة 4.77 هرتز تؤدي إلى دقة 0.0005 هرتز تقريبًا فقط عن طريق قياس طول واحد دورة مع أرقى النهج. (إذا أخذت ن دورات ، يتضاعف دقة التردد ن أيضًا.)

نصائح أخرى

كما ذكر الآخرين ، فإنك تسيء تفسير تواتر الإشارة. اسمحوا لي أن أعطي مثالا لمسح بعض الأشياء:

Fs = 200;                        %# sampling rate
t = 0:1/Fs:1-1/Fs;               %# time vector of 1 second 
f = 6;                           %# frequency of signal
x = 0.44*sin(2*pi*f*t);          %# sine wave

N = length(x);                   %# length of signal
nfft = N;                        %# n-point DFT, by default nfft=length(x)
                                 %# (Note: it is faster if nfft is a power of 2)
X = abs(fft(x,nfft)).^2 / nfft;  %# square of the magnitude of FFT

cutOff = ceil((nfft+1)/2);       %# nyquist frequency
X = X(1:cutOff);                 %# FFT is symmetric, take first half
X(2:end -1) = 2 * X(2:end -1);   %# compensate for the energy of the other half
fr = (0:cutOff-1)*Fs/nfft;       %# frequency vector

subplot(211), plot(t, x)
title('Signal (Time Domain)')
xlabel('Time (sec)'), ylabel('Amplitude')

subplot(212), stem(fr, X)
title('Power Spectrum (Frequency Domain)')
xlabel('Frequency (Hz)'), ylabel('Power')

time_frequency_domain

الآن يمكنك أن ترى أن الذروة في FFT تتوافق مع التردد الأصلي للإشارة في 6Hz

[v idx] = max(X);
fr(idx)
ans = 
      6

يمكننا حتى التحقق من ذلك نظرية بارسيفال يحمل:

( sum(x.^2) - sum(X) )/nfft < 1e-6

الخيار 2

بدلاً من ذلك ، يمكننا استخدام وظائف صندوق أدوات معالجة الإشارات:

%# estimate the power spectral density (PSD) using the periodogram
h = spectrum.periodogram;
hopts = psdopts(h);
set(hopts, 'Fs',Fs, 'NFFT',nfft, 'SpectrumType','onesided')

hpsd = psd(h, x, hopts);
figure, plot(hpsd)

Pxx = hpsd.Data;
fr = hpsd.Frequencies;
[v idx]= max(Pxx)
fr(idx)

avgpower(hpsd)

periodogram

لاحظ أن هذه الوظيفة تستخدم مقياس لوغاريتمي: plot(fr,10*log10(Pxx)) بدلاً من plot(fr,Pxx)

على افتراض أن n هو الوقت بالثواني ، فإن ترددك هو 1/30 هرتز (y=A * sin( 2* PI * f * t))

دقة التردد = نقاط معدل العينة / FFT

يتم تحديد معدل العينة من قبل Nyquist Criterium ، يجب أن يكون معدل العينة (العينات/الثانية) مرتين على الأقل مرتين على الأقل من التردد الذي يتعين تحليله ، على سبيل المثال 48 كيلو هرتز لتحليل ما يصل إلى 24 كيلو هرتز. (لبيانات "الحياة الحقيقية" ، من الجيد أن يكون لديك القليل من المخزن المؤقت).

لذلك ، قد تحتاج إلى زيادة حجم FFT الخاص بك.

ما تبحث عنه هو طريقة تقدير التردد ، وهناك الكثير. FFT هو مكون واحد من عدة طرق تقدير. فقط باستخدام صندوق ذروة الحجم ، كما هو الحال في مثالك ، يمنحك أسوأ دقة (ولكن أكبر مناعة للضوضاء لأي جيوب جيب دورية أخرى). في مواقف الضوضاء المنخفضة ، يمكنك أن تتنازل. الاستيفاء المكافئ لحجم السجل هو أحد المقرر المشترك ، ولكن قد يكون التزامن من نتائج FFT أفضل لنافذة مستطيلة. تعادل الصفر والقيام بـ FFT أطول هو ما يعادل الاستيفاء.

للحصول على الجيوب الأنفية الدقيقة في ضوضاء صفر ، ننسى FFT ، وحل المعادلة فقط في 3 مجهول ، والتي قد تنطوي على أقل من 3 أو 4 نقاط عينة غير محلية ، خوارزميات للقيام بذلك هنا و هنا.

أنا أدرج بعض طرق تقدير التردد الأخرى على بلدي صفحة الويب DSP.

إذا كنت تولد من وظيفة ، مقابل العمل مع العينات ، يمكنك إنشاء الكثير من النقاط وتشغيل FFT كبير بحيث تكون صناديق التردد صغيرة جدًا لدقة عالية. لكنه لن يحل المشكلة الأساسية.

أولاً ، تصحيح لسؤالك: (30/2PI) ليس التردد. تردد الإشارة الخاص بك هو 1/30 * مهما كان معدل أخذ العينات الذي استخدمته. ثانياً ، هل يمكن أن تخبرني ما هو طول ناقل Sampledata؟ عندما تُرجع FFT متجهًا من القيم ، ستتوافق قيمة ITH مع f_i = i/n حيث يكون n طول المتجه و I in [0 ، n-1] تريد i/n إلى 1/30 تمامًا لبعض عدد صحيح أنا. وبعبارة أخرى ، يجب أن تساوي n 30*i ، أي ، يجب أن تكون n مضاعفة 30. الآن ، هل كان طول المتجه الذي استخدمته ، مضاعف 30؟ إذا لم تحاول القيام بذلك ، وينبغي أن يحل المشكلة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top