TransGaze-Object:Transformer驱动的驾驶员注视物体预测框架——arXiv 2609.10139解读

论文:TransGaze-Object: Transformer Based Driver Gaze Object Prediction Framework in Real Driving
作者:Pavan Kumar Sharma, Ayush Pande, Pranamesh Chakraborty
arXiv:2609.10139 (2026-09-09)
篇幅:32页, 17图

核心创新

本文首次提出端到端的驾驶员注视物体预测框架——TransGaze-Object,跳过传统的”先估计注视点再关联物体”两步法,直接从驾驶员面部和交通场景信息预测注视物体(车辆/行人/信号灯等)。

一句话总结: 不再估计”驾驶员在看哪个点”,而是直接预测”驾驶员在看哪个物体”——端到端Transformer交叉注意力实现,准确率60% vs 基线51%。

问题定义

传统方法 vs 本文方法

1
2
3
4
5
6
7
传统两步法:
驾驶员面部 → 注视点估计(PoG) → 关联交通物体 → 注视物体
问题:PoG误差累积 + 关联歧义

本文端到端:
驾驶员面部 + 交通场景 → TransGaze-Object → 注视物体
优势:无中间误差累积,直接语义预测

核心挑战

挑战 描述 影响
物体级标注 需要标注驾驶员正在看哪个物体 数据采集成本高
多物体竞争 视野中多个交通物体 需要区分注意力
背景混淆 注视背景vs注视物体 23.21%误判率(基线)
实时性 驾驶场景需要实时响应 模型需轻量

方法详解

整体架构

核心代码复现

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 TransGazeObject(nn.Module):
"""
TransGaze-Object: 基于Transformer的驾驶员注视物体预测框架

论文: arXiv:2609.10139
输入: 驾驶员面部图像 + 交通场景图像
输出: 注视物体类别 + 边界框

核心创新:
1. 面部特征: 人脸特征 + 虹膜加权眼部特征
2. 场景特征: 物体边界框 + 空间位置编码
3. Transformer交叉注意力: 计算面部-物体相似度
"""

def __init__(self, num_objects=10, face_feat_dim=512,
scene_feat_dim=512, num_heads=8, num_layers=4):
super().__init__()

# 1. 面部特征提取器
self.face_encoder = FaceEncoder(feat_dim=face_feat_dim)

# 2. 场景物体特征提取器
self.scene_encoder = SceneObjectEncoder(feat_dim=scene_feat_dim)

# 3. 空间位置编码
self.spatial_pos_enc = SpatialPositionEncoding(d_model=scene_feat_dim)

# 4. Transformer交叉注意力
cross_attn_layer = nn.TransformerDecoderLayer(
d_model=face_feat_dim,
nhead=num_heads,
dim_feedforward=face_feat_dim * 4,
dropout=0.1,
activation='gelu',
batch_first=True
)
self.cross_attn = nn.TransformerDecoder(cross_attn_layer, num_layers=num_layers)

# 5. 注视物体分类头
self.gaze_object_head = nn.Sequential(
nn.Linear(face_feat_dim, face_feat_dim // 2),
nn.GELU(),
nn.Linear(face_feat_dim // 2, num_objects + 1) # +1 for background
)

# 6. 注意力权重(用于可视化)
self.attn_weights = None

def forward(self, face_img, scene_img, object_boxes=None):
"""
Args:
face_img: (B, 3, 224, 224) 驾驶员面部图像
scene_img: (B, 3, H, W) 交通场景图像
object_boxes: (B, N, 4) 检测到的物体边界框

Returns:
gaze_object_logits: (B, N+1) 注视物体分类logits
attention_weights: (B, N) 注意力权重
"""
# 1. 提取面部特征
face_feat = self.face_encoder(face_img) # (B, feat_dim)
face_feat = face_feat.unsqueeze(1) # (B, 1, feat_dim) as query

# 2. 提取场景物体特征
scene_feat = self.scene_encoder(scene_img, object_boxes) # (B, N, feat_dim)

# 3. 空间位置编码
scene_feat = self.spatial_pos_enc(scene_feat, object_boxes)

# 4. 交叉注意力: 面部query → 场景物体key/value
gaze_feat, self.attn_weights = self.cross_attn(
face_feat, scene_feat, scene_feat,
need_weights=True
)
gaze_feat = gaze_feat.squeeze(1) # (B, feat_dim)

# 5. 预测注视物体
logits = self.gaze_object_head(gaze_feat) # (B, N+1)

return logits, self.attn_weights


class FaceEncoder(nn.Module):
"""面部特征提取器:人脸特征 + 虹膜加权眼部特征"""

def __init__(self, feat_dim=512):
super().__init__()
# 人脸特征提取(可用ResNet18等backbone)
self.face_backbone = nn.Sequential(
nn.Conv2d(3, 64, 7, 2, 3), nn.BatchNorm2d(64), nn.ReLU(),
nn.MaxPool2d(3, 2, 1),
# 简化版,实际用预训练ResNet
nn.Conv2d(64, 128, 3, 1, 1), nn.BatchNorm2d(128), nn.ReLU(),
nn.AdaptiveAvgPool2d(1),
nn.Flatten(),
nn.Linear(128, feat_dim)
)

# 虹膜加权眼部特征
self.iris_encoder = nn.Sequential(
nn.Conv2d(3, 32, 3, 1, 1), nn.BatchNorm2d(32), nn.ReLU(),
nn.MaxPool2d(2),
nn.Conv2d(32, 64, 3, 1, 1), nn.BatchNorm2d(64), nn.ReLU(),
nn.AdaptiveAvgPool2d(1),
nn.Flatten(),
nn.Linear(64, feat_dim // 4)
)

# 融合
self.fusion = nn.Linear(feat_dim + feat_dim // 4, feat_dim)

def forward(self, face_img):
face_feat = self.face_backbone(face_img)
# 假设已裁剪眼部区域
eye_region = face_img[:, :, 60:120, 80:160] # 粗略眼部crop
iris_feat = self.iris_encoder(eye_region)
combined = torch.cat([face_feat, iris_feat], dim=-1)
return self.fusion(combined)


class SceneObjectEncoder(nn.Module):
"""场景物体特征提取器"""

def __init__(self, feat_dim=512):
super().__init__()
self.backbone = nn.Sequential(
nn.Conv2d(3, 64, 7, 2, 3), nn.BatchNorm2d(64), nn.ReLU(),
nn.Conv2d(64, 128, 3, 1, 1), nn.BatchNorm2d(128), nn.ReLU(),
nn.AdaptiveAvgPool2d(1),
nn.Flatten(),
nn.Linear(128, feat_dim)
)
self.proj = nn.Linear(feat_dim, feat_dim)

def forward(self, scene_img, object_boxes=None):
"""
提取场景全局特征,如果有物体框则提取每个物体特征
"""
B = scene_img.shape[0]
global_feat = self.backbone(scene_img) # (B, feat_dim)

if object_boxes is None:
# 简化:用全局特征作为单个物体特征
return global_feat.unsqueeze(1) # (B, 1, feat_dim)

# 实际应提取每个物体区域特征
N = object_boxes.shape[1]
obj_feats = []
for i in range(N):
# 简化:用全局特征+位置编码
box_feat = self.proj(global_feat)
obj_feats.append(box_feat)

return torch.stack(obj_feats, dim=1) # (B, N, feat_dim)


class SpatialPositionEncoding(nn.Module):
"""空间位置编码:物体边界框位置信息"""

def __init__(self, d_model=512):
super().__init__()
self.box_proj = nn.Linear(4, d_model) # x,y,w,h → d_model

def forward(self, feat, boxes):
if boxes is None:
return feat
pos_enc = self.box_proj(boxes) # (B, N, d_model)
return feat + pos_enc


# 测试
if __name__ == "__main__":
model = TransGazeObject(num_objects=10, face_feat_dim=512)

# 模拟输入
face = torch.randn(4, 3, 224, 224)
scene = torch.randn(4, 3, 256, 256)
boxes = torch.rand(4, 5, 4) # 5个物体

logits, attn = model(face, scene, boxes)
print(f"Face input: {face.shape}")
print(f"Scene input: {scene.shape}")
print(f"Gaze object logits: {logits.shape}")
print(f"Attention weights: {attn.shape}")
print(f"Parameters: {sum(p.numel() for p in model.parameters()):,}")

数据集:UD-FSG

属性 数值
名称 Urban Driving-Face Scene Gaze
内容 同步驾驶员面部+交通场景图像
标注 物体边界框 + 2D注视坐标 + 注视物体标签
场景 城市驾驶

实验结果

核心对比

方法 准确率 背景-物体混淆率 相对改善
PoG估计+物体关联 51% 23.21% 基线
TransGaze-Object 60% 11.68% 49.7%↓

关键发现

  1. 端到端优于两步法:直接预测注视物体比先估计注视点再关联物体准确率更高
  2. 背景混淆减少50%:最大改善在于区分”在看物体”vs”在看背景”
  3. 虹膜特征有效:虹膜加权眼部特征提升了细粒度注视方向估计

IMS 应用启示

1. 从注视点到注视物体:语义升级

传统DMS 本文方法 价值
“注视点在(x,y)” “注视物体是前方车辆” 语义可理解
注视区域分类 注视物体分类 更精确
难以判断注意力对象 直接判断注意力对象 决策友好

2. 分心检测直接应用

场景 传统方法 TransGaze-Object
看手机 注视点在下方 注视物体=”手机”
看仪表盘 注视点在正前方 注视物体=”仪表盘”
看后视镜 注视点在右侧 注视物体=”后视镜”
看前方车辆 注视点在正前方 注视物体=”前方车辆”
看行人 注视点在右侧 注视物体=”行人”

3. Euro NCAP分心检测场景对应

Euro NCAP场景 TransGaze-Object支持 准确率预期
D-02 手机使用 ✅ 直接识别注视手机 60%+
D-03 打字操作 ✅ 注视手机+下方 55%+
D-05 视线偏离 ✅ 注视物体非道路 65%+
D-07 后视镜查看 ✅ 注视后视镜物体 60%+

4. 开发落地建议

优先级 行动 价值
🔴 高 复现TransGaze-Object模型 分心检测语义升级
🔴 高 采集UD-FSG类似数据集 场景适配
🟡 中 集成到DMS管道 端到端分心检测
🟢 低 轻量化部署 边缘推理优化

论文下载


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