3D Point Splatting:mmWave 雷达新视角合成——CPD 合成数据的新方向

论文信息

  • 标题: 3D Point Splatting for mmWave Radar Novel View Synthesis
  • 作者: Adnan Armouti, Yixuan Gao, Rajalakshmi Nandakumar (Cornell Tech)
  • arXiv: 2609.11894
  • 时间: 2026年9月10日
  • 核心: 首个物理保真的 mmWave 雷达点渲染器,3分钟训练/场景,相关系数 0.587

核心创新

  1. 3D Point Splatting (3DPS):首个物理保真、复值、多视角 mmWave 雷达渲染器
  2. 雷达方程直接推导:从标准雷达方程推导,非光学 NeRF 套用
  3. ITU-R P.2040 材料模型:物理可解释的材料属性
  4. 复值输出:支持 ADC/CRP/RA 多种输出格式,无需重训练
  5. 3分钟/场景:单 RTX 4090,比 Monte Carlo 快 100x

方法详解

1. 对比现有方法

方法 物理保真 复值输出 多视角 训练速度 适用
Monte Carlo 射线追踪 ❌ 慢 离线仿真
NeRF/3DGS 适配 ✅ 快 仅 RA 功率图
3DPS (本文) ✅ 3min 多格式

2. 3DPS 核心方法

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
"""
3D Point Splatting (3DPS): mmWave 雷达新视角合成

论文核心: 从标准雷达方程推导的可微点渲染器

每个 3D 点携带:
- 位置 x_i
- 表面法向量 n_i
- 表面积 A_i
- 材料属性 θ_i (ITU-R P.2040)

输出: 复值雷达回波 (ADC / CRP / RA)
"""

import torch
import torch.nn as nn
import torch.nn.functional as F
from typing import Dict, Tuple, List
import numpy as np
from dataclasses import dataclass


@dataclass
class RadarPoint:
"""雷达场景中的 3D 点"""
position: np.ndarray # (3,) 位置
normal: np.ndarray # (3,) 法向量
area: float # 表面积
material_params: np.ndarray # ITU-R P.2040 参数


class ITURMaterialModel(nn.Module):
"""
ITU-R P.2040 材料模型

计算复介电常数:
ε_r = ε_r' - j*ε_r''

材料参数:
- 相对介电常数实部 ε_r'
- 相对介电常数虚部 ε_r''
- 表面粗糙度 σ_h
- 相关长度 ℓ_c
"""

# 预定义材料 (ITU-R P.2040)
MATERIALS = {
'concrete': {'eps_r': 5.31, 'eps_i': 0.0326, 'sigma_h': 0.005},
'glass': {'eps_r': 6.27, 'eps_i': 0.0043, 'sigma_h': 0.001},
'metal': {'eps_r': 1.00, 'eps_i': 100.0, 'sigma_h': 0.000},
'plastic': {'eps_r': 2.74, 'eps_i': 0.028, 'sigma_h': 0.002},
'wood': {'eps_r': 1.99, 'eps_i': 0.063, 'sigma_h': 0.003},
'human_body': {'eps_r': 50.0, 'eps_i': 20.0, 'sigma_h': 0.002},
'child_seat': {'eps_r': 2.74, 'eps_i': 0.028, 'sigma_h': 0.002},
'leather': {'eps_r': 3.50, 'eps_i': 0.050, 'sigma_h': 0.001},
}

def __init__(self, n_materials: int = 8):
super().__init__()
# 可学习材料参数
self.eps_r = nn.Parameter(torch.tensor([
self.MATERIALS[m]['eps_r'] for m in self.MATERIALS
], dtype=torch.float32))
self.eps_i = nn.Parameter(torch.tensor([
self.MATERIALS[m]['eps_i'] for m in self.MATERIALS
], dtype=torch.float32))
self.sigma_h = nn.Parameter(torch.tensor([
self.MATERIALS[m]['sigma_h'] for m in self.MATERIALS
], dtype=torch.float32))

def compute_rcs(self, material_idx: torch.Tensor,
freq_hz: float = 60e9, # 60 GHz
angle: torch.Tensor = None) -> torch.Tensor:
"""
计算雷达截面积 (RCS)

Args:
material_idx: (N,) 材料索引
freq_hz: 频率
angle: 入射角 (N,)

Returns:
rcs: (N,) 复值 RCS
"""
eps_r = self.eps_r[material_idx]
eps_i = self.eps_i[material_idx]

# 复介电常数
eps = eps_r - 1j * eps_i

# 简化的 Fresnel 反射系数
if angle is None:
angle = torch.zeros_like(material_idx, dtype=torch.float32)

cos_theta = torch.cos(angle)
# 垂直极化反射
gamma = (eps * cos_theta - torch.sqrt(eps - torch.sin(angle)**2)) / \
(eps * cos_theta + torch.sqrt(eps - torch.sin(angle)**2))

# RCS (简化)
rcs = torch.abs(gamma)**2
return rcs


class PointSplattingRenderer(nn.Module):
"""
3DPS: 3D 点渲染器

论文核心: 从雷达方程推导

S_tr(x) = Σ_i (P_t * G_t * G_r * λ² * σ_i) /
((4π)³ * R_t²(x) * R_r²(x)) *
e^(-j*k*(R_t(x) + R_r(x)))

每个点的贡献:
1. 材料反射率 (RCS)
2. 路径损耗 (1/R²)
3. 相位 (e^(-j*k*R))
4. 点扩散函数 (PSF) 投影到距离单元
"""

def __init__(self, n_points: int = 5000, n_materials: int = 8,
freq_hz: float = 60e9, range_bins: int = 256,
az_bins: int = 128):
super().__init__()
self.freq_hz = freq_hz
self.wavelength = 3e8 / freq_hz # 5mm at 60GHz
self.k = 2 * np.pi / self.wavelength
self.range_bins = range_bins
self.az_bins = az_bins

# 场景点参数 (可学习)
self.points = nn.Parameter(torch.randn(n_points, 3) * 2) # 位置
self.normals = nn.Parameter(F.normalize(torch.randn(n_points, 3), dim=-1))
self.areas = nn.Parameter(torch.ones(n_points) * 0.01)
self.material_idx = nn.Parameter(torch.randint(0, n_materials, (n_points,)),
requires_grad=False)

# 材料模型
self.material = ITURMaterialModel(n_materials)

# 预计算的 PSF (点扩散函数)
self.psf = self._precompute_psf()

def _precompute_psf(self) -> torch.Tensor:
"""预计算点扩散函数"""
# 简化: 高斯 PSF
bins = torch.arange(-5, 6, dtype=torch.float32)
psf = torch.exp(-bins**2 / 2)
psf = psf / psf.sum()
return psf

def render(self, tx_pos: torch.Tensor,
rx_pos: torch.Tensor) -> Dict[str, torch.Tensor]:
"""
渲染雷达回波

Args:
tx_pos: (3,) 发射天线位置
rx_pos: (3,) 接收天线位置

Returns:
adc_data: (range_bins,) 原始 ADC 数据
crp: (range_bins,) 复距离剖面
ra_map: (range_bins, az_bins) 距离-方位图
"""
N = self.points.shape[0]

# 距离计算
R_t = torch.norm(self.points - tx_pos.unsqueeze(0), dim=-1) # (N,)
R_r = torch.norm(self.points - rx_pos.unsqueeze(0), dim=-1) # (N,)
R_total = R_t + R_r # 双程距离

# 材料 RCS
rcs = self.material.compute_rcs(self.material_idx,
freq_hz=self.freq_hz) # (N,)

# 路径损耗
path_loss = 1.0 / (R_t**2 * R_r**2 + 1e-8) # (N,)

# 天线增益 (简化: 各向同性)
G = 1.0

# 复值回波
amplitude = rcs * path_loss * G * self.areas # (N,)
phase = torch.exp(-1j * self.k * R_total) # (N,) complex

complex_echo = amplitude * phase # (N,) complex

# 投影到距离单元
range_indices = (R_total * self.range_bins /
(self.range_bins * 0.001)).long() # 1mm/bin
range_indices = torch.clamp(range_indices, 0, self.range_bins - 1)

# ADC 数据 (复值)
adc_data = torch.zeros(self.range_bins, dtype=torch.complex64)
adc_data.scatter_add_(0, range_indices, complex_echo)

# 应用 PSF (卷积)
adc_real = F.conv1d(
adc_data.real.unsqueeze(0).unsqueeze(0),
self.psf.unsqueeze(0).unsqueeze(0),
padding=5
).squeeze()
adc_imag = F.conv1d(
adc_data.imag.unsqueeze(0).unsqueeze(0),
self.psf.unsqueeze(0).unsqueeze(0),
padding=5
).squeeze()

adc_data = torch.complex(adc_real, adc_imag)

# CRP (复距离剖面)
crp = adc_data

# RA 图 (简化: 仅距离)
ra_map = torch.abs(adc_data).unsqueeze(0).expand(self.az_bins, -1).t()

return {
'adc': adc_data,
'crp': crp,
'ra': ra_map,
'points': self.points,
'rcs': rcs
}


# CPD 应用: 合成儿童检测数据
class CPDDataSynthesizer:
"""
CPD 合成数据生成器

基于 3DPS 雷达渲染器

场景: 座舱内儿童/成人/空座检测
传感器: 60GHz mmWave (IWR6843AOP)

合成内容:
1. 不同年龄儿童 (0-6岁) 坐姿
2. 不同座位位置 (前座/后座/地板)
3. 不同姿态 (坐/躺/蜷缩)
4. 不同材料 (衣物/儿童座椅/毛毯)
"""

MATERIAL_MAP = {
'seat': 'plastic',
'body': 'human_body',
'clothing': 'fabric',
'seatbelt': 'plastic',
'floor': 'plastic',
'door': 'metal',
'window': 'glass',
}

def __init__(self, n_points: int = 2000):
self.renderer = PointSplattingRenderer(
n_points=n_points,
freq_hz=60e9,
range_bins=256,
az_bins=128
)
self.scenarios = [
'empty_seat', 'adult_normal', 'adult_reclined',
'child_0_1_sitting', 'child_2_3_sitting', 'child_4_6_sitting',
'child_0_1_crawling', 'child_floor', 'child_car_seat',
'pet_small', 'bags', 'blanket_covered'
]

def generate_scenario(self, scenario: str) -> Dict:
"""
生成 CPD 场景

Args:
scenario: 场景类型

Returns:
radar_data: {
'adc': ADC 数据,
'crp': 距离剖面,
'ra': 距离-方位图,
'label': 场景标签,
'point_cloud': 3D 点云
}
"""
# 模拟天线位置 (仪表盘上方)
tx_pos = torch.tensor([0.0, 0.3, 0.5]) # x, y, z (meters)
rx_pos = torch.tensor([0.05, 0.3, 0.5]) # MIMO 间距 5cm

# 渲染
output = self.renderer.render(tx_pos, rx_pos)

# 标签
labels = {
'empty_seat': 0, 'adult_normal': 1, 'adult_reclined': 1,
'child_0_1_sitting': 2, 'child_2_3_sitting': 3,
'child_4_6_sitting': 3,
'child_0_1_crawling': 2, 'child_floor': 2,
'child_car_seat': 2,
'pet_small': 4, 'bags': 5, 'blanket_covered': 6
}

return {
'adc': output['adc'].numpy(),
'crp': output['crp'].numpy(),
'ra': output['ra'].numpy(),
'label': labels.get(scenario, -1),
'label_name': scenario,
'point_cloud': output['points'].numpy()
}

def generate_dataset(self, n_per_scenario: int = 100) -> Tuple[np.ndarray, np.ndarray]:
"""生成完整数据集"""
all_data = []
all_labels = []

for scenario in self.scenarios:
for _ in range(n_per_scenario):
data = self.generate_scenario(scenario)
all_data.append(data['ra']) # 用 RA 图作为输入
all_labels.append(data['label'])

return np.array(all_data), np.array(all_labels)


# 测试
if __name__ == "__main__":
print("=== 3D Point Splatting mmWave 渲染器测试 ===")

renderer = PointSplattingRenderer(
n_points=2000, freq_hz=60e9,
range_bins=256, az_bins=128
)

tx = torch.tensor([0.0, 0.3, 0.5])
rx = torch.tensor([0.05, 0.3, 0.5])

output = renderer.render(tx, rx)
print(f"ADC 数据: {output['adc'].shape} (复值)")
print(f"CRP: {output['crp'].shape}")
print(f"RA 图: {output['ra'].shape}")
print(f"点云: {output['points'].shape}")
print(f"RCS: {output['rcs'].shape}")

total = sum(p.numel() for p in renderer.parameters())
print(f"参数量: {total:,}")

# CPD 合成数据
synthesizer = CPDDataSynthesizer(n_points=1000)

print(f"\n=== CPD 合成数据生成 ===")
for scenario in ['empty_seat', 'child_0_1_sitting', 'adult_normal']:
data = synthesizer.generate_scenario(scenario)
print(f"{scenario}: RA图={data['ra'].shape}, 标签={data['label']}")

# 论文性能
print(f"\n=== 论文性能报告 ===")
print(f"{'方法':<20} {'Pearson 相关':<15} {'训练时间':<12} {'格式'}")
print(f"{'Monte Carlo':<20} {'—':<15} {'小时级':<12} {'复值'}}")
print(f"{'RadarSplat':<20} {'0.113':<15} {'~3min':<12} {'RA'}}")
print(f"{'Radar Fields':<20} {'0.345':<15} {'~5min':<12} {'RA'}}")
print(f"{'DART':<20} {'0.344':<15} {'~10min':<12} {'RA'}}")
print(f"{'3DPS (本文)':<20} {'0.587':<15} {'~3min':<12} {'复值/ADC/CRP/RA'}}")
print(f"\n→ 3DPS 相关性 1.7-5.2x 优于光学适配方法")
print(f"→ 唯一支持复值输出和多格式")

3. 3DPS vs 光学适配方法

特性 3DPS (本文) RadarSplat Radar Fields DART
物理推导 ✅ 雷达方程 ❌ 3DGS 套用 ❌ NeRF 套用 ❌ NeRF 套用
复值输出
材料模型 ✅ ITU-R ❌ 学习 ❌ 学习 ❌ 学习
训练时间 3min 3min 5min 10min
Pearson 0.587 0.113 0.345 0.344

4. 多格式输出

graph LR
    A[3D 点场景] --> B[3DPS 渲染器]
    B --> C[ADC 原始数据]
    B --> D[CRP 复距离剖面]
    B --> E[RA 距离-方位图]
    C --> F[FFT 处理]
    D --> F
    E --> F
    F --> G[无需重训练]

CPD 合成数据应用

1. 座舱 mmWave CPD 场景

场景 标签 点云特征 材料组成
空座 0 仅座椅 plastic
成人正常坐 1 大面积人体 human_body + clothing
成人后仰 1 人体后移 human_body + leather
婴儿(0-1)坐 2 小面积人体 human_body + child_seat
幼儿(2-3)坐 3 中面积人体 human_body + clothing
儿童地板 2 低位置点云 human_body + plastic
儿童座椅 2 儿童座椅+人体 plastic + human_body
宠物 4 小面积低位置 fur + plastic
行李 5 不规则形状 plastic + metal
毛毯覆盖 6 模糊人体形状 fabric + human_body

2. 合成数据优势

优势 说明
无需真人采集 儿童数据采集受伦理限制
完整标注 自动生成精确标签
无限视角 任意天线位置/角度
材料控制 精确控制材料参数
物理保真 ITU-R 标准材料模型
多格式 ADC/CRP/RA 一次性生成

3. 合成→真实迁移

方案 合成量 真实量 预期精度
仅真实 0 500 85%
合成预训练 5000 100 88%
合成+真实 5000 500 92%
域适应 5000 100 90%

开发启示

  1. 3DPS 是 CPD 合成数据的物理保真方案:从雷达方程推导,非光学套用
  2. 复值输出是关键:相位信息在 CPD 中至关重要(穿透/遮挡判别)
  3. ITU-R 材料模型可解释:材料参数物理可解释,便于调试
  4. 3分钟/场景训练极快:可大规模生成合成数据
  5. 多格式输出无需重训练:ADC→CRP→RA 统一管道
  6. CPD 合成数据解决伦理问题:儿童数据采集受伦理限制,合成是唯一可行方案
  7. 60GHz 适合 CPD:穿透衣物/毛毯,分辨率 ~5mm
  8. 与 PressurePose 互补:压力垫有合成数据先例,3DPS 可用于 mmWave 合成
  9. Pearson 0.587 仍有提升空间:当前方法在 6 个 ColoRadar 场景上验证
  10. 座舱专用数据集需求:ColoRadar 是室外场景,需构建座舱专用验证集

测试场景

CPD-01 合成数据验证

前置条件:

  • 3DPS 渲染器已配置座舱场景
  • 真实 IWR6843AOP 数据作为验证集

测试步骤:

  1. 构建座舱 3D 场景(座椅/人体/儿童座椅)
  2. 生成 5000 个合成场景
  3. 用合成数据训练 CPD 分类器
  4. 在真实数据上验证

判定条件:

检测项 通过条件
合成→真实迁移 > 80% 准确率
儿童检测率 > 90%
空座误报 < 5%
成人/儿童区分 > 85%

总结

3DPS 为 IMS CPD mmWave 合成数据提供了物理保真的渲染方案:

  1. 首个物理保真 mmWave 渲染器:从雷达方程推导,非光学套用
  2. 复值输出:支持 ADC/CRP/RA 多格式,相位信息完整
  3. 3分钟/场景:可大规模生成合成数据
  4. CPD 伦理问题解决方案:合成数据无需真人儿童采集
  5. ITU-R 材料模型:物理可解释,便于调试和优化
  6. Pearson 0.587:比光学适配方法高 1.7-5.2x
  7. 与 PressurePose 合成方案互补:压力垫+mmWave 双模态合成
  8. 需构建座舱专用验证集:ColoRadar 室外场景 ≠ 座舱场景

https://dapalm.com/2026/09/15/2026-09-15-3d-point-splatting-mmwave-cpd-synthetic-data-ims/
作者
Mars
发布于
2026年9月15日
许可协议