2015-06-05 9 views
6

Ich bin Anfänger in der Signalverarbeitung, in dieser Frage möchte ich fragen, wie Energie für jedes Frequenzband um interessierte Frequenz F zu erhalten. Ich habe eine Formel gefunden, aber ich weiß nicht, wie man es in Python implementiert. Das ist die Formel, und meine Fourier-Transformations-Plot: enter image description hereBerechnen Energie für jedes Frequenzband um Frequenz F von Interesse in Python

x = np.linspace(0,5,100) 
y = np.sin(2*np.pi*x) 

## fourier transform 
f = np.fft.fft(y) 
## sample frequencies 
freq = np.fft.fftfreq(len(y), d=x[1]-x[0]) 
plt.plot(freq, abs(f)**2) ## will show a peak at a frequency of 1 as it should. 

enter image description here

+1

Sie sind so nah, was ist falsch mit 'sum (abs (f [Fd: F + d]) ** 2)'? – Mike

Antwort

0

das Signalverarbeitungsmodul Unter Verwendung von Finding local maxima/minima with Numpy in a 1D numpy array Sie folgende tun würde:

from scipy.signal import argrelextrema 
import numpy as np 

delta = 0.1 
F = 1 
X_delta = abs(freq - F) < delta 
A_f_delta = abs(f[X_delta])**2 
maximum_ix = argrelextrema(A_f, np.greater) 
E_F_delta = np.sum(A_f[maximum_ix])/2 
E_F_delta 
2453.8235776144866 
+0

Ich sehe nicht, wie dies die Frage beantwortet: die Energie E_F in der Formel summiert die quadrierten Fourier-Koeffizienten * um die Frequenz F *, über eine * Frequenzbreite * Delta. Was diese Antwort macht, ist völlig anders: sie beschränkt die Summe auf die genauen (ein Punkt) lokalen Maxima (es gibt kein Delta, sogar in dieser Lösung, so dass es nicht einmal funktionieren kann!). – EOL

+0

oy ok so fügte ich f und delta in meine Antwort ein, ich denke, dass es in meiner ersten Antwort implizit war ... es ist nicht erforderlich, die Frage zu beantworten, da es nur eine einzige Frequenz hat. – maxymoo

+1

Das ist gut, aber warum alle Zeilen, die bei 'maximum_ix' beginnen: Sie beantworten die Frage an der Zeile' A_f_delta = ... '(was in der ursprünglichen Frage eigentlich E_F genannt wird). Randnotiz: Mit Ihrer Argumentation über die einzelne Frequenz, die nur auf die Peaks hinweist, könnten Sie den ganzen Weg gehen und sogar alle quadrierten Amplituden addieren, da Ihr 'argrelextrema()' die einzigen nicht vernachlässigbaren Amplituden aufnimmt. Das wäre natürlich im allgemeinen Fall wegen des Satzes von Parseval ganz nutzlos (da das Ergebnis das gleiche wäre, als würde man dasselbe mit dem ursprünglichen Signal machen). – EOL

0

Sie sind fast da als Mike pointiert, aber hier ist ein anderer Ansatz, der einfacher zu verstehen ist. Sie können eine Variable setzen, die das gefilterte Signal enthält und ein 1d-Array von Af zurückgibt, und dann th anwenden e obige Formel, die ganz einfach (quadrierte Summe dieser Amplituden)

Filter aus den Signalen wie diese

from scipy.signal import butter, lfilter 
def butter_bandpass(lowcut, highcut, fs, order=5): 
    nyq = 0.5 * fs 
    low = lowcut/nyq 
    high = highcut/nyq 
    b, a = butter(order, [low, high], btype='band') 
    return b, a  
def butter_bandpass_filter(data, lowcut, highcut, fs, order=5): 
    b, a = butter_bandpass(lowcut, highcut, fs, order=order) 
    y = lfilter(b, a, data) 
    return y 

nun unter der Annahme y ist Ihr ursprüngliches Signal und Sie brauchen Energie von 5 Hz Komponente in Signal ist,

#let fs = 250 
#let order = 5 
oneD_array_of_amps_of_fiveHz_component = butter_bandpass_filter(y, 4, 6, 250, 5) 
#calculate energy like this 
energy_of_fiveHz_comp = sum([x*2 for x in oneD_array_of_amps_of_fiveHz_component]) 
Verwandte Themen