驾驶员姿态+面部状态联合疲劳检测:多模态融合优于单一方法

驾驶员姿态+面部状态联合疲劳检测:多模态融合优于单一方法

核心发现

Nature Scientific Reports 2026 发表的驾驶员姿态研究:

方法 准确率 优势 劣势
仅面部状态 85% 直接疲劳指标 墨镜/口罩遮挡失效
仅驾驶员姿态 78% 不受遮挡影响 间接指标,延迟大
多模态融合 93% 互补优势 计算复杂度增加

研究动机

单一模态的局限

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
疲劳检测单一方法的局限:

┌─────────────────────────────────────────────────────┐
│ 面部状态检测 │
├─────────────────────────────────────────────────────┤
│ │
│ 指标: │
│ - PERCLOS(眼睑闭合百分比) │
│ - 打哈欠频率 │
│ - 视线方向 │
│ │
│ 局限: │
│ ❌ 墨镜遮挡眼部 │
│ ❌ 口罩遮挡嘴部 │
│ ❌ 大角度侧脸 │
│ ❌ 夜间光照不足 │
│ │
└─────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────┐
│ 驾驶员姿态检测 │
├─────────────────────────────────────────────────────┤
│ │
│ 指标: │
│ - 握方向盘力度变化 │
│ - 身体晃动频率 │
│ - 头部姿态变化 │
│ - 座椅压力分布 │
│ │
│ 局限: │
│ ❌ 间接指标,延迟大 │
│ ❌ 个体差异大 │
│ ❌ 道路条件干扰 │
│ │
└─────────────────────────────────────────────────────┘

结论:多模态融合是最佳方案

方法详解

多模态融合架构

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
212
213
214
215
216
217
218
219
220
221
222
223
224
"""
多模态疲劳检测架构

驾驶员姿态 + 面部状态联合分析
"""

import torch
import torch.nn as nn
import torch.nn.functional as F

class FacialStateEncoder(nn.Module):
"""
面部状态编码器

提取 PERCLOS、打哈欠、视线特征
"""

def __init__(self):
super().__init__()

# 面部特征提取
self.face_cnn = nn.Sequential(
nn.Conv2d(3, 64, 7, 2, 3),
nn.ReLU(),
nn.MaxPool2d(3, 2),
nn.Conv2d(64, 128, 3, 2, 1),
nn.ReLU(),
nn.Conv2d(128, 256, 3, 2, 1),
nn.ReLU(),
nn.AdaptiveAvgPool2d(1)
)

# PERCLOS 分支
self.perclos_head = nn.Sequential(
nn.Linear(256, 64),
nn.ReLU(),
nn.Linear(64, 1) # PERCLOS 值
)

# 打哈欠分支
self.yawn_head = nn.Sequential(
nn.Linear(256, 64),
nn.ReLU(),
nn.Linear(64, 1) # 打哈欠概率
)

# 视线分支
self.gaze_head = nn.Sequential(
nn.Linear(256, 64),
nn.ReLU(),
nn.Linear(64, 2) # 视线方向 (pitch, yaw)
)

def forward(self, face_image):
"""
Args:
face_image: (B, 3, 224, 224)

Returns:
facial_features: (B, 256+1+1+2)
"""
# 特征提取
features = self.face_cnn(face_image).flatten(1)

# 各分支输出
perclos = self.perclos_head(features)
yawn = torch.sigmoid(self.yawn_head(features))
gaze = self.gaze_head(features)

# 拼接
return torch.cat([features, perclos, yawn, gaze], dim=1)


class DrivingPostureEncoder(nn.Module):
"""
驾驶员姿态编码器

提取握方向盘、身体晃动、头部姿态特征
"""

def __init__(self, seq_len: int = 300):
"""
Args:
seq_len: 时间序列长度(10秒 @ 30fps)
"""
super().__init__()

# 骨骼点序列编码
self.skeleton_encoder = nn.Sequential(
nn.Conv1d(3, 64, 3, 1, 1), # (x, y, conf) × 17 关键点
nn.ReLU(),
nn.Conv1d(64, 128, 3, 1, 1),
nn.ReLU(),
nn.Conv1d(128, 256, 3, 1, 1),
nn.AdaptiveAvgPool1d(1)
)

# 时序建模
self.temporal_encoder = nn.LSTM(
input_size=256,
hidden_size=128,
num_layers=2,
batch_first=True,
bidirectional=True
)

# 头部姿态分支
self.head_pose_head = nn.Sequential(
nn.Linear(256, 64),
nn.ReLU(),
nn.Linear(64, 3) # (roll, pitch, yaw)
)

# 身体晃动分支
self.body_motion_head = nn.Sequential(
nn.Linear(256, 64),
nn.ReLU(),
nn.Linear(64, 1) # 晃动强度
)

def forward(self, skeleton_sequence):
"""
Args:
skeleton_sequence: (B, seq_len, 17, 3)

Returns:
posture_features: (B, 256)
"""
B, T, J, C = skeleton_sequence.shape

# 展平关键点维度
skeleton_flat = skeleton_sequence.view(B, T, J * C)

# 时序编码
temporal_features, _ = self.temporal_encoder(skeleton_flat)

# 取最后时刻
last_features = temporal_features[:, -1, :]

return last_features


class MultiModalFatigueDetector(nn.Module):
"""
多模态疲劳检测器

融合面部状态和驾驶员姿态
"""

def __init__(self):
super().__init__()

# 模态编码器
self.facial_encoder = FacialStateEncoder()
self.posture_encoder = DrivingPostureEncoder()

# 多模态融合
self.fusion = nn.Sequential(
nn.Linear(256 + 260, 256), # 姿态 + 面部
nn.ReLU(),
nn.Dropout(0.3),
nn.Linear(256, 128),
nn.ReLU(),
)

# 疲劳分类头
self.classifier = nn.Sequential(
nn.Linear(128, 64),
nn.ReLU(),
nn.Linear(64, 3) # 清醒, 轻度疲劳, 重度疲劳
)

# 注意力融合权重
self.attention = nn.Sequential(
nn.Linear(256 + 260, 64),
nn.ReLU(),
nn.Linear(64, 2),
nn.Softmax(dim=1)
)

def forward(self, face_image, skeleton_sequence):
"""
Args:
face_image: (B, 3, 224, 224)
skeleton_sequence: (B, seq_len, 17, 3)

Returns:
fatigue_level: (B, 3)
attention_weights: (B, 2)
"""
# 1. 编码各模态
facial_features = self.facial_encoder(face_image)
posture_features = self.posture_encoder(skeleton_sequence)

# 2. 计算注意力权重
concat_features = torch.cat([posture_features, facial_features], dim=1)
attention_weights = self.attention(concat_features)

# 3. 加权融合
weighted_facial = facial_features * attention_weights[:, 1:2]
weighted_posture = posture_features * attention_weights[:, 0:1]

fused = torch.cat([weighted_posture, weighted_facial], dim=1)

# 4. 分类
features = self.fusion(fused)
fatigue_logits = self.classifier(features)

return fatigue_logits, attention_weights


# 使用示例
if __name__ == "__main__":
model = MultiModalFatigueDetector()

# 模拟输入
face = torch.randn(2, 3, 224, 224)
skeleton = torch.randn(2, 300, 17, 3) # 10秒 @ 30fps

# 检测
logits, attention = model(face, skeleton)

print(f"疲劳等级: {logits.argmax(dim=1)}")
print(f"注意力权重 [姿态, 面部]: {attention}")

关键指标

面部状态指标

指标 计算方法 疲劳阈值
PERCLOS 60秒内眼睑开度 < 20% 的比例 ≥ 30%
打哈欠频率 每分钟打哈欠次数 ≥ 3 次
眨眼频率 每分钟眨眼次数 < 10 或 > 30
视线偏离 视线偏离道路的时间比例 ≥ 20%

驾驶员姿态指标

指标 计算方法 疲劳阈值
头部晃动 头部姿态标准差 ≥ 10°
身体晃动 躯干位移标准差 ≥ 5cm
方向盘握力 握力变化频率 降低 30%
反应延迟 对方向盘校正的响应时间 增加 50%

实验结果

多模态融合优势

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
遮挡场景性能对比:

┌─────────────────────────────────────────────────────┐
│ │
│ 正常场景: │
│ 仅面部: 85% ████████████████████░░░ │
│ 仅姿态: 78% ████████████████░░░░░░ │
│ 多模态: 93% ████████████████████████░ │
│ │
│ 墨镜遮挡: │
│ 仅面部: 62% ████████████░░░░░░░░░░░ │
│ 仅姿态: 78% ████████████████░░░░░░ │
│ 多模态: 89% ████████████████████░░░ │
│ │
│ 口罩遮挡: │
│ 仅面部: 70% ██████████████░░░░░░░░ │
│ 仅姿态: 78% ████████████████░░░░░░ │
│ 多模态: 88% ████████████████████░░░ │
│ │
│ 夜间低光: │
│ 仅面部: 68% █████████████░░░░░░░░░ │
│ 仅姿态: 75% ███████████████░░░░░░░ │
│ 多模态: 86% ██████████████████░░░░ │
│ │
└─────────────────────────────────────────────────────┘

注意力权重分析

场景 姿态权重 面部权重 说明
正常 0.35 0.65 面部为主
墨镜 0.58 0.42 姿态补偿
口罩 0.48 0.52 略偏向姿态
夜间 0.45 0.55 姿态补偿低光

Euro NCAP 合规

测试场景覆盖

Euro NCAP 场景 单一面部 多模态 合规
FT-01 疲劳检测
FT-02 墨镜场景
FT-03 夜间场景 ⚠️
FT-04 微睡眠

IMS 开发启示

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
"""
IMS 疲劳检测鲁棒性设计

处理各种遮挡场景
"""

class IMSRobustFatigueDetector:
"""
IMS 鲁棒疲劳检测器
"""

def __init__(self):
self.facial_detector = FacialStateEncoder()
self.posture_detector = DrivingPostureEncoder()
self.fusion = MultiModalFatusion()

# 遮挡检测
self.occlusion_detector = OcclusionDetector()

def detect_with_occlusion(self, frame, skeleton):
"""
检测疲劳,自动处理遮挡

Args:
frame: 图像帧
skeleton: 骨骼点序列

Returns:
fatigue_result: {
'level': int,
'confidence': float,
'modality_used': str,
'occlusion_detected': str
}
"""
# 1. 检测遮挡
occlusion = self.occlusion_detector.detect(frame)

# 2. 根据遮挡选择模态
if occlusion['eyes_occluded']:
# 眼部遮挡,依赖姿态
return self._detect_by_posture(skeleton, occlusion)
elif occlusion['mouth_occluded']:
# 嘴部遮挡,仍可用眼部
return self._detect_by_face_partial(frame, skeleton, occlusion)
else:
# 无遮挡,多模态融合
return self._detect_multimodal(frame, skeleton, occlusion)

2. 部署建议

场景 推荐配置
高端车型 多摄像头 + 座椅传感器 + 完整多模态
中端车型 单摄像头 + 骨骼点检测 + 轻量融合
低端车型 单摄像头 + 面部检测 + 姿态辅助

总结

多模态疲劳检测核心优势:

  1. 鲁棒性 - 单一模态失效时自动补偿
  2. 准确率提升 - 93% vs 85%(单一面部)
  3. 遮挡适应 - 墨镜/口罩场景仍有效
  4. 夜间可用 - 姿态补偿低光不足

对 IMS 开发的启示:

  • 多模态是疲劳检测的未来方向
  • 注意力机制实现自适应融合
  • 遮挡检测是鲁棒性的关键

参考资源

资源 链接
论文 Nature Scientific Reports s41598-026-44994-4
Euro NCAP euroncap.com/protocols

驾驶员姿态+面部状态联合疲劳检测:多模态融合优于单一方法
https://dapalm.com/2026/04/26/2026-04-26-posture-facial-fatigue-fusion/
作者
Mars
发布于
2026年4月26日
许可协议