认知分心检测:眼动+视频融合方案EyeCue解读

认知分心检测:眼动+视频融合方案EyeCue解读

论文信息

核心创新

首次提出眼动+自我中心视频融合框架,通过建模驾驶员注视点与驾驶场景的交互,实现非侵入式认知分心检测,准确率达74.38%,比现有方法提升7%


一、问题定义:认知分心是DMS最后的难关

1.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
def distraction_types_comparison():
"""
驾驶员分心类型对比
"""
types = {
'手动分心': {
'定义': '手离开方向盘(如拿手机)',
'可观测性': '✅ 高(可通过摄像头检测)',
'检测难度': '🟢 低',
'现有方案': 'YOLO姿态估计'
},
'视觉分心': {
'定义': '视线离开道路(如看导航)',
'可观测性': '✅ 高(可通过眼动仪检测)',
'检测难度': '🟡 中',
'现有方案': '视线估计+ROI判断'
},
'认知分心': {
'定义': '注意力被无关驾驶的思绪分散(如发呆)',
'可观测性': '❌ 低(外表看似正常)',
'检测难度': '🔴 高',
'现有方案': '❌ 缺乏有效方案'
}
}

return types

1.2 认知分心的隐蔽性

graph LR
    A[认知分心场景] --> B[外表看似正常]
    B --> C[视线仍在道路]
    B --> D[双手仍在方向盘]
    B --> E[无明显肢体动作]
    
    C --> F[但注意力分散]
    D --> F
    E --> F
    
    F --> G[反应时延增加]
    F --> H[事故风险上升]
    
    G --> I[🔴 难以检测]
    H --> I

关键问题:

  • 传统方法依赖可观测行为(姿态、视线方向)
  • 认知分心时驾驶员”看起来”在正常驾驶
  • 需要更深层的行为模式分析

二、EyeCue方法详解

2.1 核心思路

关键洞察: 认知分心体现在眼动与场景的交互异常

状态 视线位置 场景上下文 交互模式
正常 注视交通灯 等待信号 ✅ 符合预期
认知分心 注视路边停车 直行路段 ❌ 异常关注

2.2 系统架构

sequenceDiagram
    participant C as 摄像头
    participant E as 眼动仪
    participant V as 视频编码器
    participant G as 眼动编码器
    participant Q as GDSQ模块
    participant F as 融合分类器
    
    C->>V: 自我中心视频
    E->>G: 眼动数据(注视点序列)
    
    V->>Q: 视频token序列
    G->>Q: 注视点位置
    
    Q->>Q: 动态选择注视相关token
    Q->>F: 注视增强特征
    
    V->>F: 全局视频特征
    G->>F: 眼动模式特征
    
    F->>F: 跨模态融合
    F->>F: 分类(分心/正常)

2.3 关键模块

2.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
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
import torch
import torch.nn as nn
from transformers import VideoMAEForPreTraining

class VideoEncoder(nn.Module):
"""
视频编码器:提取驾驶场景上下文

使用VideoMAE预训练模型
"""

def __init__(self, model_name='videomae-base', num_frames=16):
super().__init__()

# 加载预训练VideoMAE
self.video_mae = VideoMAEForPreTraining.from_pretrained(
f"MCG-NJU/{model_name}"
)

# 冻结底层,只训练顶层
for param in self.video_mae.parameters():
param.requires_grad = False

# 分类头
self.classifier = nn.Sequential(
nn.Linear(768, 256),
nn.ReLU(),
nn.Dropout(0.3),
nn.Linear(256, 2) # 分心/正常
)

def forward(self, video_frames):
"""
前向传播

Args:
video_frames: (B, T, C, H, W) 视频帧

Returns:
features: (B, 768) 视频特征
logits: (B, 2) 分类logits
"""
# VideoMAE编码
outputs = self.video_mae(video_frames, output_hidden_states=True)
features = outputs.hidden_states[-1][:, 0] # CLS token

# 分类
logits = self.classifier(features)

return features, logits

# 测试
video_encoder = VideoEncoder()
video_frames = torch.randn(2, 16, 3, 224, 224) # (batch, frames, channels, H, W)
features, logits = video_encoder(video_frames)
print(f"视频特征: {features.shape}, 分类: {logits.shape}")

2.3.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
class GazeEncoder(nn.Module):
"""
眼动编码器:提取注视模式

输入:注视点序列 (x, y, t)
输出:眼动特征
"""

def __init__(self, input_dim=3, hidden_dim=128, num_layers=2):
super().__init__()

# LSTM建模时序眼动模式
self.lstm = nn.LSTM(
input_size=input_dim,
hidden_size=hidden_dim,
num_layers=num_layers,
batch_first=True,
bidirectional=True
)

# 注意力池化
self.attention = nn.Sequential(
nn.Linear(hidden_dim * 2, 64),
nn.Tanh(),
nn.Linear(64, 1)
)

def forward(self, gaze_sequence):
"""
前向传播

Args:
gaze_sequence: (B, T, 3) 注视点序列 (x, y, t)

Returns:
features: (B, hidden_dim*2) 眼动特征
"""
# LSTM编码
lstm_out, _ = self.lstm(gaze_sequence) # (B, T, hidden_dim*2)

# 注意力权重
attn_weights = self.attention(lstm_out) # (B, T, 1)
attn_weights = torch.softmax(attn_weights, dim=1)

# 加权池化
features = torch.sum(lstm_out * attn_weights, dim=1) # (B, hidden_dim*2)

return features

# 测试
gaze_encoder = GazeEncoder()
gaze_sequence = torch.randn(2, 100, 3) # (batch, 100个注视点, xyt)
features = gaze_encoder(gaze_sequence)
print(f"眼动特征: {features.shape}")

2.3.3 GDSQ模块(核心创新)

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
class GDSQ(nn.Module):
"""
Gaze-Driven Semantic Query Module

核心创新:用眼动引导视频token选择

思路:
- 驾驶员看哪,就从视频中选择对应的视觉token
- 实现眼动-场景上下文交互建模
"""

def __init__(self, video_dim=768, gaze_dim=256, num_heads=8):
super().__init__()

# 跨模态注意力
self.cross_attention = nn.MultiheadAttention(
embed_dim=video_dim,
num_heads=num_heads,
batch_first=True
)

# 眼动投影(将2D注视点映射到视频token)
self.gaze_proj = nn.Linear(gaze_dim, video_dim)

# 门控融合
self.gate = nn.Sequential(
nn.Linear(video_dim * 2, video_dim),
nn.Sigmoid()
)

def forward(self, video_tokens, gaze_features, gaze_positions):
"""
前向传播

Args:
video_tokens: (B, N, 768) 视频token序列
gaze_features: (B, 256) 眼动特征
gaze_positions: (B, T, 2) 注视点位置(归一化)

Returns:
enhanced_features: (B, 768) 注视增强特征
"""
B, N, D = video_tokens.shape

# 眼动投影为query
gaze_query = self.gaze_proj(gaze_features).unsqueeze(1) # (B, 1, 768)

# 跨模态注意力:眼动引导选择视频token
attn_out, attn_weights = self.cross_attention(
query=gaze_query,
key=video_tokens,
value=video_tokens
) # (B, 1, 768)

# 门控融合
global_feature = video_tokens.mean(dim=1) # (B, 768)
combined = torch.cat([attn_out.squeeze(1), global_feature], dim=-1)
gate_weights = self.gate(combined)

enhanced_features = gate_weights * attn_out.squeeze(1) + (1 - gate_weights) * global_feature

return enhanced_features, attn_weights

# 测试
gdsq = GDSQ()
video_tokens = torch.randn(2, 196, 768) # (batch, patches, dim)
gaze_features = torch.randn(2, 256)
gaze_positions = torch.rand(2, 100, 2)

enhanced_features, attn_weights = gdsq(video_tokens, gaze_features, gaze_positions)
print(f"增强特征: {enhanced_features.shape}, 注意力权重: {attn_weights.shape}")

2.4 完整模型

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 EyeCue(nn.Module):
"""
EyeCue完整模型

融合:视频编码器 + 眼动编码器 + GDSQ
"""

def __init__(self, num_classes=2):
super().__init__()

self.video_encoder = VideoEncoder()
self.gaze_encoder = GazeEncoder()
self.gdsq = GDSQ()

# 最终分类器
self.classifier = nn.Sequential(
nn.Linear(768 + 256, 128),
nn.ReLU(),
nn.Dropout(0.3),
nn.Linear(128, num_classes)
)

def forward(self, video_frames, gaze_sequence):
"""
前向传播

Args:
video_frames: (B, T, C, H, W)
gaze_sequence: (B, T_g, 3)

Returns:
logits: (B, 2)
"""
# 视频编码
video_features, _ = self.video_encoder(video_frames) # (B, 768)

# 眼动编码
gaze_features = self.gaze_encoder(gaze_sequence) # (B, 256)

# 融合
combined_features = torch.cat([video_features, gaze_features], dim=-1)

# 分类
logits = self.classifier(combined_features)

return logits

# 测试
model = EyeCue()
video_frames = torch.randn(2, 16, 3, 224, 224)
gaze_sequence = torch.randn(2, 100, 3)

logits = model(video_frames, gaze_sequence)
print(f"预测结果: {torch.argmax(logits, dim=-1)}")

三、CogDrive数据集

3.1 数据集构建

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
def cogdrive_dataset_stats():
"""
CogDrive数据集统计
"""
stats = {
'总样本数': 3662,
'来源': [
'DR(eye)VE - 498样本',
'BDD-A - 1000样本',
'DADA-2000 - 1200样本',
'TrafficGaze - 964样本'
],
'标注': '认知分心二分类',
'场景覆盖': [
'不同道路类型(城市/高速/乡村)',
'不同时间段(白天/夜晚)',
'不同天气(晴天/雨天)'
]
}

return stats

3.2 标注流程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def annotation_procedure():
"""
认知分心标注流程

基于DR(eye)VE协议:
1. 观察驾驶员注视点序列
2. 判断注视是否符合驾驶任务预期
3. 标记异常关注为认知分心
"""
procedure = [
'步骤1:提取注视点序列(每帧注视位置)',
'步骤2:分析注视点分布(熵、分散度)',
'步骤3:对比场景上下文(注视是否合理)',
'步骤4:专家标注分心状态(正常/分心)'
]

return procedure

四、实验结果

4.1 性能对比

方法 模态 准确率 提升
EyeCue 视频+眼动 74.38% -
DCDD 图像+眼动 67.2% +7.18%
VideoMAE 仅视频 66.5% +7.88%
Gaze-only 仅眼动 62.1% +12.28%
LSTM 仅眼动 60.3% +14.08%

4.2 场景泛化性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def cross_scenario_performance():
"""
跨场景性能测试

EyeCue在各类场景下准确率均>70%
"""
performance = {
'城市道路': '72.5%',
'高速公路': '75.2%',
'乡村道路': '71.8%',
'白天': '76.1%',
'夜晚': '70.3%',
'晴天': '74.8%',
'雨天': '71.2%'
}

return performance

五、IMS应用方案

5.1 硬件配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
def ims_cognitive_detection_hardware():
"""
IMS认知分心检测硬件方案
"""
hardware = {
'眼动传感器': {
'方案A': 'Tobii 4C眼动仪($150)',
'方案B': 'Smart Eye DMS集成眼动(已有)',
'方案C': 'AR眼镜(Meta Aria Gen2,$300)'
},
'场景摄像头': {
'型号': '前视摄像头(已有)',
'分辨率': '1920x1080',
'帧率': '30fps'
},
'处理器': {
'型号': 'Qualcomm QCS8255',
'NPU': 'Hexagon 26 TOPS',
'内存': '8GB'
}
}

return hardware

5.2 实时处理流程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
def real_time_processing():
"""
实时认知分心检测流程

输入:前视摄像头 + 眼动数据
输出:分心警告(视觉+听觉)
"""
flow = {
'Step1': '采集前视视频(30fps)',
'Step2': '采集眼动数据(60Hz注视点)',
'Step3': '视频预处理(裁剪、归一化)',
'Step4': '眼动序列构建(最近5秒)',
'Step5': 'EyeCue模型推理(<100ms)',
'Step6': '判断分心状态',
'Step7': '发出警告(若分心持续>10秒)'
}

return flow

5.3 与Euro NCAP对接

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def euro_ncap_cognitive_requirements():
"""
Euro NCAP认知分心要求(2026新增)
"""
requirements = {
'检测场景': [
'驾驶员注意力分散(持续关注非驾驶相关区域)',
'思维游离("发呆"状态)'
],
'检测时延': '≤10秒',
'警告方式': '视觉+听觉双重警告',
'精度要求': '≥70%(建议≥80%)'
}

return requirements

六、局限与改进方向

6.1 当前局限

问题 原因 影响
准确率仅74% 认知状态内在复杂性 仍有26%误判
需眼动硬件 依赖专用传感器 成本增加
场景依赖 训练数据覆盖有限 泛化性待提升
实时性 视频模型计算量大 需GPU加速

6.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
def future_improvements():
"""
未来改进方向
"""
improvements = {
'多模态融合': {
'方案': '眼动+生理信号(心率变异性)',
'预期': '准确率提升至85%+'
},
'轻量化模型': {
'方案': '知识蒸馏+量化',
'预期': '推理速度提升3x'
},
'自监督学习': {
'方案': '利用无标签数据预训练',
'预期': '降低标注成本'
},
'边缘部署': {
'方案': 'NPU加速推理',
'预期': '时延<50ms'
}
}

return improvements

七、总结

EyeCue首次提出眼动+视频融合的认知分心检测方案,通过GDSQ模块建模注视-场景交互,在CogDrive数据集上达到74.38%准确率,为Euro NCAP 2026认知分心要求提供了可行方案。

关键价值:

  • ✅ 非侵入式:无需生理传感器
  • ✅ 实时性:视频+眼动联合推理
  • ✅ 泛化性:跨场景准确率>70%
  • ✅ 可部署:已有硬件可复用(DMS眼动+前视摄像头)

IMS实现优先级:

  1. 立即可行:复用Smart Eye DMS眼动数据 + 前视摄像头
  2. 中期优化:训练EyeCue模型,集成到QCS8255 NPU
  3. 长期完善:多模态融合(眼动+心率变异性)

参考文献:

  1. Zhang et al., “EyeCue: Driver Cognitive Distraction Detection via Gaze-Empowered Egocentric Video Understanding”, arXiv 2605.07859, 2026.
  2. Euro NCAP, “Safe Driving Assessment Protocol v1.1”, 2026.
  3. Frontiers, “Combining EEG and Eye-tracking for Cognitive and Physiological States Monitoring”, 2025.

认知分心检测:眼动+视频融合方案EyeCue解读
https://dapalm.com/2026/08/18/2026-08-18-cognitive-distraction-eyeCue/
作者
Mars
发布于
2026年8月18日
许可协议