Euro NCAP 2026 儿童存在检测(CPD)技术路线与传感器融合方案

Euro NCAP 2026 儿童存在检测(CPD)技术路线与传感器融合方案

Euro NCAP CPD 检测要求概述

Euro NCAP 2025 路线图首次将儿童存在检测(Child Presence Detection, CPD)作为强制评估项目,2026 年继续加强要求:

检测对象与场景

年龄组 呼吸频率要求 检测场景
新生儿 30 bpm 睡眠/清醒,有无肢体动作
1 岁 25 bpm 同上
3 岁 22 bpm 同上
6 岁 18 bpm 同上

检测条件

1
2
3
4
5
6
7
8
9
儿童位置要求:
✅ 所有可能的车内位置
✅ 儿童安全座椅(CRS)
✅ 可移动座椅
✅ 所有排座椅
✅ 脚部空间

排除区域:
❌ 行李箱(从后备箱/后门无法到达的区域)

检测精度要求

条件 要求
覆盖物穿透 必须穿透毯子检测呼吸运动
多乘员区分 区分成人和儿童
占员计数 检测成人(系安全带/未系)和儿童数量
直接传感 2025 年起仅奖励直接传感系统

技术路线对比

传感器选项

传感器类型 检测原理 优势 劣势
60GHz 雷达 呼吸微动检测 穿透力强、隐私友好 成本较高
红外摄像头 热成像 直观、可分类 隐私问题、受温度影响
RGB 摄像头 视觉识别 成本低、可分类 隐私问题、光照敏感
UWB 雷达 超宽带脉冲 高精度、低功耗 成本高
压力传感器 座椅压力分布 成本低、可靠 无法区分静默儿童

Euro NCAP 推荐方案

直接传感 + 多模态融合

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
方案 A:雷达主导
┌─────────────────────────────────────┐
60GHz 雷达 (主传感器) │
│ ├─ 呼吸频率检测 │
│ ├─ 微动模式识别 │
│ └─ 活体确认 │
└─────────────────────────────────────┘

方案 B:雷达 + 摄像头融合
┌─────────────────────────────────────┐
60GHz 雷达 (呼吸检测) │
│ + │
│ 红外摄像头 (儿童定位/分类) │
│ ↓ │
│ 多模态融合 → 最终判断 │
└─────────────────────────────────────┘

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
import numpy as np
from dataclasses import dataclass

@dataclass
class RadarConfig:
"""60GHz CPD 雷达配置"""
# 射频参数
center_frequency: float = 60e9 # 中心频率 60GHz
bandwidth: float = 4e9 # 带宽 4GHz
num_tx_antennas: int = 3 # 发射天线数
num_rx_antennas: int = 4 # 接收天线数

# 啁啾参数
chirp_duration: float = 100e-6 # 啁啾持续时间 100μs
num_chirps_per_frame: int = 128 # 每帧啁啾数
frame_period: float = 100e-3 # 帧周期 100ms

# 分辨率
range_resolution: float = None # 距离分辨率(计算)
velocity_resolution: float = None # 速度分辨率(计算)

def __post_init__(self):
# 计算分辨率
self.range_resolution = 3e8 / (2 * self.bandwidth) # ~3.75cm
self.velocity_resolution = 3e8 / (2 * self.center_frequency *
self.num_chirps_per_frame *
self.chirp_duration)


class CPDRadarProcessor:
"""
CPD 雷达信号处理器

基于 60GHz 毫米波雷达检测儿童呼吸运动
"""

def __init__(self, config: RadarConfig):
self.config = config

# 呼吸频率范围 (儿童)
self.breathing_freq_range = (0.3, 0.5) # 18-30 bpm → 0.3-0.5 Hz

# 微动检测阈值
self.motion_threshold = 1e-4 # 微动幅度阈值 (m)

# 历史数据缓存
self.range_fft_history = []
self.doppler_history = []

def process_frame(self, adc_data: np.ndarray) -> dict:
"""
处理单帧雷达数据

Args:
adc_data: ADC 数据, shape=(num_rx, num_chirps, num_samples)

Returns:
detection: CPD 检测结果
"""
# 1. 距离 FFT
range_fft = self._range_fft(adc_data)

# 2. 多普勒 FFT
doppler_fft = self._doppler_fft(range_fft)

# 3. 检测静态目标(可能的儿童)
static_targets = self._detect_static_targets(doppler_fft)

# 4. 分析呼吸微动
breathing_detected = []
for target in static_targets:
breathing = self._analyze_breathing(target['range_bin'])
if breathing['detected']:
breathing_detected.append({
'range': target['range'],
'breathing_rate': breathing['rate'],
'confidence': breathing['confidence']
})

return {
'child_detected': len(breathing_detected) > 0,
'children': breathing_detected,
'timestamp': self._get_timestamp()
}

def _range_fft(self, adc_data: np.ndarray) -> np.ndarray:
"""距离 FFT"""
num_samples = adc_data.shape[-1]
range_fft = np.fft.fft(adc_data, axis=-1)
return range_fft[:, :, :num_samples//2] # 取正频率部分

def _doppler_fft(self, range_fft: np.ndarray) -> np.ndarray:
"""多普勒 FFT"""
doppler_fft = np.fft.fftshift(
np.fft.fft(range_fft, axis=1),
axes=1
)
return doppler_fft

def _detect_static_targets(self, doppler_fft: np.ndarray) -> list:
"""检测静态目标(多普勒速度接近零)"""
static_targets = []

# 多普勒零频附近的 bin
zero_doppler_bin = doppler_fft.shape[1] // 2
doppler_margin = 2 # ±2 bins

# 提取静态目标
static_profile = np.mean(
np.abs(doppler_fft[:,
zero_doppler_bin-doppler_margin:zero_doppler_bin+doppler_margin+1,
:]),
axis=1
)

# 峰值检测
mean_power = np.mean(static_profile)
std_power = np.std(static_profile)
threshold = mean_power + 3 * std_power

peaks = np.where(np.max(static_profile, axis=0) > threshold)[0]

for peak_bin in peaks:
range_m = peak_bin * self.config.range_resolution
static_targets.append({
'range_bin': peak_bin,
'range': range_m,
'power': np.max(static_profile[:, peak_bin])
})

return static_targets

def _analyze_breathing(self, range_bin: int) -> dict:
"""
分析呼吸微动

通过 FFT 分析相位变化频率来检测呼吸
"""
# 需要累积多帧数据进行呼吸频率分析
# 简化实现:假设已有历史相位数据

# 呼吸频率范围
min_freq, max_freq = self.breathing_freq_range

# 对相位序列做 FFT
# phase_history: 历史相位数据

# 返回检测结果
return {
'detected': True, # 简化
'rate': 25, # bpm
'confidence': 0.85
}

def _get_timestamp(self) -> float:
import time
return time.time()

雷达 + 摄像头融合方案

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
from typing import List, Tuple, Optional
from dataclasses import dataclass
import numpy as np

@dataclass
class Detection:
"""检测结果"""
position: Tuple[float, float, float] # (x, y, z) 相对车辆坐标系
bounding_box: Optional[Tuple[int, int, int, int]] = None # (x, y, w, h)
confidence: float = 0.0
class_label: str = "unknown"
breathing_rate: Optional[float] = None # bpm


class SensorFusionCPD:
"""
多传感器融合 CPD 系统

融合雷达和摄像头数据检测儿童
"""

def __init__(self):
# 雷达处理器
self.radar_processor = CPDRadarProcessor(RadarConfig())

# 摄像头参数(假设已标定)
self.camera_intrinsics = np.array([
[800, 0, 640],
[0, 800, 360],
[0, 0, 1]
])

# 雷达到摄像头的变换矩阵
self.radar_to_camera = np.eye(4)

# 检测阈值
self.breathing_rate_child_max = 30 # bpm
self.breathing_rate_child_min = 18 # bpm
self.height_child_max = 1.2 # m

def detect(self,
radar_data: np.ndarray,
camera_frame: np.ndarray) -> List[Detection]:
"""
融合检测

Args:
radar_data: 雷达 ADC 数据
camera_frame: 摄像头图像帧

Returns:
detections: 检测到的儿童列表
"""
# 1. 雷达处理
radar_result = self.radar_processor.process_frame(radar_data)

if not radar_result['child_detected']:
return []

# 2. 摄像头处理(假设使用预训练模型)
camera_detections = self._process_camera(camera_frame)

# 3. 数据关联
fused_detections = self._associate_and_fuse(
radar_result['children'],
camera_detections
)

return fused_detections

def _process_camera(self, frame: np.ndarray) -> List[Detection]:
"""
摄像头处理

使用深度学习模型检测儿童
"""
# 这里应该调用实际的检测模型
# 简化实现:返回空列表
return []

def _associate_and_fuse(self,
radar_targets: List[dict],
camera_detections: List[Detection]) -> List[Detection]:
"""
数据关联与融合
"""
fused = []

for radar_target in radar_targets:
# 雷达目标位置
radar_pos = np.array([
radar_target['range'], # 假设距离在车辆前方
0, # 假设横向位置
0 # 假设高度
])

# 转换到摄像头坐标系
camera_pos = self._transform_radar_to_camera(radar_pos)

# 投影到图像平面
image_point = self._project_to_image(camera_pos)

# 查找关联的摄像头检测
associated_camera = self._find_associated_detection(
image_point,
camera_detections
)

# 构建融合检测结果
detection = Detection(
position=tuple(radar_pos),
confidence=radar_target['confidence'],
class_label="child" if self._is_child(radar_target) else "adult",
breathing_rate=radar_target.get('breathing_rate')
)

if associated_camera:
detection.bounding_box = associated_camera.bounding_box
detection.confidence = (detection.confidence +
associated_camera.confidence) / 2

if detection.class_label == "child":
fused.append(detection)

return fused

def _transform_radar_to_camera(self, radar_pos: np.ndarray) -> np.ndarray:
"""坐标变换"""
homogeneous = np.append(radar_pos, 1)
camera_pos = self.radar_to_camera @ homogeneous
return camera_pos[:3]

def _project_to_image(self, point_3d: np.ndarray) -> Tuple[int, int]:
"""3D 点投影到图像平面"""
point_2d = self.camera_intrinsics @ point_3d
point_2d = point_2d[:2] / point_2d[2]
return int(point_2d[0]), int(point_2d[1])

def _find_associated_detection(self,
image_point: Tuple[int, int],
detections: List[Detection]) -> Optional[Detection]:
"""查找关联的摄像头检测"""
if not detections:
return None

min_distance = float('inf')
associated = None

for det in detections:
if det.bounding_box:
# 计算边界框中心
cx = det.bounding_box[0] + det.bounding_box[2] // 2
cy = det.bounding_box[1] + det.bounding_box[3] // 2

# 计算距离
distance = np.sqrt((cx - image_point[0])**2 +
(cy - image_point[1])**2)

if distance < min_distance and distance < 100: # 100 pixel threshold
min_distance = distance
associated = det

return associated

def _is_child(self, radar_target: dict) -> bool:
"""判断是否为儿童"""
breathing_rate = radar_target.get('breathing_rate')

if breathing_rate is None:
return False

return self.breathing_rate_child_min <= breathing_rate <= self.breathing_rate_child_max

Magna CPD 技术方案解析

Magna 于 2025 年发布的 CPD 方案采用雷达 + 摄像头融合:

技术特点

1
2
3
4
5
6
7
8
9
10
传感器配置:
├─ 60GHz 毫米波雷达
│ ├─ 4 4 收天线阵列
│ ├─ 呼吸微动检测
│ └─ 穿透毯子/衣物

└─ 车内摄像头
├─ RGB-IR 双模式
├─ 儿童定位与分类
└─ 隐私保护模式

检测流程

graph TD
    A[雷达扫描] --> B{检测到静态目标?}
    B -->|否| A
    B -->|是| C[分析呼吸频率]
    C --> D{呼吸频率 18-30bpm?}
    D -->|否| E[标记为成人/非活体]
    D -->|是| F[触发摄像头确认]
    F --> G{摄像头检测到儿童?}
    G -->|是| H[触发 CPD 警报]
    G -->|否| I[低置信度标记]

IMS 开发启示

1. 硬件选型建议

组件 推荐型号 参数 成本估计
60GHz 雷达 TI IWR6843AOP 4Tx4Rx, 60-64GHz $30-50
车内摄像头 OV2311 RGB-IR 2MP, 全局快门 $15-25
处理器 TI TDA4VM 8 TOPS, 视觉加速 $50-80

2. 算法开发优先级

优先级 模块 技术要点
P0 雷达呼吸检测 微动信号处理、FFT 频谱分析
P1 静态目标检测 多普勒零频提取、CFAR 检测
P2 多传感器标定 雷达-摄像头外参标定
P3 儿童分类 呼吸频率 + 体型特征融合

3. Euro NCAP 合规测试场景

场景 测试内容 通过条件
CPD-01 新生儿在 CRS ≤90 秒检测并警告
CPD-02 3 岁儿童被毯子覆盖 ≤90 秒检测并警告
CPD-03 多儿童场景 正确计数和定位
CPD-04 成人 + 儿童混合 区分成人和儿童

4. 隐私保护设计

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
class PrivacyAwareCPD:
"""
隐私保护的 CPD 系统

设计原则:
1. 仅在检测到潜在儿童时启用摄像头
2. 数据本地处理,不上传云端
3. 提供数据删除选项
"""

def __init__(self):
self.radar_only_mode = True
self.camera_enabled = False
self.data_retention_days = 7

def detect(self, radar_data, camera_frame=None):
# 1. 雷达优先检测
radar_result = self._radar_detect(radar_data)

# 2. 仅在需要时启用摄像头
if radar_result['potential_child'] and not self.radar_only_mode:
self.camera_enabled = True
camera_result = self._camera_detect(camera_frame)
else:
self.camera_enabled = False
camera_result = None

# 3. 融合决策
return self._fuse_results(radar_result, camera_result)

def _radar_detect(self, radar_data):
# 简化实现
return {'potential_child': True, 'breathing_rate': 25}

def _camera_detect(self, frame):
# 简化实现
return {'detected': True, 'class': 'child'}

def _fuse_results(self, radar_result, camera_result):
# 简化实现
return {'child_detected': True}

总结

Euro NCAP 2026 CPD 要求推动车内儿童检测技术快速发展:

  1. 技术路线:60GHz 雷达 + 摄像头融合是主流方案
  2. 核心能力:呼吸微动检测 + 儿童分类
  3. 开发重点:雷达信号处理、多传感器融合、隐私保护

IMS 开发应优先实现雷达呼吸检测,再逐步集成摄像头分类能力。


参考来源:


Euro NCAP 2026 儿童存在检测(CPD)技术路线与传感器融合方案
https://dapalm.com/2026/06/13/2026-06-13-Euro-NCAP-2026-CPD-Radar-Camera-Fusion/
作者
Mars
发布于
2026年6月13日
许可协议