2016-09-30 4 views
3

Je veux supprimer une fréquence (un pic) du signal et tracer ma fonction sans elle. Après fft j'ai trouvé la fréquence et l'amplitude et je ne suis pas sûr de ce que je dois faire maintenant. Par exemple, je veux supprimer mon plus haut sommet (marqué d'un point rouge sur l'intrigue).Comment supprimer la fréquence du 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

Vous devez filtrer le signal. Quel type de filtre et comment vous le configurez sera déterminé à la fois par les fréquences que vous voulez conserver et celles que vous voulez supprimer. Vous voudrez peut-être vous procurer une introduction au livre DSP ou commencer ici: https://en.wikipedia.org/wiki/Filter_(signal_processing) – Turn

+0

Ce message peut être utile: http://forrestbao.blogspot.rs/2014/ 07/signal-filtering-using-inverse-fft-in.html – Prefect

+0

Copie possible de [filtre passe-bande fft en python] (http://stackoverflow.com/questions/19122157/fft-bandpass-filter-in-python) – strpeter

Répondre

1

Je voulais quelque chose comme ça. Je sais qu'il y a une meilleure solution mais mes travaux piratés. :) Deuxième pic est supprimé.

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

C'est totalement bien. En termes de fantaisie, vous venez d'appliquer un "filtre passe-bas de mur de briques dans le domaine fréquentiel". Qu'est-ce que l'autre réponse (la conception d'un filtre coupe-bande) a des avantages et des inconvénients par rapport à ce que vous avez fait. Pour voir l'inconvénient de ce que vous avez fait, notez comment les deux pics dans le domaine fréquentiel ont une certaine largeur - ils ne sont pas seulement deux impulsions. C'est parce que ni l'une ni l'autre fréquence ne se trouve exactement sur une fréquence bin, donc il faut * toutes * fréquences pour les faire. –

+0

En coupant toutes les fréquences> 0,6, le résultat ressemble à une belle sinusoïde, mais si vous tracez une sinusoïde * réelle * au-dessus de votre tracé le plus à droite, vous verrez les distorsions subtiles introduites en filtrant les fréquences avec " petites "amplitudes. –

+0

@AhmedFasih merci pour les avis! Pouvez-vous suggérer un livre ou un article pour le traitement du signal? – Prefect

5

Vous pouvez concevoir un filtre coupe-bande:

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)