GazeDPTR:大规模车内注视估计综合方案——CVPR 2024论文解读与IMS启示

论文:What Do You See in Vehicle? Comprehensive Vision Solution for In-Vehicle Gaze Estimation
作者:Yihua Cheng, Yaning Zhu, Zongji Wang 等
会议:CVPR 2024
数据集:IVGaze(44,705张图片,125名受试者)

核心创新

本文提供了车内注视估计的综合解决方案——IVGaze数据集 + GazeDPTR模型 + 透明棋盘标定法。GazeDPTR(Dual-stream Gaze Pyramid Transformer)通过双流处理原始图像和归一化图像,在极端头部旋转下保持6.71°角误差。

一句话总结: 首个大规模车内注视数据集(125人,含眼镜/口罩)+ 双流金字塔Transformer = 车内注视估计SOTA。

问题定义

车内注视估计三大挑战

挑战 描述 现有方法缺陷
数据稀缺 无车内专用大数据集 室内数据集不适用车内角度/光照
标定复杂 后视镜等注视目标超出摄像头FoV 无法精确标注3D注视向量
视觉噪声 低分辨率+极端角度+眼镜/口罩 面部特征被遮挡

方法详解

1. IVGaze数据集

属性 数值
图片数 44,705
受试者 125人
标注 精确3D注视向量(非区域分类)
特殊情况 包含眼镜、口罩
场景 真实车辆座舱

2. 透明棋盘标定法

创新点: 解决注视目标在摄像头FoV外的标定问题

1
2
3
4
5
传统标定:                   透明棋盘标定:
标定板在摄像头前 标定板透明,放在驾驶员和摄像头之间
→ 只能标定FoV内目标 → 通过深度相机+透明棋板
→ 数学链接座舱内所有物理目标到摄像头坐标系
→ 后视镜、侧窗等均可标定

3. GazeDPTR模型

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
import torch
import torch.nn as nn
import torch.nn.functional as F

class GazeDPTR(nn.Module):
"""
GazeDPTR: Dual-stream Gaze Pyramid Transformer

CVPR 2024论文核心方法实现
双流处理: 原始图像 + 归一化图像
金字塔特征: 多层级面部特征

Args:
feat_dim: 特征维度
num_heads: 注意力头数
num_layers: Transformer层数
"""

def __init__(self, feat_dim=512, num_heads=8, num_layers=4):
super().__init__()

# 1. 原始图像流(捕获全局面部信息)
self.raw_stream = PyramidBackbone(
in_channels=3,
feat_dim=feat_dim,
levels=3 # 金字塔3层
)

# 2. 归一化图像流(视角校正后,捕获细粒度眼部)
self.normalized_stream = PyramidBackbone(
in_channels=3,
feat_dim=feat_dim,
levels=3
)

# 3. 摄像头姿态引导(指导双流融合)
self.camera_pose_embed = nn.Sequential(
nn.Linear(6, feat_dim // 4), # 6DoF摄像头姿态
nn.GELU(),
nn.Linear(feat_dim // 4, feat_dim)
)

# 4. 双流Transformer融合
self.fusion_transformer = DualStreamFusion(
d_model=feat_dim,
num_heads=num_heads,
num_layers=num_layers
)

# 5. 注视输出头
self.gaze_head = nn.Sequential(
nn.Linear(feat_dim, feat_dim // 2),
nn.GELU(),
nn.Linear(feat_dim // 2, 3) # 3D注视向量
)

def forward(self, raw_img, normalized_img, camera_pose):
"""
Args:
raw_img: (B, 3, 224, 224) 原始驾驶员面部图像
normalized_img: (B, 3, 224, 224) 视角归一化图像
camera_pose: (B, 6) 6DoF摄像头姿态

Returns:
gaze_vector: (B, 3) 3D注视方向向量
"""
# 1. 双流金字塔特征提取
raw_feat = self.raw_stream(raw_img) # (B, feat_dim)
norm_feat = self.normalized_stream(normalized_img) # (B, feat_dim)

# 2. 摄像头姿态引导
pose_embed = self.camera_pose_embed(camera_pose) # (B, feat_dim)

# 3. Transformer融合
fused = self.fusion_transformer(
raw_feat, norm_feat, pose_embed
) # (B, feat_dim)

# 4. 注视向量预测
gaze = self.gaze_head(fused)
gaze = F.normalize(gaze, p=2, dim=-1) # 单位向量

return gaze


class PyramidBackbone(nn.Module):
"""金字塔特征提取器:多层级面部特征"""

def __init__(self, in_channels=3, feat_dim=512, levels=3):
super().__init__()
self.levels = levels

# 多尺度卷积特征
self.convs = nn.ModuleList([
nn.Sequential(
nn.Conv2d(in_channels if i == 0 else 64*(2**i),
64*(2**(i+1)), 3, 2, 1),
nn.BatchNorm2d(64*(2**(i+1))),
nn.ReLU()
)
for i in range(levels)
])

# 各层级投影
self.projections = nn.ModuleList([
nn.Linear(64 * (2**(i+1)), feat_dim // levels)
for i in range(levels)
])

# 最终融合
self.fusion = nn.Linear(feat_dim, feat_dim)

def forward(self, x):
features = []
feat = x
for i in range(self.levels):
feat = self.convs[i](feat)
# 全局平均池化
pooled = F.adaptive_avg_pool2d(feat, 1).flatten(1)
# 投影
projected = self.projections[i](pooled)
features.append(projected)

# 拼接并融合
combined = torch.cat(features, dim=-1)
return self.fusion(combined)


class DualStreamFusion(nn.Module):
"""双流Transformer融合"""

def __init__(self, d_model=512, num_heads=8, num_layers=4):
super().__init__()

# 交叉注意力:原始流query ↔ 归一化流key/value
cross_attn_layer = nn.TransformerDecoderLayer(
d_model=d_model,
nhead=num_heads,
dim_feedforward=d_model * 4,
dropout=0.1,
activation='gelu',
batch_first=True
)
self.cross_attn = nn.TransformerDecoder(cross_attn_layer, num_layers)

# 摄像头姿态门控
self.pose_gate = nn.Sequential(
nn.Linear(d_model, d_model),
nn.Sigmoid()
)

def forward(self, raw_feat, norm_feat, pose_embed):
"""
双流融合 + 摄像头姿态引导
"""
# 原始流作为query,归一化流作为key/value
raw_query = raw_feat.unsqueeze(1) # (B, 1, d_model)
norm_kv = norm_feat.unsqueeze(1) # (B, 1, d_model)

# 交叉注意力
fused = self.cross_attn(raw_query, norm_kv, norm_kv)
fused = fused.squeeze(1) # (B, d_model)

# 摄像头姿态门控
gate = self.pose_gate(pose_embed)
fused = fused * gate + fused

return fused


# 测试
if __name__ == "__main__":
model = GazeDPTR(feat_dim=512, num_heads=8, num_layers=4)

raw = torch.randn(4, 3, 224, 224)
norm = torch.randn(4, 3, 224, 224)
pose = torch.randn(4, 6)

gaze = model(raw, norm, pose)
print(f"Raw image: {raw.shape}")
print(f"Normalized image: {norm.shape}")
print(f"Camera pose: {pose.shape}")
print(f"Gaze vector: {gaze.shape}")
print(f"Parameters: {sum(p.numel() for p in model.parameters()):,}")

# 验证注视向量是单位向量
norms = torch.norm(gaze, dim=-1)
print(f"Gaze vector norms: {norms}")
print("✅ 应接近1.0")

实验结果

与SOTA对比

方法 数据集 角度误差(°) 备注
XGaze 通用 7.06 此前SOTA
GazeDPTR IVGaze 6.71 车内SOTA

三平面注视区域分类

将注视投射到三个平面(前窗/仪表/侧面),分类为9个区域:

区域 平均精度
前挡风玻璃 ~90%
仪表盘 ~85%
左后视镜 ~75%
右后视镜 ~72%
左侧窗 ~78%
右侧窗 ~76%
整体 81.8%

眼镜影响分析

条件 角度误差(°) 影响
无眼镜 ~6.0 基线
普通眼镜 ~8.5 +42%
太阳镜 >16.0 +167%

IMS 应用启示

1. 直接用于Euro NCAP DSM注视评估

Euro NCAP场景 GazeDPTR支持 精度预期
D-01 视线前方可控 ✅ 前挡风玻璃区域 90%+
D-02 手机使用 ✅ 下方区域检测 80%+
D-05 视线偏离 ✅ 侧窗/后视镜 75%+
D-07 后视镜查看 ✅ 后视镜区域 72%+

2. 太阳镜问题:IMS最大挑战

方案 可行性 成本
红外摄像头穿透太阳镜 ✅ 高 中(需IR传感器)
多角度摄像头减少遮挡 ⚠️ 中 高(多摄像头)
红外补光灯减少反射 ⚠️ 中 低
基于头部姿态替代 ⚠️ 低精度 低

3. 部署建议

组件 推荐配置 参数
摄像头 STURDeCAM57 / ST VD56GA 1.1MP, IR, 全局快门
红外补光 940nm LED 减少太阳镜反射
处理器 QCS8255 Hexagon NPU
注视模型 GazeDPTR轻量化 量化到INT8
区域分类 三平面投影 9区域

4. 与CCGF(追踪丢失恢复)集成

1
2
3
GazeDPTR(正常追踪) ──→ 60帧历史缓冲 ──→ CCGF(追踪丢失时)
↑ ↓
└────────── 恢复追踪后切换回 ←──────────┘

论文与数据集

  • CVPR 2024论文
  • IVGaze数据集:44,705张图片,125人
  • 透明棋盘标定法:解决FoV外注视目标标定

本文为论文解读类博客,包含方法详解、代码复现、性能对比、IMS落地指导。