这里以EEGLAB中的数据为例。本文参考自《python脑电处理中文手册》。
首先讲一下EEGLAB工具包怎么下载:
首先去EEGLAB官网中下载eeglab压缩包,https://sccn.ucsd.edu/eeglab/download.php。需要提交一个申请,填上自己名字后即可获得压缩包。解压缩后,双击打开文件夹,就可以看到sample_data文件夹中的.set文件和.locs文件了。
因为我们这里不用matlab进行脑电分析,我们只需要调用eeglab中的脑电数据集,因此不需要将工具包添加到matlab中。如哟需要,可自行搜索相关教程。
1.读取数据
(1)加载数据并查看数据信息
# 导入必要的包
import numpy as np
import mne
import matplotlib
matplotlib.use('TkAgg') # 使用这个命令,绘制的图形可以独立弹窗并能使用交互式命令(用这个命令后plot生成的图可以点击更改设置)
import matplotlib.pyplot as plt
# 读取数据
data_path = 'H:/app_app/EEG_LAB/eeglab_current/eeglab2023.1/sample_data/eeglab_data.set'
raw = mne.io.read_raw_eeglab(data_path, preload=True)
print(raw.info) # 查看raw中详细信息
上述代码的输出为:
Reading H:\app_app\EEG_LAB\eeglab_current\eeglab2023.1\sample_data\eeglab_data.fdt
Reading 0 ... 30503 = 0.000 ... 238.305 secs...
C:\Users\路还长别猖狂\AppData\Local\Temp\ipykernel_21232\2699441557.py:2: RuntimeWarning: Estimated head radius (0.1 cm) is below the 3rd percentile for infant head size. Check if the montage_units argument is correct (the default is "mm", but your channel positions may be in different units).
raw = mne.io.read_raw_eeglab(data_path, preload=True)
<Info | 8 non-empty values
bads: []
ch_names: FPz, EOG1, F3, Fz, F4, EOG2, FC5, FC1, FC2, FC6, T7, C3, C4, Cz, ...
chs: 32 EEG
custom_ref_applied: False
dig: 35 items (3 Cardinal, 32 EEG)
highpass: 0.0 Hz
lowpass: 64.0 Hz
meas_date: unspecified
nchan: 32
projs: []
sfreq: 128.0 Hz
>
(2)从上述代码中可以看到,"ch_names"中显示了标准的电极通道名称(注意旧版本的mne中加载的名称非标准,我这里用的是mne==1.3.1版本),但是电极位置没有设置,因此需要调用.locs文件手动导入电极位置。
# 设置.locs文件地址
locs_info_path = 'H:/app_app/EEG_LAB/eeglab_current/eeglab2023.1/sample_data/eeglab_chan32.locs'
# 读取电极位置中的信息
montage = mne.channels.read_custom_montage(locs_info_path)
# 更新电极位置
raw.set_montage(montage)
(3)从 http://raw.info中看到,导联名称已经是标准名称了,不需要再更改导联名称。但是看到ch_names中有两个EOG(眼电)信号,但是chs中却识别到了32个EEG,实际上去掉两个EOG,应为30个
channel_type_dict = {"EOG1": "eog", "EOG2": "eog"}
raw.set_channel_types(channel_type_dict)
执行完后已经显示30个eeg通道,2个eog通道了。
(4)可视化数据波形图
查看原始数据波形图:
raw.plot(duration=5, n_channels=32, clipping=None)
# 是以独立弹窗的形式出现的,可以点击help查看使用规则,单击通道名称可以标记坏道(之后该系列文章中会提到)
图1 原始数据波形图
查看原始数据功率谱密度图:
注:对功率谱密度不了解的,可以看这两篇文章:随机信号的功率谱密度究竟有什么物理意义? 或者 信号处理之功率谱原理与python实现-腾讯云开发者社区-腾讯云
# 这个函数在新版本mne中已经被替代了
raw.plot_psd(average=True)
# 可使用以下函数,效果一致
raw.compute_psd().plot(average=True)
图2 功率谱密度
从功率谱密度中可以看到,在60Hz处有明显异样,可能是存在噪声,因此需要在滤波步骤中滤除。
查看原始数据eeg电极分布位置:
raw.plot_sensors(ch_type='eeg', show_names=True)
图3 电极分布图
在脑地形图上绘制功率谱图:
raw.compute_psd().plot_topo()
图4 功率谱图
2.滤波
(1)缺陷滤波
刚才在功率谱密度图处提到,60Hz处有噪声,需要剔除,这时就需要进行缺陷滤波(一定是从功率谱密度图中看)。同时查看缺陷滤波后的功率谱密度图。
raw = raw.notch_filter(freqs=(60))
raw.plot_psd(average=True)
图5 功率谱密度
(2)高低通滤波
高通滤波为了消除电压漂移,低通滤波为了消除高频噪音。这里选择0.1Hz高通滤波,30Hz低通滤波。
raw = raw.filter(l_freq=0.1, h_freq=30)
raw.plot_psd(average=True)
图6 功率谱密度
mne中默认使用FIR滤波方法:
raw = raw.filter(l_freq=0.1, h_freq=30, method='fir') <<==>> raw = raw.filter(l_freq=0.1, h_freq=30)
若想使用IIR滤波方法,可以使用如下命令:
raw = raw.filter(l_freq=0.1, h_freq=30, method='iir')
关于IIR滤波器和FIR滤波器的区别
(1)滤波器结构不同:IIR滤波器具有反馈结构,而FIR滤波器则不具有反馈结构。
(2)滤波器特性不同:IIR滤波器具有较高的滤波效率和较小的延迟时间,能够实现更加复杂的滤波特性;而FIR滤波器具有较高的稳定性和可靠性,不会出现稳定性问题和非线性失真,能够实现精确的滤波特性和灵活的滤波器设计。
(3)滤波器设计方法不同:IIR滤波器的设计方法主要是基于模拟滤波器的设计方法,可以通过差分方程、极点和零点等来实现滤波器的设计;而FIR滤波器的设计方法主要是基于窗函数的设计方法,可以通过窗函数、截止频率和滤波器阶数等来实现滤波器的设计。
IIR滤波器和FIR滤波器的应用
(1)IIR滤波器的应用:IIR滤波器主要应用于音频信号处理、语音信号处理、图像处理、传感器信号处理等方面,如音频均衡器、陷波滤波器、数字滤波器等。
(2)FIR滤波器的应用:FIR滤波器主要应用于通信系统、雷达信号处理、生物医学信号处理等方面,如低通滤波器、高通滤波器、带通滤波器等。