SGAP-Gaze:场景网格注意力的驾驶员视线落点估计网络

SGAP-Gaze:场景网格注意力的驾驶员视线落点估计网络

论文信息

  • 标题:SGAP-Gaze: Scene Grid Attention Based Point-of-Gaze Estimation Network for Driver Gaze
  • 作者:Pranamesh Chakraborty 等
  • 会议:arXiv 2026
  • 链接:https://arxiv.org/abs/2604.19888

核心创新

首个融合驾驶员面部与道路场景的视线落点(Point-of-Gaze, PoG)估计网络,通过场景网格注意力机制实现视线在道路场景中的精确定位,误差降低23.5%。

关键突破:

  1. 新建UD-FSG数据集(同步驾驶员面部+道路场景)
  2. 场景网格注意力融合面部+场景特征
  3. 视线落点误差从136.8像素降至104.7像素
  4. 外围区域(边缘视线)检测性能显著提升

问题定义

传统方法的局限

方法 输入 输出 局限
视线区域分类 面部图像 粗粒度区域(左/中/右) 无法精确定位
3D视线向量 面部图像 方向向量 无法映射到具体场景
SGAP-Gaze 面部+场景 场景中的落点坐标 ✅ 精确落点

应用场景

graph LR
    A[DMS摄像头] --> B[驾驶员面部]
    C[前视摄像头] --> D[道路场景]
    
    B --> E[SGAP-Gaze]
    D --> E
    
    E --> F{视线落点判定}
    
    F --> G[正在观察前车]
    F --> H[查看左侧车道]
    F --> I[分心看手机]

方法详解

1. 整体架构

graph TB
    subgraph 输入
        A[驾驶员面部]
        B[道路场景]
    end
    
    A --> C[面部特征提取<br/>ResNet-18]
    A --> D[眼部特征提取]
    A --> E[虹膜特征提取]
    
    C --> F[多模态融合]
    D --> F
    E --> F
    
    F --> G[视线意图向量]
    
    B --> H[场景网格划分<br/>8x8网格]
    G --> I[场景网格注意力]
    H --> I
    
    I --> J[注意力权重计算]
    J --> K[视线落点预测]

2. 核心模块实现

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

class MultiModalFaceFusion(nn.Module):
"""多模态面部特征融合

融合:面部全局特征 + 眼部局部特征 + 虹膜精细特征
"""

def __init__(self, backbone='resnet18'):
super().__init__()

# 面部特征提取器
self.face_encoder = self._get_backbone(backbone)

# 眼部特征提取器(共享权重)
self.eye_encoder = self._get_backbone(backbone)

# 虹膜特征提取器(轻量级)
self.iris_encoder = nn.Sequential(
nn.Conv2d(3, 32, 3, padding=1),
nn.ReLU(),
nn.MaxPool2d(2),
nn.Conv2d(32, 64, 3, padding=1),
nn.ReLU(),
nn.AdaptiveAvgPool2d(1)
)

# 融合层
self.fusion = nn.Sequential(
nn.Linear(512 * 3, 256), # face(512) + eye(512) + iris(64) -> 256
nn.ReLU(),
nn.Dropout(0.3),
nn.Linear(256, 128) # 视线意图向量
)

def _get_backbone(self, name):
"""获取骨干网络"""
import torchvision.models as models

if name == 'resnet18':
model = models.resnet18(pretrained=True)
# 移除最后的全连接层
model = nn.Sequential(*list(model.children())[:-1])

return model

def forward(self, face_img, left_eye_img, right_eye_img, iris_img):
"""
Args:
face_img: (B, 3, 224, 224) 面部图像
left_eye_img: (B, 3, 64, 64) 左眼图像
right_eye_img: (B, 3, 64, 64) 右眼图像
iris_img: (B, 3, 32, 32) 虹膜图像

Returns:
gaze_intent: (B, 128) 视线意图向量
"""
# 提取特征
face_feat = self.face_encoder(face_img).squeeze(-1).squeeze(-1) # (B, 512)

# 眼部特征(左右眼平均)
left_eye_feat = self.eye_encoder(left_eye_img).squeeze(-1).squeeze(-1)
right_eye_feat = self.eye_encoder(right_eye_img).squeeze(-1).squeeze(-1)
eye_feat = (left_eye_feat + right_eye_feat) / 2 # (B, 512)

# 虹膜特征
iris_feat = self.iris_encoder(iris_img).squeeze(-1).squeeze(-1) # (B, 64)

# 填充虹膜特征到512维
iris_feat_padded = F.pad(iris_feat, (0, 512 - 64)) # (B, 512)

# 拼接融合
concat_feat = torch.cat([face_feat, eye_feat, iris_feat_padded], dim=1) # (B, 1536)

# 视线意图向量
gaze_intent = self.fusion(concat_feat) # (B, 128)

return gaze_intent

2.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
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
class SceneGridAttention(nn.Module):
"""场景网格注意力模块

将道路场景划分为网格,计算视线意图与每个网格的注意力权重
"""

def __init__(self, scene_grid_size=(8, 8), gaze_dim=128, scene_feat_dim=512):
super().__init__()

self.grid_size = scene_grid_size

# 场景特征提取器
self.scene_encoder = self._get_backbone('resnet18')

# 网格特征映射
self.grid_proj = nn.Linear(scene_feat_dim, 256)

# 视线意图映射
self.gaze_proj = nn.Linear(gaze_dim, 256)

# 注意力计算
self.attention = nn.MultiheadAttention(
embed_dim=256,
num_heads=8,
batch_first=True
)

# 落点预测
self.pog_predictor = nn.Sequential(
nn.Linear(256, 128),
nn.ReLU(),
nn.Linear(128, 2) # (x, y) 坐标
)

def _get_backbone(self, name):
"""获取骨干网络"""
import torchvision.models as models

model = models.resnet18(pretrained=True)
model = nn.Sequential(*list(model.children())[:-1])

return model

def forward(self, scene_img, gaze_intent):
"""
Args:
scene_img: (B, 3, H, W) 道路场景图像
gaze_intent: (B, 128) 视线意图向量

Returns:
pog: (B, 2) 视线落点坐标(归一化)
attention_weights: (B, grid_h, grid_w) 注意力权重分布
"""
B = scene_img.size(0)

# 1. 提取场景特征
scene_feat = self.scene_encoder(scene_img).squeeze(-1).squeeze(-1) # (B, 512)

# 2. 网格投影(模拟网格特征)
# 实际应对场景图进行网格划分后提取特征
grid_h, grid_w = self.grid_size
grid_feats = self.grid_proj(scene_feat).unsqueeze(1).expand(B, grid_h * grid_w, -1) # (B, 64, 256)

# 3. 视线意图投影
gaze_query = self.gaze_proj(gaze_intent).unsqueeze(1) # (B, 1, 256)

# 4. 注意力计算
attn_output, attn_weights = self.attention(
query=gaze_query,
key=grid_feats,
value=grid_feats
) # attn_output: (B, 1, 256), attn_weights: (B, 1, 64)

# 5. 落点预测
pog = self.pog_predictor(attn_output.squeeze(1)) # (B, 2)

# 6. 重塑注意力权重
attention_weights = attn_weights.squeeze(1).view(B, grid_h, grid_w) # (B, 8, 8)

return pog, attention_weights


class SGAPGaze(nn.Module):
"""SGAP-Gaze完整模型

论文:SGAP-Gaze: Scene Grid Attention Based Point-of-Gaze Estimation
"""

def __init__(self, config=None):
super().__init__()

self.config = config or {}

# 面部特征融合
self.face_fusion = MultiModalFaceFusion()

# 场景网格注意力
self.scene_attention = SceneGridAttention()

def forward(self, inputs):
"""
Args:
inputs: dict
- face: (B, 3, 224, 224)
- left_eye: (B, 3, 64, 64)
- right_eye: (B, 3, 64, 64)
- iris: (B, 3, 32, 32)
- scene: (B, 3, H, W)

Returns:
output: dict
- pog: (B, 2) 视线落点
- attention: (B, 8, 8) 注意力分布
"""
# 1. 视线意图提取
gaze_intent = self.face_fusion(
inputs['face'],
inputs['left_eye'],
inputs['right_eye'],
inputs['iris']
)

# 2. 场景网格注意力
pog, attention = self.scene_attention(inputs['scene'], gaze_intent)

return {
'pog': pog,
'attention': attention,
'gaze_intent': gaze_intent
}


# 测试模型
if __name__ == "__main__":
model = SGAPGaze()

# 模拟输入
batch_size = 4
inputs = {
'face': torch.randn(batch_size, 3, 224, 224),
'left_eye': torch.randn(batch_size, 3, 64, 64),
'right_eye': torch.randn(batch_size, 3, 64, 64),
'iris': torch.randn(batch_size, 3, 32, 32),
'scene': torch.randn(batch_size, 3, 720, 1280)
}

# 前向传播
output = model(inputs)

print(f"视线落点: {output['pog']}")
print(f"注意力分布形状: {output['attention'].shape}")

UD-FSG数据集

数据集构成

指标 数值
总样本数 50,000+
场景类型 城市道路、高速公路、郊区
光照条件 白天、黄昏、夜晚
分辨率 面部224x224,场景1280x720
标注类型 视线落点(x,y)坐标

与现有数据集对比

数据集 样本数 场景同步 标注类型
MPIIGaze 213K 视线向量
GazeCapture 2.5M 视线向量
UD-FSG 50K 场景落点

实验结果

性能对比

模型 UD-FSG误差 LBW误差 备注
GazePTR 136.8 83.0 基线
SGAP-Gaze 104.7 63.5 -23.5%

空间分布分析

视线区域 传统方法误差 SGAP-Gaze误差 提升
中央区域 85.2 72.3 -15%
边缘区域 198.5 145.6 -27%

IMS开发启示

1. 系统集成方案

graph LR
    A[DMS摄像头<br/>驾驶员面部] --> C[SGAP-Gaze]
    B[前视摄像头<br/>道路场景] --> C
    
    C --> D{视线落点分析}
    
    D --> E[前车关注]
    D --> F[车道检查]
    D --> G[分心判定]
    
    G --> H[发出警告]
    E --> I[安全状态]

2. 硬件配置

组件 型号 功能 成本
DMS摄像头 OV2311 RGB-IR 面部+眼部+虹膜 $15
前视摄像头 IMX390 道路场景 $25
处理器 QCS8255 SGAP-Gaze推理 $35

3. 与Euro NCAP对接

ENCAP要求 SGAP-Gaze支持
视线偏离检测 ✅ 精确落点定位
分心检测 ✅ 场景上下文关联
驾驶员关注判定 ✅ 前车/后视镜关注分析

参考文献

  1. arXiv 2604.19888, “SGAP-Gaze: Scene Grid Attention Based Point-of-Gaze Estimation”, 2026
  2. Cheng et al., “Gaze estimation using transformer”, 2024

本文为SGAP-Gaze论文的详细解读与代码实现,面向IMS开发者提供场景感知的视线落点估计方案。


SGAP-Gaze:场景网格注意力的驾驶员视线落点估计网络
https://dapalm.com/2026/07/28/2026-07-28-sgap-gaze-scene-attention-driver-pog/
作者
Mars
发布于
2026年7月28日
许可协议