ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

EEGLAB安装、EDF数据导入与脑电预处理全流程详解(Matlab)

EEGLAB安装、EDF数据导入与脑电预处理全流程详解(Matlab) EEGLAB 这套工具链我前前后后折腾了小半年从安装一路做到预处理出干净数据中间踩过的坑比想象中多得多。今天这篇就围绕“EEGLAB 安装、EDF 数据导入、EEG 预处理Matlab”这个主线把整套流程掰开揉碎讲清楚。不管你是刚接触脑电的初学者还是已经在跑实验、攒了一批 EDF 文件等着处理的科研党这篇文章都能给你一套能直接照做的方案省去你翻论坛、试错的时间。先说清楚这套东西解决什么问题EEGLAB 是 Matlab 环境下最主流的开源 EEG 分析工具箱你拿到手的原始脑电数据通常是 EDF 格式欧洲数据格式医院设备、开源数据集里很常见里面混着工频干扰、眼电、肌电、漂移没法直接用。安装好 EEGLAB把 EDF 读进去再做滤波、重参考、去伪迹、坏导插值这一套预处理流程走完才能得到能用于后续 ERP 分析、时频分析、脑网络分析的干净数据。适合谁看刚装好 Matlab、连 EEGLAB 都还没装上的人有数据但导入报错的人对预处理流程只有模糊概念、想知道每一步为什么这样做的人。我尽量用直白的话讲原理用能复现的步骤讲操作每个环节都说清楚“为什么”而不是丢给你一串命令。1. 环境准备先搞定 Matlab 和 EEGLAB 安装1.1 Matlab 版本选择和安装的坑这一步看起来简单实际上很多新手在版本兼容性上栽跟头。EEGLAB 官方支持的 Matlab 版本范围很宽从 R2013b 到最新的 R2024a 基本都能跑但不同版本对工具箱函数、Java 环境、绘图渲染的兼容性有差异。我个人长期用的是 R2021b 和 R2023a跑 EEGLAB 2023.0 都没问题处理高密度 128 导数据也不卡。安装 Matlab 时有几个必须注意的点安装路径不要带中文不要带空格最好直接放根目录比如C:\MATLAB\R2023a。EEGLAB 对路径里的特殊字符很敏感目录里有中文会导致很多插件加载报错。安装时务必勾选必要的工具箱至少包含 Signal Processing Toolbox、Statistics and Machine Learning Toolbox、Image Processing Toolbox某些插件间接依赖。如果没装后续 EEGLAB 某些函数会报错补齐安装即可不用重装整个 Matlab。首次启动后用ver命令检查工具箱是否齐全。提示Matlab 版本太老比如 R2014a 之前跑新版 EEGLAB 会缺失类定义语法支持无法加载 GUI。反过来Matlab 太新而 EEGLAB 版本太老也可能出现图形对象句柄兼容问题。总之优先选择近两年发布的 EEGLAB 版本。1.2 EEGLAB 插件下载与安装流程EEGLAB 的正式下载地址在 GitHub 和官网sccn.ucsd.edu/eeglab下载的是一个压缩包解压后就是一个包含eeglab.m的文件夹。安装不是双击而是把文件夹放到 Matlab 的搜索路径下。我推荐的做法是把整个eeglab文件夹放到C:\MATLAB\eeglab然后在 Matlab 命令行执行addpath(C:\MATLAB\eeglab) eeglab这样会启动 EEGLAB 的图形界面。但问题来了每次重启 Matlab 都要重新 addpath太麻烦。所以要在 Matlab 的home目录下建一个startup.m文件把 addpath 和 eeglab 命令写进去以后启动 Matlab 就自动打开 EEGLAB。这是我的习惯实测下来省了非常多事。% startup.m addpath(genpath(C:\MATLAB\eeglab)); eeglab;genpath会把 eeglab 下所有子目录都加进去包括插件目录这样后续装完插件后就不用再手动加路径。执行完eeglab后会弹出两个窗口一个是主界面一个是欢迎/新闻窗口后者可以关掉不影响使用。插件安装通常在两步打开 EEGLAB 菜单栏的File Manage EEGLAB extensions在列表里找到需要的插件比如 ICLabel、clean_rawdata、ERPLAB、dipfit点击安装。如果网络不好也可以从官网手动下载插件压缩包解压后放到eeglab/plugins目录重启 EEGLAB 即可。某些插件需要编译二进制文件比如 clean_rawdata 在 Windows 下会有 .mexw64 文件如果相关插件报“mex file not found”说明你的 Matlab 版本和插件编译版本不匹配可以安装插件源码版或者在 Matlab 中执行mex -setup配置编译器后在插件目录下运行mex_all重新编译。装好之后在命令行输入which clean_rawdata如果出现路径说明插件就绪。1.3 一键检查安装是否成功的小技巧安装完别急着导数据先跑一个 EEGLAB 自带的样例数据确认环境是好的。命令如下[ALLEEG EEG CURRENTSET ALLCOM] eeglab; eeglab redraw; load(eeglab_data_epochs_ica.set, -mat, EEG); EEG eeg_checkset(EEG); eeglab redraw我第一次装完光验证环境就花了十分钟结果发现某插件缺失导致整个工具箱打开闪退。所以这里郑重建议装完先做环境验证避免在数据处理中途才暴露问题。2. EDF 数据导入从文件到 EEGLAB 的完整流程2.1 EDF/EDF 格式的本质EDFEuropean Data Format是脑电、睡眠、心电等生理信号的通用存储格式。它由文件头header和信号数据块组成。文件头里记录了患者信息、记录起止时间、导联数、采样率、每导联的增益和偏移量等。EEGLAB 借助pop_biosig或pop_fileio来读取 EDF前者依赖 Biosig 工具箱后者依赖 FileIO 插件。在导入前我建议先用第三方工具比如 EDFbrowser查看一下 EDF 文件的基本信息比如导联名称、采样率、数据时长做到心里有数。你不需要知道 EDF 的字节级解析规则但你要知道你的数据是不是标准的 EDF有些设备厂商会自定义扩展头导致 EEGLAB 读出来导联顺序错乱或者单位不对。2.2 导入 EDF 的具体操作步骤在 EEGLAB 界面中点击菜单File Import data Using EEGLAB functions and plugins From EDF/EDF/BDF files (Biosig)。弹出文件选择框选中你的 .edf 文件。导入窗口里通常不需要改任何参数直接点 OK。如果导入成功主界面的数据集列表里会出现该数据集右侧显示采样点数、通道数、时间长度。用命令行的方式更加可控尤其是批量导入多文件时EEG pop_biosig(C:\data\subject01.edf); % 也可以指定范围导入 EEG pop_biosig(C:\data\subject01.edf, channels, [1:64]);我在实际工作中更倾向于先读取事件信息再导入。很多 EDF 文件其实带有事件标记比如刺激呈现、按键反应EEGLAB 会自动解析EDF annotations通道生成EEG.event。有些情况下这个注释通道会被当作普通通道导入导致后面分析时多了一个通道此时可以手动pop_select去掉。2.3 导入报错后的几个排查方向我见过最多的问题有三个提示文件无法读取或不是有效 EDF。多半是文件扩展名是 .edf但内部格式是 GDF 或其他私有格式。可用 EDFbrowser 另存为标准 EDF。导入后采样率异常比如变成 0 或负数。通常是文件头中采样率字段被写入异常改用pop_fileio读取一次。导入后波形显示出现竖直的直线跳变或者幅值单位不对通常是增益参数读取错误可以在pop_biosig后面的参数中重新指定单位或基于原始信号先乘以一个系数校准。注意EDF 文件如果太大超过几百 MB建议先用 EDFbrowser 做切割把单个文件切到 5 分钟以内再导入 EEGLAB。EEGLAB 的 GUI 在加载超大文件时容易卡死命令行导入稳定性稍好但内存占用依然很高。2.4 从导入到可视化的快速检查导入数据后第一件事不是预处理而是先画图看原始数据长什么样。用pop_eegplot(EEG, 1, 1, 1);这个命令会弹出滚动数据窗口可以逐通道查看原始波形。我通常按这几个维度做快速目检看整体幅值范围是否在合理区间微伏级别但不同放大器差异大一般在 ±200μV 内算正常看是否有通道完全平线或全是噪声看是否有明显的周期性 50Hz 工频干扰看是否有大幅漂移低频伪迹这一步建立的是“数据感觉”。预处理参数不是照抄模板的而是要看你自己的数据脏在什么地方。有些数据坏在工频有些坏在眼电有些坏在运动伪迹处理侧重点完全不一样。3. EEG 预处理全流程拆解每一步都在做什么拿到原始 EEG 数据后不能直接做 ERP 或时频分析必须先把信号中无关的伪迹和噪声去除。我把整个流程拆成六步顺序很重要每一步解决一类问题。3.1 第一步定位电极位置导入通道信息EEGLAB 里很多后续处理重参考、插值坏导、头皮拓扑图依赖电极坐标。如果你用的是国际 10-20 系统EEGLAB 自带标准坐标文件高密度设备如 128 导需要加载制造商提供的.loc、.ced或.sfp文件。导入 EDF 后通道名称通常是 Fz、Cz、Pz 这类但坐标没有读入。此时菜单Edit Channel locations弹出通道编辑窗口点击Read locations选择标准文件比如standard-10-5-cap385.elp如果通道名匹配坐标会自动赋上若某些通道找不到则需检查通道名是否标准比如有的文件里叫FZ而标准文件叫Fz需要手动改。命令行方式EEG pop_chanedit(EEG, lookup, C:\MATLAB\eeglab\plugins\dipfit\standard_BEM\elec\standard_1005.elc);这一步不做后面跑 ICA 和插值的时候会报“channel not found”或“cannot compute distance”。3.2 第二步去除直流漂移和低频漂移脑电信号本身以低频成分为主但数据记录过程中电极与皮肤之间的极化电位、受试者出汗、设备的基线漂移会让整个波形缓慢上下移动。这种漂移频率极低低于 0.1 Hz如果不滤掉会严重影响后续 ICA 分解。处理方式有两种使用高通滤波截止频率 0.5 Hz 或 1 Hz。对于关注低频成分如慢皮层电位的研究截止频率得放低到 0.01-0.05 Hz。使用 detrend 函数去除线性趋势但这只对线性漂移有效。更推荐用 FIR 高通滤波。EEGLAB 的pop_eegfiltnew函数是业界标准EEG pop_eegfiltnew(EEG, 0.5, 0);0.5是低截止频率0表示不做低通。如果你还想滤掉高频噪声可以同时设定两个截止频率比如 0.5 到 60 Hz。这里解释一下为什么是 0.5 Hz 而不是 1 Hz对于许多认知实验ERP 中的慢波成分如 CNV、晚期正电位频率较低1 Hz 高通可能会把这些成分削掉0.5 Hz 是兼顾去除漂移和保留慢波的折中。3.3 第三步去除 50Hz/60Hz 工频干扰市电造成的工频干扰在国内是 50 Hz部分地区是 60 Hz它表现为波形上有规律的细密抖动。只要实验室接地没做好采集到的数据基本都带工频。处理手段首选陷波滤波器notch filterEEGLAB 也支持但我更推荐使用 CleanLine 插件。原因在于固定陷波滤波器会在 50 Hz 附近削掉一定的幅值带宽如果 50 Hz 漂移了环境变化导致固定陷波就没用而 CleanLine 是基于自适应估计的它实时估计 50 Hz 及其谐波并去除对多通道数据效果更好。安装 CleanLine 后EEG pop_cleanline(EEG, linefreqs, 50, chanlist, 1:EEG.nbchan, ... computeSpectralPower, 0);如果你的数据采样率是 1000 Hz且后续要做的事件相关谱扰动ERSP分析也可以在 55 Hz 低通时直接滤掉 50 Hz省一步操作。但这样的话高于 50 Hz 的频率全都没了若研究 gamma 频段就不能这么干。3.4 第四步坏导检测与插值脑电采集过程中个别电极与头皮接触不良、导电膏干了或电极线松动会使该通道信号呈现持续平坦、幅值异常大或者全是高频尖波。这类通道叫坏导。坏导不一定要删除更常用的是标记后插值。EEGLAB 中可以用clean_rawdata插件自动检测坏导也可以肉眼观察。自动检测代码EEGclean clean_rawdata(EEG, 5, 0.8, 4, off, off, off);参数含义第一个5表示坏道检测阈值通道在该方差比例下是坏道0.8表示通道间相关性阈值4表示某通道如果与邻近通道的相关性低于该值则判为坏道后面几个 off 表示关闭其他步骤。运行后EEGclean.etc.clean_channel_mask中会标记哪些通道被剔除。我实际操作时不太放心自动检测的结果通常结合手动检查。先用pop_eegplot逐个通道回放把看起来完全平线或噪声显著异常的通道记录下来然后统一插值。EEG pop_select(EEG, nochannel, {Fz, Cz}); % 先删除坏导 EEG pop_interp(EEG, ref_chanlocs); % 用周围通道插值注意pop_interp需要参考原有全部通道的位置信息来插值所以最好创建一个包含原始通道坐标的ref_chanlocs变量在删坏导前保存好。3.5 第五步重参考——为什么不能直接看单极导联原始记录的电压是各电极相对于参考电极的差值国内设备常用参考位置是 Cz 或 A1/A2 乳突。由于参考点本身的电位并非零而且不同参考位置会对数据分析结果产生系统性影响所以预处理时一般要重参考。最常见的重参考方式是全脑平均参考即每个时间点用所有电极的平均电位作为新参考。这样做的好处是参考对整体信号的影响被平均化不偏向某一特定脑区缺点是在电极覆盖不均匀时平均参考会引入偏置。另一个常用方式是双侧乳突平均参考linked mastoids适合奠基性 ERP 研究。代码EEG pop_reref(EEG, []);默认空括号表示全脑平均参考。如果需要指定参考电极EEG pop_reref(EEG, [88 89]); % 假设通道 88 89 是左右乳突重参考之后再插值的顺序需要注意如果先重参考再插值插值通道会因为参考改变而重新计算理论上没问题但有些插件实现会有 bug所以稳妥起见我都是先插值坏导再重参考。顺序滤波 → 去工频 → 坏导插值 → 重参考 → 再插值若重参考过程误删通道→ 去伪迹。3.6 第六步剔除运动/眼电等噪声伪迹脑电里除了生理信号还有眼电眨眼、眼球运动、肌电咬牙、颈部紧张、心电和大幅度头动伪迹。这些伪迹幅值大、频率成分与脑电重叠不能简单用滤波去除。当前的主流方法是 ICA独立成分分析把多通道混合信号分解为统计独立的成分其中眼电、肌电、心电会集中在少数几个成分上识别后剔除再重建信号。EEGLAB 做 ICA 的流程如下在 3.2-3.5 步处理后的数据上运行EEG pop_runica(EEG, icatype, runica, extended, 1);使用 ICLabel 插件自动分类成分EEG pop_iclabel(EEG, default);查看每个成分的类别概率如brain、muscle、eye、heart、line noise、channel noise。手动标记坏成分EEG pop_selectcomps(EEG, [1 3 5]); % 选择要剔除的成分序号剔除并重建EEG pop_subcomp(EEG, [1 3 5], 0);这里0表示剔除成分后不保留数据副本。问我为什么用 ICA 而不是简单阈值剔除因为 ICA 能在高密度数据中分离空间上叠加的伪迹这是传统幅值阈值无法做到的。但前提是通道数足够多建议不少于 32 导若只有 8 通道ICA 分解效果会很差。眼电伪迹还有一种比较老的方法是用 VEOG/HEOG 通道回归去除效果不如 ICA我现在很少用。3.7 分段与基线校正为后续分析打地基伪迹剔除后如果是事件相关实验需要把连续数据切分成 epoch。切分后以刺激前一段时间为基线做基线校正目的是去除分段残余漂移造成的水平位移。EEG pop_epoch(EEG, {Stimulus}, [-0.2 0.8]); % 刺激前 200ms刺激后 800ms EEG pop_rmbase(EEG, [-200 0]); % 基线校正分段后还可以运行一次自动伪迹拒绝检测幅值超过 ±100μV 的试次并剔除EEG pop_eegthresh(EEG,1, 1:EEG.nbchan, -100, 100, -0.2, 0.8, 1, 1);不过现代的推荐做法是分段后再次做 ICA 成分识别后剔除。因为连续数据上 ICA 和分段后 ICA 识别出的眨眼、肌电会有细微差别分段后再分类有时更准。我一般连续数据 ICA 后用 ICLabel 粗筛一次分段后再复查一次剔除遗留的伪迹成分。4. 工具选型解析不是所有预处理都必须用 GUI4.1 GUI 操作 vs 脚本批处理的选择刚开始学 EEGLAB很多人习惯纯 GUI 点击。但等你手里有几十个被试、每个被试多个条件时纯 GUI 会让你重复点几千下而且无法保证每步参数完全一致。所以我的建议是GUI 用来学习和探索正式处理一定要写脚本。EEGLAB 每个菜单操作其实都会生成对应的命令行代码并且记录在EEG.history中。你可以打开Edit About EEGLAB查看当前数据集的历史操作或者用EEG.history把里面的命令行代码提取出来改成循环就能批量处理所有被试。这是 EEGLAB 设计得非常聪明的地方菜单操作到代码的无缝衔接让新手也能快速转型为脚本党。4.2 clean_rawdata、ICLabel、dipfit 等插件的分工这几个插件各管一段clean_rawdata负责坏导检测、剔除坏段、还会做 ASRArtifact Subspace Reconstruction伪迹重建。ASR 的原理是找到一段干净的校准数据计算各通道的统计特性遇到大段突然出现的伪迹时ASR 会将高方差子空间重构为低方差从而保留脑电而压制伪迹。这个插件对运动伪迹很有效果。ICLabel负责在 ICA 后对成分自动分类是深度神经网络模型预训练的返回每个成分属于 brain / muscle / eye / heart / line noise / channel noise / other 的概率。省去大量人工识别时间。dipfit负责脑电源定位如果你做源分析需要用到它做预处理时它主要提供标准电极坐标文件。我的常用组合是clean_rawdata做自动坏导剔除和坏段剔除然后用 ASR 清理连续数据中的瞬态大伪迹再做 ICA再用 ICLabel 自动标记成分人工检查一眼后剔除。4.3 Matlab 工具箱之间的依赖关系EEGLAB 依赖 Signal Processing Toolbox 的滤波函数如firls、firfilt、Statistics Toolbox 的聚类/随机函数。还有不少插件依赖dipfit自带的标准头模型文件。如果你发现某个函数报“Undefined function”优先检查对应插件是否加载而不是急着重装。5. 常见问题与排查技巧实录我把这些年遇到的高频问题整理成一张速查表再展开讲几个典型案例。现象大概率原因解决方案pop_biosig找不到函数未安装 Biosig 插件在 Manage EEGLAB extensions 中安装 biosig 插件或手动解压到 pluginsclean_rawdata报 mex 文件错误插件编译版本与 Matlab 不匹配下载源码版用mex -setup和mex_all重新编译导入 EDF 后事件为空EDF 注释通道被忽略检查 EDF 中是否含有 annotations用pop_biosig时指定blockrange通道位置不匹配通道命名不规范批量替换通道名或用自动查找模板ICA 分解时间过长数据太长或通道数过多先做降采样到 250Hz再跑 ICA滤波后波形边缘出现振铃使用了零相位滤波导致的边缘效应分段前直接对连续数据滤波滤波后丢弃边缘 0.5sICLabel 概率全为 other数据预处理不规范成分不像真信号检查是否未重参考、是否含有大量残留伪迹插值后某些通道数值异常插值边界通道位置差异大检查通道位置文件是否正确5.1 案例一EDF 导入后所有通道波形都是一条直线有次从合作医院拿到一份夜间睡眠 EDF导入 EEGLAB 后画图发现所有通道是平的。检查文件头才知道这份 EDF 记录的是微伏μV的数据但文件头里的增益字段被第三方软件写错了导致实际数值被压缩到几乎为 0。我使用 EDFbrowser 将文件重新缩放保真后再次用 pop_biosig 导入波形正常。遇到这种情况不要怀疑 EEGLAB 坏了先怀疑文件本身的元数据。5.2 案例二眨眼成分在 ICLabel 里被识别为 brainICLabel 不是万能的它训练的样本更倾向于成人清醒状态的 EEG如果你处理的是儿童数据或者睡眠数据眨眼成分和 alpha 波的空间模式可能跟训练集差异较大导致分类不准。我的做法是结合成分地形图和时程图人工判断。眨眼成分通常在地形图上呈现前额眼上方强正/负分布时间历程呈现突发性强波动频谱能量集中在低频0-5Hz但不像 alpha 那样有显著峰。人工判断优先级高于 ICLabel。5.3 案例三ASR 把正常慢波削掉了ASR 默认参数是偏保守的但遇到有较大慢波比如睡眠慢波或运动想象任务中的 mu 节律时ASR 可能将其当作伪迹重构掉。解决方法是调整 ASR 参数中的 cutoff 值默认 20改为 30 或 40 会减少对合理信号的抑制。另一个办法是只对存在强运动伪迹的数据段使用 ASR其他数据只用 ICA 处理。提示预处理参数必须记录并写入方法学部分。论文里写“EEGLAB 默认参数”是不行的要写清楚滤波截止频率、陷波频率、坏导判据、ICA 成分数量、ICLabel 分类阈值、ASR cutoff 值等。5.4 案例四批量处理时不同被试的坏导数量差很多这很正常。有的被试戴帽子时某个电极被头发挡住有的被试出汗导致乳突参考电极阻抗过高。批量脚本里不能固定坏导列表要每个文件分别检测。我是这样处理的先用 clean_rawdata 自动检测坏导再用pop_select删除之后插值每个文件都会记录一份坏导名单最后汇总成报表。这样处理可重复性更好也不会漏掉指标。6. 我的实操流程总结与补充建议整个流程走下来我个人最满意的预处理管线是下面这个顺序针对一般认知实验的 64-128 导数据导入 EDF检查事件检查采样率加载电极坐标0.5 Hz 高通滤波FIR50 Hz CleanLine 去工频clean_rawdata坏导检测flatline5corr0.8line4自动剔除坏段插值坏导全脑平均重参考分段-0.2s 到 0.8s基线校正再检查一次坏导插值ICA 分解ICLabel 分类 人工复查剔除眼动/肌电/心电成分概率 0.8 或人工判断自动阈值拒绝±100μV可结合概率分布判断保存清洗后的数据集。这套流程我基本没有改动过大量数据跑下来后续统计结果很稳定。关于参数是“经验值”还是“科学值”的问题我想多说两句。很多刚入门的同学喜欢问高通滤波截止频率到底用 0.1 还是 0.5ICA 迭代次数越多越好吗正确答案是由你的研究问题和数据特性决定。如果是 P50 感觉门控研究P50 在刺激后 50ms 左右需要 0.1-0.5Hz 高通保留慢波如果是 N400 研究0.5Hz 高通足够。处理前先查文献中同类研究怎么设置的然后固定下来不要在拿到结果后再回头改参数去凑显著那就成了 p-hacking。预处理过程中还有一个大家容易忽略的点保存数据的时候父集original data和子集preprocessed data要分开EEGLAB 的 STUDY 结构体里有 parent 和 child 关系。我习惯每个被试保存为两个文件sub01_raw.set和sub01_clean.set清晰可追溯。最后再分享一个小技巧我踩过很多次坑之后发现EDF 数据在导入后最好先把EEG.subject和EEG.session字段填好。这个看起来不影响波形处理但等你要把所有被试合并成 STUDY 时这两个字段会自动成为分组变量缺了它合并时会乱成一团。每次导入后EEG.subject S01; EEG.session 1; EEG eeg_checkset(EEG);养成这个习惯后面多被试分析能轻松一大截。还有一点关于数据量。如果你一次性导入 1 小时的高密度数据内存占用可能逼近 2GB加上 ICA 运算电脑容易卡死。我通常先把原始数据分割成 2 分钟的连续片段分段预处理后再拼回去。EEGLAB 里可以用eeg_eegrej按时间窗口切割处理完再用pop_mergeset拼接。这个方式在采集时长较长的睡眠研究里尤其实用。最后EEGLAB 也不该是你工具箱里的唯一选择。预处理阶段你可以对比 EEGLAB 和 MNE-Python基于 Python 的脑电处理库的结果两者结合使用能交叉验证。但如果你是纯 Matlab 用户EEGLAB 加这几个插件已经足够应付绝大多数场景了。文章里提供的参数和步骤都是我实际跑过的方案新手可以直接照用用一段时间后再根据自己的数据特点做微调那才是你自己的预处理管线。
返回列表