mmWave 雷达隐私保护全身建模:从稀疏点云到完整人体网格(arXiv 2609.34768 论文解读+代码复现)

mmWave 雷达隐私保护全身建模:从稀疏点云到完整人体网格

论文信息

项目 内容
标题 Privacy-Preserving Full-Body Meshing from mmWave Radar via Mesh Foundation Model Supervision
作者 Shuxing Zhang, Yongquan Ni, Zhenyu Ding, Yawen Lin
arXiv 2609.34768
年份 2026
链接 https://arxiv.org/abs/2609.34768
领域 cs.AI

1. 核心创新

1.1 问题

mmWave 雷达点云的极端稀疏性限制了人体感知:

挑战 数值
平均点数 ~6.5 点/帧
空帧比例 ~28%
之前方法限制 只能做身体部位关键点或离散动作分类

1.2 方法

提出通过 Mesh Foundation Model 监督学习,从 mmWave 点云直接生成完整人体网格:

1
mmWave 点云(6.5点)→ 编码器 → 解码器 → 完整人体网格(6800+顶点)

关键创新:

创新 描述
Mesh Foundation Model 监督 用预训练的 3D 人体网格模型提供监督信号
从稀疏到密集 6.5点 → 6800+顶点的映射
隐私保护 不使用摄像头,纯雷达
全身建模 首次从 mmWave 实现全身网格生成

2. 方法详解

2.1 架构

graph TD
    A[mmWave 点云<br/>~6.5点/帧] --> B[点云编码器<br/>PointNet++]
    
    B --> C[特征向量]
    
    C --> D[网格解码器<br/>Transformer]
    
    D --> E[人体网格<br/>6800+顶点]
    
    F[Mesh Foundation Model<br/>SMPL-X] -->|监督信号| D
    
    G[RGB 模态<br/>仅训练时] --> F

2.2 代码复现

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
"""
mmWave 隐私保护全身建模框架
从稀疏点云生成完整人体网格
"""

import torch
import torch.nn as nn
import torch.nn.functional as F
import numpy as np
from typing import Optional

class PointCloudEncoder(nn.Module):
"""
点云编码器
基于 PointNet++ 变体
"""

def __init__(self, config: dict):
super().__init__()
in_dim = config.get('in_dim', 3) # x, y, z
feat_dim = config.get('feat_dim', 256)

# 逐点 MLP
self.mlp = nn.Sequential(
nn.Linear(in_dim, 64),
nn.ReLU(inplace=True),
nn.Linear(64, 128),
nn.ReLU(inplace=True),
nn.Linear(128, 256),
nn.ReLU(inplace=True),
)

# 全局特征
self.global_feat = nn.Sequential(
nn.Linear(256, feat_dim),
nn.ReLU(inplace=True),
nn.Linear(feat_dim, feat_dim)
)

def forward(self, points: torch.Tensor) -> torch.Tensor:
"""
Args:
points: (B, N, 3) 点云坐标

Returns:
global_feature: (B, feat_dim)
"""
# 逐点特征
point_feat = self.mlp(points) # (B, N, 256)

# 最大池化
global_feat = point_feat.max(dim=1)[0] # (B, 256)

# 进一步编码
global_feat = self.global_feat(global_feat) # (B, feat_dim)

return global_feat


class MeshDecoder(nn.Module):
"""
网格解码器
从全局特征生成人体网格顶点
"""

def __init__(self, config: dict):
super().__init__()
feat_dim = config.get('feat_dim', 256)
n_vertices = config.get('n_vertices', 6890) # SMPL 顶点数

# Transformer 解码器
self.pos_embed = nn.Parameter(torch.randn(1, n_vertices, feat_dim) * 0.02)

decoder_layer = nn.TransformerDecoderLayer(
d_model=feat_dim,
nhead=4,
dim_feedforward=feat_dim * 4,
dropout=0.1,
batch_first=True
)
self.decoder = nn.TransformerDecoder(decoder_layer, num_layers=4)

# 顶点坐标输出
self.vertex_head = nn.Sequential(
nn.LayerNorm(feat_dim),
nn.Linear(feat_dim, feat_dim // 2),
nn.GELU(),
nn.Linear(feat_dim // 2, 3) # x, y, z
)

def forward(self, global_feat: torch.Tensor) -> torch.Tensor:
"""
Args:
global_feat: (B, feat_dim)

Returns:
vertices: (B, n_vertices, 3)
"""
B = global_feat.shape[0]
n_verts = self.pos_embed.shape[1]

# 记忆向量
memory = global_feat.unsqueeze(1) # (B, 1, feat_dim)

# 查询 = 位置嵌入
query = self.pos_embed.expand(B, -1, -1) # (B, n_vertices, feat_dim)

# Transformer 解码
decoded = self.decoder(query, memory) # (B, n_vertices, feat_dim)

# 顶点坐标
vertices = self.vertex_head(decoded) # (B, n_vertices, 3)

return vertices


class mmWaveBodyMesh(nn.Module):
"""
完整的 mmWave 人体网格生成模型
"""

def __init__(self, config: dict):
super().__init__()
self.encoder = PointCloudEncoder(config)
self.decoder = MeshDecoder(config)

# SMPL 参数(简化)
self.n_vertices = config.get('n_vertices', 6890)

def forward(self, points: torch.Tensor) -> dict:
"""
Args:
points: (B, N, 3) mmWave 点云

Returns:
{
'vertices': (B, V, 3), # 顶点坐标
'global_feat': (B, feat_dim) # 全局特征
}
"""
global_feat = self.encoder(points)
vertices = self.decoder(global_feat)

return {
'vertices': vertices,
'global_feat': global_feat
}

def extract_pose_keypoints(self, vertices: torch.Tensor) -> torch.Tensor:
"""
从网格顶点提取关键姿态关键点

简化版:从6890个顶点中选取17个关键点
"""
# SMPL 关节映射(简化)
joint_indices = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]

# 顶点到关节的回归(实际应通过训练学习)
joints = vertices[:, joint_indices] # (B, 17, 3)

return joints


# 使用示例
if __name__ == "__main__":
config = {
'in_dim': 3,
'feat_dim': 256,
'n_vertices': 6890, # SMPL 标准顶点数
}

model = mmWaveBodyMesh(config)

# 模拟 mmWave 点云(B=2, N=6 点)
points = torch.randn(2, 6, 3) * 2 # 随机点

output = model(points)

print(f"输入点云: {points.shape}")
print(f"输出网格: {output['vertices'].shape}")
print(f"全局特征: {output['global_feat'].shape}")

# 提取姿态
joints = model.extract_pose_keypoints(output['vertices'])
print(f"姿态关键点: {joints.shape}")

# 参数量
n_params = sum(p.numel() for p in model.parameters())
print(f"模型参数量: {n_params:,} ({n_params * 4 / 1024 / 1024:.1f} MB)")

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
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
"""
座舱 mmWave 人体网格生成与 OOP 检测
"""

class CabinBodyMeshSystem:
"""
座舱人体网格系统

应用:
1. OOP(异常姿态)检测
2. 乘员分类(通过体型)
3. 安全带佩戴状态(通过网格与安全带空间关系)
4. 儿童检测(通过体型大小)
"""

def __init__(self):
self.model = mmWaveBodyMesh({
'in_dim': 3, 'feat_dim': 128, 'n_vertices': 6890
})
self.model.eval()

# OOP 检测阈值
self.oop_thresholds = {
'forward_lean_deg': 30, # 前倾角度
'side_lean_deg': 25, # 侧倾角度
'recline_deg': 40, # 后倾角度
'child_height_ratio': 0.7 # 儿童身高比
}

def detect_oop(self, vertices: torch.Tensor,
seat_ref: tuple) -> dict:
"""
异常姿态检测

Args:
vertices: (V, 3) 人体网格顶点
seat_ref: 座椅参考点 (x, y, z)

Returns:
{'is_oop': bool, 'oop_type': str, 'confidence': float}
"""
# 提取关键点
joints = self.model.extract_pose_keypoints(
vertices.unsqueeze(0)
)[0] # (17, 3)

# 计算躯干角度
shoulder_mid = (joints[5] + joints[2]) / 2 # 肩部中点
hip_mid = (joints[11] + joints[8]) / 2 # 髋部中点

# 躯干向量
torso = shoulder_mid - hip_mid
torso_length = torch.norm(torso)

if torso_length < 0.1:
return {'is_oop': False, 'oop_type': 'unknown', 'confidence': 0}

# 归一化
torso_norm = torso / torso_length

# 角度计算
# 前倾:z分量(前后)的角度
forward_angle = torch.abs(torch.atan2(torso_norm[2], torso_norm[1]))

# 侧倾
side_angle = torch.abs(torch.atan2(torso_norm[0], torso_norm[1]))

# 后倾
recline_angle = torch.abs(torch.atan2(-torso_norm[1], torch.norm(torso_norm[:1])))

# 判断OOP
oop_type = 'normal'
is_oop = False

if forward_angle > np.radians(self.oop_thresholds['forward_lean_deg']):
oop_type = 'forward_lean'
is_oop = True
elif side_angle > np.radians(self.oop_thresholds['side_lean_deg']):
oop_type = 'side_lean'
is_oop = True
elif recline_angle > np.radians(self.oop_thresholds['recline_deg']):
oop_type = 'reclined'
is_oop = True

# 身高估计(判断儿童)
height = torch.norm(joints[0] - joints[11]) # 头到髋

confidence = min(torso_length.item() / 0.3, 1.0) # 躺在torso长度

return {
'is_oop': is_oop,
'oop_type': oop_type,
'confidence': confidence,
'forward_angle_deg': np.degrees(forward_angle.item()),
'side_angle_deg': np.degrees(side_angle.item()),
'estimated_height_m': height.item()
}


# 测试
if __name__ == "__main__":
system = CabinBodyMeshSystem()

# 模拟点云
points = torch.randn(1, 6, 3) * 2

with torch.no_grad():
output = system.model(points)
result = system.detect_oop(output['vertices'][0], seat_ref=(0, 0, 0))

print("=== OOP 检测结果 ===")
print(f"异常姿态: {result['is_oop']}")
print(f"类型: {result['oop_type']}")
print(f"前倾角度: {result.get('forward_angle_deg', 0):.1f}°")
print(f"侧倾角度: {result.get('side_angle_deg', 0):.1f}°")
print(f"估计身高: {result.get('estimated_height_m', 0):.2f}m")

3. 对 IMS 开发的启示

3.1 OOP 检测的全新路径

传统方案 mmWave 网格方案
RGB 摄像头 + 2D 姿态估计 mmWave + 3D 网格
❌ 受光照影响 ✅ 不受光照影响
❌ 遮挡时失败 ✅ 穿透遮挡
⚠️ 2D 姿态精度有限 ✅ 3D 全身网格
❌ 隐私问题 ✅ 隐私保护

3.2 应用场景

应用 描述 可行性
OOP 检测 前倾/侧倾/后倾 ✅ 直接适用
乘员分类 通过体型判断成人/儿童 ✅ 身高/体积
安全带路径 网格与安全带空间关系 ⚠️ 需融合视觉
儿童检测 通过网格大小 ✅ 但需足够点云
睡眠姿态 后倾+头部下垂 ✅

3.3 落地建议

优先级 建议
🟡 P1 跟踪论文开源代码和预训练模型
🟡 P1 评估 60GHz mmWave 在座舱内的点云密度
🟢 P2 与视觉 OOP 检测做互补验证
🟢 P2 SMPL-X 模型在边缘设备上的量化部署

3.4 当前限制

限制 描述 缓解方案
点云稀疏 6.5点/帧 多帧累积
28%空帧 无数据帧 时序插值
训练依赖RGB 需要RGB监督 仿真数据训练
模型大小 SMPL网格大 量化+蒸馏

4. 参考


mmWave 雷达隐私保护全身建模:从稀疏点云到完整人体网格(arXiv 2609.34768 论文解读+代码复现)
https://dapalm.com/2026/10/06/2026-10-06-015-mmwave-privacy-full-body-meshing-arxiv2026/
作者
Mars
发布于
2026年10月6日
许可协议