基于CSP的运动想象 EEG 特征提取和可视化

news2024/11/25 16:41:51

基于运动想象的公开数据集:Data set IVa (BCI Competition III)1
数据描述参考前文:https://blog.csdn.net/qq_43811536/article/details/134224005?spm=1001.2014.3001.5501
EEG 信号时频空域分析参考前文:https://blog.csdn.net/qq_43811536/article/details/134273470?spm=1001.2014.3001.5501

本文使用公开数据集 Data set IVa 中的部分被试数据,数据已公开可以从网盘获取:
链接:https://pan.quark.cn/s/5425ee5918f4
提取码:hJFz


目录

  • 1. 实验介绍
  • 2. EEG 特征提取和可视化
    • 2.1 比较两类信号的差异
    • 2.2 CSP特征计算
      • 2.2.1 频域特征
  • 3. 分析代码


1. 实验介绍

本任务的实验数据来自一名健康受试者,代号al。受试者在视觉提示出现后3.5s内完成以下3个运动想象中的一个:(L)左手,(R)右手,(F)右脚。分类任务中的数据只包括了右手和右脚两类,共280个试次。实验过程中使用脑电帽记录了118个通道的EEG信号,电极位置如图1所示。采集到的EEG信号首先经过带通滤波(0.05-200Hz),再经过数字化和下采样,得到采样率为100Hz的信号。

在这里插入图片描述

图1 电极位置

2. EEG 特征提取和可视化

2.1 比较两类信号的差异

人在运动想象的过程中,大脑皮层会产生两种变化明显的节律信号,分别是 8-15Hz 的 μ 节律信号和 18-24Hz 的 β 节律。在运动想象时,大脑皮层对侧运动感觉区的脑电节律能量会明显降低,而同侧运动感觉区的脑电节律能量增大,这种现象称为事件相关去同步(Event Related Desynchronization,ERD)/事件相关同步(Event Related Synchronization,ERS)。本任务要区分的两类运动想象动作都是右侧,区别在于部位不同。

我们首先计算了两类运动想象的平均功率谱,得到图1所示的结果。可以看出,两类运动想象在C3和C4通道的5-25Hz具有较大的差异,这反映的正是运动感觉区的 μ 节律和 β 节律。我们还计算了5-25Hz的功率谱拓扑图,如图2所示。

在这里插入图片描述

(a)                                                                  (b)
图1 两类信号的功率谱。(a)C3通道。(b)C4通道。

在这里插入图片描述

图2 功率谱拓扑图。左图为右手运动想象,右图为右脚运动想象。

2.2 CSP特征计算

2.2.1 频域特征

接下来,我们对EEG进行了带通滤波(12-28Hz),之后通过CSP 算法计算运动想象脑电特征,分量数目设置为10。图3展示了CSP模式图。

在这里插入图片描述

图3 CSP模式图

为了验证所提取到的CSP特征对于两类运动想象的区分性,绘制了两类样本的CSP特征。图4(a)展示了CSP特征的前两个维度,图4(b)则对10维CSP特征进行了t-SNE可视化。可以看出提取到的CSP特征具有较高的线性区分性。

在这里插入图片描述

(a)                                                                  (b)
图4 两类样本的CSP特征可视化。(a)CSP特征的前两个维度。(b)CSP特征经过t-SNE降维。

3. 分析代码

  • 主要使用Python的MNE包进行分析
  • MNE Tutorials 官网:https://mne.tools/stable/auto_tutorials/index.html
  • 部分变量说明:
    • raw:由 mne.io.RawArray() 函数创建,代表原始EEG数据
    • epochs:由 mne.Epochs() 函数创建,代表一个事件(event)对应的所有数据,在该数据集中一个事件即 “右手”或者“脚”的想象运动
raw = mne.io.RawArray(eeg_data.T, info)
from scipy.signal import welch


# raw.filter(12, 28, fir_design="firwin", skip_by_annotation="edge")

# Events and epochs
# Events
events = np.vstack((cues_pos, np.zeros(len(cues_pos)), target_label[0, :])).T.astype(int)
picks = mne.pick_types(raw.info, meg=False, eeg=True, stim=False, eog=False, exclude="bads")
# Cue onset
# Epochs
epochs = mne.Epochs(
    raw,
    events,
    events_id,
    0,
    3.5,
    proj=True,
    picks=picks,
    baseline=None,
    preload=True,
)
for i_ch in range(len(ch_name)):
    f, pxx0 = welch(epochs.get_data()[right_id,i_ch,:], fs=eeg_fs)
    f, pxx1 = welch(epochs.get_data()[foot_id,i_ch,:], fs=eeg_fs)
    plt.figure()
    plt.plot(f,10 * np.log10(pxx0.mean(axis=0)),'r',linewidth=2)
    plt.plot(f,10 * np.log10(pxx1.mean(axis=0)),'g',linewidth=2)
    plt.xlim([5,40])
    plt.xlabel('[Hz]',fontsize=16)
    plt.ylabel('[dB]',fontsize=16)
    plt.legend(['Right','Foot'],fontsize=16)
    plt.xticks(fontsize=16)  # 设置 x 轴刻度标签的字体大小为 12
    plt.yticks(fontsize=16)  # 设置 y 轴刻度标签的字体大小为 12
    plt.title(list(ch_name)[i_ch][0], fontsize=16)
    plt.tick_params(axis='both', which='major', width=2)  # 设置主要刻度线的宽度为 2
    # 设置顶部边框的粗细
    plt.gca().spines['top'].set_linewidth(2)

    # 设置底部边框的粗细
    plt.gca().spines['bottom'].set_linewidth(2)

    # 设置左侧边框的粗细
    plt.gca().spines['left'].set_linewidth(2)

    # 设置右侧边框的粗细
    plt.gca().spines['right'].set_linewidth(2)

    plt.savefig(f'Results\\topomap\\{list(ch_name)[i_ch][0]}.png')

plt.figure()
epochs[right_id].compute_psd().plot_topomap(vlim=(155,180),bands={"5-25Hz":(5,25)},ch_type="eeg", agg_fun=np.mean, dB=True)
plt.savefig(f'Results\\topomap_r.png')
plt.show()

plt.figure()
epochs[foot_id].compute_psd().plot_topomap(vlim=(155,180),bands={"5-25Hz":(5,25)},ch_type="eeg", agg_fun=np.mean, dB=True)

plt.savefig(f'Results\\topomap_f.png')

plt.show()

plt.figure()
raw.compute_psd(tmin=0,tmax=3.5).plot_topomap(vlim=(155,180),bands={"5-25Hz":(5,25)},ch_type="eeg", agg_fun=np.mean, dB=True)

plt.savefig(f'Results\\topomap_f.png')
x = epochs.get_data()
y = target_label[0, :] 
csp = CSP(n_components=10, reg=None, log=True, norm_trace=False)
csp.fit_transform(x, y)
csp.plot_patterns(epochs.info, ch_type="eeg", units="Patterns (AU)", size=1.5)
plt.show()

  1. https://bbci.de/competition/iii/desc_IVa.html ↩︎

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1186671.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

十月份 NFT 市场显示复苏迹象,等待进一步的积极发展

作者: stellafootprint.network 10 月份,比特币价格大幅飙升,NFT 市场出现了复苏迹象,月度交易量和用户数均增长了 15.2%。尽管 10 月份的数据相比 9 月份有所改善,但仍然不及 8 月份和之前几个月的水平。因此,现在断…

Cesium 笛卡尔坐标转换

Cesium中主要使用笛卡尔坐标系,球心相当于原点 z轴不是高度,高度是点到地表的距离,贴在表面高度就为0,z改变,x,y都会随之改变; 1.经纬度转笛卡尔 // (经度 纬度 高度),返回的是一个笛卡尔坐标 c…

预约按摩app小程序开发搭建;

预约按摩app小程序开发搭建; 后端:系统后端使用PHP语言开发 前端:前端使用uniapp进行前后端分离开发,支持(公中号、小程序、APP)。 用户端功能模块:技师选择、预约服务、优惠券、订单、技师服…

事件绑定-回调函数

1.事件的概念 2.小程序常用的事件集 2.1 bindtap 点击回调事件方法 2.1.1语法格式 2.1.2 事件处理中调用data 使用setDatacount:这种方式 直接使用this.data.count 2.1.3 事件处理中传参 错误示范: 传递方式:数值用{{}},直接引…

如何使用 GTX750 或 1050 显卡安装 CUDA11+

前言 由于兼容性问题,使得我们若想用较新版本的 PyTorch,通过 GPU 方式训练模型,也得更换较新版本得 CUDA 工具包。然而 CUDA 的版本又与电脑显卡的驱动程序版本关联,如果是低版本的显卡驱动程序安装 CUDA11 及以上肯定会失败。 比…

react之Component存在的2个问题

问题 只要执行setState(),即使不改变状态数据,组件也会重新render()只当前组件重新render(),就会自动重新render子组件 原因 Component中的shouldComponentUpdate()总是返回true 思路 只有当组件的state或props数据发生改变时才重新rend…

c++ 信奥赛编程 2050:【例5.20】字串包含

#include<iostream> #include<cstring> using namespace std; int main() {string str1,str2;int temp;cin>>str1>>str2;//判断长度 if(str1.size()<str2.size()){ swap(str1,str2); //交换内容 }str1str1str1; //AABCDAABCDAABCDAABCDif(str…

苹果转移供应链,促中国手机和中国制造更紧密合作,加速技术升级

随着苹果力推富士康等奔赴印度和越南设厂&#xff0c;引发的另一大反应恐怕是它所没有想到的&#xff0c;那就是中国手机和中国制造产业链的合作更加紧密了&#xff0c;中国制造产业链的技术水平反而因此得到提升。 一、产业链技术升级依赖苹果 对于制造产业链来说&#xff0c;…

12、填写NGINX配置部署前端;运行jar部署后端

后端可以部署的方式&#xff0c;首先直接运行jar是肯定可以的。此外&#xff0c;可以单独开docker容器运行在容器中。 但是这里运行在容器中必要性&#xff0c;其实并不大。 当前我们直接运行jar来运行后端。后面推出集成docker。 直接运行jar包的方式&#xff0c;首先需要打…

nginx下载安装和日志切割

目录 一、nginx安装配置 1.nginx版本 2.nginx安装配置 3.查看安装后的nginx 4.配置PATH变量 二、日志切割 1.给当前日志文件重命名 2.等待 3.写bash脚本 4.查看日志结果 5.加入crontab定时任务 结语 一、nginx安装配置 1.nginx版本 nginx如今分为商业版&#xff0…

京东API接口的应用场景:商品信息查询,商品详情获取

京东API接口的应用场景涵盖了电商业务的各个方面&#xff0c;通过API的方式&#xff0c;开发者可以方便地获取京东平台上的商品信息、用户信息、订单信息等&#xff0c;进而进行个性化的应用开发。以下是几个典型的应用场景&#xff1a; 商品信息查询&#xff1a;通过京东API接…

高性能网络编程 - The C10K problem 以及 网络编程技术角度的解决思路

文章目录 C10KC10K的由来C10K问题在技术层面的典型体现C10K问题的本质C10K解决思路思路一&#xff1a;每个进程/线程处理一个连接思路二&#xff1a;每个进程/线程同时处理多个连接&#xff08;IO多路复用&#xff09;● 实现方式1&#xff1a;直接循环处理多个连接● 实现方式…

启动Hbase出现报错

报错信息&#xff1a;slave1:head: cannot open/usr/local/hbase-2.3.1/bin/../logs/hbasewanggiqi-regionserver-slavel.out’ for reading: No such file or direslave2: head: cannot open/usr/local/hbase-2.3.1/bin/../logs/hbasewangqiqi-regionserver-slave2.out’ for …

OpenCV 图像复制和图像区域读写

图像复制 共享数据, 使用 new Mat(srcMat, ...) 和 newMatsrcMat 生成新的Mat都和原Mat共享数据, 也就是说如果修改某一Mat,其他Mat也会随之改变复制全新的Mat, 使用CopyTo() 和 Clone() 方法将生成一个全新的Mat, 新Mat和原Mat不共享数据. 图像区域和点的读写 区域读取: 通过s…

JavaEE初阶学习:Linux 基本使用和 web 程序部署

1.Linux的基本认识 Linux 是一个操作系统.(搞管理的系统) 和Windows都是同类产品~~ Linux 实际的场景: 1.服务器 2.嵌入式设备 3.移动端(手机)Android 其实就是Linux 1991年,还在读大学的 芬兰人 Linus Benedict Torvalds,搞了一个Linux 这样的系统0.01版,正式发布了~ 后…

[量化投资-学习笔记007]Python+TDengine从零开始搭建量化分析平台-布林带

布林带&#xff08;Bollinger Bands&#xff09;也称为布林通道、保力加通道&#xff0c;是由约翰布林格&#xff08;John Bollinger&#xff09;发明的技术分析指标。布林通道通常被用来确认资产价格波动范围。 布林通道是由三条平滑的曲线组成的趋势线图表&#xff0c;中线为…

HDPE双壁波纹管存在缺点,在选择使用时需要根据实际情况进行考虑

惠洁友情提醒HDPE双壁波纹管脆性较大&#xff1a;HDPE双壁波纹管的脆性较大&#xff0c;容易受到冲击和碰撞的影响&#xff0c;如果使用过程中出现破损或裂缝&#xff0c;可能会影响到其密封性能和使用寿命。 对温度敏感&#xff1a;HDPE双壁波纹管的性能受温度影响较大&#…

安全测试,接口返回内容遍历~

最近公司被人大量爬取数据&#xff0c;查了一下发现&#xff0c;用户主页接口&#xff0c;没有加用户登录校验&#xff0c;返回了用户的敏感信息有手机号和邮箱&#xff0c;其实这个接口是用不到这些信息的。再加上用户id是自增长的&#xff0c;所以很容易被别人爬取。 既然这…

【milkv】添加LCD屏GC9306

前言 本章介绍如何添加LCD屏GC9306驱动。 电路图 dts build\boards\cv180x\cv1800b_milkv_duo_sd\dts_riscv\cv1800b_milkv_duo_sd.dts &spi2 {status "okay";/delete-node/ spidev0;gc9306: gc93060{compatible "sitronix,gc9306";reg <0&g…

[PHP]得推跑腿O2O系统 v3.41

得推跑腿系统是一个以phpMySQL进行开发的主要针对本地跑腿服务的O2O系统&#xff0c;支持wap\\小程序\\App。 主要功能模块&#xff1a; 用户端&#xff1a; 1.跑腿任务发布 2.跑腿任务管理追踪 3.在线支付 4.常用地址管理 跑腿端&#xff1a; 1.跑腿任务抢单 2.跑腿员认证 3.…