Aptiv 摄像头唯一乘员检测系统 - 首个纯视觉气囊抑制方案

Aptiv 摄像头唯一乘员检测系统 - 首个纯视觉气囊抑制方案

核心问题

传统乘员检测局限:

方法 问题
压力传感器 无法检测 OOP(Out-of-Position)
超声波传感器 分辨率低,易受干扰
雷达传感器 成本高,集成复杂
多传感器融合 成本高,标定复杂

Aptiv 突破: 首个仅用摄像头的乘员检测系统,通过功能安全认证,可直接控制气囊抑制。


技术亮点

核心能力

  1. 乘员分类

    • 成人/儿童/儿童座椅/物体
    • 准确率 > 99%
  2. OOP 检测

    • 前倾/侧倾/后仰
    • 延迟 < 100ms
  3. 安全带状态

    • 正确佩戴/误用/未扣
    • 支持 Euro NCAP 2026 要求
  4. 多座位覆盖

    • 单摄像头覆盖全车
    • 支持 5 座/7 座车型

系统架构

flowchart TD
    A[OMS 摄像头] --> B[图像预处理]
    B --> C[人体检测]
    
    C --> D1[关键点提取]
    C --> D2[分割掩码]
    C --> D3[深度估计]
    
    D1 --> E[姿态分析]
    D2 --> F[体型估计]
    D3 --> G[位置估计]
    
    E --> H[决策融合]
    F --> H
    G --> H
    
    H --> I{乘员分类}
    I -->|成人| J1[正常气囊模式]
    I -->|儿童| J2[抑制气囊]
    I -->|儿童座椅| J3[抑制气囊]
    I -->|空座| J4[抑制气囊]
    I -->|OOP| J5[低功率气囊]

核心算法

人体检测与关键点

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
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
"""
Aptiv 摄像头唯一乘员检测系统

基于人体关键点和分割的多任务网络
"""

import numpy as np
import torch
import torch.nn as nn
from typing import List, Dict, Tuple, Optional

@dataclass
class OccupantDetection:
"""乘员检测结果"""
seat_position: str # 'driver', 'passenger', 'rear_left', ...
occupant_type: str # 'adult', 'child', 'child_seat', 'object', 'empty'
pose_status: str # 'normal', 'forward_lean', 'side_lean', 'backward_lean'
seatbelt_status: str # 'correct', 'misuse', 'unbuckled'
bounding_box: Tuple[int, int, int, int] # x, y, w, h
keypoints: np.ndarray # 17 关键点 (x, y, conf)
confidence: float

class AptivOccupantDetector(nn.Module):
"""
Aptiv 乘员检测网络

单一网络同时输出:
- 目标检测
- 关键点估计
- 语义分割
- 深度估计
"""

def __init__(self, num_keypoints: int = 17):
super().__init__()

# 共享骨干网络(EfficientNet-B4)
self.backbone = self._build_backbone()

# 检测头(目标检测)
self.detection_head = nn.Sequential(
nn.Conv2d(448, 256, 3, 1, 1),
nn.BatchNorm2d(256),
nn.ReLU(),
nn.Conv2d(256, 6, 1) # (x, y, w, h, conf, class)
)

# 关键点头
self.keypoint_head = nn.Sequential(
nn.Conv2d(448, 256, 3, 1, 1),
nn.BatchNorm2d(256),
nn.ReLU(),
nn.Conv2d(256, num_keypoints * 3, 1) # (x, y, conf) * 17
)

# 分割头
self.segmentation_head = nn.Sequential(
nn.Conv2d(448, 256, 3, 1, 1),
nn.BatchNorm2d(256),
nn.ReLU(),
nn.Conv2d(256, 5, 1) # background, person, child_seat, seat, belt
)

# 深度头
self.depth_head = nn.Sequential(
nn.Conv2d(448, 128, 3, 1, 1),
nn.BatchNorm2d(128),
nn.ReLU(),
nn.Conv2d(128, 1, 1)
)

def _build_backbone(self) -> nn.Module:
"""
构建骨干网络

使用 EfficientNet-B4
"""
# 简化实现
return nn.Sequential(
nn.Conv2d(3, 64, 7, 2, 3),
nn.BatchNorm2d(64),
nn.ReLU(),
nn.MaxPool2d(2),
nn.Conv2d(64, 128, 3, 2, 1),
nn.BatchNorm2d(128),
nn.ReLU(),
nn.Conv2d(128, 256, 3, 2, 1),
nn.BatchNorm2d(256),
nn.ReLU(),
nn.Conv2d(256, 448, 3, 2, 1),
nn.BatchNorm2d(448),
nn.ReLU()
)

def forward(self, x: torch.Tensor) -> Dict[str, torch.Tensor]:
"""
前向传播

Args:
x: 输入图像 (B, 3, H, W)

Returns:
多任务输出字典
"""
# 骨干网络
features = self.backbone(x)

# 多任务输出
outputs = {
'detection': self.detection_head(features),
'keypoints': self.keypoint_head(features),
'segmentation': self.segmentation_head(features),
'depth': self.depth_head(features)
}

return outputs


class OccupantDecisionEngine:
"""
乘员决策引擎

融合多任务输出,生成最终决策
"""

def __init__(self):
# 儿童判断阈值
self.child_height_threshold = 1.4 # 米
self.child_age_threshold = 12 # 岁

# OOP 判断阈值
self.lean_angle_threshold = 20 # 度

def analyze(
self,
detection_output: torch.Tensor,
keypoint_output: torch.Tensor,
segmentation_output: torch.Tensor,
depth_output: torch.Tensor,
camera_intrinsic: np.ndarray
) -> List[OccupantDetection]:
"""
分析乘员状态

Args:
detection_output: 检测输出
keypoint_output: 关键点输出
segmentation_output: 分割输出
depth_output: 深度输出
camera_intrinsic: 相机内参

Returns:
乘员检测结果列表
"""
results = []

# 1. 解析检测结果
detections = self._parse_detections(detection_output)

for det in detections:
# 2. 提取关键点
keypoints = self._extract_keypoints(
keypoint_output, det['bbox']
)

# 3. 分析姿态
pose_status = self._analyze_pose(keypoints)

# 4. 估计体型(儿童/成人)
occupant_type = self._classify_occupant(
keypoints, depth_output, camera_intrinsic
)

# 5. 检测安全带
seatbelt_status = self._detect_seatbelt(
segmentation_output, det['bbox']
)

# 6. 确定座位位置
seat_position = self._get_seat_position(det['bbox'])

results.append(OccupantDetection(
seat_position=seat_position,
occupant_type=occupant_type,
pose_status=pose_status,
seatbelt_status=seatbelt_status,
bounding_box=det['bbox'],
keypoints=keypoints,
confidence=det['confidence']
))

return results

def _parse_detections(
self,
detection_output: torch.Tensor
) -> List[Dict]:
"""
解析检测结果
"""
detections = []
# 简化实现
# 实际使用 NMS 后处理
return detections

def _extract_keypoints(
self,
keypoint_output: torch.Tensor,
bbox: Tuple[int, int, int, int]
) -> np.ndarray:
"""
提取关键点
"""
# 简化实现
return np.zeros((17, 3))

def _analyze_pose(self, keypoints: np.ndarray) -> str:
"""
分析姿态(OOP 检测)
"""
# 计算躯干角度
# 使用肩部中点到臀部中点的连线
if keypoints.shape[0] < 17:
return 'normal'

# 关键点索引(COCO 格式)
left_shoulder = keypoints[5]
right_shoulder = keypoints[6]
left_hip = keypoints[11]
right_hip = keypoints[12]

# 躯干向量
shoulder_mid = (left_shoulder[:2] + right_shoulder[:2]) / 2
hip_mid = (left_hip[:2] + right_hip[:2]) / 2

trunk_vector = shoulder_mid - hip_mid

# 计算角度(相对于垂直方向)
angle = np.arctan2(trunk_vector[0], -trunk_vector[1]) * 180 / np.pi

if abs(angle) > self.lean_angle_threshold:
if angle > 0:
return 'right_lean'
else:
return 'left_lean'

# 检测前倾(头部相对躯干位置)
nose = keypoints[0]
head_forward = nose[1] - shoulder_mid[1]
if head_forward > 50: # 像素阈值
return 'forward_lean'

return 'normal'

def _classify_occupant(
self,
keypoints: np.ndarray,
depth_output: torch.Tensor,
camera_intrinsic: np.ndarray
) -> str:
"""
分类乘员类型
"""
# 基于关键点估计身高
if keypoints.shape[0] < 17:
return 'unknown'

# 关键点索引
nose = keypoints[0]
left_ankle = keypoints[15]
right_ankle = keypoints[16]

# 估计高度(像素)
ankle_y = max(left_ankle[1], right_ankle[1])
height_pixels = ankle_y - nose[1]

# 转换为实际高度(需要深度信息)
# 简化:假设坐高约为身高的 0.52
estimated_height = height_pixels * 0.01 # 简化换算

# 分类
if estimated_height < self.child_height_threshold:
return 'child'
else:
return 'adult'

def _detect_seatbelt(
self,
segmentation_output: torch.Tensor,
bbox: Tuple[int, int, int, int]
) -> str:
"""
检测安全带状态
"""
# 分析分割结果
# 检查是否有安全带类别
# 简化实现
return 'correct'

def _get_seat_position(self, bbox: Tuple[int, int, int, int]) -> str:
"""
确定座位位置
"""
x, y, w, h = bbox
center_x = x + w / 2

# 基于位置判断座位
# 简化实现
if center_x < 960:
return 'driver'
else:
return 'passenger'


# 气囊控制决策
class AirbagDecisionUnit:
"""
气囊控制决策单元

根据乘员状态决定气囊模式
"""

def __init__(self):
# 安全等级配置
self.airbag_modes = {
'adult_normal': 'full',
'adult_oop': 'low_power',
'child': 'suppressed',
'child_seat': 'suppressed',
'empty': 'suppressed',
'object': 'suppressed'
}

def get_airbag_mode(
self,
detection: OccupantDetection
) -> str:
"""
获取气囊模式

Args:
detection: 乘员检测结果

Returns:
气囊模式: 'full', 'low_power', 'suppressed'
"""
# 构建状态键
if detection.occupant_type in ['child', 'child_seat']:
key = detection.occupant_type
elif detection.occupant_type == 'empty':
key = 'empty'
elif detection.occupant_type == 'object':
key = 'object'
elif detection.pose_status != 'normal':
key = 'adult_oop'
else:
key = 'adult_normal'

return self.airbag_modes.get(key, 'suppressed')


# 部署示例
if __name__ == "__main__":
# 创建模型
model = AptivOccupantDetector()
model.eval()

# 创建决策引擎
decision_engine = OccupantDecisionEngine()
airbag_unit = AirbagDecisionUnit()

# 模拟输入
dummy_input = torch.randn(1, 3, 720, 1280)

# 推理
with torch.no_grad():
outputs = model(dummy_input)

# 分析
# detections = decision_engine.analyze(
# outputs['detection'],
# outputs['keypoints'],
# outputs['segmentation'],
# outputs['depth'],
# np.array([[1000, 0, 640], [0, 1000, 360], [0, 0, 1]])
# )

# 获取气囊模式
# for det in detections:
# mode = airbag_unit.get_airbag_mode(det)
# print(f"座位: {det.seat_position}, 类型: {det.occupant_type}, 气囊模式: {mode}")

print("Aptiv 摄像头唯一乘员检测系统模型已就绪")

功能安全

ASIL-B 认证

安全目标:

  • 儿童座位气囊必须抑制
  • 误抑制率 < 0.01%
  • 误启用率 < 0.1%

安全机制:

  1. 双通道校验(两个独立网络)
  2. 时序一致性检查
  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
# 功能安全校验
class SafetyChecker:
"""
功能安全校验器
"""

def __init__(self):
self.history_length = 5
self.decision_history = deque(maxlen=self.history_length)

def validate(self, current_decision: str) -> bool:
"""
验证决策一致性

防止瞬态错误
"""
self.decision_history.append(current_decision)

# 需要连续 N 帧一致才输出
if len(self.decision_history) < self.history_length:
return False

# 检查一致性
if len(set(self.decision_history)) == 1:
return True

# 如果不一致,选择最安全选项
return False

性能对比

与传统方案对比

指标 压力传感器 Aptiv 摄像头
儿童检测准确率 85% 99%
OOP 检测
安全带检测
成本 $50 $30
功能安全 ASIL-A ASIL-B
部署复杂度

Euro NCAP 合规

检测场景覆盖

场景 检测能力
成人正常坐姿
成人前倾 ✅ OOP 检测
儿童(无座椅) ✅ 分类
儿童座椅(后向) ✅ 检测
儿童座椅(前向) ✅ 检测
空座 ✅ 检测
物品 ✅ 分类

IMS 开发启示

集成要点

  1. 摄像头选型

    • 广角镜头(FOV > 120°)
    • HDR 支持(应对逆光)
    • 红外补光(夜间)
  2. 标定要求

    • 相机外参标定
    • 座椅位置标定
    • 地面平面标定
  3. 测试验证

    • 不同体型志愿者
    • 不同光照条件
    • 不同儿童座椅类型

总结: Aptiv 摄像头唯一乘员检测系统突破了传统多传感器融合的局限,通过单一摄像头实现乘员分类、OOP 检测、安全带状态检测,并通过 ASIL-B 功能安全认证。IMS 开发应重点关注多任务网络设计和功能安全机制。


Aptiv 摄像头唯一乘员检测系统 - 首个纯视觉气囊抑制方案
https://dapalm.com/2026/06/12/2026-06-12-Aptiv-Camera-Only-Occupant-Detection/
作者
Mars
发布于
2026年6月12日
许可协议