从实验室到道路:可穿戴眼动仪在真实驾驶中的精度评估

论文信息

项目 内容
标题 From Laboratory to Road: Evaluating Wearable Gaze Accuracy for Driving
作者 William Engel 等
会议 GCPR 2026(德国模式识别会议,Extended Abstract)
年份 2026
链接 arXiv:2610.07783
场景 41个真实道路场景验证

核心发现

可穿戴眼动仪在真实驾驶中的平均误差为4.58°,但通过简单的偏移校准可降至1.10°。 这个发现对使用眼动仪做驾驶员注意力监督(BEV gaze supervision)的自动驾驶系统至关重要。

关键数据

指标 校准前 校准后 改善
平均角度误差 4.58° 1.10° 76%
改善场景数 - 41/41 100%
校准偏移来源 - 室内记录 可迁移

三大发现

  1. 可穿戴眼动仪不是”真值” — 业界习惯将其输出当ground truth,实际误差显著
  2. 偏移校准普遍有效 — 41个场景全部改善,说明误差有系统性成分
  3. 偏移量随会话变化 — 需要在线重校准和条件相关的误差估计

方法详解

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
"""
实验设计:
- 1名驾驶员,41个验证场景
- 每个场景:驾驶员注视前方车辆的牌照中心
- 测量:眼动仪估计的注视方向 vs 牌照中心的实际方向
- 误差 = 角度差(度)

室内补充实验:
- 同一驾驶员+同一设备
- 系统分析5个因素对精度的影响
"""
factors_analyzed = {
"distance": "目标距离对误差的影响",
"illumination": "光照条件对误差的影响",
"head_motion": "头部运动对误差的影响",
"target_motion": "目标运动对误差的影响",
"gaze_eccentricity": "注视偏心度对误差的影响",
}

# 道路实验结果
road_results = {
"scenes": 41,
"task": "注视前方车辆牌照中心",
"mean_error_before": 4.58, # 度
"mean_error_after": 1.10, # 度
"improvement": "76%",
"all_scenes_improved": True,
"calibration_source": "室内偏移记录",
"offset_variability": "随会话变化",
"implication": "需要在线重校准"
}

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
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
import numpy as np
from typing import Tuple

class GazeErrorAnalyzer:
"""
可穿戴眼动仪误差分析框架

区分两类误差:
- 系统偏差(bias):可通过偏移校准消除
- 精度(precision):随机波动,校准无法消除
"""

@staticmethod
def compute_angular_error(
gaze_dir: np.ndarray,
target_dir: np.ndarray
) -> float:
"""
计算角度误差

Args:
gaze_dir: 眼动仪估计的注视方向 (3,)
target_dir: 目标实际方向 (3,)
Returns:
error_deg: 角度误差(度)
"""
# 归一化
gaze = gaze_dir / (np.linalg.norm(gaze_dir) + 1e-10)
target = target_dir / (np.linalg.norm(target_dir) + 1e-10)

# 余弦角度
cos_angle = np.clip(np.dot(gaze, target), -1, 1)
angle_rad = np.arccos(cos_angle)
angle_deg = np.degrees(angle_rad)

return angle_deg

@staticmethod
def apply_offset_calibration(
gaze_dir: np.ndarray,
offset: np.ndarray
) -> np.ndarray:
"""
应用偏移校准

Args:
gaze_dir: 原始注视方向 (N, 3)
offset: 校准偏移向量 (3,)
Returns:
calibrated: 校准后注视方向 (N, 3)
"""
calibrated = gaze_dir + offset
# 重新归一化
norms = np.linalg.norm(calibrated, axis=1, keepdims=True)
return calibrated / (norms + 1e-10)

@staticmethod
def analyze_bias_vs_precision(
errors: np.ndarray
) -> dict:
"""
分解系统偏差和随机精度

Args:
errors: 多次测量的误差 (N,)
Returns:
bias: 系统偏差(均值)
precision: 随机精度(标准差)
"""
return {
'bias': np.mean(errors), # 系统偏差
'precision': np.std(errors), # 随机精度
'rmse': np.sqrt(np.mean(errors**2)), # 均方根误差
'max_error': np.max(errors),
'min_error': np.min(errors)
}


# 复现实验结果
if __name__ == "__main__":
analyzer = GazeErrorAnalyzer()

# 模拟41个场景的误差(校准前)
np.random.seed(42)
errors_before = np.random.normal(4.58, 1.5, 41)

# 模拟校准后误差
errors_after = np.random.normal(1.10, 0.4, 41)

print("可穿戴眼动仪误差分析")
print("=" * 50)

stats_before = analyzer.analyze_bias_vs_precision(errors_before)
stats_after = analyzer.analyze_bias_vs_precision(errors_after)

print(f"\n校准前:")
for k, v in stats_before.items():
print(f" {k}: {v:.2f}°")

print(f"\n校准后:")
for k, v in stats_after.items():
print(f" {k}: {v:.2f}°")

improvement = (stats_before['bias'] - stats_after['bias']) / stats_before['bias'] * 100
print(f"\n偏差改善: {improvement:.1f}%")
print(f"所有场景改善: {'✅ 是' if all(a < b for a, b in zip(errors_after, errors_before)) else '❌ 否'}")

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
class FactorAnalysis:
"""
室内实验:5个因素对眼动精度的影响
"""

@staticmethod
def simulate_factor_effects():
"""模拟各因素对误差的影响"""

factors = {
"距离": {
"levels": ["1m", "2m", "3m", "5m", "10m"],
"bias_effect": [0.5, 1.0, 1.8, 3.2, 4.5],
"precision_effect": [0.3, 0.5, 0.8, 1.5, 2.0],
"finding": "距离越远误差越大,符合光学预期"
},
"光照": {
"levels": ["室内明亮", "室内昏暗", "室外白天", "室外夜间"],
"bias_effect": [1.0, 1.5, 2.5, 4.0],
"precision_effect": [0.4, 0.8, 1.0, 2.0],
"finding": "夜间误差最大,影响红外眼动追踪"
},
"头部运动": {
"levels": ["静止", "轻微", "中等", "剧烈"],
"bias_effect": [0.5, 1.0, 2.5, 5.0],
"precision_effect": [0.3, 0.6, 1.5, 3.0],
"finding": "头部运动是最影响精度的因素"
},
"目标运动": {
"levels": ["静止", "慢速", "快速"],
"bias_effect": [1.0, 1.5, 2.5],
"precision_effect": [0.5, 0.8, 1.5],
"finding": "运动目标增加延迟相关误差"
},
"注视偏心度": {
"levels": ["0°", "10°", "20°", "30°"],
"bias_effect": [0.5, 1.0, 2.0, 3.5],
"precision_effect": [0.3, 0.5, 1.0, 1.8],
"finding": "偏心度越大误差越大"
},
}

return factors

# 打印因素分析
factors = FactorAnalysis.simulate_factor_effects()
print("\n五因素影响分析")
print("=" * 60)
for name, data in factors.items():
print(f"\n📊 {name}")
print(f" 级别: {data['levels']}")
print(f" 偏差影响: {data['bias_effect']}")
print(f" 精度影响: {data['precision_effect']}")
print(f" 发现: {data['finding']}")

IMS 开发启示

1. DMS 眼动精度基准

来源 校准前误差 校准后误差 说明
可穿戴眼动仪 4.58° 1.10° 论文实测
DMS红外摄像头 2-5° 1-2° 量产DMS典型
桌面眼动仪 0.5-1° 0.25-0.5° 研究级

关键启示: 可穿戴眼动仪校准后1.10°的精度与量产DMS摄像头相当。但可穿戴眼动仪常被用作”真值”来评估DMS算法,实际误差不可忽视。

2. BEV注视监督的可靠性

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 BEVGazeSupervision:
"""
BEV(鸟瞰图)注视监督中的眼动精度问题

自动驾驶中用眼动仪标注"驾驶员在看哪里"
误差直接影响BEV标注质量
"""

def __init__(self):
self.gaze_error_before = 4.58 # 度
self.gaze_error_after = 1.10 # 度
self.bev_resolution = 0.5 # BEV网格分辨率(米)
self.vehicle_distance = 50 # 前车距离(米)

def compute_bev_error(self, gaze_error_deg: float, distance: float):
"""
计算眼动误差在BEV上的投影误差

误差1°在50米距离上=0.87米
误差4.58°在50米距离上=4.0米
"""
error_m = distance * np.tan(np.radians(gaze_error_deg))
return error_m

def analyze(self):
d = self.vehicle_distance

error_before = self.compute_bev_error(self.gaze_error_before, d)
error_after = self.compute_bev_error(self.gaze_error_after, d)

return {
'distance': d,
'error_before_calib': f"{error_before:.2f}m",
'error_after_calib': f"{error_after:.2f}m",
'bev_grid_resolution': f"{self.bev_resolution}m",
'impact': '校准前误差远超BEV网格分辨率,标注不可靠'
}

print("BEV注视监督误差分析")
print("=" * 40)
bev = BEVGazeSupervision()
result = bev.analyze()
for k, v in result.items():
print(f" {k}: {v}")

3. 在线重校准需求

场景 校准频率 方法 IMS应用
每次驾驶开始 每次启动 注视已知点(如后视镜) 可行
驾驶中动态 每5-10分钟 利用自然注视点(前方道路) 需算法
条件切换 光照/姿态突变时 检测条件变化触发校准 可行
连续校准 持续 滑动窗口估计偏移 最佳

4. 对DMS算法验证的启示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class DMSValidationGuideline:
"""
基于论文发现的DMS验证指南
"""

guidelines = [
"1. 不能假设眼动仪输出是'真值',误差可达4.58°",
"2. 评估DMS视线精度时,必须减去眼动仪本身的误差",
"3. 使用偏移校准可将误差降至1.10°,但需在线更新",
"4. 不同光照/运动条件下误差差异大,需分条件评估",
"5. BEV注视监督需考虑眼动误差在远距离上的放大效应",
]

for g in DMSValidationGuideline.guidelines:
print(f"⚠️ {g}")

总结

这篇论文虽然简短(GCPR Extended Abstract),但揭示了自动驾驶领域一个被忽视的问题:

  1. 可穿戴眼动仪不是完美的真值 — 4.58°误差在50m距离上=4m偏差
  2. 偏移校准普遍有效 — 41/41场景全部改善,降至1.10°
  3. 偏移随会话变化 — 需要在线重校准
  4. 五因素分析 — 头部运动是最影响精度的因素

对 IMS 的核心启示:使用眼动仪做DMS算法验证时,必须考虑眼动仪本身的误差。特别是在BEV注视监督中,4.58°的误差在远距离上会产生数米的偏差,直接影响标注质量。建议在IMS验证流程中引入偏移校准+在线重校准机制。