认知分心检测技术综述:从眼动规律到行为建模

认知分心检测技术综述:从眼动规律到行为建模

发布时间: 2026-06-14
标签: 认知分心, Cognitive Distraction, DMS, 眼动追踪, Euro NCAP 2026
来源: 学术论文综述, Euro NCAP 2026 要求


问题定义:什么是认知分心?

认知分心(Cognitive Distraction):驾驶员虽然眼睛看向前方,但思维已经离开驾驶任务。

与视觉分心的区别

类型 眼睛位置 思维位置 检测难度
视觉分心 离开道路 离开道路 低(眼动追踪可检测)
认知分心 看向道路 离开驾驶 高(无直接视觉信号)

Euro NCAP 2026 认知分心要求

检测挑战

Euro NCAP 2026 明确指出认知分心是 待突破的技术难点

功能 状态 备注
疲劳/分心检测 ✅ 已有 眼动追踪可检测
认知分心 ❌ 待突破 重点跟踪眼动规律性、EEG替代、行为建模

技术方向

Euro NCAP 建议的技术方向:

  1. 眼动规律性分析:分析扫视模式的异常
  2. EEG 替代信号:心率变异性、皮肤电导等
  3. 行为建模:驾驶行为模式分析

技术方案综述

1. 眼动规律性分析

核心假设: 认知分心时,眼动模式变得更规律/单调,缺乏探索性扫视。

扫视熵(Saccade Entropy)

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
import numpy as np
from scipy.stats import entropy
from typing import List, Tuple

class SaccadeEntropyAnalyzer:
"""
扫视熵分析器

计算眼动扫视方向的熵值
认知分心时熵值降低(扫视更规律)
"""

def __init__(self, num_bins: int = 36):
"""
Args:
num_bins: 扫视方向量化箱数(每10度一个箱)
"""
self.num_bins = num_bins
self.history = []

def add_saccade(self, start: Tuple[float, float],
end: Tuple[float, float]):
"""
添加扫视事件

Args:
start: 起始注视点 (x, y)
end: 结束注视点 (x, y)
"""
# 计算扫视方向
dx = end[0] - start[0]
dy = end[1] - start[1]

angle = np.arctan2(dy, dx)
amplitude = np.sqrt(dx**2 + dy**2)

self.history.append({
'angle': angle,
'amplitude': amplitude
})

def compute_entropy(self, window_size: int = 50) -> float:
"""
计算扫视熵

Args:
window_size: 分析窗口大小

Returns:
扫视熵值(0-1,越高越不规律)
"""
if len(self.history) < window_size:
return 1.0

# 获取最近窗口的扫视方向
recent = self.history[-window_size:]
angles = [s['angle'] for s in recent]

# 量化到方向箱
bins = np.linspace(-np.pi, np.pi, self.num_bins + 1)
hist, _ = np.histogram(angles, bins=bins)

# 计算概率分布
prob = hist / hist.sum()

# 计算熵
max_entropy = np.log(self.num_bins)
actual_entropy = entropy(prob + 1e-10)

# 归一化到 0-1
normalized = actual_entropy / max_entropy

return normalized

def detect_cognitive_distraction(self,
threshold: float = 0.6) -> Tuple[bool, float]:
"""
检测认知分心

熵值低于阈值表示认知分心

Returns:
(是否分心, 熵值)
"""
entropy_value = self.compute_entropy()
is_distracted = entropy_value < threshold

return is_distracted, entropy_value


# 使用示例
if __name__ == "__main__":
analyzer = SaccadeEntropyAnalyzer()

# 模拟正常驾驶(多样化扫视)
for _ in range(30):
angle = np.random.uniform(-np.pi, np.pi)
amplitude = np.random.uniform(50, 200)

start = (640, 400)
end = (640 + amplitude * np.cos(angle),
400 + amplitude * np.sin(angle))

analyzer.add_saccade(start, end)

normal_entropy = analyzer.compute_entropy()
print(f"正常驾驶熵值: {normal_entropy:.3f}")

# 模拟认知分心(规律性扫视)
analyzer.history = []
for i in range(30):
# 扫视方向集中在正前方
angle = np.random.normal(0, 0.3)
amplitude = np.random.uniform(30, 80)

start = (640, 400)
end = (640 + amplitude * np.cos(angle),
400 + amplitude * np.sin(angle))

analyzer.add_saccade(start, end)

distracted_entropy = analyzer.compute_entropy()
print(f"认知分心熵值: {distracted_entropy:.3f}")

注视分散度(Gaze Dispersion)

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
class GazeDispersionAnalyzer:
"""
注视分散度分析器

认知分心时注视点更加集中
"""

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

def add_gaze(self, x: float, y: float):
"""添加注视点"""
self.gaze_history.append((x, y))

def compute_dispersion(self, window_size: int = 100) -> float:
"""
计算注视分散度

Returns:
标准差(像素),越大越分散
"""
if len(self.gaze_history) < window_size:
return 100.0 # 默认值

recent = np.array(self.gaze_history[-window_size:])

# 计算标准差
std_x = np.std(recent[:, 0])
std_y = np.std(recent[:, 1])

dispersion = np.sqrt(std_x**2 + std_y**2)

return dispersion

def detect_cognitive_distraction(self,
threshold: float = 50.0) -> Tuple[bool, float]:
"""
检测认知分心

分散度低于阈值表示认知分心
"""
dispersion = self.compute_dispersion()
is_distracted = dispersion < threshold

return is_distracted, dispersion

2. 生理信号替代

由于 EEG 不适合车载,使用替代信号:

替代信号 与认知负荷的关系 检测方法
心率变异性 (HRV) 认知负荷增加 → HRV 降低 方向盘电容传感器
皮肤电导 (EDA) 认知负荷增加 → EDA 增加 座椅传感器
呼吸频率 认知负荷增加 → 呼吸加快 安全带张力传感器
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
class PhysiologicalSignalAnalyzer:
"""
生理信号分析器

用于认知分心检测
"""

def __init__(self):
self.hrv_history = []
self.eda_history = []

def add_hrv(self, rr_intervals: List[float]):
"""
添加心率变异数据

Args:
rr_intervals: RR 间期列表(秒)
"""
# 计算 HRV 指标
if len(rr_intervals) < 2:
return

# SDNN (标准差)
sdnn = np.std(rr_intervals)

# RMSSD
diff = np.diff(rr_intervals)
rmssd = np.sqrt(np.mean(diff**2))

self.hrv_history.append({
'sdnn': sdnn,
'rmssd': rmssd
})

def add_eda(self, conductance: float):
"""
添加皮肤电导数据

Args:
conductance: 电导值 (μS)
"""
self.eda_history.append(conductance)

def analyze_cognitive_load(self) -> dict:
"""
分析认知负荷

Returns:
{
'hrv_decreased': bool,
'eda_increased': bool,
'cognitive_load_score': float
}
"""
result = {
'hrv_decreased': False,
'eda_increased': False,
'cognitive_load_score': 0.0
}

# HRV 分析
if len(self.hrv_history) >= 10:
recent_hrv = self.hrv_history[-10:]
baseline_hrv = self.hrv_history[:10]

recent_rmssd = np.mean([h['rmssd'] for h in recent_hrv])
baseline_rmssd = np.mean([h['rmssd'] for h in baseline_hrv])

result['hrv_decreased'] = recent_rmssd < baseline_rmssd * 0.8

# EDA 分析
if len(self.eda_history) >= 20:
recent_eda = np.mean(self.eda_history[-10:])
baseline_eda = np.mean(self.eda_history[:10])

result['eda_increased'] = recent_eda > baseline_eda * 1.2

# 综合认知负荷评分
score = 0.0
if result['hrv_decreased']:
score += 0.5
if result['eda_increased']:
score += 0.5

result['cognitive_load_score'] = score

return result

3. 驾驶行为建模

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
class DrivingBehaviorModel:
"""
驾驶行为模型

认知分心影响驾驶行为:
- 转向修正减少
- 车道保持变差
- 反应时间增加
"""

def __init__(self):
self.steering_history = []
self.lane_position_history = []
self.speed_history = []

def add_steering(self, angle: float, timestamp: float):
"""添加转向角度"""
self.steering_history.append({
'angle': angle,
'timestamp': timestamp
})

def add_lane_position(self, offset: float, timestamp: float):
"""添加车道偏移"""
self.lane_position_history.append({
'offset': offset,
'timestamp': timestamp
})

def analyze_behavior(self) -> dict:
"""
分析驾驶行为

Returns:
{
'steering_entropy': float,
'lane_keeping_std': float,
'behavior_anomaly': bool
}
"""
result = {
'steering_entropy': 0.0,
'lane_keeping_std': 0.0,
'behavior_anomaly': False
}

# 转向熵(认知分心时降低)
if len(self.steering_history) >= 100:
angles = [s['angle'] for s in self.steering_history[-100:]]

# 计算转向变化
changes = np.diff(angles)

# 转向熵
hist, _ = np.histogram(changes, bins=20)
prob = hist / hist.sum()
result['steering_entropy'] = entropy(prob + 1e-10)

# 车道保持标准差
if len(self.lane_position_history) >= 100:
offsets = [l['offset'] for l in self.lane_position_history[-100:]]
result['lane_keeping_std'] = np.std(offsets)

# 判断异常
result['behavior_anomaly'] = (
result['steering_entropy'] < 1.0 or
result['lane_keeping_std'] > 0.3
)

return result

多模态融合方案

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
class CognitiveDistractionDetector:
"""
认知分心检测器

多模态融合:眼动 + 生理 + 行为
"""

def __init__(self):
self.saccade_analyzer = SaccadeEntropyAnalyzer()
self.gaze_analyzer = GazeDispersionAnalyzer()
self.physio_analyzer = PhysiologicalSignalAnalyzer()
self.behavior_analyzer = DrivingBehaviorModel()

def detect(self, gaze_data: dict,
physio_data: dict,
behavior_data: dict) -> dict:
"""
检测认知分心

Returns:
{
'is_distracted': bool,
'confidence': float,
'contributing_factors': list
}
"""
factors = []
scores = []

# 1. 眼动分析
if 'saccades' in gaze_data:
for saccade in gaze_data['saccades']:
self.saccade_analyzer.add_saccade(
saccade['start'], saccade['end']
)

is_distracted, entropy = self.saccade_analyzer.detect_cognitive_distraction()
if is_distracted:
factors.append('LOW_SACCADE_ENTROPY')
scores.append(1 - entropy)

# 2. 注视分散度
if 'gaze_points' in gaze_data:
for point in gaze_data['gaze_points']:
self.gaze_analyzer.add_gaze(point[0], point[1])

is_distracted, dispersion = self.gaze_analyzer.detect_cognitive_distraction()
if is_distracted:
factors.append('LOW_GAZE_DISPERSION')
scores.append(1 - dispersion / 100.0)

# 3. 生理信号
if 'hrv' in physio_data:
self.physio_analyzer.add_hrv(physio_data['hrv'])

if 'eda' in physio_data:
self.physio_analyzer.add_eda(physio_data['eda'])

physio_result = self.physio_analyzer.analyze_cognitive_load()
if physio_result['cognitive_load_score'] > 0.5:
factors.append('HIGH_COGNITIVE_LOAD')
scores.append(physio_result['cognitive_load_score'])

# 4. 驾驶行为
behavior_result = self.behavior_analyzer.analyze_behavior()
if behavior_result['behavior_anomaly']:
factors.append('BEHAVIOR_ANOMALY')
scores.append(0.5)

# 综合判断
is_distracted = len(factors) >= 2
confidence = np.mean(scores) if scores else 0.0

return {
'is_distracted': is_distracted,
'confidence': confidence,
'contributing_factors': factors
}

对 IMS 开发的启示

1. 技术路线

阶段 技术方案 成熟度
短期 眼动规律性分析
中期 眼动 + 生理信号融合
长期 多模态深度学习 研究

2. 关键挑战

挑战 原因 应对策略
无直接信号 眼睛看向前方 分析眼动模式异常
个体差异大 不同驾驶员基线不同 建立个人基线
验证困难 无客观真值 驾驶模拟器实验

3. 测试场景

场景 触发条件 检测方法
CD-01 进行复杂心算 扫视熵降低
CD-02 情绪激动对话 HRV 降低
CD-03 长时间单调驾驶 注视分散度降低

参考资料

  1. Euro NCAP 2026 Roadmap: Vision 2030 framework
  2. 学术论文: “Eye movement patterns as indicators of cognitive distraction”
  3. IEEE T-ITS: Driver cognitive distraction detection methods

总结

认知分心检测技术要点:

  1. 眼动规律性: 扫视熵、注视分散度是关键指标
  2. 生理信号: HRV、EDA 可作为补充信号
  3. 驾驶行为: 转向熵、车道保持是辅助指标
  4. 多模态融合: 综合多种信号提高准确性

对 IMS 开发,眼动规律性分析是当前最可行的技术方案。


认知分心检测技术综述:从眼动规律到行为建模
https://dapalm.com/2026/06/14/2026-06-14-Cognitive-Distraction-Detection-Review-Eye-Movement-Physiology/
作者
Mars
发布于
2026年6月14日
许可协议