2014-01-10 46 views
1

我试图在Python中执行EEG信号的FFT,然后根据带宽确定它是alpha还是beta信号。它看起来很好,但是由此产生的情节并不像他们应该的那样,频率和幅度值并不是我所期望的。赞赏,在这里任何帮助的代码:脑电信号的带宽

from scipy.io import loadmat 
import scipy 
import numpy as np 
from pylab import * 
import matplotlib.pyplot as plt 

eeg = loadmat("eeg_2013.mat"); 
eeg1=eeg['eeg1'][0] 
eeg2=eeg['eeg2'][0] 
fs = eeg['fs'][0][0] 
fft1 = scipy.fft(eeg1) 
f = np.linspace (fs,len(eeg1), len(eeg1), endpoint=False) 
plt.figure(1) 
plt.subplot(211) 
plt.plot (f, abs (fft1)) 
plt.title ('Magnitude spectrum of the signal') 
plt.xlabel ('Frequency (Hz)') 
show() 
plt.subplot(212) 
fft2 = scipy.fft(eeg2) 
f = np.linspace (fs,len(eeg2), len(eeg2), endpoint=False) 
plt.plot (f, abs (fft2)) 
plt.title ('Magnitude spectrum of the signal') 
plt.xlabel ('Frequency (Hz)') 
show() 

而且情节: img http://oi40.tinypic.com/2qdstg1.jpg

+0

而且,最重要的是,我不知道我怎么可以从这个图读带宽... –

+1

有一个潜在的问题,取决于输入数据,或者它们是如何标准化,因为EEG信号通常有10到50赫兹的范围,你的1到9千赫,它把输入信号?你在哪里拿? – archetipo

+0

这两条线: eeg1 = EEG [ 'eeg1'] [0] eeg2 = EEG [ 'eeg2'] [0] 它是从一个.MAT文件,存储读取变量 –

回答

2

如果你的采样频率为fs,你有N=len(eeg1)样本,那么fft的过程,当然,返回数组值为N。它们中的第一个N/2对应于频率范围0..fs/2,频率的后半部分对应于镜像频率范围-fs/2..0。对于实际的输入信号,镜像的一半只是正半的复共轭,所以在进一步的分析中它可以忽略不计(但不是反傅里叶变换)。

所以基本上,你应该格式化

f=linspace(0,N-1,N)*fs/N

编辑:或者更简单的以最小的改动inital代码

f = np.linspace (0,fs,len(eeg1), endpoint=False)

所以从0到之前fsf范围并忽略输出中fft结果的后半部分:

plt.plot( f(0:N/2), abs(fft1(0:N/2)) )


新增:您可以使用fftshift交换两半,然后将正确的频率范围是

f = np.linspace (-fs/2,fs/2,len(eeg1), endpoint=False)

+0

谢谢,工作正常! –

3

为了得到FFT频率的数组,你应该使用fftfreq;它给你的频率数组作为离层使用:

from scipy.fftpack import fftfreq 

eeg = loadmat("eeg_2013.mat"); 
eeg1=eeg['eeg1'][0] 
eeg2=eeg['eeg2'][0] 
fs = eeg['fs'][0][0] 
fft1 = scipy.fft(eeg1) 
f=fftfreq(eeg1.size,1/fs) 

对不起,我不能在真实条件下测试此代码,因为你没有发布的数据样本,但我希望这应该工作。

关于如何确定带宽,据我所知,你想得到的基本频率。有多种不同的方式,不管你的信号是否有噪音或多或少,...在你的情况下,你只想知道基频f0是在8-13Hz(alpha)还是13-30Hz(beta );一个很简单的方法是计算最大范围8-13Hz FFT的:fft1[(f>8) & (f<13)].max(),如果它不是,比方说,1000多,这是一个α波,否则它是测试版。如果你的信号不太相似,请张贴一些不同种类样本的例子和结果,以便我们可以尝试更复杂的算法。