在这篇文章中,我们使用MNE(MNE-Python)来对脑电信号进行坏道处理、带通滤波以及去除市电干扰。首先,我们进行了坏道处理,这是为了排除由于电极故障或其他原因而产生的异常信号。接下来,我们进行了带通滤波,以去除不感兴趣的频率成分,如低频和高频噪声,同时保留我们感兴趣的频率范围内的信号。最后,我们还实施了去除市电干扰的步骤,这是为了消除来自电力线的交流干扰,从而进一步提高信号质量。通过这些预处理步骤,我们能够更清晰地分析和理解脑电信号,从而更好地研究大脑活动和功能。
一、数据读取
import matplotlib.pyplot as plt
import mne
from scipy.io import loadmat
data = loadmat("E:/EEG/eeg.mat")
ch_names = ['Fp1','Fpz','Fp2','AF3','AF4','F7','F5','F3','F1','Fz','F2','F4','F6'
,'F8','FT7','FC5','FC3','FC1','FCz','FC2','FC4','FC6','FT8','T7','C5'
,'C3','C1','Cz','C2','C4','C6','T8','TP7','CP5','CP3','CP1','CPz','CP2'
,'CP4','CP6','TP8','P7','P5','P3','P1','Pz','P2','P4','P6','P8','PO7'
,'PO5','PO3','POz','PO4','PO6','PO8','CB1','O1','Oz','O2','CB2']
for key in data.keys():
if key == '__header__' or key == '__version__' or key == '__globals__':
pass
else:
montage = mne.channels.make_standard_montage('standard_1020')
info = mne.create_info(ch_names = ch_names,ch_types = ['eeg' for _ in range(62)], sfreq = 200 )
raw = mne.io.RawArray(data[key], info)
scalings = {'eeg': 50}
raw.load_data()
raw.plot(scalings='auto')
plt.show(block=True)
二、坏道插值处理
在坏道处理过程中,我们首先对脑电信号进行了坏道标记,即识别并标记出可能存在问题的电极通道。这一步骤通常基于一些预定义的标准,如电极的阻抗或者信号的偏移程度。一旦标记出坏道,接下来的步骤就是进行插值处理。
raw.info['bads']=['P8','AF4']
raw.plot(scalings='auto')
plt.show(block=True)
插值处理是指利用周围正常通道的信息来估计并填补坏道处缺失的数据点,从而修复坏道。最常用的插值方法之一是通过空间邻近性来估计缺失值,基于相邻电极通道的信号来推断坏道处的信号值。完成插值处理后,我们就成功地修复了坏道,使得整个脑电数据集更加完整和可靠,为后续的分析和研究提供了更加可靠的基础。
raw_pass = raw.copy()
raw_pass.interpolate_bads()
raw_pass.plot(scalings='auto')
三、带通滤波
我们对脑电信号进行1-45Hz的带通滤波,这样可到我们想要的信号波段,1-45Hz包含了脑电信号的5中频带(δ波、θ波、α波、β波和γ波)。通过将脑电信号滤波至1到45赫兹的范围内,我们保留了这五个主要频带的信息,并且去除了不感兴趣的频率成分,使得后续的分析更加集中在我们感兴趣的脑电活动上。
raw_pass = raw_pass.copy()
raw_pass = raw_pass.filter(l_freq=1, h_freq=50,method='fir')
raw_pass.plot(scalings=scalings)
plt.show(block=True)
四、陷波处理
在下面的图中,我们可以清晰地观察到信号在50赫兹左右存在明显的市电干扰。这种干扰通常来自电力线的交流频率,可能会对脑电信号的分析和解释产生负面影响。为了消除这种干扰,我们可以采取陷波处理的方法。
raw.plot_psd(fmin=0, fmax=52,sphere=(0,0,0,0.11))
raw_pass = raw_pass.notch_filter(freqs=50)
raw_pass.plot_psd(fmin=0, fmax=64,sphere=(0,0,0,0.11))
raw_pass.plot(scalings=scalings)
plt.show(block=True)