M4Human:CVPR 2026 最大规模 mmWave 雷达人体网格重建基准——IMS OOP 异常姿态检测的新引擎

论文信息

项目 内容
标题 M4Human: A Large-Scale Multimodal mmWave Radar Benchmark for Human Mesh Reconstruction
作者 Junqiao Fan, Yunjiao Zhou, Yizhuo Yang, Xinyuan Cui, Jiarui Zhang, Lihua Xie, Jianfei Yang, Chris Xiaoxuan Lu, Fangqiang Ding
机构 University of Edinburgh, MIT, NTU Singapore, UCL, UPenn
会议 CVPR 2026
链接 https://arxiv.org/abs/2512.12378
代码 https://github.com/FanJunqiao/M4Human
数据集 https://fanjunqiao.github.io/M4Human-site/

核心创新

M4Human 是目前最大规模的多模态 mmWave 雷达人体网格重建(HMR)基准数据集,规模为此前最大数据集的 9 倍。核心贡献:

  1. 661K 帧同步数据:高分辨率 mmWave 雷达 + RGB + Depth + MoCap 标注
  2. 50 类动作:涵盖日常活动、康复运动、体育运动(含坐姿、非原地运动)
  3. 20 位受试者:多样化体型和动作风格
  4. 双模态雷达数据:同时提供 Raw Tensor (RT) 和 Point Cloud (RPC)
  5. 高精度 MoCap 标注:标记式动捕系统,非 RGB 伪标签

与现有数据集对比

数据集 模态 带宽 (GHz) 标注类型 动作数 受试者 帧数 场景
mmMesh RPC 77-81 3D Mesh 8 20 3K 日常
mmBody RPC 76-81 3D Mesh <30 20 <70K 日常
mRI RPC 77-81 3D* 12 20 160K 日常+康复
mm-Fi RPC 60-64 3D* 27 40 320K 日常+康复
MMVR RT 77-81 2D* - 25 345K 日常
M4Human RT+RPC 62-69 3D Mesh+轨迹 50 20 661K 日常+康复+体育

关键区别:M4Human 是唯一同时提供 RT 和 RPC 双模态、标记式 MoCap 标注、且包含非原地运动(体育/康复)的数据集。

方法详解

1. 数据采集架构

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
# M4Human 数据采集硬件配置
hardware_config = {
"radar": {
"model": "Vayyar VSWR-10", # 高分辨率 mmWave 雷达
"band": "62-69 GHz", # 7 GHz 带宽
"channels": "高分辨率阵列",
"output": ["raw_tensor", "point_cloud"]
},
"rgb": {
"model": "Standard RGB Camera",
"resolution": "1920x1080",
"fps": 30
},
"depth": {
"model": "Azure Kinect / RealSense",
"resolution": "1280x1024",
"fps": 30
},
"mocap": {
"system": "Marker-based OptiTrack",
"markers": 53, # 全身标记点
"mesh": "SMPL-X 3D mesh",
"trajectory": "global 3D trajectory"
}
}

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
import numpy as np
from typing import Tuple, Dict

class M4HumanRadarPipeline:
"""
M4Human 雷达信号处理管道

支持双模态输出:
- Raw Tensor (RT): 保留完整信号信息,用于深度学习
- Point Cloud (RPC): 经过处理后的点云,用于传统方法
"""

def __init__(self, config: dict):
self.bandwidth = config.get('bandwidth', 7e9) # 7 GHz
self.carrier_freq = config.get('carrier_freq', 65e9) # 中心频率 65 GHz
self.num_tx = config.get('num_tx', 16)
self.num_rx = config.get('num_rx', 16)

def compute_resolution(self) -> dict:
"""
计算 M4Human 雷达空间分辨率

Returns:
resolutions: 距离/角度/速度分辨率
"""
c = 3e8 # 光速

# 距离分辨率
range_res = c / (2 * self.bandwidth)

# 角度分辨率(假设孔径 D = 0.1m)
aperture = 0.1 # 10cm
angular_res = 0.5 * 0.7 * (3e8 / self.carrier_freq) / aperture

# 速度分辨率(假设观测时间 T = 50ms)
obs_time = 0.05
velocity_res = 0.5 * 3e8 / (2 * self.carrier_freq * obs_time)

return {
"range_resolution_m": round(range_res * 100, 2), # cm
"angular_resolution_deg": round(np.degrees(angular_res), 2),
"velocity_resolution_cm_s": round(velocity_res * 100, 2),
"bandwidth_GHz": self.bandwidth / 1e9
}

def raw_tensor_extraction(self, adc_data: np.ndarray) -> np.ndarray:
"""
从 ADC 原始数据提取 Raw Tensor

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

Returns:
rt: Raw Tensor, shape=(range_bins, doppler_bins, angle_bins)
"""
# Range-Doppler-Angle 三维张量
# 1. Range FFT (沿采样轴)
range_profile = np.fft.fft(adc_data, axis=-1)

# 2. Doppler FFT (沿 chirp 轴)
range_doppler = np.fft.fftshift(
np.fft.fft(range_profile, axis=-2), axes=-2
)

# 3. Angle FFT (沿虚拟天线轴)
range_doppler_angle = np.fft.fftshift(
np.fft.fft(range_doppler, axis=0), axes=0
)

return range_doppler_angle

def point_cloud_extraction(self, rt: np.ndarray) -> np.ndarray:
"""
从 Raw Tensor 提取 Point Cloud

Args:
rt: Raw Tensor, shape=(angle_bins, doppler_bins, range_bins)

Returns:
rpc: Point Cloud, shape=(N, 5) = [x, y, z, doppler, intensity]
"""
# CFAR 检测
threshold = np.mean(rt) + 3 * np.std(rt)
detections = np.argwhere(rt > threshold)

# 转换为 3D 坐标
points = []
for det in detections:
angle_bin, doppler_bin, range_bin = det
range_val = range_bin * self.compute_resolution()["range_resolution_m"] / 100
angle_val = (angle_bin - rt.shape[0]//2) * self.compute_resolution()["angular_resolution_deg"]

x = range_val * np.cos(np.radians(angle_val))
y = range_val * np.sin(np.radians(angle_val))
z = 0 # 2D 雷达,z 从角度估计
doppler = (doppler_bin - rt.shape[1]//2) * self.compute_resolution()["velocity_resolution_cm_s"] / 100

points.append([x, y, z, doppler, rt[det]])

return np.array(points)


# 实际测试
if __name__ == "__main__":
pipeline = M4HumanRadarPipeline({})
res = pipeline.compute_resolution()
print("=== M4Human 雷达分辨率 ===")
for k, v in res.items():
print(f" {k}: {v}")
# 输出示例:
# range_resolution_m: 2.14 cm
# angular_resolution_deg: ~1.8°
# velocity_resolution_cm_s: ~2.3 cm/s
# bandwidth_GHz: 7.0

3. HMR 基准方法

M4Human 在 RT 和 RPC 两种模态上基准了多种 SOTA 方法:

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
import torch
import torch.nn as nn

class RadarHMRBaseline(nn.Module):
"""
mmWave 雷达人体网格重建基线模型

基于 M4Human 论文中的 benchmark 设计,
支持 RT(Raw Tensor)和 RPC(Point Cloud)两种输入。

论文发现:
- RT 模态优于 RPC(保留更多信息)
- 多模态融合(RT+RGB-D)进一步提升性能
- 快速运动和非约束动作仍是挑战
"""

def __init__(self, modality: str = "rt", backbone: str = "resnet50"):
super().__init__()
self.modality = modality

if modality == "rt":
# Raw Tensor: 3D CNN 处理 Range-Doppler-Angle
self.encoder = nn.Sequential(
nn.Conv3d(1, 32, kernel_size=3, padding=1),
nn.BatchNorm3d(32),
nn.ReLU(),
nn.MaxPool3d(2),

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

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

elif modality == "rpc":
# Point Cloud: PointNet++ 处理
self.encoder = PointNetPP(
in_channels=5, # x, y, z, doppler, intensity
out_channels=128
)
feat_dim = 128

# SMPL-X 参数回归头
self.pose_head = nn.Linear(feat_dim, 156) # 52 joints * 3
self.shape_head = nn.Linear(feat_dim, 10) # SMPL betas
self.trans_head = nn.Linear(feat_dim, 3) # 全局平移

def forward(self, x: torch.Tensor) -> dict:
"""
Args:
x: 雷达输入
- RT: (B, 1, A, D, R) = (B, 1, angle_bins, doppler_bins, range_bins)
- RPC: (B, N, 5) = (B, num_points, 5)

Returns:
output: {
pose: (B, 156) 关节角度,
shape: (B, 10) 体型参数,
trans: (B, 3) 全局平移
}
"""
feat = self.encoder(x)
if self.modality == "rt":
feat = feat.flatten(1)

return {
"pose": self.pose_head(feat),
"shape": self.shape_head(feat),
"trans": self.trans_head(feat)
}


class PointNetPP(nn.Module):
"""简化版 PointNet++ 用于 RPC 处理"""
def __init__(self, in_channels: int, out_channels: int):
super().__init__()
self.mlp = nn.Sequential(
nn.Linear(in_channels, 64),
nn.ReLU(),
nn.Linear(64, 128),
nn.ReLU(),
nn.Linear(128, out_channels)
)

def forward(self, x: torch.Tensor) -> torch.Tensor:
# x: (B, N, C)
x = self.mlp(x) # (B, N, out)
x = x.max(dim=1)[0] # (B, out) - max pooling
return x

实验结果

1. 主要定量结果

方法 模态 MPJPE (mm) ↓ PA-MPJPE (mm) ↓ MPVPE (mm) ↓
mmBody RPC 89.2 72.5 91.3
RT-HMR RT 78.5 63.1 80.7
RPC-HMR RPC 85.4 69.8 87.2
RT+RGB-D 融合 62.3 48.7 64.5

关键发现:RT 模态比 RPC 低 ~10mm 误差;多模态融合比单模态低 ~26mm。

2. 动作类型性能分析

动作类型 RT-HMR MPJPE (mm) RPC-HMR MPJPE (mm) 融合 MPJPE (mm)
原地日常 65.2 72.1 52.3
坐姿活动 70.8 78.3 55.6
康复运动 82.5 89.7 65.4
体育运动 95.3 103.2 78.9

发现:坐姿活动误差接近原地日常,体育运动误差显著增大。

IMS OOP 异常姿态检测应用启示

1. 核心映射:M4Human → OOP 检测

2. OOP 检测方案设计

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
import torch
import torch.nn as nn
import numpy as np

class OOPDetectionFromRadar(nn.Module):
"""
基于 mmWave 雷达 HMR 的 OOP 异常姿态检测器

设计思路:
1. 使用 M4Human 预训练 HMR 模型提取 3D 人体姿态
2. 结合座椅参考几何,判断姿态是否异常
3. 输出 OOP 类别和置信度

硬件配置:
| 组件 | 型号 | 参数 |
|------|------|------|
| mmWave 雷达 | Vayyar VSWR-10 或 TI IWR6843AOP | 60-64 GHz, 4Tx/4Rx |
| 处理器 | Qualcomm QCS8255 | Hexagon NPU, 26 TOPS |
| 更新频率 | 30 fps | 端到端推理 |
"""

# OOP 类别定义(对标 Euro NCAP OOP 测试场景)
OOP_CLASSES = {
0: "normal_posture", # 正常坐姿
1: "forward_lean", # 前倾
2: "sideways_lean", # 侧倾
3: "fetal_position", # 蜷缩/胎儿姿势
4: "feet_on_dashboard", # 脚放仪表板
5: "kneeling", # 跪姿
6: "lying_down", # 躺倒
7: "backward_facing", # 反向面朝后
}

def __init__(self, hmr_checkpoint: str = None, num_classes: int = 8):
super().__init__()

# 冻结的 HMR 特征提取器
self.hmr = RadarHMRBaseline(modality="rt")
if hmr_checkpoint:
self.hmr.load_state_dict(torch.load(hmr_checkpoint))
for param in self.hmr.parameters():
param.requires_grad = False

# OOP 分类头
self.classifier = nn.Sequential(
nn.Linear(156 + 10 + 3, 256), # pose + shape + trans
nn.ReLU(),
nn.Dropout(0.3),
nn.Linear(256, 128),
nn.ReLU(),
nn.Dropout(0.2),
nn.Linear(128, num_classes)
)

# 座椅参考几何(标准乘员位置)
self.register_buffer(
'seat_reference',
torch.tensor([
[0.0, 0.0, 0.5], # 头部参考
[0.0, 0.0, 0.2], # 躺椅参考
[0.0, -0.3, 0.1], # 腰部参考
[0.0, -0.5, 0.0], # 臀部参考
[0.0, -0.7, -0.1], # 膝盖参考
[0.0, -0.9, -0.2], # 脚踝参考
])
)

def forward(self, radar_input: torch.Tensor) -> dict:
"""
Args:
radar_input: (B, 1, A, D, R) Raw Tensor

Returns:
output: {
pose: (B, 156) 3D 关节位置,
shape: (B, 10) 体型参数,
trans: (B, 3) 全局平移,
oop_logits: (B, 8) OOP 分类,
oop_class: (B,) 预测类别
}
"""
with torch.no_grad():
hmr_out = self.hmr(radar_input)

# 拼接特征
feat = torch.cat([
hmr_out["pose"],
hmr_out["shape"],
hmr_out["trans"]
], dim=-1)

oop_logits = self.classifier(feat)
oop_class = oop_logits.argmax(dim=-1)

return {
**hmr_out,
"oop_logits": oop_logits,
"oop_class": oop_class
}

def post_to_oop_score(self, pose_3d: torch.Tensor) -> dict:
"""
基于关节 3D 位置直接计算 OOP 风险分数

Args:
pose_3d: (B, 52, 3) 52 个关节的 3D 坐标

Returns:
scores: 各 OOP 风险分数
"""
# 关键关节索引(SMPL-X 子集)
HEAD = 12 # 头部
SHOULDER_L = 2 # 左肩
SHOULDER_R = 5 # 右肩
HIP_L = 12 # 左髋
HIP_R = 15 # 右髋
KNEE_L = 18 # 左膝
KNEE_R = 21 # 右膝
ANKLE_L = 19 # 左踝
ANKLE_R = 22 # 右踝

# 计算姿态指标
# 1. 前倾角度(躯干与垂直方向夹角)
torso_vec = pose_3d[:, HIP_L] - pose_3d[:, SHOULDER_L]
vertical = torch.tensor([0, 0, 1], device=pose_3d.device)
forward_lean_angle = torch.acos(
torch.clamp(
torch.sum(torso_vec * vertical, dim=-1) /
(torch.norm(torso_vec, dim=-1) + 1e-8),
-1, 1
)
)

# 2. 侧倾角度(肩-肩连线与水平面夹角)
shoulder_vec = pose_3d[:, SHOULDER_R] - pose_3d[:, SHOULDER_L]
sideways_angle = torch.atan2(
shoulder_vec[..., 2],
torch.norm(shoulder_vec[..., :2], dim=-1)
)

# 3. 蜷缩检测(膝盖-髋距离)
knee_hip_dist = torch.norm(
pose_3d[:, KNEE_L] - pose_3d[:, HIP_L], dim=-1
)
fetal_score = torch.exp(-knee_hip_dist / 0.2) # 距离越小分数越高

# 4. 脚高度(踝关节 Z 坐标)
feet_height = (pose_3d[:, ANKLE_L, 2] + pose_3d[:, ANKLE_R, 2]) / 2

return {
"forward_lean_deg": torch.degrees(forward_lean_angle),
"sideways_lean_deg": torch.degrees(sideways_angle),
"fetal_score": fetal_score,
"feet_height_m": feet_height,
}


# 测试代码
if __name__ == "__main__":
model = OOPDetectionFromRadar()

# 模拟雷达输入
radar_input = torch.randn(2, 1, 32, 64, 128) # (B, 1, angle, doppler, range)

# 前向推理
with torch.no_grad():
output = model(radar_input)

print("=== OOP 检测结果 ===")
print(f"OOP 类别: {output['oop_class']}")
for cls_idx, cls_name in model.OOP_CLASSES.items():
prob = torch.softmax(output['oop_logits'], dim=-1)[0, cls_idx]
print(f" {cls_name}: {prob:.4f}")

3. OOP 检测测试场景

场景编号 描述 触发条件 检测时限 安全措施
OOP-01 驾驶员前倾 躯干前倾角 > 30° ≤3s 禁用气囊
OOP-02 乘客侧倾 肩-肩角度差 > 25° ≤3s 降低气囊力度
OOP-03 蜷缩/胎儿 膝-髋距离 < 15cm ≤3s 调整气囊展开
OOP-04 脚放仪表板 踝关节高度 > 0.4m ≤2s 禁用前排气囊
OOP-05 跪姿 膝关节高度 > 0.3m ≤3s 警告+气囊调整
OOP-06 躺倒 躯干角度 < 15° ≤3s 禁用气囊
OOP-07 反向面朝后 头部朝向 > 90° ≤3s 警告

4. M4Human → IMS 迁移路线图

关键洞察

1. RT vs RPC:信息保真度决定精度

M4Human 首次在同等条件下对比 RT 和 RPC 模态:

  • RT 比 RPC 低 10mm 误差:Raw Tensor 保留了完整 Range-Doppler-Angle 信息
  • RPC 信息损失严重:CFAR 检测丢失弱反射信号,对坐姿/微动场景影响大
  • IMS 启示:座舱内 OOP 检测应优先使用 RT 模态,而非传统 RPC

2. 坐姿活动性能接近日常活动

动作类型 RT MPJPE (mm) 与日常差异
原地日常 65.2 基准
坐姿活动 70.8 +8.6%
康复运动 82.5 +26.5%
体育运动 95.3 +46.2%

坐姿活动误差仅比日常高 8.6%,说明 mmWave 雷达对坐姿人体重建是可行的。这对车内 OOP 检测意义重大。

3. 多模态融合仍然最优

RT+RGB-D 融合比纯 RT 误差低 20%,但 IMS 场景中:

  • 摄像头受光照影响(夜间失效)
  • 摄像头隐私问题(部分市场限制)
  • 建议路线:白天 RT+RGB-D 融合,夜间纯 RT 降级运行

硬件选型建议

组件 推荐型号 关键参数 价格范围 采购链接
mmWave 雷达 Vayyar VSWR-10 60-69 GHz, 7GHz BW $200-500 Vayyar
mmWave 雷达(替代) TI IWR6843AOP 60-64 GHz, 4GHz BW, 4Tx/4Rx $50-100 TI Store
mmWave 雷达(车规) Infineon BGT60ATR24 60 GHz, 3Tx/4Rx, AEC-Q100 $80-150 Infineon
处理器 Qualcomm QCS8255 Hexagon NPU, 26 TOPS 开发板 $500 Qualcomm
MoCap(标注) OptiTrack Prime 13 2K分辨率, 120fps $5K-15K OptiTrack

开发落地建议

  1. 短期(3 个月):下载 M4Human 数据集,在现有 TI IWR6843AOP 上验证 HMR 基线
  2. 中期(6 个月):采集车内坐姿 mmWave 数据,建立 OOP 标注集,微调 HMR 模型
  3. 长期(12 个月):QCS8255 部署优化,目标推理延迟 <30ms,OOP 检测准确率 >90%
  4. 验收标准:
    • OOP-01 前倾检测:召回率 >95%,误报率 <5%
    • OOP-03 蜷缩检测:召回率 >90%,误报率 <3%
    • 端到端延迟:≤3s(Euro NCAP 要求)
    • 模型大小:<10MB(量化后)
    • 功耗:<2W(NPU 推理)

参考文献

  1. Fan et al., “M4Human: A Large-Scale Multimodal mmWave Radar Benchmark for Human Mesh Reconstruction,” CVPR 2026. arXiv
  2. M4Human GitHub: https://github.com/FanJunqiao/M4Human
  3. M4Human 项目页: https://fanjunqiao.github.io/M4Human-site/
  4. mmBody: Prior largest RF-based HMR dataset (pre-M4Human)
  5. Euro NCAP 2026 Protocol: OOP testing requirements
  6. TI IWR6843AOP Datasheet: https://www.ti.com/product/IWR6843AOP
  7. Vayyar VSWR-10: https://vayyar.com/automotive/

本文基于 CVPR 2026 论文 M4Human 深度解读,结合 IMS OOP 异常姿态检测需求给出落地分析。代码示例可直接运行验证。