瞳孔动力学揭示L2自动驾驶认知负荷:基线瞳孔直径比TEPR更可靠

论文信息

  • 标题: Pupillary dynamics during hands-off L2 driving and transitions of control under high cognitive load
  • 发表: 2026年 (PubMed ID: 42579679)
  • 领域: 自动驾驶人机交互、认知负荷监测
  • 链接: https://pubmed.ncbi.nlm.nih.gov/42579679/

核心发现

这项研究揭示了L2自动驾驶中瞳孔动力学与认知负荷的关键关系:

  1. 基线瞳孔直径(而非TEPR振幅)是认知负荷的可靠指标
  2. 基线瞳孔越大 → TEPR越小 — 持续高负荷状态下任务诱发反应减弱
  3. 这一关系在纠正瞳孔光反射后依然成立
  4. 对DMS设计有直接指导意义:持续监测基线瞳孔直径比等待任务事件更可靠

技术背景

瞳孔与认知的关系链

1
2
3
4
5
认知负荷 ↑ 
→ 大脑顶叶/前额叶活动 ↑
→ Locus Coeruleus (蓝斑核) 去甲肾上腺素 ↑
→ 瞳孔扩大 ↑ (交感激活, 副交感抑制)
→ 基线瞳孔直径 ↑

两种瞳孔指标

指标 定义 物理意义 检测难度
基线瞳孔直径 任务前静息态瞳孔大小 持续性认知负荷累积 低(持续测量)
TEPR (Task-Evoked Pupillary Response) 任务事件引起的瞳孔变化幅度 事件相关认知投入 高(需事件同步)

传统认知与本研究发现对比

传统假设 本研究颠覆
TEPR是认知负荷的金标准 基线瞳孔更可靠
基线瞳孔只是参考 基线瞳孔是核心指标
需要设计特定任务来诱发TEPR 持续监测基线即可
瞳孔标准差反映负荷波动 平均值才是可靠指标

技术方案

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
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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
"""
L2自动驾驶瞳孔认知负荷监测系统
基于: Pupillary dynamics during hands-off L2 driving (2026)

核心: 持续监测基线瞳孔直径,而非等待任务事件
依赖:opencv, numpy
"""

import numpy as np
from typing import Tuple, List
from dataclasses import dataclass

@dataclass
class PupilMetrics:
"""瞳孔指标数据类"""
baseline_diameter: float # 基线瞳孔直径 (mm)
current_diameter: float # 当前瞳孔直径 (mm)
tepr: float # 任务诱发瞳孔响应 (mm)
cognitive_load_index: float # 认知负荷指数 (0-1)
arousal_level: float # 唤醒水平 (0-1)
load_trend: str # 负荷趋势: rising/stable/falling

class PupillaryCognitiveMonitor:
"""
瞳孔认知负荷监测器

论文核心结论:
- 基线瞳孔直径均值是认知负荷的可靠指标
- 基线越高 → TEPR越小 (负荷饱和效应)
- 持续监测比事件触发更实用

部署: DMS摄像头 + IR补光 → 瞳孔检测 → 认知负荷评估
"""

def __init__(self,
baseline_window: int = 30, # 基线窗口30秒
sampling_rate: int = 60, # 60Hz瞳孔检测
plr_correction: bool = True, # 瞳孔光反射校正
load_threshold: float = 0.7): # 高负荷阈值
self.baseline_window = baseline_window
self.sampling_rate = sampling_rate
self.plr_correction = plr_correction
self.load_threshold = load_threshold

# 滑动窗口
self.pupil_history: List[float] = []
self.luminance_history: List[float] = []
self.max_history = baseline_window * sampling_rate

# 基线
self.resting_baseline = 4.0 # 静息基线瞳孔 (mm), 需标定

def update(self, pupil_diameter: float, luminance: float) -> PupilMetrics:
"""
更新瞳孔数据并计算指标

Args:
pupil_diameter: 当前瞳孔直径 (mm)
luminance: 当前环境照度 (lux)

Returns:
PupilMetrics: 瞳孔指标
"""
# 瞳孔光反射校正
if self.plr_correction:
corrected_diameter = self._correct_plr(pupil_diameter, luminance)
else:
corrected_diameter = pupil_diameter

# 更新历史
self.pupil_history.append(corrected_diameter)
self.luminance_history.append(luminance)

if len(self.pupil_history) > self.max_history:
self.pupil_history.pop(0)
self.luminance_history.pop(0)

# 计算指标
baseline = np.mean(self.pupil_history) if len(self.pupil_history) >= 10 else corrected_diameter
tepr = corrected_diameter - baseline
cognitive_index = self._compute_load_index(baseline)
arousal = self._compute_arousal(baseline)
trend = self._compute_trend()

return PupilMetrics(
baseline_diameter=baseline,
current_diameter=corrected_diameter,
tepr=tepr,
cognitive_load_index=cognitive_index,
arousal_level=arousal,
load_trend=trend
)

def _correct_plr(self, diameter: float, luminance: float) -> float:
"""
瞳孔光反射(PLR)校正

瞳孔大小同时受认知负荷和光照影响
需要去除光照引起的瞳孔变化

PLR模型: D = D_cognitive * f(luminance)
f(l) = 4.0 + 1.5 * exp(-l / 100) # 简化模型
"""
# 经验PLR函数
plr_predicted = 4.0 + 1.5 * np.exp(-luminance / 100)
plr_ratio = diameter / (plr_predicted + 1e-6)

# 校正后的直径 (去除光照效应)
corrected = self.resting_baseline * plr_ratio
return np.clip(corrected, 2.0, 8.0)

def _compute_load_index(self, baseline: float) -> float:
"""
计算认知负荷指数 (0-1)

基线瞳孔直径越大 → 负荷越高
归一化到静息基线
"""
# 线性归一化
load = (baseline - self.resting_baseline) / (self.resting_baseline * 0.5)
return np.clip(load, 0.0, 1.0)

def _compute_arousal(self, baseline: float) -> float:
"""
计算唤醒水平 (LC-NE系统代理)

蓝斑核-去甲肾上腺素系统活动
与瞳孔基线直接相关
"""
# Sigmoid归一化
arousal = 1.0 / (1.0 + np.exp(-(baseline - self.resting_baseline) / 0.3))
return float(arousal)

def _compute_trend(self) -> str:
"""计算负荷趋势"""
if len(self.pupil_history) < 30:
return "stable"

recent = np.mean(self.pupil_history[-30:])
older = np.mean(self.pupil_history[-60:-30]) if len(self.pupil_history) >= 60 else recent

diff = recent - older
if diff > 0.1:
return "rising"
elif diff < -0.1:
return "falling"
return "stable"

def should_alert(self, metrics: PupilMetrics) -> Tuple[bool, str]:
"""是否需要发出认知负荷警告"""
if metrics.cognitive_load_index > self.load_threshold:
if metrics.load_trend == "rising":
return True, "认知负荷持续上升,建议接管"
elif metrics.cognitive_load_index > 0.85:
return True, "认知负荷过高,存在分心风险"

return False, ""


# 测试
if __name__ == "__main__":
monitor = PupiliaryCognitiveMonitor(
baseline_window=30,
sampling_rate=60,
plr_correction=True
)

# 模拟L2驾驶场景
np.random.seed(42)

# 场景1: 正常驾驶 (低负荷)
print("=== 场景1: 正常L2驾驶 ===")
for t in range(60):
pupil = 4.2 + np.random.randn() * 0.1 # 基线附近
lux = 500 + np.random.randn() * 20
m = monitor.update(pupil, lux)
print(f"基线瞳孔: {m.baseline_diameter:.2f}mm")
print(f"认知负荷: {m.cognitive_load_index:.2f}")
print(f"唤醒水平: {m.arousal_level:.2f}")
alert, msg = monitor.should_alert(m)
print(f"警告: {alert} {msg}")

# 场景2: 高负荷接管 (执行副任务)
print("\n=== 场景2: 高认知负荷 ===")
for t in range(120):
pupil = 5.0 + np.random.randn() * 0.15 # 基线扩大
lux = 480 + np.random.randn() * 20
m = monitor.update(pupil, lux)
print(f"基线瞳孔: {m.baseline_diameter:.2f}mm")
print(f"认知负荷: {m.cognitive_load_index:.2f}")
print(f"唤醒水平: {m.arousal_level:.2f}")
print(f"趋势: {m.load_trend}")
alert, msg = monitor.should_alert(m)
print(f"警告: {alert} {msg}")

# 场景3: 极端负荷
print("\n=== 场景3: 极端认知负荷 ===")
for t in range(120):
pupil = 5.8 + np.random.randn() * 0.2 # 接近最大
lux = 460 + np.random.randn() * 20
m = monitor.update(pupil, lux)
print(f"基线瞳孔: {m.baseline_diameter:.2f}mm")
print(f"认知负荷: {m.cognitive_load_index:.2f}")
alert, msg = monitor.should_alert(m)
print(f"警告: {alert} {msg}")

架构图


与现有PERCLOS方案的互补

维度 PERCLOS 瞳孔基线 互补性
检测对象 眼睑闭合 瞳孔直径 不同生理通道
时间尺度 60秒窗口 30秒窗口 更快响应
负荷类型 疲劳负荷 认知/情绪负荷 不同维度
L2接管 不敏感 高度敏感 关键场景
光照依赖 低 高(需PLR校正) 需IR+光传感
计算成本 低 中 可接受

多模态融合方案

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
class MultiModalCognitiveMonitor:
"""
PERCLOS + 瞳孔基线 + 眨眼频率 多模态融合
"""

def __init__(self):
self.perclos_window = 60 # 60秒
self.pupil_window = 30 # 30秒
self.blink_window = 60 # 60秒

def compute_combined_load(self, perclos: float, pupil_baseline: float,
blink_rate: float) -> dict:
"""
计算综合认知负荷

Args:
perclos: PERCLOS值 (0-100)
pupil_baseline: 基线瞳孔直径 (mm)
blink_rate: 眨眼频率 (次/分钟)

Returns:
综合负荷评估
"""
# 各维度归一化
fatigue_score = min(perclos / 30.0, 1.0) # PERCLOS > 30% = 严重疲劳
cognitive_score = min((pupil_baseline - 4.0) / 2.0, 1.0) # 基线>6mm = 高负荷
blink_score = min(abs(blink_rate - 15) / 15, 1.0) # 偏离15次/分

# 加权融合
combined = 0.4 * fatigue_score + 0.4 * cognitive_score + 0.2 * blink_score

return {
'fatigue': fatigue_score,
'cognitive': cognitive_score,
'blink_anomaly': blink_score,
'combined': combined,
'level': self._classify(combined)
}

def _classify(self, score: float) -> str:
if score < 0.3: return "正常"
elif score < 0.6: return "轻度负荷"
elif score < 0.8: return "中度负荷"
else: return "严重负荷"

IMS开发启示

1. L2接管检测的终极方案

Euro NCAP 2026要求”无响应驾驶员干预”,瞳孔基线是接管前早期预警的理想指标:

场景 PERCLOS 瞳孔基线 建议
正常L2驾驶 <10% ~4.0mm 无需干预
轻度分心 10-20% ~4.5mm 一级提醒
认知超载 15-25% ~5.5mm 二级警告
疲劳+分心 >30% ~5.0mm 紧急接管

2. 硬件需求

组件 规格 说明
IR摄像头 OV2311, 2MP, 全局快门 现有DMS方案
IR补光 940nm, 120mW/sr 现有DMS方案
光传感器 TSL2591, 0.1-88000 lux PLR校正必需
处理 QCS8255 Hexagon NPU 瞳孔检测+PLR校正

3. Euro NCAP 2026对应

Euro NCAP要求 瞳孔方案 满足度
认知分心检测 基线瞳孔持续监测 ✅ 首个量化方案
L2接管预警 高负荷→TEPR饱和 ✅
驾驶员干预 极端负荷触发接管 ✅
实时性 30秒窗口, 60Hz采样 ✅

总结

这项研究的IMS价值不在于瞳孔检测技术本身(已有成熟方案),而在于以下关键认知:

  • 基线瞳孔直径 > TEPR — 持续监测比事件触发更可靠
  • 基线越高 → TEPR越小 — 负荷饱和效应,不能只看TEPR
  • L2接管场景 — 瞳孔是认知超载的最早生理标志
  • 与PERCLOS互补 — 一个测疲劳,一个测认知,双管齐下