一、什么是 Montage?
1.1 通俗理解
Montage (蒙太奇)在脑电领域指的是电极在头皮上的位置布局。
想象一下:
(1)你的头皮是一张地图 🗺️
(2)每个电极是一个城市标记点 📍
(3)Montage 就是告诉你每个"城市"在地图上的坐标
1.2 为什么 Montage 很重要?
没有位置信息的数据就像:
(1)知道有 64 个人在说话,但不知道他们坐在哪里
(2)知道有温度数据,但不知道温度计放在哪个城市
有了 Montage 才能:
(1)🗺️ 绘制脑地形图(头皮电活动分布图)
(2)🔗 进行源定位(推测大脑内部哪个区域活跃)
(3)📊 对比不同被试的相同脑区
二、10-20 国际标准系统
2.1 什么是 10-20 系统?
这是国际通用的电极放置标准,"10-20"的含义是:
(1)相邻电极之间的距离是头骨前后/左右总距离的 10% 或 20%
2.2 电极命名规则
每个电极名称由字母 + 数字组成:

数字规则:
(1)奇数(1,3,5,7):左侧
(2)偶数(2,4,6,8):右侧
(3)z(zero):中线

2.3 可视化 10-20 系统
python
# 第二天完整代码开头(先运行这个)
import matplotlib
matplotlib.use('TkAgg')
import matplotlib.pyplot as plt
import mne
import numpy as np
import os
from collections import Counter
# 加载数据
sample_data_folder = mne.datasets.sample.data_path()
raw_fname = os.path.join(sample_data_folder, 'MEG', 'sample', 'sample_audvis_raw.fif')
raw = mne.io.read_raw_fif(raw_fname, preload=False)
print("✅ 数据加载完成")
三、实战:探索数据通道(重要!)
在实际分析中,数据往往不像教科书那么"标准"。我们必须先了解数据里有什么,才能正确处理。
3.1 查看通道类型
python
print("\n📊 通道类型统计:")
ch_types = raw.get_channel_types()
type_counts = Counter(ch_types)
for ch_type, count in type_counts.items():
print(f" {ch_type}: {count} 个")
输出示例:
python
mag: 102 个 ← 脑磁图磁力计
grad: 204 个 ← 脑磁图梯度计
eeg: 60 个 ← 脑电图
stim: 1 个 ← 刺激标记通道
eog: 1 个 ← 眼电
3.2 查看 EEG 通道名称(关键!)
python
# 找到所有 EEG 通道的索引
eeg_picks = mne.pick_types(raw.info, eeg=True)
print(f"\nEEG 通道数量: {len(eeg_picks)}")
# 查看 EEG 通道的名称
eeg_names = [raw.ch_names[i] for i in eeg_picks]
print(f"前10个 EEG 通道名称: {eeg_names[:10]}")
关键发现: 实际数据中的 EEG 通道名是 EEG 001, EEG 002, ...,而标准 Montage 中的名称是 Fz, Cz, Pz, ...
这就是设置 Montage 时会报错的原因!
四、解决通道名不匹配问题(实战核心)
4.1 问题诊断流程图
python
数据通道名: EEG 001, EEG 002, EEG 003, ...
↓
❌ 不匹配
↓
标准Montage: Fz, Cz, Pz, C3, C4, ...
↓
【解决方案】
↓
提取EEG通道 → 重命名 → 设置Montage
4.2 解决方案:提取 + 重命名 + 设置
这是最常用的处理方法,分为三步:
python
# ========== 步骤1:提取 EEG 通道 ==========
print("\n步骤1:提取 EEG 通道...")
raw_eeg = raw.copy().pick_types(eeg=True)
print(f" 提取了 {len(raw_eeg.ch_names)} 个 EEG 通道")
print(f" 通道名称示例: {raw_eeg.ch_names[:5]}")
# ========== 步骤2:创建标准 Montage ==========
print("\n步骤2:创建标准 Montage...")
montage = mne.channels.make_standard_montage('standard_1020')
print(f" 标准 Montage 包含 {len(montage.ch_names)} 个电极")
print(f" 标准电极名称示例: {montage.ch_names[:5]}")
# ========== 步骤3:重命名通道 ==========
print("\n步骤3:重命名通道...")
# 建立映射关系:EEG 001 → Fz, EEG 002 → Cz, ...
eeg_names = raw_eeg.ch_names # 原始名称列表
standard_names = montage.ch_names[:len(eeg_names)] # 取相同数量的标准名称
# 创建重命名字典
rename_dict = dict(zip(eeg_names, standard_names))
raw_eeg.rename_channels(rename_dict)
print("✅ 通道已重命名为标准 10-20 名称")
print(f" 示例: {list(rename_dict.items())[:3]}")
print(f" 重命名完成!")
print(f" 新通道名称: {raw_eeg.ch_names[:5]}")
# ========== 步骤4:设置 Montage ==========
print("\n步骤4:设置 Montage...")
raw_eeg.set_montage(montage)
print(" ✅ Montage 设置成功!")
至于为什么要加list,运行这段代码就知道了:
python
rename_dict = {'Fz': 'Frontal', 'Cz': 'Central', 'Pz': 'Parietal', 'Oz': 'Occipital'}
# 情况1:不加 list
print(rename_dict.items())
# 输出:dict_items([('Fz', 'Frontal'), ('Cz', 'Central'), ('Pz', 'Parietal'), ('Oz', 'Occipital')])
# 不能加 [:3],会报错
# 情况2:加 list
print(list(rename_dict.items()))
# 输出:[('Fz', 'Frontal'), ('Cz', 'Central'), ('Pz', 'Parietal'), ('Oz', 'Occipital')]
# 情况3:加 list 并且只取前3个
print(list(rename_dict.items())[:3])
# 输出:[('Fz', 'Frontal'), ('Cz', 'Central'), ('Pz', 'Parietal')] ← 干净清爽
4.3 代码详解
zip() 函数的作用:
python
# zip 将两个列表配对
list1 = ['EEG 001', 'EEG 002', 'EEG 003']
list2 = ['Fz', 'Cz', 'Pz']
# zip 后变成:
# [('EEG 001', 'Fz'), ('EEG 002', 'Cz'), ('EEG 003', 'Pz')]
# dict() 将其变成字典:
# {'EEG 001': 'Fz', 'EEG 002': 'Cz', 'EEG 003': 'Pz'}
⚠️ 重要提示: 这个重命名假设 EEG 001 对应 Fz、EEG 002 对应 Cz...实际情况中,你需要根据实验记录来确定对应关系!
五、可视化电极位置
5.1 2D 电极位置图
python
print("\n显示 2D 电极位置...")
raw_eeg.plot_sensors(show_names=True, title='EEG 电极位置(10-20系统)', block=True)
怎么看这个图?
(1)圆圈代表电极位置
(2)鼻子朝上(上方是额头方向)
(3)左耳在左边,右耳在右边
(4)可以直观看到电极覆盖的脑区
5.2 查看电极坐标
python
print("\n部分电极的 3D 坐标:")
for ch in ['Fz', 'Cz', 'Pz', 'Oz', 'C3', 'C4']:
if ch in montage.ch_names:
pos = montage.get_positions()['ch_pos'][ch]
print(f" {ch}: x={pos[0]*1000:.1f}mm, y={pos[1]*1000:.1f}mm, z={pos[2]*1000:.1f}mm")
输出示例:
python
Fz: x=0.0mm, y=70.0mm, z=0.0mm ← 额头正中
Cz: x=0.0mm, y=0.0mm, z=70.0mm ← 头顶正中
Pz: x=0.0mm, y=-70.0mm, z=0.0mm ← 后脑正中
Oz: x=0.0mm, y=-140.0mm, z=-30.0mm ← 枕骨位置
5.3 3D 电极位置图(可选)
python
print("\n尝试 3D 电极位置...")
try:
raw_eeg.plot_sensors(kind='3d', title='3D 电极位置视图', block=True)
except Exception as e:
print(f" 需要安装 pyvista: pip install pyvista")
六、通道管理技能
6.1 选择特定电极
python
print("\n选择特定电极:")
# 选择运动想象常用的电极
selected = ['Fz', 'Cz', 'Pz', 'C3', 'C4']
raw_selected = raw_eeg.copy().pick([ch for ch in selected if ch in raw_eeg.ch_names])
print(f" 选择的电极: {raw_selected.ch_names}")
# 可视化选中的电极
raw_selected.plot_sensors(show_names=True, title='运动想象常用电极', block=True)
6.2 通道类型修改
python
print("\n修改通道类型:")
# 假设 C3 和 C4 是主要的运动区电极
raw_selected.set_channel_types({
'C3': 'eeg',
'C4': 'eeg',
'Cz': 'eeg'
})
print(f" C3 类型: {raw_selected.get_channel_types(picks='C3')[0]}")
七、完整可运行代码
python
# ========== 环境设置 ==========
import matplotlib
matplotlib.use('TkAgg')
import matplotlib.pyplot as plt
import mne
import numpy as np
import os
from collections import Counter
print("="*60)
print("📘 MNE-Python 第2天:Montage与通道信息管理")
print("="*60)
# ---------- 1. 加载数据 ----------
sample_data_folder = mne.datasets.sample.data_path()
raw_fname = os.path.join(sample_data_folder, 'MEG', 'sample', 'sample_audvis_raw.fif')
raw = mne.io.read_raw_fif(raw_fname, preload=False)
print("✅ 数据加载完成")
# ---------- 2. 探索数据通道 ----------
print("\n📊 通道类型统计:")
ch_types = raw.get_channel_types()
type_counts = Counter(ch_types)
for ch_type, count in type_counts.items():
print(f" {ch_type}: {count} 个")
print("\n🔍 查看 EEG 通道:")
eeg_picks = mne.pick_types(raw.info, eeg=True)
print(f" EEG 通道数量: {len(eeg_picks)}")
print(f" EEG 通道名称示例: {[raw.ch_names[i] for i in eeg_picks[:5]]}")
# ---------- 3. 提取 EEG + 重命名 + 设置 Montage ----------
print("\n🔧 处理步骤:提取 → 重命名 → 设置 Montage")
# 步骤1:提取 EEG 通道
raw_eeg = raw.copy().pick_types(eeg=True)
print(f" 步骤1: 提取了 {len(raw_eeg.ch_names)} 个 EEG 通道")
# 步骤2:创建标准 Montage
montage = mne.channels.make_standard_montage('standard_1020')
print(f" 步骤2: 标准 Montage 有 {len(montage.ch_names)} 个电极")
# 步骤3:重命名
eeg_names = raw_eeg.ch_names
standard_names = montage.ch_names[:len(eeg_names)]
rename_dict = dict(zip(eeg_names, standard_names))
raw_eeg.rename_channels(rename_dict)
print(f" 步骤3: 重命名完成,示例: {list(rename_dict.items())[:3]}")
# 步骤4:设置 Montage
raw_eeg.set_montage(montage)
print(" 步骤4: ✅ Montage 设置成功!")
# ---------- 4. 可视化 ----------
print("\n🎨 可视化电极位置:")
raw_eeg.plot_sensors(show_names=True, title='EEG 电极位置(10-20系统)', block=True)
# ---------- 5. 通道操作练习 ----------
print("\n🔧 通道操作练习:")
selected = ['Fz', 'Cz', 'Pz', 'C3', 'C4']
raw_selected = raw_eeg.copy().pick([ch for ch in selected if ch in raw_eeg.ch_names])
print(f" 选择的电极: {raw_selected.ch_names}")
raw_selected.set_channel_types({'C3': 'eeg', 'C4': 'eeg'})
print(" ✅ 通道类型设置完成")
print("\n" + "="*60)
print("✅ 第2天学习完成!")
print("="*60)