我试图用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()以及情节:

发布于 2014-01-11 11:16:46
如果您的采样频率是fs,并且您有N=len(eeg1)样本,那么fft过程当然会返回一个N值数组。它们中的第一N/2对应于频率范围0..fs/2,频率的后半部分对应于镜像频率范围-fs/2..0。对于实际输入信号,镜像半是正半的复共轭,因此可以在进一步的分析中忽略它(而不是在反fft中)。
所以从本质上说,你应该
f=linspace(0,N-1,N)*fs/N
编辑:或者更简单,只需对inital代码进行最小的更改。
f = np.linspace (0,fs,len(eeg1), endpoint=False)
因此,f从0到fs之前的范围,忽略了fft的后半部分,得到了输出:
plt.plot( f(0:N/2), abs( fft1(0:N/2) ) )
补充:您可以使用fftshift来交换这两个部分,那么正确的频率范围是
f = np.linspace (-fs/2,fs/2,len(eeg1), endpoint=False)
发布于 2014-01-11 14:46:59
为了获得快速傅立叶变换频率的数组,您应该使用弗特弗雷克;它提供了一系列用作脓肿的频率:
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 (β);一个非常简单的方法是在8-13Hz范围内计算fft的最大值:fft1[(f>8) & (f<13)].max(),如果它大于1000,它是一个α波,否则就是β。如果您的信号不太相似,请张贴一些不同类型的样本的例子和结果,以便我们可以尝试更复杂的算法。
https://stackoverflow.com/questions/21052052
复制相似问题