BiFuseNet:3D面部AI同时检测酒驾、疲劳与愤怒,88%酒精检测准确率

论文信息


核心创新

ECU团队开发了一个名为”Jack of Many Faces”的统一3D深度学习系统,通过单一模型同时检测三种最危险的驾驶状态:

  1. 酒精损伤 — BAC估计准确率 88.41%
  2. 疲劳 — 检测准确率 95%
  3. 情绪(愤怒) — 情绪波动检测

关键突破在于:能区分疲劳和酒精的相似面部表现。此前大多数AI工具只能检测单一因素,而实际中严重疲劳与酒精损伤在面部表现上高度相似。


技术架构

1. 统一3D面部检测模型

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
"""
BiFuseNet: 双模态融合的驾驶员损伤检测系统
论文: ECU BMVC25 + ICMI25
核心: RGB + IR 双输入融合,3D面部几何提取

依赖: torch>=2.0, torchvision>=0.15, mediapipe>=0.10
"""

import torch
import torch.nn as nn
import torch.nn.functional as F
from typing import Tuple

class BiFuseNetBackbone(nn.Module):
"""
双模态融合骨干网络

输入: RGB视频帧 + IR红外视频帧
输出: 面部3D几何特征 + 损伤状态估计
"""

def __init__(self, num_classes: int = 3):
super().__init__()
# RGB分支 (可见光)
self.rgb_encoder = self._build_encoder(in_channels=3)
# IR分支 (红外)
self.ir_encoder = self._build_encoder(in_channels=1)
# 融合层
self.fusion = nn.Sequential(
nn.Linear(512 * 2, 256),
nn.ReLU(),
nn.Dropout(0.3),
nn.Linear(256, 128)
)
# 三头输出: 酒精/疲劳/情绪
self.alcohol_head = nn.Linear(128, 3) # sober/moderate/severe
self.fatigue_head = nn.Linear(128, 3) # alert/mild/severe
self.emotion_head = nn.Linear(128, 3) # calm/angry/aggressive

def _build_encoder(self, in_channels: int) -> nn.Module:
"""轻量3D CNN编码器"""
return nn.Sequential(
nn.Conv3d(in_channels, 32, kernel_size=(3,3,3), padding=1),
nn.BatchNorm3d(32),
nn.ReLU(),
nn.MaxPool3d((1,2,2)),
nn.Conv3d(32, 64, kernel_size=(3,3,3), padding=1),
nn.BatchNorm3d(64),
nn.ReLU(),
nn.MaxPool3d((1,2,2)),
nn.Conv3d(64, 128, kernel_size=(3,3,3), padding=1),
nn.BatchNorm3d(128),
nn.ReLU(),
nn.AdaptiveAvgPool3d((1,1,1)),
nn.Flatten(),
nn.Linear(128, 512)
)

def forward(self, rgb: torch.Tensor, ir: torch.Tensor) -> Tuple[torch.Tensor, torch.Tensor, torch.Tensor]:
"""
前向传播

Args:
rgb: RGB视频片段, shape=(B, 3, T, H, W)
ir: IR视频片段, shape=(B, 1, T, H, W)

Returns:
alcohol_pred: 酒精损伤等级 (B, 3)
fatigue_pred: 疲劳等级 (B, 3)
emotion_pred: 情绪等级 (B, 3)
"""
rgb_feat = self.rgb_encoder(rgb) # (B, 512)
ir_feat = self.ir_encoder(ir) # (B, 512)

# 双模态融合
fused = torch.cat([rgb_feat, ir_feat], dim=1)
shared_feat = self.fusion(fused) # (B, 128)

alcohol_pred = self.alcohol_head(shared_feat)
fatigue_pred = self.fatigue_head(shared_feat)
emotion_pred = self.emotion_head(shared_feat)

return alcohol_pred, fatigue_pred, emotion_pred


class FacialLandmarkExtractor(nn.Module):
"""
面部关键点提取器

提取68个面部关键点,计算:
- 眨眼频率 (EAR, Eye Aspect Ratio)
- 面部肌肉微动作
- 头部姿态估计
"""

def __init__(self):
super().__init__()
# 关键点检测
self.landmark_det = nn.Sequential(
nn.Conv2d(3, 64, 7, stride=2, padding=3),
nn.ReLU(),
nn.MaxPool2d(2),
nn.Conv2d(64, 128, 3, padding=1),
nn.ReLU(),
nn.MaxPool2d(2),
nn.Conv2d(128, 256, 3, padding=1),
nn.ReLU(),
nn.AdaptiveAvgPool2d((1,1)),
nn.Flatten(),
nn.Linear(256, 68 * 2) # 68个关键点 x,y
)

def compute_ear(self, landmarks: torch.Tensor) -> torch.Tensor:
"""计算眼睛纵横比(EAR)"""
# 左眼: points 36-41, 右眼: points 42-47
left_eye = landmarks[:, 36:42]
right_eye = landmarks[:, 42:48]

def ear(eye):
# EAR = (|p2-p6| + |p3-p5|) / (2 * |p1-p4|)
vertical_1 = torch.norm(eye[:, 1] - eye[:, 5], dim=1)
vertical_2 = torch.norm(eye[:, 2] - eye[:, 4], dim=1)
horizontal = torch.norm(eye[:, 0] - eye[:, 3], dim=1)
return (vertical_1 + vertical_2) / (2.0 * horizontal + 1e-6)

return (ear(left_eye) + ear(right_eye)) / 2.0


if __name__ == "__main__":
# 模型初始化
model = BiFuseNetBackbone()
landmark_ext = FacialLandmarkExtractor()

# 模拟输入
B, T, H, W = 1, 16, 224, 224
rgb = torch.randn(B, 3, T, H, W)
ir = torch.randn(B, 1, T, H, W)

# 前向传播
alcohol, fatigue, emotion = model(rgb, ir)

print(f"酒精检测: {F.softmax(alcohol, dim=1)}")
print(f" → 预测: {['清醒', '中度', '严重'][alcohol.argmax()]}")
print(f"疲劳检测: {F.softmax(fatigue, dim=1)}")
print(f" → 预测: {['清醒', '轻度', '严重'][fatigue.argmax()]}")
print(f"情绪检测: {F.softmax(emotion, dim=1)}")
print(f" → 预测: {['平静', '愤怒', '攻击性'][emotion.argmax()]}")

# 关键点提取
face_img = torch.randn(1, 3, 224, 224)
landmarks = landmark_ext.landmark_det(face_img).view(1, 68, 2)
ear = landmark_ext.compute_ear(landmarks)
print(f"EAR值: {ear.item():.4f} (< 0.2 可能闭眼)")

total_params = sum(p.numel() for p in model.parameters())
print(f"\n模型参数量: {total_params:,}")

2. BiFuseNet双模态融合策略


性能指标

检测维度 准确率 分级能力 说明
酒精损伤 (BAC) 88.41% 3级(清醒/中度/严重) 超越NHTSA要求的被动检测阈值
疲劳 95.00% 3级(清醒/轻度/严重) 高于PERCLOS基线方法
情绪(愤怒) - 3级(平静/愤怒/攻击性) 首个统一检测方案
夜间IR融合 显著提升 - BiFuseNet双模态融合

与现有方案对比

方案 检测方式 酒精准确率 疲劳准确率 多状态 夜间可用
呼气式检测 接触式 99%+ ❌ ❌ ✅
血液检测 接触式 99%+ ❌ ❌ ✅
PERCLOS 视觉 ❌ ~85% ❌ 需IR
单一CNN 视觉 ~75% ~80% ❌ ❌
BiFuseNet RGB+IR 88.41% 95% ✅ ✅

NHTSA法规背景

美国HALT Act要求

时间节点 要求 当前状态
2021年 Infrastructure Investment and Jobs Act 通过 Section 24220
2024年 NHTSA 初始研究报告 技术尚不成熟
2026年2月 NHTSA 向国会报告 无商用系统能同时满足被动+准确
2027年 原定最终技术规则 预计延期
2029年 原定生效日期 不确定

NHTSA 2026年2月报告关键结论:

“no commercially available system could yet detect alcohol impairment both passively and accurately enough to support the mandated regulation”

BiFuseNet的突破意义: 88.41%的酒精检测准确率是目前被动式(非接触)视觉方案的最高水平,虽未达到法规要求的99%+,但首次证明了多状态统一检测的技术可行性。


IMS开发启示

1. 直接可落地的技术方案

IMS模块 可用方案 优先级
酒驾检测(2026新增) BiFuseNet面部3D分析 🔴 高
疲劳检测 EAR + 面部肌肉微动作 🟡 中(已有PERCLOS,可增强)
情绪检测 面部关键点 + 3D几何 🟡 中(新需求)
夜间检测 RGB+IR双模态融合 🔴 高(夜间场景必需)

2. 硬件配置建议

组件 推荐型号 参数 说明
RGB摄像头 OV2311 2MP, 1600×1200, 全局快门 已在IMS中使用
IR摄像头 MLX90640 32×24热成像阵列 低成本IR方案
IR补光 SFH 4740 940nm, 120mW/sr 与现有DMS共用
处理器 QCS8255 Hexagon NPU, 26 TOPS 3D CNN需NPU加速

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
# 3D CNN模型量化部署方案
import torch
import onnxruntime as ort
from pathlib import Path

def export_to_onnx(model: nn.Module, output_path: str):
"""导出为ONNX格式"""
dummy_rgb = torch.randn(1, 3, 16, 224, 224)
dummy_ir = torch.randn(1, 1, 16, 224, 224)

torch.onnx.export(
model, (dummy_rgb, dummy_ir), output_path,
input_names=['rgb_input', 'ir_input'],
output_names=['alcohol', 'fatigue', 'emotion'],
opset_version=16,
dynamic_axes={
'rgb_input': {0: 'batch'},
'ir_input': {0: 'batch'}
}
)
print(f"ONNX模型已导出: {output_path}")

def quantize_for_edge(onnx_path: str, quantized_path: str):
"""INT8量化用于边缘部署"""
from onnxruntime.quantization import quantize_dynamic, QuantType

quantize_dynamic(
onnx_path,
quantized_path,
weight_type=QuantType.QInt8
)
print(f"量化模型已保存: {quantized_path}")

# 比较模型大小
orig_size = Path(onnx_path).stat().st_size / 1024 / 1024
quant_size = Path(quantized_path).stat().st_size / 1024 / 1024
print(f"原始: {orig_size:.1f}MB → 量化: {quant_size:.1f}MB ({quant_size/orig_size*100:.0f}%)")

def benchmark_on_npu(quantized_path: str):
"""在Hexagon NPU上基准测试"""
# QCS8255 Hexagon NPU benchmark
session = ort.InferenceSession(
quantized_path,
providers=['QNNExecutionProvider'] # Qualcomm NPU
)

import time, numpy as np
rgb_input = np.random.randn(1, 3, 16, 224, 224).astype(np.float32)
ir_input = np.random.randn(1, 1, 16, 224, 224).astype(np.float32)

# 预热
for _ in range(5):
session.run(None, {'rgb_input': rgb_input, 'ir_input': ir_input})

# 推理测试
times = []
for _ in range(50):
t0 = time.perf_counter()
outputs = session.run(None, {'rgb_input': rgb_input, 'ir_input': ir_input})
times.append((time.perf_counter() - t0) * 1000)

print(f"平均推理时间: {np.mean(times):.1f}ms")
print(f"P95延迟: {np.percentile(times, 95):.1f}ms")
print(f"FPS: {1000/np.mean(times):.1f}")

4. 与Euro NCAP 2026的对接

Euro NCAP 2026要求 BiFuseNet对应 满足度
酒驾损伤检测 88.41%准确率,3级分类 ⚠️ 接近但不满足法规级
疲劳检测 95%准确率 ✅ 超出要求
情绪/攻击性检测 3级愤怒分类 ✅ 附加功能
夜间IR检测 BiFuseNet RGB+IR融合 ✅

IMS落地路线图

Phase 1: 数据采集(3个月)

  • 采集白天/夜间 RGB+IR 面部视频
  • 标注3级酒精/疲劳/情绪状态
  • 数据增强:不同光照、遮挡、角度

Phase 2: 模型训练(2个月)

  • 基于3D CNN训练BiFuseNet
  • INT8量化优化
  • 在QCS8255 NPU上部署

Phase 3: 验证测试(2个月)

  • 封闭场地测试(模拟酒驾场景)
  • 实际道路测试(夜间场景)
  • 与现有PERCLOS疲劳检测对比

总结

BiFuseNet是酒精损伤被动检测领域的重要突破:

  • 首次用单一3D模型同时检测酒精/疲劳/情绪三种状态
  • 88.41%酒精检测准确率是被动视觉方案的最高水平
  • RGB+IR双模态融合解决了夜间检测难题
  • 仍需提升至99%+才能满足NHTSA法规要求
  • 但已满足Euro NCAP 2026对DMS增强功能的要求