个体校准+可解释DMS:面部地标驱动的人类感知自动驾驶交互框架

Frontiers in Robotics and AI论文解读

Candela et al., “Interpretable Driver Behavioral State Monitoring using Facial Landmarks for Human-Autonomous Vehicle Interaction”, Front. Robot. AI, 2026.

论文信息

项目 内容
标题 Interpretable Driver Behavioral State Monitoring using Facial Landmarks for Human-Autonomous Vehicle Interaction
作者 Candela, Mandujano-Carrillo, Vidal-Lopez, Ramírez-Moreno, Martinez, Lozoya-Santos
期刊 Frontiers in Robotics and AI (Human-Robot Interaction section)
年份 2026
DOI 10.3389/frobt.2026.1896859

核心创新

首次在真实自动驾驶车辆(Polaris GEM e6,drive-by-wire+LiDAR)上集成:

  1. 个体校准面部行为监测——为每个驾驶员建立个人基线
  2. 可解释HMI可视化——ROS+Foxglove实时显示车辆状态+驾驶员状态
  3. 5种行为状态识别——neutral/eye_closure/out_of_safe_zone/yawning/excessive_blinking

系统架构

5种行为状态定义

状态 标签 触发条件 个体校准参数
Neutral 正常驾驶 所有指标在基线±1σ内 EAR/MAR/头部角度基线
Eye Closure 闭眼 EAR < 个人阈值 EAR_neutral + 标准差
Out-of-Safe-Zone 头部偏离 头部角度超出安全范围 偏航/俯仰基线
Yawning 打哈欠 MAR > 个人阈值 MAR_neutral + 标准差
Excessive Blinking 频繁眨眼 眨眼率 > 个人阈值×1.5 眨眼频率基线

个体校准方法

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
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
"""
个体校准面部行为监测框架

论文核心:不使用固定阈值,而是为每个驾驶员建立个人基线
这与通航40飞行员研究(Frontiers Neuroergonomics)的结论一致:
"跨人泛化失败→需个体校准"

校准流程:
1. 驾驶员正常驾驶5秒(neutral状态)
2. 计算个人基线:EAR/MAR/头部角度的均值+标准差
3. 后续状态检测:z-score超个人阈值→判定异常
"""

import numpy as np
from dataclasses import dataclass
from typing import Tuple, Optional
from enum import Enum

class BehavioralState(Enum):
NEUTRAL = "neutral"
EYE_CLOSURE = "eye_closure"
OUT_OF_SAFE_ZONE = "out_of_safe_zone"
YAWNING = "yawning"
EXCESSIVE_BLINKING = "excessive_blinking"

@dataclass
class IndividualBaseline:
"""个体校准基线"""
ear_mean: float # 眼睛纵横比均值
ear_std: float # 标准差
mar_mean: float # 嘴纵横比均值
mar_std: float
head_pitch_mean: float # 头部俯仰
head_pitch_std: float
head_yaw_mean: float # 头部偏航
head_yaw_std: float
blink_rate_baseline: float # 眨眼频率(次/分钟)

@property
def ear_threshold(self):
"""闭眼阈值:均值-2σ"""
return self.ear_mean - 2 * self.ear_std

@property
def mar_threshold(self):
"""打哈欠阈值:均值+3σ"""
return self.mar_mean + 3 * self.mar_std

@property
def blink_rate_threshold(self):
"""频繁眨眼阈值:基线×1.5"""
return self.blink_rate_baseline * 1.5


class BehavioralStateDetector:
"""
基于个体校准的行为状态检测器

使用MediaPipe 468个3D面部地标
特征:EAR(眼睛) + MAR(嘴) + 头部姿态
分类器:SVM(论文中最佳)
"""

def __init__(self):
self.baseline: Optional[IndividualBaseline] = None
self.calibrated = False
self.history = []
self.blink_timestamps = []

def calibrate(self, neutral_features: list) -> bool:
"""
个体校准:从neutral状态数据建立基线

Args:
neutral_features: [(ear, mar, pitch, yaw, blink), ...]
至少5秒数据(150帧@30fps)
"""
if len(neutral_features) < 30:
return False

ears = [f[0] for f in neutral_features]
mars = [f[1] for f in neutral_features]
pitches = [f[2] for f in neutral_features]
yaws = [f[3] for f in neutral_features]
blinks = [f[4] for f in neutral_features if len(f) > 4]

blink_rate = len([b for b in blinks if b]) * (60 / (len(neutral_features) / 30))

self.baseline = IndividualBaseline(
ear_mean=np.mean(ears), ear_std=np.std(ears),
mar_mean=np.mean(mars), mar_std=np.std(mars),
head_pitch_mean=np.mean(pitches), head_pitch_std=np.std(pitches),
head_yaw_mean=np.mean(yaws), head_yaw_std=np.std(yaws),
blink_rate_baseline=blink_rate,
)
self.calibrated = True
return True

def detect(self, ear: float, mar: float,
pitch: float, yaw: float,
timestamp: float) -> BehavioralState:
"""
实时行为状态检测

基于个体阈值的规则判定
"""
if not self.calibrated:
return BehavioralState.NEUTRAL

self.history.append((ear, mar, pitch, yaw, timestamp))
if len(self.history) > 90: # 3秒@30fps
self.history = self.history[-90:]

# 闭眼检测
if ear < self.baseline.ear_threshold:
return BehavioralState.EYE_CLOSURE

# 打哈欠
if mar > self.baseline.mar_threshold:
return BehavioralState.YAWNING

# 频繁眨眼
recent_blinks = [h for h in self.history
if h[0] < self.baseline.ear_mean - self.baseline.ear_std
and timestamp - h[4] < 60] # 1分钟内
blink_rate = len(recent_blinks)
if blink_rate > self.baseline.blink_rate_threshold:
return BehavioralState.EXCESSIVE_BLINKING

# 头部偏离
pitch_z = abs(pitch - self.baseline.head_pitch_mean) / max(self.baseline.head_pitch_std, 0.01)
yaw_z = abs(yaw - self.baseline.head_yaw_mean) / max(self.baseline.head_yaw_std, 0.01)
if pitch_z > 2 or yaw_z > 2:
return BehavioralState.OUT_OF_SAFE_ZONE

return BehavioralState.NEUTRAL


# ==================== SVM分类器 ====================
from sklearn.svm import SVC
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import cross_val_score
import numpy as np

def train_classifiers(X: np.ndarray, y: np.ndarray):
"""
训练SVM和RF分类器

论文结果:
- SVM: 10折CV ~91% 准确率/F1
- RF: 10折CV ~91%,但室外测试降至~70%
- CNN: ~80% F1
- RNN: ~80% F1
- 启发式规则: ~81% F1

SVM最稳定,混淆集中在out-of-safe-zone/neutral
"""
# SVM (论文最佳)
svm = SVC(kernel='rbf', C=10, gamma='scale', random_state=42)
svm_scores = cross_val_score(svm, X, y, cv=10, scoring='f1_macro')

# RF
rf = RandomForestClassifier(n_estimators=100, random_state=42)
rf_scores = cross_val_score(rf, X, y, cv=10, scoring='f1_macro')

print("=== 分类器性能对比(10折CV)===")
print(f"SVM: F1={svm_scores.mean():.3f} ± {svm_scores.std():.3f}")
print(f"RF: F1={rf_scores.mean():.3f} ± {rf_scores.std():.3f}")
print(f"论文参考: SVM ~91%, RF ~91%(室内), RF ~70%(室外)")

return svm, rf


# ==================== 测试 ====================
if __name__ == "__main__":
# 模拟个体校准
np.random.seed(42)

# neutral状态5秒(150帧)
neutral_data = [
(np.random.normal(0.28, 0.02), # EAR
np.random.normal(0.12, 0.02), # MAR
np.random.normal(0, 2), # pitch
np.random.normal(0, 3), # yaw
False) # blink
for _ in range(150)
]

detector = BehavioralStateDetector()
success = detector.calibrate(neutral_data)

print(f"个体校准: {'成功' if success else '失败'}")
print(f"EAR基线: {detector.baseline.ear_mean:.3f} ± {detector.baseline.ear_std:.3f}")
print(f"EAR闭眼阈值: {detector.baseline.ear_threshold:.3f}")
print(f"MAR基线: {detector.baseline.mar_mean:.3f} ± {detector.baseline.mar_std:.3f}")
print(f"MAR打哈欠阈值: {detector.baseline.mar_threshold:.3f}")
print(f"眨眼频率基线: {detector.baseline.blink_rate_baseline:.1f}次/分")

# 模拟实时检测
print(f"\n--- 实时行为检测 ---")
test_frames = [
(0.25, 0.12, 0, 0, 0, "正常驾驶"),
(0.10, 0.12, 0, 0, 0.5, "闭眼"), # EAR低
(0.28, 0.45, 0, 0, 0, "打哈欠"), # MAR高
(0.28, 0.12, 25, 0, 0, "头部偏离"), # pitch大
(0.28, 0.12, 0, 0, 0, "正常"),
]

for ear, mar, pitch, yaw, t, expected in test_frames:
state = detector.detect(ear, mar, pitch, yaw, t)
print(f" EAR={ear:.2f} MAR={mar:.2f} pitch={pitch:.0f}° → {state.value:20s} (期望: {expected})")

实验结果

分类器性能

分类器 10折CV F1 室外测试F1 稳定性
SVM ~91% ~91% ✅ 最稳定
随机森林 ~91% ~70% ⚠️ 室外退化
CNN ~80% ~80% —
RNN ~80% ~80% —
启发式规则 ~81% ~81% ✅ 基线参考

关键统计显著性

状态 特征 Kruskal-Wallis p值 显著性
闭眼 EAR <0.001 ✅ 极显著
打哈欠 MAR <0.001 ✅ 极显著
频繁眨眼 眨眼率 <0.01 ✅ 显著
头部偏离 头部旋转 >0.05 ❌ 不显著

关键发现: 头部偏离(out-of-safe-zone)与neutral状态无统计显著差异——说明个体校准对头部姿态的效果有限。

与通航40飞行员研究的呼应

维度 本论文(Frontiers Robotics) 40飞行员(Frontiers Neuroergonomics)
个体校准 ✅ 核心设计 ✅ 结论:跨人泛化失败
可解释性 ✅ 面部地标+HMI ✅ Grad-CAM
真实环境 ✅ 自驾车室外 ✅ 真实飞行
SVM vs DL SVM>DL —
个体变异 室外退化→需个体适应 跨飞行员泛化失败

两篇论文独立得出了相同结论:个体校准是DMS的必需设计。

HMI可视化设计

ROS + Foxglove架构

HMI设计原则

原则 说明
透明性 驾驶员能看到车辆”看到”什么
状态可视化 自动驾驶状态机当前状态
行为反馈 驾驶员行为状态的实时可视化
信任建设 理解车辆决策→信任自动驾驶

IMS开发启示

1. 个体校准的工程实现

步骤 时长 数据需求 实现
1. 检测到驾驶员 <1s 人脸检测成功 YOLO27n
2. neutral基线 5-15s ≥150帧正常驾驶 EAR/MAR/头部角度
3. 阈值计算 <1s 均值±2-3σ 统计计算
4. 实时检测 持续 30fps z-score规则/SVM
5. 基线更新 每30min 滑动窗口 渐进更新

2. SVM vs DL的选择

论文结论:SVM在真实室外环境中优于DL。

维度 SVM CNN/RNN
数据需求 少(<100样本/类) 多(>1000)
室外泛化 ✅ 稳定 ⚠️ 退化
边缘部署 ✅ <1MB ⚠️ 5-10MB
可解释性 ✅ 支持向量可视化 ❌ 黑盒
帧率 ✅ >100fps 30-60fps

IMS建议: DMS分类层优先SVM,DL作为融合信号而非主分类器。

3. HMI作为信任建设工具

论文的另一贡献:将DMS状态可视化给驾驶员——不是单向监测,而是双向交互。

DMS状态 HMI显示 效果
Neutral “系统监测正常” 建立信任
Eye Closure “检测到闭眼,请保持清醒” 意识唤醒
Out-of-zone “请调整坐姿/视线” 行为纠正
Yawning “建议休息” 预防性建议

局限性

  1. 头部偏离不显著:个体校准对头部偏离效果有限
  2. 室外退化:RF从91%降至70%,SVM仍稳定
  3. 5状态有限:未覆盖分心(手机)、认知疲劳等复杂状态
  4. 无IR夜间:RealSense L515不适合完全黑暗
  5. 校准假设neutral:如果校准时已疲劳,基线偏差

结论

这篇论文再次验证了个体校准和可解释性在DMS中的核心地位。SVM在真实环境中的稳定性优于DL,说明简单+校准可能比复杂+通用更可靠。

对IMS的核心启示:

  1. 个体校准是必需的——两篇独立论文都得出此结论
  2. SVM应作为DMS基线分类器——稳定、轻量、可解释
  3. HMI双向交互——DMS不只是监测,也是信任建设工具
  4. 头部姿态需更鲁棒的特征——简单角度不显著,需序列模式

参考来源:

  • Candela et al., Front. Robot. AI, 2026, DOI: 10.3389/frobt.2026.1896859
  • MediaPipe面部地标 (google.github.io/mediapipe)
  • ROS + Foxglove Studio (foxglove.dev)
  • Polaris GEM e6自动驾驶平台