跳到主要内容

WiFi-DensePose 使用指南

· 阅读需 16 分钟
otqsoft
Front And Rear End Engineers @ gitee

基于 WiFi 信号的隐私安全人体感知系统

无需摄像头、无需穿戴设备、无需互联网——仅靠 WiFi 信号实现穿墙人体检测、姿态估计、呼吸/心率监测。

一、项目简介

WiFi-DensePose(项目代号 π RuView)是一个边缘 AI 感知系统,利用 WiFi 信号实现人体感知。其核心原理是:WiFi 路由器发出的无线电波在遇到人体时会产生散射,通过分析信道状态信息(CSI)的变化,系统可以重建人体姿态、检测生命体征。

技术背景

该系统基于卡内基梅隆大学的 DensePose From WiFi 研究成果,将学术概念扩展为可实际部署的边缘系统。核心技术栈包括:

  • RuVector:AI 信号处理引擎,包含注意力机制、图算法、稀疏求解器等
  • RuvSense:多站感知融合框架,支持 360 度全覆盖
  • SONA:自优化神经架构,支持设备端持续学习

与传统方案对比

特性WiFi-DensePose摄像头方案穿戴设备方案
隐私保护✅ 无图像,无视频❌ 需要隐私协议⚠️ 依赖佩戴
穿墙能力✅ 可穿透墙壁❌ 需要视线❌ 仅接触式
黑暗环境✅ 不受影响⚠️ 需要红外✅ 不受影响
部署成本~¥50/区域¥1500+/区域¥200+/人
隐私法规✅ 不受 GDPR 视频条款约束❌ 需要合规处理⚠️ 需要同意

二、核心功能

2.1 感知能力

功能说明性能
姿态估计17 个 COCO 关键点的 3D 人体姿态54,000 fps(Rust)
呼吸检测非接触式呼吸频率监测6-30 BPM
心率检测非接触式心率监测40-120 BPM
存在感知房间级人体存在检测< 1ms 延迟
穿墙感知穿透墙壁、家具、废墟最深 5 米
多人追踪同时追踪多人,独立姿态和体征每 AP 约 3-5 人
跌倒检测自动检测跌倒事件可配置灵敏度

2.2 智能特性

特性说明
自学习从原始 WiFi 数据自主学习,无需标注训练集
跨环境泛化训练一次,部署到任何房间,无需重训练
跨视角融合多传感器融合,消除盲点和深度模糊
自适应分类器自动学习房间独特的信号特征

2.3 边缘智能模块

系统提供 65 个可热加载的 WASM 模块,直接运行在 ESP32 传感器上:

类别模块示例
医疗健康睡眠呼吸暂停、心律失常、步态分析、癫痫检测
安全防护入侵检测、周界突破、徘徊检测、恐慌运动
智能建筑暖通控制、照明分区、电梯计数、会议室管理
零售分析队列长度、停留热力图、客流统计、翻台率
工业安全叉车接近、密闭空间监测、结构振动

三、系统架构

WiFi 路由器 → 电波穿过房间 → 碰到人体 → 散射

ESP32 网格(3-6 节点)采集 CSI 信号

信号处理:Hampel 滤波 → SpotFi 相位校正 → 菲涅尔区建模

AI 骨干(RuVector):注意力网络 → 图算法 → 压缩表示

神经网络 → 17 个身体关键点 + 生命体征

输出:REST API / WebSocket / Web UI

组件说明

组件功能
感知服务器Rust 实现,Axum 框架,提供 REST API 和 WebSocket
信号处理6 种 SOTA 算法(SpotFi、Hampel、菲涅尔等)
AI 骨干RuVector 引擎,注意力机制 + 图算法
Web UIThree.js 3D 可视化,实时姿态展示
ESP32 固件CSI 采集 + 设备端处理 + WASM 模块运行

四、环境要求

软件要求

软件最低版本说明
Docker20.0+推荐部署方式
Python3.10+用于验证和旧版 API
Rust1.70+源码编译需要
操作系统Windows 10+、macOS 10.15+、Ubuntu 18.04+
内存4 GB推荐 8 GB+
磁盘2 GB 可用模型和数据存储

硬件要求(可选)

硬件成本能力
ESP32-S3 开发板(3-6 个)~¥50/个完整 CSI:姿态、呼吸、心跳、存在
Intel 5300 / Atheros 网卡¥300-700完整 CSI,3x3 MIMO(仅 Linux)
任意 WiFi 笔记本¥0仅 RSSI:粗略存在和运动检测

无硬件也可运行:系统默认使用模拟数据源,可以体验完整功能。

五、部署方法

方式一:Docker 部署(推荐)

这是最简单的部署方式,无需安装任何工具链。

步骤 1:拉取镜像

docker pull ruvnet/wifi-densepose:latest

镜像大小约 132 MB,支持 amd64 和 arm64 架构。

步骤 2:启动容器

docker run -d --name wifi-densepose \
-p 3000:3000 \
-p 3001:3001 \
-p 5005:5005/udp \
-e RUVIEW_ALLOW_UNAUTHENTICATED=1 \
ruvnet/wifi-densepose:latest

端口说明:

端口协议用途
3000TCPREST API + Web UI
3001TCPWebSocket 实时流
5005UDPESP32 CSI 数据接收

步骤 3:验证服务

# 健康检查
curl http://localhost:3000/health

# 服务器信息
curl http://localhost:3000/api/v1/info

# 生命体征
curl http://localhost:3000/api/v1/vital-signs

# 姿态估计
curl http://localhost:3000/api/v1/pose/current

步骤 4:打开浏览器

访问 http://localhost:3000 即可看到 Web UI。

Windows 端口被占用时

如果 3000 端口被占用,可以映射到其他端口:

docker run -d --name wifi-densepose \
-p 3010:3000 \
-p 3011:3001 \
-p 5005:5005/udp \
-e RUVIEW_ALLOW_UNAUTHENTICATED=1 \
ruvnet/wifi-densepose:latest

Docker Compose 部署

cd docker
docker compose up -d

方式二:源码编译部署(Rust)

适合需要自定义修改或追求最佳性能的场景。

步骤 1:安装 Rust

# Windows/macOS/Linux
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

步骤 2:克隆并编译

git clone https://github.com/ruvnet/RuView.git
cd RuView/rust-port/wifi-densepose-rs

# 编译(约 5-10 分钟)
cargo build --release

# 运行测试(1,400+ 测试)
cargo test --workspace --no-default-features

步骤 3:启动服务

# 模拟数据源(无需硬件)
./target/release/sensing-server --source simulate --http-port 3000 --ws-port 3001

# ESP32 数据源
./target/release/sensing-server --source esp32 --udp-port 5005 --http-port 3000

# Windows WiFi RSSI
./target/release/sensing-server --source wifi --http-port 3000

CLI 参数说明

参数说明默认值
--source数据源:autowifiesp32simulateauto
--http-portHTTP 服务端口8080
--ws-portWebSocket 端口8765
--udp-portESP32 CSI 数据接收端口5005
--model加载训练好的 .rvf 模型
--train训练模式
--dataset数据集路径
--epochs训练轮次100
--benchmark运行性能基准测试
--export-rvf导出 RVF 模型包

方式三:Python 旧版部署

适合需要使用 Python API 或进行二次开发的场景。

步骤 1:安装依赖

cd v1
pip install -r requirements-lock.txt
pip install -e .

步骤 2:启动服务

# 启动 API 服务器
python -m src.main

# 或使用 CLI
wifi-densepose start

步骤 3:运行测试

cd v1
python -m pytest tests/ -v

六、使用说明

Web UI 可视化

访问 http://localhost:3000 打开内置的 Three.js 可视化界面,包含:

  • 3D 人体骨架:17 个 COCO 关键点的实时渲染
  • 信号幅度热力图:子载波幅度的可视化
  • 相位图:CSI 相位变化的实时展示
  • 生命体征面板:呼吸频率和心率的实时显示

REST API 接口

健康检查

curl http://localhost:3000/health

返回示例:

{
"status": "ok",
"source": "simulated",
"clients": 0,
"tick": 12345
}

获取生命体征

curl http://localhost:3000/api/v1/vital-signs

返回示例:

{
"breathing_rate_bpm": 16.2,
"heart_rate_bpm": 72.1,
"breathing_confidence": 0.87,
"heartbeat_confidence": 0.63,
"signal_quality": 0.49
}

获取姿态估计

curl http://localhost:3000/api/v1/pose/current

返回示例:

{
"persons": [
{
"id": 0,
"confidence": 0.9,
"keypoints": [
{"name": "nose", "x": 329.3, "y": 153.7, "z": -0.31, "confidence": 0.0},
{"name": "left_eye", "x": 323.8, "y": 142.3, "z": -0.31, "confidence": 0.0},
{"name": "right_eye", "x": 334.4, "y": 145.1, "z": -0.31, "confidence": 0.0}
],
"position": [-1.2, 0.0, -0.5],
"zone": "tracked"
}
],
"total_persons": 1
}

获取感知数据

curl http://localhost:3000/api/v1/sensing/latest

服务器信息

curl http://localhost:3000/api/v1/info

返回示例:

{
"backend": "rust",
"version": "0.3.3",
"environment": "production",
"features": {
"pose_estimation": true,
"vital_signs": true,
"signal_processing": true,
"streaming": true,
"wifi_sensing": true
}
}

完整 API 端点列表

方法端点说明
GET/health健康检查
GET/api/v1/info服务器信息
GET/api/v1/sensing/latest最新感知帧
GET/api/v1/vital-signs生命体征(呼吸+心率)
GET/api/v1/pose/current姿态估计(17 关键点)
GET/api/v1/bssid多 BSSID 注册表
GET/api/v1/model/layers渐进加载状态
GET/api/v1/model/sona/profilesSONA 环境画像
POST/api/v1/model/sona/activate激活 SONA 画像
GET/api/v1/models可用模型列表
POST/api/v1/models/load加载模型
GET/api/v1/recording/list录制会话列表
POST/api/v1/recording/start开始录制 CSI
POST/api/v1/recording/stop停止录制
GET/api/v1/train/status训练状态
POST/api/v1/train/start开始训练
POST/api/v1/adaptive/train训练自适应分类器

WebSocket 实时流

实时感知数据通过 WebSocket 推送,适合需要低延迟数据的应用场景。

连接地址

ws://localhost:3001/ws/sensing

或使用 HTTP 端口(推荐):

ws://localhost:3000/ws/sensing

Python 示例

import asyncio
import websockets
import json

async def stream():
uri = "ws://localhost:3001/ws/sensing"
async with websockets.connect(uri) as ws:
async for message in ws:
data = json.loads(message)
persons = data.get("persons", [])
vitals = data.get("vital_signs", {})
print(f"人数: {len(persons)}, "
f"呼吸: {vitals.get('breathing_rate_bpm', 'N/A')} BPM")

asyncio.run(stream())

JavaScript 示例

const ws = new WebSocket("ws://localhost:3001/ws/sensing");

ws.onmessage = (event) => {
const data = JSON.parse(event.data);
console.log("人数:", data.persons?.length ?? 0);
console.log("呼吸:", data.vital_signs?.breathing_rate_bpm, "BPM");
};

ws.onerror = (err) => console.error("WebSocket 错误:", err);

curl 测试(需要安装 wscat)

npm install -g wscat
wscat -c ws://localhost:3001/ws/sensing

观测台可视化

项目提供了一个电影级的 Three.js 观测台界面,包含 5 个全息面板:

  1. 子载波流形:CSI 子载波的 3D 可视化
  2. 生命体征预言机:呼吸和心率的实时显示
  3. 存在热力图:房间内人员分布
  4. 相位星座:CSI 相位变化的星座图
  5. 收敛引擎:信号收敛状态

访问地址:http://localhost:3000/ui/observatory.html

运行截图

七、ESP32 硬件接入

硬件准备

组件规格参考价格
ESP32-S3 开发板8MB Flash + 8MB PSRAM¥50-70
USB 数据线Type-C(需要数据线,不是充电线)
WiFi 路由器任意家用路由器已有
CP210x 驱动USB-UART 桥接驱动免费

推荐开发板:ESP32-S3-DevKitC-1、XIAO ESP32-S3。

安装驱动

下载并安装 CP210x 驱动

插入 ESP32-S3 后,在设备管理器中确认出现 COM 口(如 COM7)。

固件刷写

方式 A:使用预编译固件(推荐)

Releases 下载预编译二进制文件。

安装刷写工具:

pip install esptool

刷写固件:

python -m esptool --chip esp32s3 --port COM7 --baud 460800 \
write_flash --flash_mode dio --flash_size 8MB \
0x0 bootloader.bin \
0x8000 partition-table.bin \
0x10000 esp32-csi-node.bin

方式 B:Docker 编译

cd E:\AI\wifi-densepose

MSYS_NO_PATHCONV=1 docker run --rm \
-v "$(pwd)/firmware/esp32-csi-node:/project" -w /project \
espressif/idf:v5.2 bash -c \
"rm -rf build sdkconfig && idf.py set-target esp32s3 && idf.py build"

编译完成后,使用同样的 esptool 命令刷写 build/ 目录下的三个 bin 文件。

WiFi 配置

刷写固件后,通过串口配置 WiFi 凭据(无需重新刷固件):

# 安装依赖
pip install esptool nvs-partition-gen

# 配置 WiFi
python firmware/esp32-csi-node/provision.py --port COM7 \
--ssid "你的WiFi名称" \
--password "你的WiFi密码" \
--target-ip "你电脑的局域网IP" \
--edge-tier 2

参数说明:

参数说明示例
--portESP32 串口号COM7
--ssidWiFi 名称"MyHomeWiFi"
--passwordWiFi 密码"mypassword"
--target-ip运行感知服务器的电脑 IP192.168.1.20
--target-portUDP 端口5005(默认)
--node-id节点编号0, 1, 2...
--edge-tier处理层级0=原始流, 1=基础DSP, 2=完整体征

处理层级说明

层级功能内存占用
Tier 0原始 CSI 流传输0 KB
Tier 1相位清理 + 子载波选择 + 压缩~30 KB
Tier 2存在检测 + 呼吸 + 心率 + 跌倒检测~33 KB
Tier 3Tier 2 + WASM 自定义模块~160 KB/模块

串口监控

pip install pyserial
python -m serial.tools.miniterm COM7 115200

正常启动输出:

I (321) main: ESP32-S3 CSI Node (ADR-018) -- Node ID: 1
I (345) main: WiFi STA initialized, connecting to SSID: MyWiFi
I (1023) main: Connected to WiFi
I (1025) main: CSI streaming active -> 192.168.1.20:5005

多节点网格

部署 3-6 个节点可以实现 360 度全覆盖和 3D 姿态估计:

# 节点 0
python firmware/esp32-csi-node/provision.py --port COM7 \
--ssid "YourWiFi" --password "secret" --target-ip 192.168.1.20 \
--node-id 0 --tdm-slot 0 --tdm-total 3 --edge-tier 2

# 节点 1
python firmware/esp32-csi-node/provision.py --port COM8 \
--ssid "YourWiFi" --password "secret" --target-ip 192.168.1.20 \
--node-id 1 --tdm-slot 1 --tdm-total 3 --edge-tier 2

# 节点 2
python firmware/esp32-csi-node/provision.py --port COM9 \
--ssid "YourWiFi" --password "secret" --target-ip 192.168.1.20 \
--node-id 2 --tdm-slot 2 --tdm-total 3 --edge-tier 2

多节点使用 TDM(时分复用)协议轮流发射,避免自干扰。

Windows 防火墙

需要开放 UDP 5005 端口以接收 ESP32 数据:

# 以管理员身份运行 PowerShell
netsh advfirewall firewall add rule name="ESP32 CSI" dir=in action=allow protocol=UDP localport=5005

启动感知服务器接收硬件数据

# Docker 方式
docker stop wifi-densepose
docker rm wifi-densepose
docker run -d --name wifi-densepose \
-p 3000:3000 -p 3001:3001 -p 5005:5005/udp \
-e RUVIEW_ALLOW_UNAUTHENTICATED=1 \
ruvnet/wifi-densepose:latest --source esp32

# 源码方式
./target/release/sensing-server --source esp32 --udp-port 5005 --http-port 3000

八、数据源配置

系统支持多种数据源,通过 --source 参数指定:

模拟数据(默认)

无需任何硬件,系统生成模拟 CSI 数据。

docker run -p 3000:3000 ruvnet/wifi-densepose:latest
# 默认 --source auto,无硬件时自动使用模拟数据

Windows WiFi(RSSI)

使用 Windows 内置 WiFi 网卡扫描附近接入点的 RSSI 信号。无需特殊硬件,支持存在检测和粗略运动分类。

./target/release/sensing-server --source wifi --http-port 3000 --tick-ms 500

注意:RSSI 模式不支持姿态估计,仅支持存在检测和运动分类。

macOS WiFi(RSSI)

使用 CoreWLAN 框架扫描 WiFi 信号。

# 编译 Swift 辅助程序(仅需一次)
swiftc -O v1/src/sensing/mac_wifi.swift -o mac_wifi

# 运行
./target/release/sensing-server --source macos --http-port 3000 --tick-ms 500

Linux WiFi(RSSI)

使用 iw 命令扫描 WiFi 信号。

sudo ./target/release/sensing-server --source linux --http-port 3000 --tick-ms 500

ESP32 CSI(完整功能)

接收 ESP32-S3 节点的 CSI 数据流,支持所有功能。

./target/release/sensing-server --source esp32 --udp-port 5005 --http-port 3000

九、Python 流水线验证

项目包含一个确定性验证脚本,用于证明信号处理流水线是真实代码而非模拟。

运行验证

# 安装依赖
pip install numpy scipy pydantic pydantic-settings

# 运行验证
python v1/data/proof/verify.py

验证结果

WiFi-DensePose: Trust Kill Switch -- Pipeline Proof Replay

[1/4] LOADING REFERENCE SIGNAL
Path: v1/data/proof/sample_csi_data.json
Size: 10,745,444 bytes

[2/4] PROCESSING THROUGH PRODUCTION PIPELINE
Frames processed: 100
Processing time: 0.0964s (1037 frames/sec)

[3/4] SHA-256 HASH COMPARISON
Computed: a69f754be65e12122af82f6c1946e5c3...
Expected: a69f754be65e12122af82f6c1946e5c3...
Status: MATCH

VERDICT: PASS

生成新的预期哈希

如果更新了依赖版本,需要重新生成预期哈希:

python v1/data/proof/verify.py --generate-hash
python v1/data/proof/verify.py

十、常见问题

Docker 相关

Q: 容器启动失败,提示端口被占用

A: 更换映射端口:

docker run -d --name wifi-densepose -p 3010:3000 -p 3011:3001 -p 5005:5005/udp \
-e RUVIEW_ALLOW_UNAUTHENTICATED=1 ruvnet/wifi-densepose:latest

Q: 容器启动后立即退出

A: 检查日志:

docker logs wifi-densepose

常见原因是需要设置认证参数,添加 -e RUVIEW_ALLOW_UNAUTHENTICATED=1

Q: Docker 服务未启动

A: 启动 Docker Desktop,等待状态栏显示"Docker Desktop is running"。

ESP32 相关

Q: 找不到串口

A: 检查以下几点:

  1. 安装 CP210x 驱动
  2. 使用数据线而非充电线
  3. 在设备管理器中检查 COM 口

Q: WiFi 连接失败

A: 重新运行 provision.py,确保 SSID 和密码正确。

Q: 服务器收不到 ESP32 数据

A: 检查以下几点:

  1. --target-ip 是否为电脑的实际局域网 IP
  2. 防火墙是否开放 UDP 5005 端口
  3. ESP32 和电脑是否在同一局域网

Q: 串口监控无输出

A: 确认波特率为 115200,串口号正确。

性能相关

Q: Docker 镜像中的 Rust 服务器性能如何?

A: 性能指标:

  • 全 CSI 流水线:54,000 fps
  • 生命体征检测:11,665 fps
  • 运动检测:186 ns
  • 比 Python 版本快约 810 倍

Q: 系统支持多少人同时追踪?

A: 每个 AP 约 3-5 人(56 子载波限制),多 AP 可线性扩展。

附录:性能基准

操作PythonRust加速比
CSI 预处理~5 ms5.19 µs1000x
相位清理~3 ms3.84 µs780x
特征提取~8 ms9.03 µs890x
运动检测~1 ms186 ns5400x
全流水线~15 ms18.47 µs810x
资源PythonRust
内存~500 MB~100 MB
Docker 镜像569 MB132 MB
测试数411,400+
最后更新时间: 2026/7/31 13:40:35|访问次数: 0|豫ICP备2025159864号|