4D雷达感知算法综述:从稀疏目标检测到动态场景重建

论文信息

项目 内容
标题 4D Radar Perception Algorithms for Autonomous Driving: A Review
arXiv 2609.19216
提交时间 2026-09-16
页数 12页, 9图, 5表
投稿 IEEE Sensors Journal
搜索范围 Google Scholar, IEEE Xplore, arXiv, OpenAlex (截至2026-08-18)

核心内容

从稀疏目标感知到动态空间理解——4D雷达感知的任务演进综述。

综述覆盖范围

任务类别 子任务 论文数
信号处理 雷达表示、增强 大量
目标感知 检测、跟踪、分类 大量
运动与定位 SLAM、里程计 中等
空间感知 占用预测、语义分割 新兴
动态场景 场景流、重建 前沿

4D雷达 vs 3D雷达

特性 3D雷达 4D雷达
维度 距离、水平角、速度 距离、水平角、俯仰角、速度
高度信息 ❌ 无 ✅ 有
点云密度 稀疏 中等
恶劣天气 ✅ 鲁棒 ✅ 鲁棒
成本 中(¥3000-5000) 中高(¥5000-10000)
代表芯片 TI AWR1843 Continental ARS540, Oculii

4D雷达在座舱内的应用

座舱4D雷达能力

能力 外部4D雷达 座舱4D雷达
乘员检测 N/A ✅ 多人定位
CPD N/A ✅ 穿透毯子
生命体征 N/A ✅ 呼吸/心跳
OOP姿态 N/A ⚠️ 精度有限
手势识别 N/A ✅ 粗大手势
乘员分类 N/A ✅ 体型区分

座舱感知任务映射

关键算法分类

方法类型 子类 适用任务 代表方法
雷达仅 CNN/Transformer 检测/分类 PointNet++, RadarNet
多模态融合 雷达+LiDAR 3D检测 ESAFusion
多模态融合 雷达+摄像头 乘员感知 Murata+SmartEye
跨模态蒸馏 LiDAR→雷达 占用预测 Knowledge Transfer
物理先验 多普勒+高程 运动/速度 Physics-informed

核心代码:4D雷达座舱感知

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
import torch
import torch.nn as nn
import numpy as np
from scipy import signal as sig

class Radar4DCabinPerception(nn.Module):
"""4D雷达座舱感知多任务模型"""

def __init__(self, n_range=128, n_doppler=64, n_azimuth=32,
n_elevation=16):
super().__init__()

# 输入: 4D张量 (B, 1, Elevation, Azimuth, Range, Doppler)
# 简化为两个3D输入

# Range-Azimuth-Elevation (空间信息)
self.spatial_encoder = nn.Sequential(
nn.Conv3d(1, 32, 3, padding=1),
nn.BatchNorm3d(32), nn.ReLU(),
nn.MaxPool3d(2),

nn.Conv3d(32, 64, 3, padding=1),
nn.BatchNorm3d(64), nn.ReLU(),
nn.MaxPool3d(2),

nn.Conv3d(64, 128, 3, padding=1),
nn.BatchNorm3d(128), nn.ReLU(),
nn.AdaptiveAvgPool3d(1),
)

# Range-Doppler (速度信息)
self.velocity_encoder = nn.Sequential(
nn.Conv2d(1, 32, 3, padding=1),
nn.BatchNorm2d(32), nn.ReLU(),
nn.MaxPool2d(2),

nn.Conv2d(32, 64, 3, padding=1),
nn.BatchNorm2d(64), nn.ReLU(),
nn.MaxPool2d(2),

nn.Conv2d(64, 128, 3, padding=1),
nn.BatchNorm2d(128), nn.ReLU(),
nn.AdaptiveAvgPool2d(1),
)

# 融合
self.fusion = nn.Sequential(
nn.Linear(128 * 2, 256),
nn.ReLU(),
nn.Dropout(0.2),
)

# 多任务头
self.occupant_head = nn.Linear(256, 5) # 0-4人
self.cpd_head = nn.Linear(256, 2) # 有人/无人
self.breathing_head = nn.Linear(256, 1) # 呼吸频率
self.posture_head = nn.Linear(256, 5) # 姿态分类
self.gesture_head = nn.Linear(256, 8) # 手势分类

def forward(self, spatial_data, velocity_data):
"""
Args:
spatial_data: (B, 1, E, A, R) 空间RDA
velocity_data: (B, 1, R, D) Range-Doppler

Returns:
dict of task outputs
"""
spatial_feat = self.spatial_encoder(spatial_data).flatten(1)
velocity_feat = self.velocity_encoder(velocity_data).flatten(1)

fused = self.fusion(torch.cat([spatial_feat, velocity_feat], dim=1))

return {
'occupant_count': self.occupant_head(fused),
'cpd_presence': self.cpd_head(fused),
'breathing_rate': self.breathing_head(fused),
'posture': self.posture_head(fused),
'gesture': self.gesture_head(fused),
}


# 微多普勒生命体征提取
class VitalSignsExtractor:
"""4D雷达微多普勒生命体征提取"""

def __init__(self, fs=20, range_bin=None):
self.fs = fs # 帧率
self.range_bin = range_bin # 目标距离bin

def extract_breathing(self, range_doppler_sequence):
"""
从Range-Doppler序列提取呼吸

Args:
range_doppler_sequence: (T, R, D) 时序R-D图

Returns:
breathing_rate: 呼吸频率 (Hz)
breathing_signal: 呼吸波形
"""
# 1. 找到目标距离bin(最大能量)
if self.range_bin is None:
energy = np.sum(np.abs(range_doppler_sequence)**2, axis=2)
self.range_bin = np.argmax(np.sum(energy, axis=0))

# 2. 提取目标bin的相位序列
target = range_doppler_sequence[:, self.range_bin, :]

# 3. 低速Doppler区域(呼吸0.1-0.5Hz对应低速)
low_doppler = target[:, :8] # 前8个Doppler bin
phase = np.angle(np.sum(low_doppler, axis=1))
phase = np.unwrap(phase)

# 4. 带通滤波 0.1-0.5 Hz
b, a = sig.butter(4, [0.1, 0.5], btype='band', fs=self.fs)
breathing_signal = sig.filtfilt(b, a, phase)

# 5. FFT找呼吸频率
freqs = np.fft.rfftfreq(len(breathing_signal), 1/self.fs)
spectrum = np.abs(np.fft.rfft(breathing_signal))
breathing_rate = freqs[np.argmax(spectrum)]

return breathing_rate, breathing_signal

def extract_heartbeat(self, range_doppler_sequence):
"""提取心跳(0.8-2.0 Hz)"""
if self.range_bin is None:
energy = np.sum(np.abs(range_doppler_sequence)**2, axis=2)
self.range_bin = np.argmax(np.sum(energy, axis=0))

target = range_doppler_sequence[:, self.range_bin, :]
low_doppler = target[:, :8]
phase = np.unwrap(np.angle(np.sum(low_doppler, axis=1)))

# 去除呼吸成分
b_breath, a_breath = sig.butter(4, [0.1, 0.5], btype='band', fs=self.fs)
breathing = sig.filtfilt(b_breath, a_breath, phase)
residual = phase - sig.filtfilt(
sig.butter(4, [0.1, 0.5], btype='band', fs=self.fs)[0],
sig.butter(4, [0.1, 0.5], btype='band', fs=self.fs)[1],
phase
)

# 心跳带通 0.8-2.0 Hz
b_heart, a_heart = sig.butter(4, [0.8, 2.0], btype='band', fs=self.fs)
heart_signal = sig.filtfilt(b_heart, a_heart, residual)

freqs = np.fft.rfftfreq(len(heart_signal), 1/self.fs)
spectrum = np.abs(np.fft.rfft(heart_signal))
heart_rate = freqs[np.argmax(spectrum)]

return heart_rate, heart_signal


# 测试
if __name__ == "__main__":
# 模型测试
model = Radar4DCabinPerception()
spatial = torch.randn(2, 1, 16, 32, 128) # (B, C, E, A, R)
velocity = torch.randn(2, 1, 128, 64) # (B, C, R, D)

outputs = model(spatial, velocity)
print("=== 4D雷达座舱感知多任务 ===")
for task, out in outputs.items():
print(f" {task}: {out.shape}")

params = sum(p.numel() for p in model.parameters())
print(f"\n参数量: {params/1e6:.2f}M")

# 生命体征提取测试
print("\n=== 生命体征提取 ===")
rd_seq = np.random.randn(200, 128, 64) + 1j * np.random.randn(200, 128, 64)
# 添加模拟呼吸信号
t = np.arange(200) / 20
breathing_mod = np.sin(2 * np.pi * 0.25 * t) # 15 breaths/min
rd_seq[:, 50, 0] += breathing_mod # 注入到特定bin

extractor = VitalSignsExtractor(fs=20)
br_rate, br_signal = extractor.extract_breathing(rd_seq)
print(f" 呼吸频率: {br_rate:.2f} Hz ({br_rate*60:.0f} breaths/min)")

IMS 开发启示

4D雷达在座舱的独特价值

价值 说明
俯仰角信息 可区分前排/后排乘员
多目标分离 多人场景更好分离
微多普勒精度 呼吸/心跳检测更准
点云密度 比UWB更密,可做粗姿态

座舱4D雷达芯片选型

芯片 频段 通道 俯仰角 成本 适用
Continental ARS540 76-81GHz 4D ✅ 高 高端
Oculii Eagle 76-81GHz 4D ✅ 中高 中高端
TI AWR2944 76-81GHz 4Tx/4Rx ✅ 中 主流
Calterah Albicetti 60GHz 3D/4D ⚠️ 低中 入门

与综述中提到的趋势对齐

综述趋势 IMS对应
稀疏→密集感知 UWB(稀疏)→4D(密集)
单模态→融合 雷达+摄像头融合
目标→场景 从”有没有人”到”人在做什么”
物理先验利用 多普勒物理特性做生命体征

总结

4D雷达感知正在从稀疏目标检测演进到动态场景理解。对 IMS 团队:

  1. 4D雷达的俯仰角信息是座舱新增量 — 可区分乘员前后位置
  2. 微多普勒是生命体征检测核心 — 呼吸+心跳可从4D雷达提取
  3. 多模态融合是主流 — 雷达+摄像头优于单模态
  4. 跨模态蒸馏是新方向 — LiDAR标注→雷达训练
  5. 动态场景重建是未来 — 从检测到理解
  6. 关注IEEE Sensors Journal这篇综述 — 12页覆盖全面

参考链接: