RePos:跨环境WiFi 3D人体姿态估计新方法

RePos:跨环境WiFi 3D人体姿态估计新方法

论文信息

  • 标题: RePos: Relative-to-Absolute Pose Factorization for Cross-Environment WiFi-Based 3D Human Pose Estimation
  • 发表: arXiv 2025
  • 链接: https://arxiv.org/html/2607.02986

研究背景

传统人体姿态估计依赖摄像头,但在车内监控场景面临挑战:

  • 隐私问题(车内摄像头)
  • 光照敏感(夜间/强光)
  • 视角限制(侧身/后排)

WiFi CSI(信道状态信息)信号可穿透障碍物,不依赖光照,为车内乘员姿态估计提供了新思路。

核心创新

问题定义

WiFi CSI 信号中人体位置与姿态高度耦合,导致跨环境泛化困难。RePos 提出姿态-位置解耦框架

1
2
传统方法:CSI → 混合特征 → 绝对姿态(过拟合位置)
RePos方法:CSI → 相对姿态 + 位置估计 → 绝对姿态

核心架构

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

class RePosNet(nn.Module):
"""RePos: 相对-绝对姿态分解网络"""

def __init__(self,
num_joints: int = 17,
hidden_dim: int = 256):
super().__init__()

# CSI 特征编码器
self.csi_encoder = nn.Sequential(
nn.Conv1d(1, 64, kernel_size=7, padding=3),
nn.BatchNorm1d(64),
nn.ReLU(inplace=True),
nn.Conv1d(64, 128, kernel_size=5, padding=2),
nn.BatchNorm1d(128),
nn.ReLU(inplace=True),
nn.Conv1d(128, hidden_dim, kernel_size=3, padding=1),
nn.BatchNorm1d(hidden_dim),
nn.ReLU(inplace=True),
)

# 相对姿态估计分支
self.pose_head = nn.Sequential(
nn.Linear(hidden_dim, 512),
nn.ReLU(inplace=True),
nn.Dropout(0.3),
nn.Linear(512, num_joints * 3) # 17 关键点 × 3D坐标
)

# 根节点位置估计分支
self.root_head = nn.Sequential(
nn.Linear(hidden_dim, 256),
nn.ReLU(inplace=True),
nn.Linear(256, 3) # 根节点 3D 位置
)

# 跨环境适配层
self.environment_adapter = nn.Sequential(
nn.Linear(hidden_dim, 128),
nn.ReLU(inplace=True),
nn.Linear(128, hidden_dim),
nn.Tanh() # 环境无关特征
)

def forward(self, csi_signal):
"""
Args:
csi_signal: WiFi CSI 信号 (B, 1, N)
N = 发射天线 × 接收天线 × 子载波数

Returns:
pose_3d: 绝对 3D 姿态 (B, 17, 3)
root_pos: 根节点位置 (B, 3)
"""
# 编码 CSI 特征
csi_feat = self.csi_encoder(csi_signal) # (B, hidden_dim, N)
global_feat = csi_feat.mean(dim=2) # Global Average Pooling

# 环境无关特征
adapted_feat = self.environment_adapter(global_feat)

# 相对姿态估计
relative_pose = self.pose_head(adapted_feat) # (B, 51)
relative_pose = relative_pose.view(-1, 17, 3)

# 根节点位置估计
root_pos = self.root_head(adapted_feat) # (B, 3)

# 组合为绝对姿态
absolute_pose = relative_pose + root_pos.unsqueeze(1)

return absolute_pose, root_pos


class RePosTrainer:
"""RePos 训练器"""

def __init__(self, model, config):
self.model = model
self.optimizer = torch.optim.AdamW(model.parameters(), lr=1e-4)
self.pose_weight = config.get('pose_weight', 1.0)
self.root_weight = config.get('root_weight', 0.5)

def compute_loss(self, pred_pose, pred_root, gt_pose, gt_root):
"""
计算损失函数

Args:
pred_pose: 预测姿态 (B, 17, 3)
pred_root: 预测根节点 (B, 3)
gt_pose: 真实姿态 (B, 17, 3)
gt_root: 真实根节点 (B, 3)
"""
# 姿态损失(相对姿态)
relative_gt = gt_pose - gt_root.unsqueeze(1)
relative_pred = pred_pose - pred_root.unsqueeze(1)
pose_loss = F.mse_loss(relative_pred, relative_gt)

# 根节点位置损失
root_loss = F.mse_loss(pred_root, gt_root)

# 总损失
total_loss = self.pose_weight * pose_loss + self.root_weight * root_loss

return total_loss, {'pose_loss': pose_loss.item(),
'root_loss': root_loss.item()}

WiFi CSI 信号处理

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

class CSIPreprocessor:
"""WiFi CSI 信号预处理器"""

def __init__(self,
tx_antennas: int = 3,
rx_antennas: int = 3,
subcarriers: int = 30):
self.tx = tx_antennas
self.rx = rx_antennas
self.subcarriers = subcarriers

def extract_csi(self, raw_packet) -> np.ndarray:
"""
从原始数据包提取 CSI

Args:
raw_packet: WiFi 数据包

Returns:
csi_matrix: CSI 矩阵 (tx, rx, subcarriers)
"""
# 这里简化处理,实际需要根据硬件解析
# Intel CSI Tool / Atheros CSI Tool 等格式不同
csi = np.zeros((self.tx, self.rx, self.subcarriers), dtype=complex)

# 提取幅度和相位
amplitude = np.abs(csi)
phase = np.angle(csi)

return amplitude, phase

def denoise_csi(self, csi: np.ndarray) -> np.ndarray:
"""
CSI 信号去噪

Args:
csi: 原始 CSI 信号

Returns:
denoised: 去噪后的 CSI
"""
# PCA 降维去噪
from sklearn.decomposition import PCA

# 展平为 2D
csi_flat = csi.reshape(-1, csi.shape[-1])

pca = PCA(n_components=0.95) # 保留 95% 方差
denoised_flat = pca.inverse_transform(pca.fit_transform(csi_flat))

denoised = denoised_flat.reshape(csi.shape)

return denoised

def compute_doppler_features(self, csi_sequence: np.ndarray) -> np.ndarray:
"""
计算 Doppler 特征(用于检测运动)

Args:
csi_sequence: CSI 时间序列 (T, tx, rx, subcarriers)

Returns:
doppler_features: Doppler 特征图
"""
# 时域差分
delta = np.diff(csi_sequence, axis=0)

# 功率谱密度
doppler = np.abs(delta) ** 2

# 时间积分
doppler_features = doppler.mean(axis=0)

return doppler_features

实验结果

Person-in-WiFi-3D 数据集

方法 MPJPE (mm) P-MPJPE (mm) 跨环境泛化
DT-Pose 78.2 65.3
RePos-D (直接) 75.5 62.1 中等
RePos 72.8 58.9

车内场景测试

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
class InCabinPoseEstimator:
"""车内姿态估计器"""

def __init__(self, config: dict):
# WiFi CSI 接收器
self.csi_receiver = self._init_csi_hardware(
config.get('wifi_interface', 'wlan0')
)

# RePos 模型
self.pose_model = RePosNet(num_joints=17)
self.pose_model.load_state_dict(
torch.load(config['model_path'])
)

# 坐标系转换(WiFi → 车内坐标)
self.calibration_matrix = self._load_calibration(
config['calibration_file']
)

def estimate_pose(self, window_sec: float = 1.0) -> dict:
"""
估计当前乘员姿态

Args:
window_sec: 时间窗口(秒)

Returns:
result: {
'pose_3d': np.ndarray (17, 3),
'root_position': np.ndarray (3,),
'confidence': float
}
"""
# 采集 CSI 信号
csi_sequence = self.csi_receiver.collect(window_sec)

# 预处理
csi_tensor = self._preprocess_csi(csi_sequence)

# 推理
with torch.no_grad():
pose_3d, root_pos = self.pose_model(csi_tensor)

# 坐标转换
pose_vehicle = self._transform_to_vehicle(pose_3d)

return {
'pose_3d': pose_vehicle.numpy(),
'root_position': root_pos.numpy(),
'confidence': self._compute_confidence(csi_sequence)
}

def detect_oop(self, pose_3d: np.ndarray) -> str:
"""
检测异常姿态(OOP - Out of Position)

Args:
pose_3d: 3D 姿态 (17, 3)

Returns:
oop_status: 'normal' | 'lean_forward' | 'recline' | 'stand'
"""
# 提取关键姿态角度
torso_angle = self._compute_torso_angle(pose_3d)
head_position = pose_3d[0] # 头部关键点

# 判断姿态
if torso_angle > 30: # 前倾超过30度
return 'lean_forward'
elif torso_angle < -20: # 后仰超过20度
return 'recline'
elif head_position[2] > 0.5: # 头部高度异常
return 'stand'
else:
return 'normal'

IMS 开发启示

1. 技术路线对比

方案 优势 劣势 适用场景
摄像头姿态估计 精度高、可视化 光照敏感、隐私问题 驾驶员监控
压力传感器 直接、可靠 接触式、标定复杂 座椅占用检测
WiFi CSI 姿态 隐私友好、全光照 精度待提升 后排乘员监控

2. Euro NCAP OOP 检测建议

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# OOP 检测场景定义
OOP_SCENARIOS = {
'lean_forward': {
'description': '驾驶员前倾',
'trigger': 'torso_angle > 30°',
'threshold': 30, # 度
'warning_level': 1,
},
'recline_excessive': {
'description': '座椅过度后仰',
'trigger': 'torso_angle < -25°',
'threshold': -25,
'warning_level': 2,
},
'unbuckled_movement': {
'description': '未系安全带时身体移动',
'trigger': 'pose_variance > 0.1 AND seatbelt == False',
'threshold': 0.1,
'warning_level': 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
class OMSController:
"""OMS 控制器"""

def __init__(self, config):
# 多模态传感器融合
self.wifi_pose = InCabinPoseEstimator(config['wifi'])
self.camera_pose = CameraPoseEstimator(config['camera'])
self.seat_pressure = PressureSensorReader(config['pressure'])

# 融合权重
self.weights = {
'wifi': 0.4,
'camera': 0.4,
'pressure': 0.2
}

def get_fused_pose(self):
"""获取融合后的姿态估计"""
# WiFi 姿态
wifi_result = self.wifi_pose.estimate_pose()

# 摄像头姿态(如有)
camera_result = self.camera_pose.estimate_pose() if self.camera_available else None

# 压力传感器
pressure_data = self.seat_pressure.read()

# 加权融合
if camera_result:
fused_pose = (
self.weights['wifi'] * wifi_result['pose_3d'] +
self.weights['camera'] * camera_result['pose_3d']
)
else:
fused_pose = wifi_result['pose_3d']

return fused_pose

硬件需求

组件 型号 参数 用途
WiFi 收发器 Intel 5300 3×3 MIMO CSI 采集
SDR 板卡 USRP N210 20 MHz 带宽 高精度 CSI
车载 WiFi Qualcomm QCA6390 WiFi 6 低成本方案

总结

RePos 通过姿态-位置解耦,解决了 WiFi CSI 姿态估计的跨环境泛化问题,为车内乘员监控提供了隐私友好的技术方案。结合摄像头和压力传感器的多模态融合,可满足 Euro NCAP 2026 OOP 检测要求。


参考链接:


RePos:跨环境WiFi 3D人体姿态估计新方法
https://dapalm.com/2026/07/24/2026-07-24-repos-wifi-3d-pose-estimation/
作者
Mars
发布于
2026年7月24日
许可协议