2016-09-30 2 views
3

Ich möchte eine Frequenz (eine Spitze) aus dem Signal entfernen und meine Funktion ohne sie grafisch darstellen. Nach fft habe ich Frequenz und Amplitude gefunden und bin mir nicht sicher, was ich jetzt machen soll. Zum Beispiel möchte ich meine höchste Spitze entfernen (markiert mit rotem Punkt in der Zeichnung).So entfernen Sie die Frequenz vom Signal

import numpy as np 
import matplotlib.pyplot as plt 

# create data 
N = 4097 
T = 100.0 
t = np.linspace(-T/2,T/2,N) 
f = np.sin(50.0 * 2.0*np.pi*t) + 0.5*np.sin(80.0 * 2.0*np.pi*t) 

#plot function 
plt.plot(t,f,'r') 
plt.show() 

# perform FT and multiply by dt 
dt = t[1]-t[0] 
ft = np.fft.fft(f) * dt  
freq = np.fft.fftfreq(N, dt) 
freq = freq[:N/2+1] 
amplitude = np.abs(ft[:N/2+1]) 
# plot results 
plt.plot(freq, amplitude,'o-') 
plt.legend(('numpy fft * dt'), loc='upper right') 
plt.xlabel('f') 
plt.ylabel('amplitude') 
#plt.xlim([0, 1.4]) 


plt.plot(freq[np.argmax(amplitude)], max(amplitude), 'ro') 
print "Amplitude: " + str(max(amplitude)) + " Frequency: " + str(freq[np.argmax(amplitude)]) 

plt.show() 
+2

müssen Sie das Signal filtern. Welche Art von Filter und wie Sie ihn konfigurieren, hängt davon ab, welche Frequenzen Sie behalten möchten und welche Sie entfernen möchten. Vielleicht möchten Sie sich ein Intro zum DSP-Buch besorgen oder hier starten: https://en.wikipedia.org/wiki/Filter_(signal_processing) – Turn

+0

Dieser Beitrag könnte nützlich sein: http://forrestbao.blogspot.rs/2014/ 07/signal-filtering-using-inverse-fft-in.html – Prefect

+0

Mögliches Duplikat von [fft bandpass filter in python] (http://stackoverflow.com/questions/19122157/fft-bandpass-filter-in-python) – strpeter

Antwort

1

ich so etwas wie dies wollte. Ich weiß, dass es eine bessere Lösung gibt als meine gehackten Arbeiten. :) Der zweite Peak wird entfernt.

import numpy as np 
import matplotlib.pyplot as plt 
from scipy.fftpack import rfft, irfft, fftfreq, fft 
import scipy.fftpack 

# Number of samplepoints 
N = 500 
# sample spacing 
T = 0.1 

x = np.linspace(0.0, N*T, N) 
y = 5*np.sin(x) + np.cos(2*np.pi*x) 

yf = scipy.fftpack.fft(y) 
xf = np.linspace(0.0, 1.0/(2.0*T), N/2) 
#fft end 

f_signal = rfft(y) 
W = fftfreq(y.size, d=x[1]-x[0]) 

cut_f_signal = f_signal.copy() 
cut_f_signal[(W>0.6)] = 0 

cut_signal = irfft(cut_f_signal) 



# plot results 
f, axarr = plt.subplots(1, 3) 
axarr[0].plot(x, y) 
axarr[0].plot(x,5*np.sin(x),'g') 

axarr[1].plot(xf, 2.0/N * np.abs(yf[:N//2])) 
axarr[1].legend(('numpy fft * dt'), loc='upper right') 
axarr[1].set_xlabel("f") 
axarr[1].set_ylabel("amplitude") 


axarr[2].plot(x,cut_signal) 
axarr[2].plot(x,5*np.sin(x),'g') 

plt.show() 

enter image description here

enter image description here

+1

Das ist völlig in Ordnung. In ausgeklügelten Begriffen haben Sie gerade einen "Brick-Wall-Tiefpassfilter in der Frequenzdomäne" angewendet. Was die andere Antwort (das Entwerfen eines Bandstop-Filters) hat, hat Vor- und Nachteile im Vergleich zu dem, was Sie getan haben. Um den Nachteil dessen, was Sie getan haben, zu sehen, beachten Sie, wie beide Spitzen im Frequenzbereich eine gewisse Breite haben - sie sind nicht nur zwei Impulse. Das liegt daran, dass keine der Frequenzen genau auf einem Frequenz-Bin liegt, also braucht es * alle * Frequenzen, um sie zu erzeugen. –

+0

Wenn Sie alle Frequenzen> 0.6 abschneiden, sieht das Ergebnis wie eine schöne Sinuskurve aus, aber wenn Sie eine * tatsächliche * Sinuskurve oben auf der rechten Seite zeichnen, werden Sie die subtilen Verzerrungen durch das Herausfiltern der Frequenzen mit " kleine "Amplituden. –

+0

@AhmedFasih danke für Hinweise! Können Sie mir ein Buch oder einen Artikel zur Signalverarbeitung vorschlagen? – Prefect

5

können Sie entwerfen ein Sperrfilter:

wc = freq[np.argmax(amplitude)]/(0.5/dt) 
wp = [wc * 0.9, wc/0.9] 
ws = [wc * 0.95, wc/0.95] 
b, a = signal.iirdesign(wp, ws, 1, 40) 
f = signal.filtfilt(b, a, f) 
Verwandte Themen