长时间窄范围注视估计:差分估计方法解决长时驾驶注视漂移

论文信息

项目 内容
标题 Adapting Appearance-Based Gaze Estimation to Narrow-Range, Long-Duration Screen Viewing
作者 Jordan Prescott et al.
arXiv 2610.11036
发表时间 2026年10月8日
关键词 注视估计、差分估计、长时间驾驶、屏幕观看、窄范围

核心创新

解决长时间窄范围注视(如长时间驾驶/屏幕观看)中注视估计漂移的问题。

问题定义

场景 注视范围 持续时间 传统方法问题
驾驶 窄(前方±30°) 1-8小时 漂移累积
屏幕观看 窄(屏幕内±15°) 数小时 精度下降
实验室校准 全范围(±60°) 分钟级 可用但不可持续

差分估计方法

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

class DifferentialGazeEstimator:
"""
差分注视估计器

论文核心思想:
不直接估计绝对注视角度,
而是估计相对于前一帧的注视变化量

优势:
1. 消除累积漂移
2. 对缓慢变化不敏感
3. 适合长时间窄范围场景
"""

def __init__(self, initial_gaze: np.ndarray = None):
"""
Args:
initial_gaze: 初始注视方向 (pitch, yaw) in degrees
"""
self.current_gaze = initial_gaze if initial_gaze is not None else np.array([0.0, 0.0])
self.gaze_history = [self.current_gaze.copy()]
self.confidence_history = []

def update(self, delta_gaze: np.ndarray, confidence: float = 0.8) -> np.ndarray:
"""
差分更新注视方向

Args:
delta_gaze: (2,) 注视变化量 (delta_pitch, delta_yaw) in degrees
confidence: 估计置信度 0-1

Returns:
current_gaze: 更新后的注视方向
"""
# 低置信度时衰减更新
alpha = confidence * 0.9 # 平滑因子

# 差分更新
self.current_gaze = self.current_gaze + alpha * delta_gaze

# 记录历史
self.gaze_history.append(self.current_gaze.copy())
self.confidence_history.append(confidence)

# 保持历史长度
if len(self.gaze_history) > 300: # 10秒@30fps
self.gaze_history.pop(0)
self.confidence_history.pop(0)

return self.current_gaze.copy()

def detect_drift(self, window: int = 60) -> float:
"""
检测累积漂移

Args:
window: 检测窗口大小(帧数)

Returns:
drift: 窗口内的总漂移量(度)
"""
if len(self.gaze_history) < window:
return 0.0

recent = np.array(self.gaze_history[-window:])
drift = np.linalg.norm(recent[-1] - recent[0])
return float(drift)

def recalibrate(self, anchor_gaze: np.ndarray, weight: float = 0.5):
"""
在线重校准

当检测到漂移或驾驶员有明确的注视点时
用锚点修正当前估计

Args:
anchor_gaze: (2,) 校准锚点注视方向
weight: 校准权重 0-1
"""
self.current_gaze = (1 - weight) * self.current_gaze + weight * anchor_gaze
print(f"重校准: {self.current_gaze}")


# 对比:绝对估计 vs 差分估计
class AbsoluteGazeEstimator:
"""传统绝对注视估计(对比基线)"""

def __init__(self):
self.history = []

def estimate(self, features: np.ndarray) -> np.ndarray:
"""直接回归绝对角度"""
# 简化实现
gaze = np.array([0.0, 0.0]) # 实际用CNN回归
self.history.append(gaze)
return gaze


# 测试
if __name__ == "__main__":
np.random.seed(42)

# 模拟长时间驾驶注视
true_gaze = np.array([0.0, 0.0])
diff_estimator = DifferentialGazeEstimator(initial_gaze=true_gaze.copy())

# 模拟300帧(10秒@30fps)
for i in range(300):
# 真实注视变化(缓慢漂移+小幅扫视)
delta = np.random.randn(2) * 0.3 # 小变化
if i == 150:
delta += np.array([5.0, 0]) # 大幅扫视

true_gaze += delta

# 模拟估计噪声
delta_noisy = delta + np.random.randn(2) * 0.5

# 差分更新
estimated = diff_estimator.update(delta_noisy, confidence=0.85)

if i % 100 == 0:
error = np.linalg.norm(estimated - true_gaze)
print(f"帧{i}: 真值={true_gaze.round(2)}, 估计={estimated.round(2)}, 误差={error:.2f}°")

drift = diff_estimator.detect_drift(window=60)
print(f"\n最近60帧漂移: {drift:.2f}°")

IMS开发启示

1. 长时间驾驶的注视漂移问题

当前IMS注视估计器在长时间运行后会出现精度下降。差分估计提供了一种解决方案:

方案 累积误差 实时性 实现复杂度 推荐
绝对估计(当前) 1-3°/小时 高 低 短时可用
差分估计 <0.5°/小时 高 中 ⭐长时间推荐
定期重校准 1°/小时 高 中 辅助手段
两者融合 <0.3°/小时 高 中高 ⭐最优

2. 在线重校准时机

触发条件 方法 可靠性
驾驶员看前方路中 车道检测+注视对齐 高
驾驶员看后视镜 已知位置+注视收敛 中
车辆直线行驶 轨迹+注视一致性 中
检测到漂移>1° 自动触发 高

3. 对IMS现有模块的影响

1
2
3
4
5
6
7
8
9
10
11
IMS注视估计增强方案:

当前管路:
人脸关键点 → 头部姿态 → 眼球方向 → 绝对注视角度 → 视线落点

增强管路:
人脸关键点 → 头部姿态 → 眼球方向 → 差分注视变化
↓
差分估计器 → 注视角度 → 视线落点
↓
漂移检测 → 在线重校准

论文arXiv: 2610.11036