单通道耳内EEG预测驾驶员分心:实时监测新突破

论文信息

核心创新

首次验证单通道耳内EEG可实时解码驾驶员认知分心状态,且时序特性与传统24通道头皮EEG高度一致。这解决了传统EEG系统不实用的问题——传统系统需要佩戴多电极帽,无法在真实驾驶环境中应用。

关键发现:

  • 耳内EEG检测延迟与头皮EEG基本同步
  • 眼动速度是最早期的行为标记
  • 单通道方案精度略低但时序稳定性达标

方法详解

1. 实验设计

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
"""
实验设置:高沉浸驾驶模拟器双任务范式
"""
class DualTaskParadigm:
"""
双任务设计:
1. 主任务:持续车辆控制
2. 次任务:心算问题(低/高认知负荷)

目的:诱发认知分心状态
"""

def __init__(self):
# 驾驶模拟器:VICTOR (BMW i3平台)
self.simulator = {
'platform': 'BMW i3 mockup',
'display': '275° curved screen',
'render': 'SILAB 7.0',
'frame_rate': 60
}

# 次任务:心算
self.secondary_task = {
'type': 'mental_arithmetic',
'display': 'central dashboard',
'levels': ['low_load', 'high_load']
}

# 数据采集
self.sensors = {
'ear_eeg': {
'device': 'IDUN in-ear EEG',
'channels': 1,
'sampling_rate': 250
},
'scalp_eeg': {
'device': 'mBrainTrain SMARTING',
'channels': 24,
'sampling_rate': 250
},
'eye_tracking': {
'device': 'Tobii Pro Glasses 3',
'metrics': ['gaze_position', 'pupil_diameter']
}
}

2. 时序解码方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
import numpy as np
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
from sklearn.model_selection import cross_val_score

class TimeResolvedMVPA:
"""
时序多变量模式分析 (MVPA)

核心思想:
- 使用LDA在每个时间点解码认知负荷状态
- 时间泛化分析评估解码稳定性
"""

def __init__(self, time_window=1000, step=50):
self.time_window = time_window # ms
self.step = step # ms
self.lda = LinearDiscriminantAnalysis()

def decode_time_resolved(self, X, y, times):
"""
时序解码主函数

Args:
X: (n_trials, n_channels, n_times) EEG数据
y: (n_trials,) 标签 (0=低负荷, 1=高负荷)
times: 时间轴 (ms)

Returns:
decoding_accuracy: 每个时间点的解码准确率
"""
n_trials, n_channels, n_times = X.shape
decoding_acc = []

# 滑动窗口解码
for t in range(0, n_times - self.time_window, self.step):
# 提取时间窗口特征
X_window = X[:, :, t:t+self.time_window].mean(axis=2)

# 交叉验证
scores = cross_val_score(
self.lda, X_window, y, cv=5
)
decoding_acc.append(scores.mean())

return np.array(decoding_acc)

def temporal_generalization(self, X, y):
"""
时间泛化分析

训练在时间t,测试在时间t'
评估解码模型的时序稳定性
"""
n_trials, n_channels, n_times = X.shape
gen_matrix = np.zeros((n_times, n_times))

# 训练每个时间点的模型
models = []
for t in range(n_times):
X_t = X[:, :, t]
model = LinearDiscriminantAnalysis()
model.fit(X_t, y)
models.append(model)

# 测试跨时间泛化
for i, model in enumerate(models):
for j in range(n_times):
X_test = X[:, :, j]
gen_matrix[i, j] = model.score(X_test, y)

return gen_matrix

3. 信号预处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
import mne
from scipy.signal import butter, filtfilt

class EEGPreprocessing:
"""EEG信号预处理流程"""

def __init__(self, sfreq=250):
self.sfreq = sfreq

def preprocess_pipeline(self, raw_eeg):
"""
预处理管道

步骤:
1. 带通滤波 (1-40 Hz)
2. 陷波滤波 (50 Hz)
3. ICA去伪迹
4. 重参考
"""
# 带通滤波
raw_eeg = self._bandpass_filter(raw_eeg, 1, 40)

# 陷波滤波
raw_eeg = self._notch_filter(raw_eeg, 50)

# ICA去伪迹(眼动、肌电)
# 单通道使用简化方法
raw_eeg = self._artifact_removal(raw_eeg)

return raw_eeg

def _bandpass_filter(self, data, low, high):
"""Butterworth带通滤波"""
nyq = self.sfreq / 2
b, a = butter(4, [low/nyq, high/nyq], btype='band')
return filtfilt(b, a, data, axis=-1)

def _notch_filter(self, data, freq):
"""陷波滤波去除工频干扰"""
nyq = self.sfreq / 2
b, a = butter(2, [(freq-1)/nyq, (freq+1)/nyq], btype='bandstop')
return filtfilt(b, a, data, axis=-1)

def _artifact_removal(self, data):
"""
伪迹去除

单通道EEG使用阈值法:
- 幅值超过±100 μV视为伪迹
- 使用滑动窗口中值替代
"""
threshold = 100e-6 # 100 μV
window = 500 # samples

for i in range(len(data)):
if abs(data[i]) > threshold:
# 用窗口中值替代
start = max(0, i - window//2)
end = min(len(data), i + window//2)
data[i] = np.median(data[start:end])

return data

实验结果

1. 解码性能对比

模态 峰值准确率 检测延迟 时序稳定性
24通道头皮EEG 68% 320 ms
单通道耳内EEG 62% 340 ms
眼动速度 71% 180 ms
头部旋转 55% 420 ms

2. 时序特性分析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
"""
关键时序发现
"""
temporal_findings = {
'early_markers': {
'eye_velocity': {
'latency': '180 ms',
'interpretation': '眼动速度最早反映认知负荷变化'
},
'eeg_theta': {
'latency': '320 ms',
'interpretation': '前额叶theta升高反映认知努力'
}
},

'temporal_overlap': {
'ear_vs_scalp': {
'correlation': 0.92,
'interpretation': '耳内EEG与头皮EEG时序高度一致'
}
},

'scalp_topography': {
'peak_regions': ['F3', 'F4', 'Fz'],
'interpretation': '前额叶和眼动控制区主导解码'
}
}

3. 神经机制

研究发现解码相关的脑电信号与以下过程紧密关联:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
neural_mechanisms = {
'frontal_theta': {
'frequency': '4-7 Hz',
'role': '工作记忆负荷',
'increase': '认知负荷↑ → theta功率↑'
},

'alpha_suppression': {
'frequency': '8-12 Hz',
'role': '注意力分配',
'decrease': '认知投入↑ → alpha功率↓'
},

'oculomotor_link': {
'evidence': '解码最强信号位于眼动控制区',
'interpretation': '认知负荷影响眼动模式,EEG间接反映'
}
}

代码复现

完整解码流程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
"""
单通道耳内EEG认知分心解码完整示例
"""
import numpy as np
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
from sklearn.model_selection import StratifiedKFold
import matplotlib.pyplot as plt

class EarEEGDecoder:
"""耳内EEG认知分心解码器"""

def __init__(self, sfreq=250, epoch_window=(-0.5, 2.0)):
self.sfreq = sfreq
self.epoch_window = epoch_window
self.preprocessor = EEGPreprocessing(sfreq)

def decode_cognitive_load(self, raw_eeg, events, labels):
"""
解码认知负荷

Args:
raw_eeg: 原始EEG数据 (n_samples,)
events: 事件标记时间点 (n_events,)
labels: 认知负荷标签 (n_events,) 0=低, 1=高

Returns:
results: 解码结果字典
"""
# 1. 预处理
clean_eeg = self.preprocessor.preprocess_pipeline(raw_eeg)

# 2. 分段(epoch)
epochs = self._extract_epochs(clean_eeg, events)

# 3. 特征提取
features = self._extract_features(epochs)

# 4. 时序解码
decoding_curve = self._time_resolved_decode(features, labels)

# 5. 时间泛化分析
gen_matrix = self._temporal_generalization(features, labels)

return {
'decoding_accuracy': decoding_curve,
'generalization_matrix': gen_matrix,
'peak_accuracy': np.max(decoding_curve),
'peak_latency': np.argmax(decoding_curve) * 4 # ms
}

def _extract_epochs(self, eeg, events):
"""提取事件相关分段"""
pre_samples = int(abs(self.epoch_window[0]) * self.sfreq)
post_samples = int(self.epoch_window[1] * self.sfreq)
epoch_len = pre_samples + post_samples

epochs = []
for event_time in events:
start = event_time - pre_samples
end = event_time + post_samples

if start >= 0 and end < len(eeg):
epochs.append(eeg[start:end])

return np.array(epochs)

def _extract_features(self, epochs):
"""提取频域特征"""
from scipy.fft import fft

n_epochs, n_times = epochs.shape
features = np.zeros((n_epochs, n_times, 5)) # 5个频带

# FFT提取频带功率
freqs = np.fft.fftfreq(n_times, 1/self.sfreq)

for i, epoch in enumerate(epochs):
fft_vals = np.abs(fft(epoch))

# 频带定义
bands = {
'delta': (1, 4),
'theta': (4, 8),
'alpha': (8, 12),
'beta': (12, 30),
'gamma': (30, 40)
}

for j, (band, (low, high)) in enumerate(bands.items()):
mask = (freqs >= low) & (freqs < high)
features[i, :, j] = fft_vals[mask].mean() if mask.any() else 0

return features

def _time_resolved_decode(self, features, labels):
"""时序解码"""
n_epochs, n_times, n_features = features.shape

decoding_acc = []
cv = StratifiedKFold(n_splits=5, shuffle=True)

for t in range(n_times):
X_t = features[:, t, :]

scores = []
for train_idx, test_idx in cv.split(X_t, labels):
X_train, X_test = X_t[train_idx], X_t[test_idx]
y_train, y_test = labels[train_idx], labels[test_idx]

lda = LinearDiscriminantAnalysis()
lda.fit(X_train, y_train)
scores.append(lda.score(X_test, y_test))

decoding_acc.append(np.mean(scores))

return np.array(decoding_acc)

def _temporal_generalization(self, features, labels):
"""时间泛化矩阵"""
n_epochs, n_times, n_features = features.shape

# 训练所有时间点的模型
models = []
for t in range(n_times):
X_t = features[:, t, :]
lda = LinearDiscriminantAnalysis()
lda.fit(X_t, labels)
models.append(lda)

# 计算泛化矩阵
gen_matrix = np.zeros((n_times, n_times))
for i, model in enumerate(models):
for j in range(n_times):
X_test = features[:, j, :]
gen_matrix[i, j] = model.score(X_test, labels)

return gen_matrix


# 使用示例
if __name__ == "__main__":
# 模拟数据
np.random.seed(42)
n_samples = 60000 # 4分钟 @ 250Hz
n_events = 100

raw_eeg = np.random.randn(n_samples) * 50e-6 # 50 μV噪声
events = np.sort(np.random.randint(1000, n_samples-1000, n_events))
labels = np.random.randint(0, 2, n_events)

# 解码
decoder = EarEEGDecoder()
results = decoder.decode_cognitive_load(raw_eeg, events, labels)

print(f"峰值准确率: {results['peak_accuracy']:.1%}")
print(f"峰值延迟: {results['peak_latency']} ms")

可视化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
def plot_decoding_results(results, times):
"""可视化解码结果"""

fig, axes = plt.subplots(1, 2, figsize=(12, 5))

# 1. 解码准确率曲线
ax = axes[0]
ax.plot(times, results['decoding_accuracy'], 'b-', linewidth=2)
ax.axhline(0.5, color='gray', linestyle='--', label='Chance')
ax.axvline(0, color='red', linestyle=':', label='Stimulus onset')
ax.set_xlabel('Time (ms)')
ax.set_ylabel('Decoding Accuracy')
ax.set_title('Time-Resolved Decoding')
ax.legend()
ax.grid(True, alpha=0.3)

# 2. 时间泛化矩阵
ax = axes[1]
im = ax.imshow(results['generalization_matrix'],
extent=[times[0], times[-1], times[-1], times[0]],
cmap='RdBu_r', vmin=0.4, vmax=0.8)
ax.set_xlabel('Testing Time (ms)')
ax.set_ylabel('Training Time (ms)')
ax.set_title('Temporal Generalization')
plt.colorbar(im, ax=ax, label='Accuracy')

plt.tight_layout()
plt.savefig('ear_eeg_decoding_results.png', dpi=150)
plt.show()

IMS应用启示

1. 多模态融合方案

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
class MultimodalCognitiveDetector:
"""
多模态认知分心检测系统

融合:
- 耳内EEG(神经信号)
- 眼动追踪(行为信号)
- 座舱摄像头(视觉信号)
"""

def __init__(self):
# 各模态检测器
self.ear_eeg_decoder = EarEEGDecoder()
self.eye_velocity_analyzer = EyeVelocityAnalyzer()
self.video_analyzer = VideoCognitiveAnalyzer()

# 融合层
self.fusion_layer = nn.Sequential(
nn.Linear(3, 16),
nn.ReLU(),
nn.Linear(16, 2)
)

def detect(self, eeg_stream, eye_data, video_frame):
"""
多模态融合检测

优先级:
1. 眼动速度(最快,180ms)
2. 耳内EEG(中等,340ms)
3. 视频分析(最慢,500ms+)
"""
# 早期警告(眼动)
eye_prob = self.eye_velocity_analyzer(eye_data)
if eye_prob > 0.8:
return self._early_alert(eye_prob)

# 中期确认(EEG)
eeg_prob = self.ear_eeg_decoder(eeg_stream)

# 晚期综合(视频)
video_prob = self.video_analyzer(video_frame)

# 融合决策
probs = torch.tensor([eye_prob, eeg_prob, video_prob])
final_prob = self.fusion_layer(probs)

return final_prob

2. 实时监测架构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
"""
实时认知负荷监测系统架构
"""
class RealtimeCognitiveMonitor:
"""实时认知负荷监测"""

def __init__(self, buffer_size=30): # 30秒缓冲
self.buffer_size = buffer_size
self.eeg_buffer = []
self.event_buffer = []

# 警告阈值
self.thresholds = {
'early_warning': 0.6, # 眼动触发
'warning': 0.7, # EEG确认
'alert': 0.85 # 综合判断
}

def process_frame(self, eeg_sample, eye_sample, timestamp):
"""
处理单帧数据

流程:
1. 实时眼动分析(最快)
2. 滑动窗口EEG解码(中等)
3. 综合判断与警告
"""
# 更新缓冲
self.eeg_buffer.append(eeg_sample)
if len(self.eeg_buffer) > self.buffer_size * 250:
self.eeg_buffer.pop(0)

# 1. 眼动实时分析
eye_load = self._analyze_eye_velocity(eye_sample)

# 2. EEG滑动窗口解码
if len(self.eeg_buffer) >= 5 * 250: # 至少5秒数据
eeg_load = self._decode_eeg_window()
else:
eeg_load = 0.5 # 数据不足,中性值

# 3. 综合判断
cognitive_load = 0.4 * eye_load + 0.6 * eeg_load

# 4. 生成警告
return self._generate_alert(cognitive_load, timestamp)

def _generate_alert(self, load, timestamp):
"""生成分级警告"""
if load > self.thresholds['alert']:
return {
'level': 3,
'type': 'COGNITIVE_OVERLOAD',
'message': '认知负荷过高,请停车休息',
'timestamp': timestamp
}
elif load > self.thresholds['warning']:
return {
'level': 2,
'type': 'COGNITIVE_DISTRACTION',
'message': '注意力分散,请集中驾驶',
'timestamp': timestamp
}
elif load > self.thresholds['early_warning']:
return {
'level': 1,
'type': 'ATTENTION_DROP',
'message': '注意力下降提示',
'timestamp': timestamp
}

return None

3. Euro NCAP对接

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
def map_to_encap_cognitive_assessment(cognitive_load_score):
"""
映射到Euro NCAP认知分心评估

Euro NCAP 2026要求:
- 认知分心检测(新增)
- 持续监测
- 分级警告
"""
if cognitive_load_score > 0.8:
# 高认知负荷,建议接管
return {
'encap_level': 'SEVERE',
'action': 'RECOMMEND_TAKEOVER',
'points': 0 # 扣分项
}
elif cognitive_load_score > 0.6:
# 中度分心,警告
return {
'encap_level': 'MODERATE',
'action': 'WARNING',
'points': 2
}
elif cognitive_load_score > 0.4:
# 轻度,提示
return {
'encap_level': 'MILD',
'action': 'INFORMATION',
'points': 3
}
else:
# 正常
return {
'encap_level': 'NORMAL',
'action': 'NONE',
'points': 4 # 满分
}

4. 硬件集成方案

方案 传感器 成本 精度 实用性
方案A 耳内EEG耳机 $200 高(日常穿戴)
方案B 座舱摄像头 $50
方案C EEG+眼动融合 $300
方案D 头皮EEG帽 $500+ 低(不实用)

推荐方案: 方案C(多模态融合),耳内EEG作为核心,眼动追踪作为早期预警。

技术亮点总结

方面 贡献
硬件创新 首次验证单通道耳内EEG可行
时序分析 提供毫秒级解码精度
多模态对比 系统比较EEG/眼动/头部运动
实用价值 低侵入性方案适合量产

参考文献

  1. Li et al., “Driver Distraction From the EEG Perspective: A Review”, 2024
  2. Ronca et al., “EEG-based distraction index”, 2024
  3. Euro NCAP, “Occupant Monitoring Protocol”, 2026

开发优先级: 🔴 高(认知分心是Euro NCAP 2026新增要求)
技术成熟度: TRL 4(实验室验证)
部署难度: 中等(需耳内EEG硬件配合)
量产时间线: 2027-2028年(预估)


单通道耳内EEG预测驾驶员分心:实时监测新突破
https://dapalm.com/2026/07/23/2026-07-23-ear-eeg-cognitive-distraction/
作者
Mars
发布于
2026年7月23日
许可协议