DoRF++:把 NeRF 理念搬进 WiFi CSI——多普勒辐射场驱动的座舱占用感知新范式

IEEE 802.11bf 正在标准化 WiFi 感知,CSI(Channel State Information)成为替代摄像头的隐私友好方案。DoRF++ 首次将 NeRF 的神经辐射场概念引入 WiFi 感知,把多普勒速度投影建模为”虚拟相机视图”,用球面 Transformer 实现跨用户泛化。

论文信息

项目 内容
标题 DoRF++: Spherical Representation Learning over Doppler Radiance Fields for Robust Wi-Fi Sensing
arXiv 2608.08381
提交日期 2026-08-09
领域 cs.CV, eess.SP
关键词 WiFi CSI, Doppler radiance fields, NeRF, spherical Transformer, HAR

核心创新

1. 多普勒辐射场 (DoRF)

将 WiFi CSI 中提取的多普勒速度投影建模为虚拟相机视图:

1
2
WiFi CSI → 多普勒速度投影 → 稀疏/多样的"虚拟视图" → 
DoRF 推断潜在 3D 运动序列 → 球面表征 → 球面 Transformer 分类

2. 球面学习设计

将运动序列投影到单位球面上的等角网格,用球面 Transformer 处理:

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
"""
DoRF++ 核心实现

论文核心思路:
1. 从 CSI 提取多普勒速度投影
2. 将投影视为虚拟相机对 3D 运动的观测
3. 用 NeRF 思想从多视图重建潜在 3D 运动
4. 将重建运动投影到球面等角网格
5. 球面 Transformer 进行动作分类
"""

import torch
import torch.nn as nn
import numpy as np
from typing import Tuple, Optional

class DopplerProjectionExtractor(nn.Module):
"""
从 WiFi CSI 提取多普勒速度投影

CSI → 时频分析 → 多普勒频移 → 速度投影
每个收发天线对提供一个投影方向
"""

def __init__(self, num_tx: int = 1, num_rx: int = 3, num_subcarriers: int = 56):
super().__init__()
self.num_tx = num_tx
self.num_rx = num_rx
self.num_subcarriers = num_subcarriers
self.num_views = num_tx * num_rx # 虚拟视图数

# CSI → 多普勒的 FFT 变换
self.doppler_fft_size = 64

def forward(self, csi: torch.Tensor) -> torch.Tensor:
"""
Args:
csi: (B, T, num_tx, num_rx, num_subcarriers)

Returns:
doppler_projections: (B, num_views, T_doppler)
"""
B, T, tx, rx, S = csi.shape

# CSI 时频变换 → 多普勒速度
# 对时间维度做 FFT 得到多普勒频移
doppler = torch.fft.fft(csi, n=self.doppler_fft_size, dim=1)
doppler = torch.abs(doppler) # 幅度谱

# 每个收发对一个投影
doppler = doppler.view(B, tx * rx, -1, S) # (B, views, T_doppler, S)

# 沿子载波维度聚合
doppler = doppler.mean(dim=-1) # (B, views, T_doppler)

return doppler


class DopplerRadianceField(nn.Module):
"""
多普勒辐射场 (DoRF)

借鉴 NeRF 思想:
- 输入:多个多普勒投影(虚拟视图)
- 输出:潜在 3D 运动序列

DoRF(M) = {(d_i, v_i)} where d_i 是方向, v_i 是多普勒观测
"""

def __init__(
self,
num_views: int = 3,
latent_dim: int = 256,
motion_dim: int = 3, # 3D 运动序列
num_harmonics: int = 16
):
super().__init__()
self.num_views = num_views
self.latent_dim = latent_dim
self.motion_dim = motion_dim
self.num_harmonics = num_harmonics

# 方向编码(球谐函数)
self.direction_encoder = nn.Sequential(
nn.Linear(2 * num_harmonics, latent_dim), # 球谐展开
nn.GELU(),
nn.Linear(latent_dim, latent_dim)
)

# 多普勒观测编码
self.doppler_encoder = nn.Sequential(
nn.Linear(1, latent_dim // 2),
nn.GELU(),
nn.Linear(latent_dim // 2, latent_dim)
)

# 运动 field MLP
self.motion_mlp = nn.Sequential(
nn.Linear(latent_dim * 2, latent_dim),
nn.GELU(),
nn.Linear(latent_dim, latent_dim),
nn.GELU(),
nn.Linear(latent_dim, motion_dim + 1) # 3D运动 + 密度
)

def forward(
self,
doppler_projections: torch.Tensor, # (B, V, T_d)
directions: torch.Tensor # (V, 2) 方位角+仰角
) -> torch.Tensor:
"""
Returns:
motion_3d: (B, motion_dim, T_d) 潜在3D运动
"""
B, V, T_d = doppler_projections.shape

# 方向编码
dir_emb = self.direction_encoder(directions) # (V, latent_dim)

# 多普勒编码
dop_emb = self.doppler_encoder(
doppler_projections.unsqueeze(-1)
) # (B, V, T_d, latent_dim)

# 融合
dir_emb = dir_emb.unsqueeze(0).unsqueeze(2) # (1, V, 1, latent_dim)
fused = torch.cat([dop_emb, dir_emb.expand_as(dop_emb)], dim=-1)

# 运动 field
output = self.motion_mlp(fused) # (B, V, T_d, motion_dim+1)
motion = output[..., :self.motion_dim] # (B, V, T_d, 3)
density = output[..., self.motion_dim:] # (B, V, T_d, 1)

# 加权聚合
weights = torch.softmax(density, dim=1) # 沿视图维度
motion_3d = (motion * weights).sum(dim=1) # (B, T_d, 3)

return motion_3d


class SphericalProjection(nn.Module):
"""
将 3D 运动序列投影到球面等角网格

球面坐标: (θ, φ) → 筃角网格 (H_grid × W_grid)
"""

def __init__(self, grid_height: int = 32, grid_width: int = 64):
super().__init__()
self.H = grid_height
self.W = grid_width

# 预计算球面网格
theta = torch.linspace(0, np.pi, grid_height)
phi = torch.linspace(0, 2 * np.pi, grid_width)
theta, phi = torch.meshgrid(theta, phi, indexing='ij')

# 球面 → 笛卡尔
x = torch.sin(theta) * torch.cos(phi)
y = torch.sin(theta) * torch.sin(phi)
z = torch.cos(theta)

self.register_buffer('grid_3d', torch.stack([x, y, z], dim=-1))

def forward(self, motion_3d: torch.Tensor) -> torch.Tensor:
"""
Args:
motion_3d: (B, T, 3)
Returns:
spherical_map: (B, T, H, W)
"""
B, T, _ = motion_3d.shape

# 计算运动方向在球面上的投影
motion_norm = motion_3d / (torch.norm(motion_3d, dim=-1, keepdim=True) + 1e-8)

# 球面映射
spherical_map = torch.zeros(B, T, self.H, self.W)
for b in range(B):
for t in range(T):
d = motion_norm[b, t]
# 找最近网格点
dist = torch.norm(self.grid_3d - d, dim=-1)
idx = torch.argmin(dist.view(-1))
i, j = idx // self.W, idx % self.W
spherical_map[b, t, i, j] = torch.norm(motion_3d[b, t])

return spherical_map


class SphericalTransformer(nn.Module):
"""
球面 Transformer 用于动作分类

在球面上做注意力计算,保持旋转等变性
"""

def __init__(
self,
grid_height: int = 32,
grid_width: int = 64,
embed_dim: int = 256,
num_heads: int = 8,
num_layers: int = 4,
num_classes: int = 10
):
super().__init__()
self.H = grid_height
self.W = grid_width

# 输入投影
self.input_proj = nn.Conv2d(1, embed_dim, kernel_size=3, padding=1)

# 球面位置编码
self.pos_embed = nn.Parameter(
torch.randn(1, embed_dim, grid_height, grid_width) * 0.02
)

# Transformer 层
encoder_layer = nn.TransformerEncoderLayer(
d_model=embed_dim * grid_width,
nhead=num_heads,
dim_feedforward=embed_dim * 4,
batch_first=True
)
self.transformer = nn.TransformerEncoder(encoder_layer, num_layers)

# 分类头
self.cls_head = nn.Sequential(
nn.Linear(embed_dim * grid_width, embed_dim),
nn.GELU(),
nn.Linear(embed_dim, num_classes)
)

def forward(self, spherical_map: torch.Tensor) -> torch.Tensor:
"""
Args:
spherical_map: (B, T, H, W)
Returns:
logits: (B, num_classes)
"""
B, T, H, W = spherical_map.shape

# 每帧投影到嵌入空间
x = spherical_map.view(B * T, 1, H, W)
x = self.input_proj(x) # (B*T, D, H, W)
x = x + self.pos_embed

# 展平空间维度
x = x.flatten(2).transpose(1, 2) # (B*T, H*W, D)
x = x.view(B, T, -1) # (B, T, H*W*D)

# Transformer
x = self.transformer(x)

# 池化 + 分类
x = x.mean(dim=1)
logits = self.cls_head(x)

return logits


class DoRFPlusPlus(nn.Module):
"""
完整 DoRF++ 管道

CSI → 多普勒投影 → DoRF 3D运动重建 → 球面投影 → 球面Transformer → 分类
"""

def __init__(self, num_classes: int = 10):
super().__init__()
self.doppler_extractor = DopplerProjectionExtractor()
self.dorf = DopplerRadianceField(num_views=3)
self.sph_proj = SphericalProjection()
self.sph_transformer = SphericalTransformer(num_classes=num_classes)

def forward(self, csi: torch.Tensor) -> torch.Tensor:
# 1. 提取多普勒投影
projections = self.doppler_extractor(csi)

# 2. DoRF 重建 3D 运动
# 假设方向已知(天线阵列配置)
directions = torch.randn(3, 2)
motion_3d = self.dorf(projections, directions)

# 3. 球面投影
sph_map = self.sph_proj(motion_3d)

# 4. 球面 Transformer 分类
logits = self.sph_transformer(sph_map)

return logits


# ============ 测试 ============
if __name__ == "__main__":
torch.manual_seed(42)

# 模拟 CSI 输入
B, T = 2, 100 # 2个样本, 100时间步
csi = torch.randn(B, T, 1, 3, 56, dtype=torch.cfloat) # 1TX, 3RX, 56子载波

# DoRF++ 模型
model = DoRFPlusPlus(num_classes=8)

# 前向
logits = model(csi)

print("=" * 60)
print("DoRF++ 测试结果")
print("=" * 60)
print(f"CSI 输入: {csi.shape} (complex)")
print(f"分类输出: {logits.shape}")
print(f"预测类别: {logits.argmax(dim=-1)}")

# 参数量
params = sum(p.numel() for p in model.parameters())
print(f"参数: {params:,} ({params/1e6:.2f}M)")

关键技术对比

WiFi CSI vs mmWave 雷达

维度 WiFi CSI mmWave 雷达
硬件成本 $5-15 (ESP32) $30-100 (TI)
分辨率 厘米级 毫米级
穿透性 强(穿墙) 弱(需要直射)
隐私 完全无图像 无图像
标准化 IEEE 802.11bf FMCW 标准
部署难度 极低(WiFi路由器自带) 中等(需专用雷达)

DoRF++ vs 现有 CSI 方法

方法 表征 跨用户泛化 多AP支持 球面处理
Wi-CSNet 时序CSI 弱 ✗ ✗
DFS-CSI (Transformer) 原始CSI 中 ✗ ✗
DoRF 多普勒辐射场 中 ✓ ✗
DoRF++ 球面多普勒 强 ✓ ✓

IMS 开发启示

1. WiFi CSI 作为座舱感知补充

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 车内 WiFi 感知方案
cabin_wifi_sensing = {
"hardware": "ESP32 + 车载WiFi路由器",
"cost": "<$20/车",
"use_cases": [
"乘员检测(有无人体)",
"粗略动作分类(坐/躺/走动)",
"呼吸频率估计(静止状态)",
"跌倒检测(后排乘客)"
],
"limitations": [
"分辨率低(无法做姿态估计)",
"受车内金属反射干扰",
"需要多点部署提高精度"
],
"complementary_to": [
"mmWave 雷达(高精度姿态)",
"IR 摄像头(眼动/表情)",
"座椅压力传感器(接触检测)"
]
}

2. 多传感器融合架构

3. CPD 儿童检测:WiFi CSI 辅助

1
2
3
4
5
6
7
8
9
# WiFi CSI 在 CPD 中的角色
cpd_wifi_role = {
"primary": "排除/确认车内有人",
"secondary": "粗略定位(前排/后排/后备箱)",
"response_time": "<500ms",
"accuracy": ">90% 存在检测",
"false_alarm_rate": "<5%",
"complement": "雷达确认体型(成人vs儿童)"
}

IEEE 802.11bf 标准化进展

项目 状态
标准编号 IEEE 802.11bf
目标 WLAN 感知标准化
核心能力 设备无关、非接触、隐私保护的感知
CSI 支持 子载波级精度的信道信息
应用场景 存在检测、手势识别、呼吸监测
预计发布 2025-2026

商用进展

RuView 项目(开源)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
ruview_config = {
"hardware": "ESP32 + WiFi 路由器",
"cost": "$15 per node",
"capabilities": [
"存在检测",
"呼吸频率",
"睡眠监测",
"跌倒检测",
"房间活跃度",
"浴室占用",
"老人异常不动",
"多房间转移"
],
"entities_per_node": 21, # 11原始信号 + 10推断语义状态
"home_assistant": True, # 集成 HA
"github": "https://github.com/ruvnet/RuView"
}

WiFi 人体识别突破

2026年5月《ScienceDaily》报道:普通 WiFi 可以近乎完美地识别人体身份。

  • 不依赖 CSI,使用新的信号处理方法
  • 利用人体对 WiFi 信号的独特反射模式
  • 准确率接近 100%
  • 可用于驾驶员身份认证

部署路线图

阶段 时间 目标 硬件
P0 3个月 WiFi 存在检测 ESP32 + 车载路由器
P1 6个月 粗略动作分类 ESP32 + 多AP
P2 12个月 DoRF++ 运动理解 车载计算平台
P3 18个月 多模态融合 雷达 + WiFi + 摄像头

参考文献

  1. DoRF++ 论文: arXiv:2608.08381
  2. RuView 项目: GitHub
  3. IEEE 802.11bf 标准化: WLAN 感知
  4. Wi-CSNet: 时空 CSI 模型
  5. DFS-CSI: Transformer-based HAR
  6. WiFi 人体识别突破: ScienceDaily 2026-05

发布时间: 2026-08-25 04:30
标签: WiFi CSI, DoRF, NeRF, 球面Transformer, 隐私感知, CPD, 座舱感知, IEEE 802.11bf