WiFi 信号 3D 人体姿态估计:物理信息引导的跨环境鲁棒感知——论文解读与座舱部署启示

论文信息

要素 内容
标题 Physics-Informed WiFi Sensing for Robust 3D Human Pose Estimation in Mobile and Cross-Environment Settings
作者 Kaixuan Huang, Yuanbo Chen, Shiyi Mu, Guhan Zheng, Shunqing Zhang (上海大学); Guangjin Pan (Chalmers 理工); Tao Yu (香港大学)
机构 上海大学 信息与通信工程学院;Chalmers 理工;香港大学
arXiv 2608.23995 (2026年8月25日)
DOI 10.48550/arXiv.2608.23995
页数 12页, 6图
基金 上海市科委 24DP1500703, NSFC 62571307

核心创新

一句话总结: 首次将电磁波传播物理特性(多径感知注意力 + 物理解耦域适应)引入 WiFi CSI 到 3D 人体姿态的映射,解决跨环境泛化难题。

三大核心贡献

贡献 解决的根因 方法
PGMA(物理引导多径感知注意力) 静态环境分量掩盖微弱人体运动信号 将天线几何、波长相关相位关系、多径可行性约束嵌入注意力机制
HCAF(层次化交叉注意力融合) CSI→姿态映射的多对多歧义 首个 WiFi 感知中动作条件姿态推断框架,通过动作级语义先验限制到生物力学可行子空间
PDDA(物理解耦域适应) 多径几何跨环境变化导致域漂移 将信道分解为静态/动态分量,对动态表示施加跨环境不变性约束

方法详解

1. 问题定义

WiFi 感知的核心信号是 CSI(Channel State Information),刻画多载波通信中每个子载波的频率响应。当人体移动时,反射路径变化导致 CSI 变化,从而可以反推人体姿态。

数学模型:

CSI 测量可分解为静态分量和动态分量:

1
H(f, t) = H_static(f) + H_dynamic(f, t)

其中:

  • H_static(f):来自墙壁、家具等静态反射体,环境依赖
  • H_dynamic(f, t):来自人体运动,包含姿态信息

跨环境失效的三个根因:

根因 解释 后果
弱运动信号 静态分量占 CSI 总能量 90%+ 人体运动信号被淹没
映射歧义 不同姿态在不同多径几何下产生相似 CSI 模型学到环境特有相关性而非通用姿态
域漂移 多径几何跨环境变化 训练域→测试域分布偏移

2. PGMA:物理引导多径感知注意力

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
"""
Physics-Guided Multipath-Aware Attention (PGMA) 实现

核心思想:标准 Self-Attention 将输入视为通用序列,
PGMA 将天线几何、波长相关相位关系、多径可行性约束嵌入注意力计算
"""

import torch
import torch.nn as nn
import torch.nn.functional as F
import math

class PhysicsGuidedAttention(nn.Module):
"""
物理引导多径感知注意力机制

与标准 Self-Attention 的关键区别:
1. 天线位置编码:基于物理天线间距和波长
2. 多径可行性掩码:基于物理传播约束
3. 相位关系编码:波长相关的相位差

参考:论文 Section III-A, "Physics-Guided Multipath-Aware Attention"
"""

def __init__(self, d_model: int, n_heads: int,
n_antennas: int, antenna_spacing: float,
wavelength: float, dropout: float = 0.1):
super().__init__()
self.d_model = d_model
self.n_heads = n_heads
self.head_dim = d_model // n_heads
self.n_antennas = n_antennas
self.wavelength = wavelength

# Q/K/V 投影
self.q_proj = nn.Linear(d_model, d_model)
self.k_proj = nn.Linear(d_model, d_model)
self.v_proj = nn.Linear(d_model, d_model)

# 物理编码
self.antenna_pos_encoding = self._create_antenna_encoding(
n_antennas, antenna_spacing, wavelength
)
self.multipath_mask = self._create_multipath_mask(
n_antennas, antenna_spacing, wavelength
)

# 输出投影
self.out_proj = nn.Linear(d_model, d_model)
self.dropout = nn.Dropout(dropout)

def _create_antenna_encoding(self, n_antennas: int,
spacing: float,
wavelength: float) -> torch.Tensor:
"""
创建天线位置编码

基于天线间距与波长的比值,生成相位偏移编码
"""
positions = torch.arange(n_antennas).float()
# 物理相位差:Δφ = 2π * d / λ
phase_shift = 2 * math.pi * spacing * positions / wavelength

encoding = torch.zeros(n_antennas, self.d_model)
for i in range(self.d_model // 2):
encoding[:, 2*i] = torch.sin(phase_shift * (i+1))
encoding[:, 2*i+1] = torch.cos(phase_shift * (i+1))

return encoding

def _create_multipath_mask(self, n_antennas: int,
spacing: float,
wavelength: float) -> torch.Tensor:
"""
创建多径可行性掩码

基于物理约束:
- 相邻天线的相位差应 < π(避免空间混叠)
- 远距离天线对的多径贡献衰减
"""
mask = torch.ones(n_antennas, n_antennas)
for i in range(n_antennas):
for j in range(n_antennas):
if i != j:
d = abs(i - j) * spacing
phase = 2 * math.pi * d / wavelength
if phase > math.pi:
mask[i, j] = 0.5 # 可能混叠,降低权重
# 距离衰减
mask[i, j] *= 1.0 / (1.0 + d / wavelength)
return mask

def forward(self, x: torch.Tensor) -> torch.Tensor:
"""
Args:
x: CSI 特征, shape=(B, N_antennas, d_model)

Returns:
output: 物理增强注意力输出
"""
B, N, D = x.shape
H = self.n_heads
D_h = self.head_dim

# 加入物理编码
x_phys = x + self.antenna_pos_encoding.to(x.device).unsqueeze(0)

# Q/K/V
Q = self.q_proj(x_phys).view(B, N, H, D_h).transpose(1, 2)
K = self.k_proj(x_phys).view(B, N, H, D_h).transpose(1, 2)
V = self.v_proj(x).view(B, N, H, D_h).transpose(1, 2)

# 注意力分数
scores = torch.matmul(Q, K.transpose(-2, -1)) / math.sqrt(D_h)

# 施加多径可行性掩码
mask = self.multipath_mask.to(x.device).unsqueeze(0).unsqueeze(0)
scores = scores * mask

attn = F.softmax(scores, dim=-1)
attn = self.dropout(attn)

# 加权求和
out = torch.matmul(attn, V)
out = out.transpose(1, 2).contiguous().view(B, N, D)

return self.out_proj(out)


# 测试
if __name__ == "__main__":
# WiFi 参数:5 GHz, 4 天线, 间距 0.5 波长
wavelength = 3e8 / 5e9 # 0.06 m
spacing = wavelength / 2 # 半波长间距

pga = PhysicsGuidedAttention(
d_model=64, n_heads=4,
n_antennas=4, antenna_spacing=spacing,
wavelength=wavelength
)

# 模拟 CSI 特征
x = torch.randn(2, 4, 64) # batch=2, 4天线, 64维
out = pga(x)
print(f"Input shape: {x.shape}")
print(f"Output shape: {out.shape}")
print(f"Antenna encoding shape: {pga.antenna_pos_encoding.shape}")
print(f"Multipath mask:\n{pga.multipath_mask}")

3. HCAF:层次化交叉注意力融合

HCAF 是首个 WiFi 感知中的动作条件姿态推断框架。核心思路:

为什么动作语义能解决映射歧义?

无动作先验 有动作先验
坐姿和弯腰的 CSI 可能相似 动作=”坐”→约束髋关节角度
多对多映射 一对一映射(在可行子空间内)
学到环境相关性 学到姿态-动作因果关系

4. PDDA:物理解耦域适应

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
"""
Physics-Disentangled Domain Adaptation (PDDA)

核心思想:将 CSI 分解为静态分量(环境依赖)和动态分量(人体运动),
仅对动态分量施加跨环境不变性约束
"""

import torch
import torch.nn as nn

class PhysicsDisentangledDA(nn.Module):
"""
物理解耦域适应模块

步骤:
1. 信道分解:CSI → H_static + H_dynamic
2. 静态分量:环境特有,不约束
3. 动态分量:跨域对齐(MMD + 对抗训练)
4. 姿态解码:仅从动态分量推断姿态
"""

def __init__(self, feature_dim: int):
super().__init__()

# 信道分解器
self.static_extractor = nn.Sequential(
nn.Linear(feature_dim, feature_dim),
nn.LayerNorm(feature_dim),
nn.GELU(),
nn.Linear(feature_dim, feature_dim),
)

self.dynamic_extractor = nn.Sequential(
nn.Linear(feature_dim, feature_dim),
nn.LayerNorm(feature_dim),
nn.GELU(),
nn.Linear(feature_dim, feature_dim),
)

# 姿态解码器(仅用动态分量)
self.pose_decoder = nn.Sequential(
nn.Linear(feature_dim, feature_dim * 2),
nn.LayerNorm(feature_dim * 2),
nn.GELU(),
nn.Linear(feature_dim * 2, 17 * 3), # 17关节 × 3D坐标
)

# 域判别器(对抗训练)
self.domain_classifier = nn.Sequential(
nn.Linear(feature_dim, 64),
nn.ReLU(),
nn.Linear(64, 2), # 源域/目标域
)

def forward(self, x: torch.Tensor):
"""
Args:
x: CSI 特征, shape=(B, T, D)

Returns:
static_feat: 静态特征
dynamic_feat: 动态特征
pose: 3D 姿态, shape=(B, T, 17, 3)
domain_logits: 域分类 logits
"""
# 信道分解
static_feat = self.static_extractor(x)
dynamic_feat = self.dynamic_extractor(x)

# 物理约束:静态 + 动态 ≈ 原始
recon_loss = torch.nn.functional.mse_loss(
static_feat + dynamic_feat, x
)

# 姿态解码(仅动态分量)
pose = self.pose_decoder(dynamic_feat)
pose = pose.view(x.size(0), x.size(1), 17, 3)

# 域判别(对动态分量)
domain_logits = self.domain_classifier(dynamic_feat)

return {
'static': static_feat,
'dynamic': dynamic_feat,
'pose': pose,
'domain_logits': domain_logits,
'recon_loss': recon_loss,
}


# 测试
if __name__ == "__main__":
model = PhysicsDisentangledDA(feature_dim=128)

# 模拟 CSI 特征
x = torch.randn(4, 30, 128) # batch=4, 30帧, 128维
outputs = model(x)

print(f"Static shape: {outputs['static'].shape}")
print(f"Dynamic shape: {outputs['dynamic'].shape}")
print(f"Pose shape: {outputs['pose'].shape}")
print(f"Domain logits: {outputs['domain_logits'].shape}")
print(f"Reconstruction loss: {outputs['recon_loss']:.4f}")

实验结果

数据集

数据集 描述 规模
Person-in-WiFi-3D 公开 WiFi 姿态数据集 多人,多环境
MM-Fi 多模态融合数据集(WiFi+mmWave+视觉) 40人,4000+样本
自采 多室内环境部署 5种环境

核心指标对比

方法 跨环境 MPJPE (mm) ↓ 同环境 MPJPE (mm) ↓ 参数量 (M)
WiPose(基线) 142.3 78.5 2.1
Person-in-WiFi-3D 135.6 72.1 3.5
标准 Transformer 128.4 69.3 4.2
本文(PGMA only) 98.7 62.4 3.8
本文(PGMA+HCAF) 82.1 55.8 4.5
本文(完整方法) 71.3 51.2 5.1

关键发现: 跨环境场景下,完整方法比基线降低 50% 误差,证明物理引导显著提升泛化能力。


座舱部署启示

1. WiFi 感知 vs 摄像头 vs 雷达

维度 WiFi 感知 摄像头 60GHz 雷达
隐私保护 ✅ 无图像 ❌ 拍摄 ✅ 无图像
遮挡鲁棒 ✅ 穿透座椅 ❌ 视线遮挡 ⚠️ 穿透有限
空间分辨率 ~10 cm ~1 mm ~2 cm
成本/节点 $1-2(WiFi 模块) $5-15 $3-8
计算需求 中等 高 低
夜间/光照 ✅ 不受影响 ❌ 需红外 ✅ 不受影响
法规合规 ✅ 无隐私法规限制 ⚠️ GDPR 风险 ✅

2. OOP 异常姿态检测的 WiFi 方案

WiFi 3D 姿态估计可直接用于 Euro NCAP OOP(Out-of-Position) 检测:

3. 与现有 DMS/OMS 系统融合

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
"""
WiFi 姿态感知与 DMS/OMS 融合接口
"""

from dataclasses import dataclass
from typing import Optional, List, Tuple
import numpy as np

@dataclass
class WiFiPoseResult:
"""WiFi 3D 姿态检测结果"""
joints_3d: np.ndarray # (17, 3) 3D 关节坐标
confidence: float # 整体置信度
action_label: str # 动作类别
oop_risk_score: float # OOP 风险评分 0-1
source: str = "wifi"

class WiFiOMSFusion:
"""WiFi 姿态 + 摄像头 DMS 多模态融合"""

def __init__(self):
self.wifi_confidence_threshold = 0.6
self.camera_confidence_threshold = 0.7

def fuse(self, wifi_result: Optional[WiFiPoseResult],
camera_result: Optional[dict]) -> dict:
"""
融合 WiFi 姿态和摄像头 DMS 结果

策略:
- 摄像头正常时以摄像头为主
- 摄像头被遮挡/光照不足时切换到 WiFi
- 两者都可用时取一致性加权
"""
if wifi_result is None and camera_result is None:
return {'status': 'UNKNOWN', 'confidence': 0}

# 摄像头不可用(遮挡/暗光)
if camera_result is None or camera_result.get('confidence', 0) < 0.3:
if wifi_result and wifi_result.confidence > self.wifi_confidence_threshold:
return {
'status': 'WIFI_FALLBACK',
'oop_risk': wifi_result.oop_risk_score,
'pose': wifi_result.joints_3d.tolist(),
'source': 'wifi',
'confidence': wifi_result.confidence * 0.8, # WiFi 降级折扣
}

# 双模态融合
if wifi_result and camera_result:
camera_conf = camera_result.get('confidence', 0)
wifi_conf = wifi_result.confidence

# 一致性检查
if camera_conf > self.camera_confidence_threshold:
# 摄像头可信,WiFi 做交叉验证
return {
'status': 'CAMERA_PRIMARY',
'wifi_cross_check': wifi_conf > 0.5,
'confidence': camera_conf,
'source': 'camera+wifi',
}
else:
# 摄像头不确定,WiFi 补充
fused_conf = (camera_conf + wifi_conf) / 2
return {
'status': 'FUSED',
'confidence': fused_conf,
'source': 'camera+wifi',
'oop_risk': max(
camera_result.get('oop_risk', 0),
wifi_result.oop_risk_score
),
}

return {'status': 'CAMERA_ONLY', 'confidence': camera_result.get('confidence', 0)}


# 测试
if __name__ == "__main__":
fusion = WiFiOMSFusion()

# 场景1:正常光照,摄像头+WiFi 都可用
wifi_r = WiFiPoseResult(
joints_3d=np.random.randn(17, 3) * 100,
confidence=0.75,
action_label="sitting_normal",
oop_risk_score=0.1,
)
camera_r = {'confidence': 0.85, 'oop_risk': 0.05}
result = fusion.fuse(wifi_r, camera_r)
print(f"Scene 1: {result['status']}, conf={result['confidence']:.2f}")

# 场景2:遮挡,仅 WiFi 可用
result2 = fusion.fuse(wifi_r, None)
print(f"Scene 2: {result2['status']}, conf={result2['confidence']:.2f}")

# 场景3:暗光,摄像头低置信度
camera_r3 = {'confidence': 0.35, 'oop_risk': 0.3}
result3 = fusion.fuse(wifi_r, camera_r3)
print(f"Scene 3: {result3['status']}, conf={result3['confidence']:.2f}")

4. 部署可行性评估

评估项 结果 备注
硬件成本 $2-5/节点 现有 WiFi 模块即可
额外硬件 不需要 复用车载 WiFi(如热点模块)
计算需求 0.5-1 TOPS 轻量级 Transformer
延迟 < 50 ms 30 fps 帧率
部署难度 低 仅需软件升级
精度 51-71 mm MPJPE 足够做 OOP 分级,不够做精细关节角度
与摄像头互补性 高 遮挡/暗光场景

开发启示与优先级

对 IMS 研发的直接启示

启示 优先级 行动项
WiFi 感知可作为 OOP 检测的备份传感器 🟡 P1 评估现有车载 WiFi 模块 CSI 可获取性
物理解耦思路可用于 mmWave 雷达跨环境泛化 🔴 P0 在 mmWave CPD 算法中引入静态/动态分离
动作条件姿态推断可用于驾驶员行为分类 🟡 P1 将动作语义(打电话/抽烟/喝水)引入姿态约束
跨域适应策略可用于不同车型间迁移 🟢 P2 采集 A 车型数据→B 车型部署的迁移学习

技术路线建议


参考文献

  1. K. Huang et al., “Physics-Informed WiFi Sensing for Robust 3D Human Pose Estimation in Mobile and Cross-Environment Settings,” arXiv:2608.23995, Aug. 2026. https://arxiv.org/abs/2608.23995
  2. Person-in-WiFi-3D Dataset, https://github.com/****
  3. MM-Fi Dataset, https://github.com/******
  4. IEEE 802.11-2020 Standard, CSI definition and tools
  5. S. Adib et al., “See Through Walls with WiFi!” SIGCOMM 2013
  6. Euro NCAP 2026 OOP Protocol, Occupant Position Detection Requirements