点击上面"脑机接口社区"关注我们

更多技术干货第一时间送达

有后台留言问,代码是在哪里运行的。这里说明一下,案例介绍的代码均在jupyter notebook中运行的,当然这些代码也可以在PyCharm等IDE中运行(不过可能存在再不同环境下代码需要稍微改动的情况。)

Python脑电图处理案例:

import mne
from mne.datasets import sample
# 加载数据文件
data_path = sample.data_path()
raw_fname = data_path + '/MEG/sample/sample_audvis_filt-0-40_raw.fif'
event_fname = data_path + '/MEG/sample/sample_audvis_filt-0-40_raw-eve.fif'
# 这些EEG数据已经默认有平均参考(average reference)
raw = mne.io.read_raw_fif(raw_fname, preload=True)

# 只筛选 EEG 和 EOG数据
raw.pick_types(meg=False, eeg=True, eog=True)# 查看 raw 信息, 可以发现有59个EEG通道和1个EOG通道
print(raw.info)

实际上,拥有一些EOG通道的EEG通道是很普遍的。在实际获取EEG数据时,会受到眼动等活动的影响。

如果要更改通道类型,可以使用mne.io.Raw.set_channel_types()方法。
例如,要将EOG通道视为EEG,可以使用以下方法更改其类型:

raw.set_channel_types(mapping={'EOG 061': 'eeg'})
print(raw.info)

比较上面前后两个打印中的红框内容,可以发现,EOG已被EEG取代了。

# 更改EOG通道的名称
raw.rename_channels(mapping={'EOG 061': 'EOG'})# 为了讲述案例,我们将EOG频道重设为EOG类型。
raw.set_channel_types(mapping={'EOG': 'eog'})
"""
样本数据集中的EEG通道有对应通道位置。这些位置可在每个通道说明的"位置"中找到。下面是获取第一个通道的位置
"""print(raw.info['chs'][0]['loc'])
[-0.03737009  0.10568011  0.07333875
  0.00235201  0.11096951 -0.035004580.   1.   0.    0.    0.    1. ]
"""
可以使用mne.io.Raw.plot_sensors()绘制通道位置。
如果您的数据没有位置,则可以使用MNE随附的Montages来设置
"""
raw.plot_sensors()

raw.plot_sensors('3d')  # in 3D

设置脑电图参考

首先,从原始对象中删除参考。

这显示的移除了MNE默认的EEG平均参考。

raw_no_ref, _ = mne.set_eeg_reference(raw, [])

EEG channel type selected for re-referencing

EEG data marked as already having the desired reference. Preventing automatic future re-referencing to an average reference.

Removing existing average EEG reference projection.

然后,定义了Epochs,并计算了左听觉状态的ERP。

reject = dict(eeg=180e-6, eog=150e-6)
event_id, tmin, tmax = {'left/auditory': 1}, -0.2, 0.5
events = mne.read_events(event_fname)
epochs_params = dict(events=events, event_id=event_id, tmin=tmin, tmax=tmax,reject=reject)evoked_no_ref = mne.Epochs(raw_no_ref, **epochs_params).average()
del raw_no_ref  # save memorytitle = 'EEG Original reference'
evoked_no_ref.plot(titles=dict(eeg=title), time_unit='s')
evoked_no_ref.plot_topomap(times=[0.1], size=3., title=title, time_unit='s')

设置平均参考电极

"""
平均参考:通常默认情况下添加,但也可以显式添加。
"""raw.del_proj()
raw_car, _ = mne.set_eeg_reference(raw, 'average', projection=True)
evoked_car = mne.Epochs(raw_car, **epochs_params).average()
del raw_car  # save memorytitle = 'EEG Average reference'
evoked_car.plot(titles=dict(eeg=title), time_unit='s')
evoked_car.plot_topomap(times=[0.1], size=3., title=title, time_unit='s')

自定义参考:使用通道EEG 001和EEG 002的平均值作为参考

raw_custom, _ = mne.set_eeg_reference(raw, ['EEG 001', 'EEG 002'])
evoked_custom = mne.Epochs(raw_custom, **epochs_params).average()
del raw_custom  # save memorytitle = 'EEG Custom reference'
evoked_custom.plot(titles=dict(eeg=title), time_unit='s')
evoked_custom.plot_topomap(times=[0.1], size=3.,title=title, time_unit='s')

可以使用' / '分隔的'标记'来选择Epochs中的试验子集。

首先,我们创建一个包含4个条件的Epochs对象。

event_id = {'left/auditory': 1, 'right/auditory': 2,'left/visual': 3, 'right/visual': 4}
epochs_params = dict(events=events, event_id=event_id, tmin=tmin, tmax=tmax,reject=reject)
epochs = mne.Epochs(raw, **epochs_params)print(epochs)

接下来,我们创建左刺激和右刺激试验的平均值。

我们可以使用基本的操作,例如,构建和绘制不同的ERP。

left, right = epochs["left"].average(), epochs["right"].average()# create and plot difference ERP
joint_kwargs = dict(ts_args=dict(time_unit='s'),topomap_args=dict(time_unit='s'))
mne.combine_evoked([left, -right], weights='equal').plot_joint(**joint_kwargs)
    Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EEG : ['EEG 001']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']

这是权重相等的差异。 如果试验编号不平衡,则也可以考虑使每个条件的事件数相等(使用epochs.equalize_event_counts)。 例如,首先,我们为每种情况创建单独的ERP。

aud_l = epochs["auditory", "left"].average()
aud_r = epochs["auditory", "right"].average()
vis_l = epochs["visual", "left"].average()
vis_r = epochs["visual", "right"].average()all_evokeds = [aud_l, aud_r, vis_l, vis_r]
print(all_evokeds)
"""
这可以通过Python列表理解来简化
"""all_evokeds = [epochs[cond].average() for cond in sorted(event_id.keys())]
print(all_evokeds)# 然后,我们也以这种方式构造和绘制左右试验的未加权平均值:
mne.combine_evoked([aud_l, -aud_r, vis_l, -vis_r], weights='equal').plot_joint(**joint_kwargs)
    Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EEG : ['EEG 001']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']Rejecting  epoch based on EOG : ['EOG']
[<Evoked  |  'left/auditory' (average, N=56), [-0.1998, 0.49949] sec, 59 ch, ~3.1 MB>, <Evoked  |  'left/visual' (average, N=67), [-0.1998, 0.49949] sec, 59 ch, ~3.1 MB>, <Evoked  |  'right/auditory' (average, N=62), [-0.1998, 0.49949] sec, 59 ch, ~3.1 MB>, <Evoked  |  'right/visual' (average, N=56), [-0.1998, 0.49949] sec, 59 ch, ~3.1 MB>]

通常,在字典或列表中存储诱发对象是有意义的——无论是不同的条件,还是不同的主题。

"""
如果将它们存储在一个列表中,就可以很容易地对它们求平均值,例如,跨主题(或条件)的总平均值。
"""
grand_average = mne.grand_average(all_evokeds)
mne.write_evokeds('tmp\\tmp-ave.fif', all_evokeds)# 如果“诱发对象”对象存储在词典中,则可以按名称检索它们。
all_evokeds = dict((cond, epochs[cond].average()) for cond in event_id)
print(all_evokeds['left/auditory'])# 除了显式访问外,还可以用于设置标题。
for cond in all_evokeds:all_evokeds[cond].plot_joint(title=cond, **joint_kwargs)

文章来源于网络,仅用于学术交流,不用于商业行为,

若有侵权及疑问,请后台留言,管理员即时删侵!

更多阅读

DEAP:使用生理信号进行情绪分析的数据库(二、实验设计与主观分析)

脑电数据处理分析教程汇总(eeglab, mne-python)

运动想象,脑电情绪等公开数据集汇总

P300脑机接口及数据集处理

快速入门脑机接口:BCI基础(一)

谷歌联合强脑科技进入脑机接口领域
Nature科学报告:根据大脑思维意图来生成对应匹配的图像

如何快速找到脑机接口社区的历史文章?

脑机接口BCI学习交流QQ群:515148456

微信群请扫码添加,Rose拉你进群

(请务必填写备注,eg. 姓名+单位+专业/领域/行业)

长按加群

欢迎点个在看鼓励一下​​​​​​​

Python-EEG处理和事件相关电位(ERP)相关推荐

  1. 脑电分析系列[MNE-Python-20]| 脑电图处理和事件相关电位(ERP)

    今天主要介绍一下MNE-Python中进行脑电图处理和事件相关电位(ERP). 有后台留言问,代码是在哪里运行的.这里说明一下,案例介绍的代码均在jupyter notebook中运行的,当然这些代码 ...

  2. HAPPE+ER:一款让脑电研究人员“更快乐”的软件,可用于事件相关电位(ERP)分析的标准化预处理管道

    导读 事件相关电位(ERP)设计是用脑电图(EEG)检测神经认知功能的常用方法.然而,传统的ERP数据预处理方法是手动编辑,这是一个主观且耗时的过程.最近创建了许多自动化通道,以满足EEG数据预处理的 ...

  3. python与erp_Python-EEG处理和事件相关电位(ERP)

    更多技术干货第一时间送达 脑机接口社区推荐搜索 脑机接口 MNE EEGLAB 算法 汇总 数据 有后台留言问,代码是在哪里运行的.这里说明一下,案例介绍的代码均在jupyter notebook中运 ...

  4. 你对P300事件相关电位知道多少?

    目录 P300简介 P300特性 P300家族 P300脑机接口刺激范式 1.P300的经典范式 P300的应用 本教程为脑机学习者Rose发表于公众号:脑机接口社区 .QQ交流群:903290195 ...

  5. 事件相关电位(ERP)在临床心理学中的运用

    美国佛罗里达州立大学生物医学科学系在Annual review of clinical psychology杂志发表文章,综述了事件相关电位(ERP)在临床心理学中的运用.ERPs是对大脑活动的直接测 ...

  6. 事件相关电位(ERP)的简单处理流程(含MATLAB代码)

    事件相关电位的呈现是在特定频带下的时域波形,从这个角度出发的话,其处理就涉及到滤波:此外由于脑电信号易受噪声干扰,所以单独测出的每两次的数据肯定是不同的,甚至会差别很大,即使是在同一条件下,这就需要去 ...

  7. 脑电信号处理与特征提取——1. 脑电、诱发电位和事件相关电位(胡理)

    目录 一. 脑电.诱发电位和事件相关电位 1.1 EEG基本知识 1.2 经典的ERPs成分及研究 1.2.1 ERPs命名规则及分类 1.2.2 常见的脑电成分 1.2.3 P300及Oddball ...

  8. python安装教程32位-python为什么要装32位的

    Python(发音:英[ˈpaɪθən],美[ˈpaɪθɑ:n]),是一种面向对象.直译式电脑编程语言,也是一种功能强大的通用型语言,已经具有近二十年的发展历史,成熟且稳定.它包含了一组完善而且容易理 ...

  9. Python总结:保留小数点任意位round函数不够精确

    QUESTION:Python总结:保留小数点任意位round函数不够精确 ANWSER: 目录 QUESTION:Python总结:保留小数点任意位round函数不够精确 ANWSER: 一:使用r ...

最新文章

  1. iptables命令(备忘)
  2. 单片机实现环形队列_单片机模块化程序: 难道有环形队列串口发送数据就万事大吉了吗...
  3. ServletConfig对象和ServletContext对象
  4. Bootstrap HTML编码规范之减少标签的数量
  5. Spring Security(四) —— 核心过滤器源码分析
  6. 源码网络-推荐精品×××站
  7. Rpc框架dubbo-client(v2.6.3) 源码阅读(二)
  8. bcb quickrep保存为 图片_不容错过的SCI图片处理和组图方法
  9. 卡巴斯基称发现美国中情局CIA 开发的新恶意软件
  10. 一分钟教你学会配置eslint,还在为风格单双引号,对象末位逗号要不要,引用各种报错而烦恼?(建议收藏!详细中文注释)...
  11. Linux emacs考场配置及对拍脚本
  12. CentOS服务器上搭建Gitlab安装步骤、中文汉化详细步骤、日常管理以及异常故障排查
  13. 小D课堂 - 新版本微服务springcloud+Docker教程_5-07 断路器dashboard监控仪表
  14. win10子系统ubuntu WSL下无法用git下载代码
  15. 怎么把word目录里面的“目录”两个字去掉
  16. C语言输出大写金额,编程实现,输入一个人民币小写金额值,转化为大写金额值输出。先实现基本功能...
  17. 计算机音乐吧粉刷匠,奥尔夫小班音乐活动:《粉刷匠》
  18. tic tac toe php,Python函数找出tic tac toe获胜者
  19. R-S编码译码-缩短码(10,6)
  20. 公众号第三方平台开发 教程六 代公众号使用JS SDK说明

热门文章

  1. ssh 远程登陆异常SSH_EXCHANGE_IDENTIFICATION及解决过程
  2. vs2017 2019 下载更新慢的解决方法
  3. BigDecimal空指针异常——个人应用
  4. 无法在终端中显示Git树
  5. 在不丢失堆栈跟踪的情况下重新抛出Java中的异常
  6. Math.Pow()是如何在.NET Framework中实现的?
  7. 资源已存在时POST的HTTP响应代码
  8. 遍历JavaScript中的数组
  9. vs2015_ef 连接mysql
  10. 【248】◀▶IEW-Unit13