InCabin Europe 2026全景:相机×雷达×织物传感器的座舱感知融合

1. 会议概述

InCabin Europe 2026(与AutoSens Europe同期,巴塞罗那)展示了座舱感知技术的最新进展。核心趋势是从单一传感器向多模态融合演进,每个传感器负责不同感知维度,通过融合算法形成完整座舱理解。

2. 关键技术展示

2.1 Deep-In-Sight:摄像头+60GHz雷达融合CPD

模式 工作条件 传感器 检测目标
可见模式 乘员未被遮挡 摄像头 乘员身份、位置、座椅映射
隐蔽模式 乘员被毯子/前排遮挡 60GHz雷达 呼吸微动检测
融合模式 部分遮挡 摄像头+雷达 综合:可见部分用视觉,不可见部分用雷达

关键突破: 当摄像头看不到毯子下的儿童时,雷达通过呼吸微动检测其存在。这是目前CPD最实用的融合方案。

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
"""
Deep-In-Sight风格的摄像头-雷达融合CPD框架

硬件:
- OMS摄像头 (RGB-IR, 5MP, 全局快门)
- Murata 60GHz mmWave radar (4Tx/4Rx)
- 边缘处理器 (QCS8255 Hexagon NPU)

依赖: numpy>=1.24, opencv-python>=4.8
"""

import numpy as np
import cv2
from typing import Dict, Tuple, Optional


class CameraRadarFusionCPD:
"""
摄像头-雷达融合儿童存在检测

融合策略:
1. 摄像头检测可见乘员(人脸/人体检测+分类)
2. 雷达检测微动(呼吸/心跳)
3. 决策融合: OR逻辑 + 置信度加权
"""

def __init__(self, config: dict):
self.camera_confidence_threshold = config.get('cam_thresh', 0.7)
self.radar_confidence_threshold = config.get('radar_thresh', 0.6)
self.radar_breathing_threshold = config.get('breath_thresh', 0.3)

def camera_detect(self, image: np.ndarray) -> Dict:
"""
摄像头检测模块

Returns:
{
'occupant_detected': bool,
'classification': 'adult'|'child'|'empty'|'unknown',
'confidence': float,
'bbox': (x, y, w, h)
}
"""
# 实际使用YOLO/SSD等目标检测模型
# 这里用简化逻辑演示
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) if len(image.shape) == 3 else image

# 模拟检测结果
# 实际: model = load_model('occupant_detection.onnx')
# results = model(image)

# 简化: 基于图像亮度区域检测
_, binary = cv2.threshold(gray, 50, 255, cv2.THRESH_BINARY)
contours, _ = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

if not contours:
return {
'occupant_detected': False,
'classification': 'empty',
'confidence': 0.9,
'bbox': None
}

# 最大轮廓
c = max(contours, key=cv2.contourArea)
if cv2.contourArea(c) < 500:
return {
'occupant_detected': False,
'classification': 'empty',
'confidence': 0.85,
'bbox': None
}

x, y, w, h = cv2.boundingRect(c)
area_ratio = (w * h) / (image.shape[0] * image.shape[1])

# 基于大小粗略分类
if area_ratio > 0.15:
cls = 'adult'
elif area_ratio > 0.05:
cls = 'child'
else:
cls = 'unknown'

return {
'occupant_detected': True,
'classification': cls,
'confidence': min(0.95, 0.5 + area_ratio * 3),
'bbox': (x, y, w, h)
}

def radar_detect(self, radar_cube: np.ndarray) -> Dict:
"""
60GHz雷达检测模块

Args:
radar_cube: range-Doppler数据 (N_range x N_doppler)

Returns:
{
'presence_detected': bool,
'breathing_detected': bool,
'breathing_rate': float, # breaths/min
'confidence': float
}
"""
# 1. 距离-多普勒图分析
# 呼吸频率范围: 0.2-0.5 Hz (12-30 breaths/min)
# 心跳频率范围: 1.0-2.0 Hz (60-120 bpm)

# 2. 提取微动信号
# 在低多普勒频率区域寻找能量峰值
low_doppler = radar_cube[:, :5] # 前5个多普勒bin(低频)
energy = np.sum(np.abs(low_doppler), axis=1)

# 3. 检测存在(总能量超过阈值)
total_energy = np.sum(energy)
presence = total_energy > self.radar_breathing_threshold * 1e6

# 4. 呼吸率估计(FFT分析)
if presence:
# 提取时间序列(跨多帧的range bin能量)
# 简化: 用radar_cube的慢时间FFT
slow_time_signal = np.sum(radar_cube, axis=0)
fft = np.fft.rfft(slow_time_signal)
freqs = np.fft.rfftfreq(len(slow_time_signal), d=0.05) # 20fps

# 在呼吸频率范围寻找峰值
breath_mask = (freqs >= 0.2) & (freqs <= 0.5)
if np.any(breath_mask):
peak_idx = np.argmax(np.abs(fft[breath_mask]))
breath_freq = freqs[breath_mask][peak_idx]
breathing_rate = breath_freq * 60 # 转换为 breaths/min
breathing = True
else:
breathing_rate = 0
breathing = False
else:
breathing = False
breathing_rate = 0

confidence = min(1.0, total_energy / 1e7)

return {
'presence_detected': presence,
'breathing_detected': breathing,
'breathing_rate': breathing_rate,
'confidence': confidence
}

def fuse(
self,
camera_result: Dict,
radar_result: Dict
) -> Dict:
"""
决策融合

策略:
- 摄像头可见 → 用摄像头分类
- 摄像头不可见,雷达有微动 → 判定有乘员(可能被遮挡)
- 两者都不可见 → 判定空座
- 两者都可见 → 加权融合
"""
cam_det = camera_result['occupant_detected']
rad_det = radar_result['presence_detected']

if cam_det and rad_det:
# 两者都检测到:以摄像头分类为主
return {
'occupant_present': True,
'classification': camera_result['classification'],
'source': 'camera+radar',
'confidence': 0.95,
'breathing': radar_result['breathing_detected'],
'breathing_rate': radar_result.get('breathing_rate', 0)
}
elif not cam_det and rad_det:
# 摄像头看不到,雷达检测到微动 → 被遮挡的乘员
return {
'occupant_present': True,
'classification': 'occluded_occupant',
'source': 'radar_only',
'confidence': radar_result['confidence'],
'breathing': radar_result['breathing_detected'],
'breathing_rate': radar_result.get('breathing_rate', 0)
}
elif cam_det and not rad_det:
# 摄像头看到,雷达没微动 → 可能是物体/影像
return {
'occupant_present': True,
'classification': camera_result['classification'],
'source': 'camera_only',
'confidence': camera_result['confidence'] * 0.8, # 降低置信度
'breathing': False,
'breathing_rate': 0
}
else:
# 两者都没检测到 → 空座
return {
'occupant_present': False,
'classification': 'empty',
'source': 'both_negative',
'confidence': 0.9,
'breathing': False,
'breathing_rate': 0
}


# 测试
if __name__ == "__main__":
fusion = CameraRadarFusionCPD({
'cam_thresh': 0.7,
'radar_thresh': 0.6,
'breath_thresh': 0.3
})

# 模拟场景1: 可见儿童
img1 = np.random.randint(40, 60, (1080, 1920, 3), dtype=np.uint8)
img1[400:700, 800:1000] = 120 # 模拟乘员
radar1 = np.random.randn(64, 32) * 0.01 + 0.5 # 有微动信号

cam1 = fusion.camera_detect(img1)
rad1 = fusion.radar_detect(radar1)
result1 = fusion.fuse(cam1, rad1)
print(f"场景1 (可见乘员): {result1['classification']}, 置信度={result1['confidence']:.2f}")

# 模拟场景2: 被毯子遮挡的儿童(摄像头看不到,雷达检测到呼吸)
img2 = np.random.randint(40, 45, (1080, 1920, 3), dtype=np.uint8) # 几乎均匀
radar2 = np.random.randn(64, 32) * 0.01 + 2.0 # 强微动信号

cam2 = fusion.camera_detect(img2)
rad2 = fusion.radar_detect(radar2)
result2 = fusion.fuse(cam2, rad2)
print(f"场景2 (遮挡乘员): {result2['classification']}, 来源={result2['source']}")
print(f" 呼吸检测: {result2['breathing']}, 呼吸率: {result2.get('breathing_rate', 0):.1f} bpm")

2.2 Brighter Signals:织物压力传感器

Brighter Signals展示了安装在座椅泡沫和面套之间的薄型织物传感器,可绘制座垫上的重量分布图。

能力 指标 对IMS的价值
乘员分类 小型成人 vs 大型儿童 自适应安全气囊部署
头部接近检测 前倾/低头姿态 OOP异常姿态预警
成本 现有方案成本的~50% 大规模部署经济性
量产状态 约10个OEM/Tier1试点 接近量产

2.3 Aptiv AOC:纯摄像头占位分类

Aptiv的Advanced Occupancy Classification (AOC)系统是行业首个纯摄像头占位分类方案,无需座椅压力传感器。

对比维度 传统方案(多传感器) Aptiv AOC(纯摄像头)
传感器数量 4-6个(压力+重量+安全带) 1个(已有OMS摄像头)
布线复杂度 高 低(复用摄像头)
零件成本 $30-50 $15-20(降40%)
分类精度 95-98% 90-95%(持续优化)

2.4 Smart Eye:凝视+AI助手融合

Smart Eye展示了将DMS凝视数据与语音助手融合的方案——驾驶员看向车外物体并问”那是什么?”,系统通过凝视方向理解上下文。

2.5 rFpro仿真:虚拟座舱验证

rFpro展示了座舱仿真环境,用于DMS算法虚拟测试:

  • “蜥蜴运动”测试:头部朝前但眼球偏转,检测系统是否捕获细微眼动
  • 金属框架反射建模:座椅金属架对雷达的反射建模
  • 面部IR反射建模:鼻梁与脸颊的对比度差异建模

3. 多传感器融合架构建议

4. 各方案对Euro NCAP覆盖矩阵

Euro NCAP要求 摄像头 60GHz雷达 UWB雷达 织物传感器 红外安全带
乘员分类 ✅ AOC ✅ 大小区分 ⚠️ 有限 ✅ 重量分布 ❌
CPD儿童检测 ⚠️ 遮挡失效 ✅ 呼吸检测 ✅ 微动 ⚠️ 仅座上 ❌
OOP姿态 ⚠️ 可见时有效 ⚠️ 距离测量 ❌ ✅ 压力分布 ❌
安全带误用 ⚠️ RGB受限 ❌ ❌ ❌ ✅ 路径追踪
后排覆盖 ⚠️ 需多摄像头 ✅ ✅ ✅ 每座一个 ✅

5. 对IMS开发的优先级建议

优先级 融合方案 实现路径 预期收益
P0 摄像头+红外安全带 复用OMS摄像头+ZF IR Belt 满足安全带误用检测要求
P0 摄像头+60GHz雷达 摄像头检测可见,雷达检测遮挡 满足CPD要求
P1 +织物压力传感器 座椅内嵌织物传感器 提升OOP+乘员分类
P2 +UWB雷达 车内UWB锚点 补充CPD+活体检测

6. 成本与工程权衡

方案组合 估算BOM 覆盖能力 量产时间
摄像头 only (Aptiv AOC) $15-20 分类+部分OOP 已量产
摄像头+IR安全带 $20-30 +安全带误用 2026 Q3
摄像头+60GHz雷达 $35-50 +CPD+遮挡检测 2027
摄像头+雷达+织物 $45-65 全功能覆盖 2027-2028
全方案(+UWB) $55-80 最佳覆盖 2028+

参考来源: