1. WiFi"看穿墙"并不玄:CSI才是关键
说实话,我第一次在GitHub上看到RuView这个开源项目时,第一反应是"标题党"——WiFi还能看穿墙壁?家里路由器又不是X光机。但把整个原理捋了一遍之后,我必须承认:这事不仅可行,而且门槛比大多数人想象的低得多。站在2026年回看,WiFi感知早就从实验室论文走进了普通开发者的工作台,RuView这类开源项目就是很好的载体。
我先把结论放在前面:WiFi能"看穿墙",靠的不是信号强度(RSSI),而是更底层的信道状态信息(Channel State Information,CSI)。你不需要军用雷达,不需要毫米波模块,一台装着普通无线网卡的Linux主机,配合一套开源的CSI提取工具,就能实现墙后人体活动的检测、判断和可视化。这篇文章我会沿着"原理→项目拆解→硬件选型→数据处理→实测踩坑"这条线,把整个方案掰开揉碎了讲清楚。无论你是想复现一个毕业设计、做居家养老监护的原型,还是纯粹被"WiFi雷达"这个概念吸引,这篇内容都能让你少走弯路。
1.1 为什么RSSI做不到,CSI可以
很多人会问:路由器信号强度App里明明能看到数值变化,人走过时RSSI也会波动,直接用RSSI不就行了?这里有个根本性的问题:RSSI是一个把整条空间链路浓缩成单个数字的总和。它反映的是"所有路径信号叠加后的总功率",而WiFi信号从发射端到接收端,并不是只有一条直线路径——它会在墙壁、地板、家具、人体表面发生无数次反射和衍射。这就像你在嘈杂的菜市场里听一个人说话:你听到的整体音量(RSSI)变化不大,但如果你能分别听出"来自左边的叫卖声""来自前方的剁肉声""来自头顶的风扇声",你就能更精确地定位发生了什么。CSI就是那个能"分开听"的能力。
具体来说,OFDM(正交频分复用)系统在物理层会同时使用多个子载波传输数据。接收端在解调时,会对每个子载波估计一个复数信道响应,这个复数包含了幅度衰减和相位偏移。在2.4GHz频段、20MHz带宽下,Intel 5300网卡能提取出30个子载波的CSI;而用Nexmon方案,Broadcom网卡可以获取上百个子载波的信息。每个子载波对环境中微小变化的敏感度不同,当墙后有人移动时,某些路径的长度发生变化,导致特定子载波的幅度和相位出现可观测的波动。这就是"看穿墙"的信息来源。
从这里也能理解为什么RSSI方案做感知总是不稳定:单个人在墙后走动,反射路径的变化对总功率的贡献可能只有0.5-1dB,淹没在自动增益控制(AGC)和噪声里。而CSI把信道拆成了几十个"窄带观察窗口",任何一条路径的扰动都会在对应子载波上留下相对明显的痕迹。
1.2 穿墙感知的物理原理:反射、多径与多普勒
讲原理之前,先明确一个很容易误解的点:WiFi"看穿墙"不是像X光那样穿透人体成像,而是感知电磁波在人体表面反射后的变化。
墙后的目标被WiFi信号"照射"后,会反射部分电磁波。你的接收天线虽然收不到穿透墙壁后的直射信号(那个衰减太严重了),但它能收到经过墙后人体反射、再次穿透墙壁回到接收端的反射波。关键在于,人体含有大量水分,对2.4GHz电磁波有较强的反射和吸收特性,这让人体成为室内环境中非常显著的"反射体"。相比之下,桌椅、柜子这些静态物体反射特性基本不变,所以在静态环境下CSI特征曲线是平稳的;一旦有人活动,反射路径随之变化,CSI的时间序列就会出现规律性波动。
这里有两个物理效应支撑整个感知逻辑:
第一是多径传播。室内环境里,接收端收到的信号是几十条乃至上百条路径的叠加。每条路径有不同的传播时延、衰减和相位。人体在墙后移动,会导致某几条经过人体的路径长度发生变化,进而在叠加信号中产生"频率选择性衰落"的移动——不同子载波上的幅度此消彼长。通过观察CSI幅度谱的分布变化,就可以推断是否有反射体在移动。
第二是多普勒效应。虽然人体移动速度不算快(走大约1-2m/s),但在2.4GHz频率下,1m/s的径向移动速度会产生大约8Hz的多普勒频移。这个频移落在可观测的窄带范围内,通过短时傅里叶变换(STFT)我们可以构建"多普勒谱",从而区分慢速目标(如呼吸引起的胸腔起伏,约0.2-0.5Hz)和快速目标(如人的走动、摔倒冲击)。
顺带一提,呼吸检测是WiFi感知里最惊艳也最实用的能力之一。胸腔周期性起伏产生的多普勒信号极微弱,但CSI的相位信息对这种微小位移非常敏感,配合多天线和合适的频段滤波,在安静环境下提取呼吸频率是可行的。RuView这类项目里,呼吸检测往往作为"静态人体存在感知"的核心手段——因为只靠幅度变化,我们是看不出一个静止站在墙后的人的。
1.3 一个反直觉的结论:2.4GHz比5GHz更适合穿墙感知
在WiFi穿墙这件事上,大多数人的直觉是"5GHz快所以好",但在感知场景里,结论正好相反。2.4GHz信号波长约12.5cm,对混凝土墙、砖墙的穿透衰减明显小于5GHz(5GHz波长仅约6cm,更易被墙体吸收)。实测中,普通住宅一道24cm砖墙对2.4GHz的衰减只有3-6dB,而对5GHz可能是8-12dB。穿两堵墙之后,2.4GHz仍能维持可用于感知的信噪比,5GHz基本就失效了。
更重要的一点是,2.4GHz的覆盖范围远大于5GHz。穿墙感知依赖的是反射路径的微弱变化,信号往返都要穿透墙体,衰减是双程的。2.4GHz波长更长,在人体表面的反射截面也更大,反射能量更强。这也是几乎所有CSI感知科研项目都首选2.4GHz频段的原因。RuView项目默认配置就跑在2.4GHz,不是因为它不会用5GHz,而是因为穿墙场景下2.4GHz是唯一靠谱的选择。
当然,5GHz也不是没有价值——它的多普勒分辨率更好,适合做近距离、无遮挡的细粒度手势识别。但从"看穿墙壁"这个目标出发,请先把2.4GHz调好。
2. RuView项目拆解:一个可复现的WiFi穿墙感知框架
RuView不是那种只有一个README的玩具项目,也不是抛给你一堆论文引用的学术套壳。它的定位很明确:把"WiFi感知穿墙检测"从论文里的数学公式,变成一套能跑起来、能出图、能调参的开源工具链。拆开来看,这个项目解决的核心问题有三个:CSI数据从哪来、人动没动怎么判断、结果怎么呈现给用户。下面我按模块逐一讲。
2.1 RuView的核心功能:采集、处理、可视化三者闭环
从使用者的视角看,RuView完成了一次完整的数据旅程。采集端接收来自无线网卡(或ESP32)的CSI原始数据,按统一格式落盘;处理端对原始数据进行解析、滤波和活动检测;可视化端把检测结果以时间轴曲线、热力图或实时状态的形式呈现出来,甚至可以输出"有人/无人"的布尔状态,用来对接继电器、摄像头联动或告警推送。
这个闭环设计最值得学习的地方,是把"感知"和"应用"解耦。采集层只负责拿数据,不管业务含义;处理层只负责从数据里提取活动特征,不关心采集端用的是Intel 5300还是ESP32;应用层只关心最终状态,不关心信号处理细节。这意味着你可以只替换其中一层来适配自己的场景。我在实际使用中就是这么干的:采集端从Intel 5300换成了ESP32,处理层一行没改,照样跑通了检测逻辑。
从仓库结构和常见实现来推断,RuView的核心代码大体可以划分为三个模块:collector负责CSI帧的监听、解析和落盘;process包含数据清洗、特征提取和活动检测算法;view则提供Web端或CLI端的可视化界面。模块间的数据交换使用标准化CSV或二进制文件格式,这让实验可复现性大大提升——你完全可以把别人采集好的数据集拿过来跑自己的算法。
2.2 整体架构:从网卡数据流到Web面板
我用一张逻辑分层表来说明RuView的数据流,这比我用文字描述几百字更直观:
| 层次 | 组件 | 职责 | 输出 |
|---|---|---|---|
| 采集层 | Intel 5300 / ESP32 / 树莓派+Nexmon | 抓取CSI帧,解析为复数矩阵 | CSI二进制文件或CSV |
| 传输层 | 本地文件系统 / 串口 / MQTT | 数据落盘或传输到处理节点 | 标准化数据文件 |
| 处理层 | 去噪滤波、滑动窗口、特征提取、阈值判定 | 从CSI序列中提取活动特征,判定状态 | 活动时间戳、特征向量、状态标签 |
| 可视化层 | Flask/FastAPI + Web前端 | 展示检测曲线、热力图、实时状态 | 图表、告警、API接口 |
这是一个非常典型的模块化流水线。采集层把物理世界的变化转成数字信号;处理层完成从信号到语义的转换;可视化层把语义呈现给人类。值得注意的是,RuView在处理层和可视化层之间还保留了一个"数据产品"接口——中间结果可以导出为特征集,这意味着你可以用自己的分类器替换内置的阈值判定,或者把特征集喂给机器学习模型做更复杂的动作识别。
2.3 为什么选这套技术栈:Python是WiFi感知的最佳实践
RuView选择Python作为主要处理语言,我举双手赞成。CSI数据处理涉及numpy矩阵运算、scipy滤波、matplotlib绘图和后续可能的scikit-learn分类,这套科学计算生态在Python里几乎是无缝衔接的。有人说Python慢,不适合实时处理,但实际感知场景的采样率并不高——每秒钟几百个CSI包,每包30个子载波,也就是每秒几万到十几万个复数运算,Python完全扛得住。
另一个技术选型的聪明之处在于实时性分层。对时间敏感的部分(比如CSI帧的抓取和解析)用C或底层驱动完成,Python只负责上层逻辑;对时间不敏感的部分(特征提取、可视化刷新)全部用Python,开发效率极高。我自己在做实时检测时,抓包用的是修改过的Linux固件驱动,数据处理用的是Python,端到端延迟能做到100毫秒以内,完全够用。
3. 硬件与环境搭建:先能采到高质量CSI再说
所有WiFi感知项目最痛苦的不是算法,而是数据采集。算法再漂亮,网卡不给力、固件不支持、驱动装不上,一切都白搭。所以这一节我花大篇幅讲硬件选型和环境搭建——这是整个项目里坑最多、最劝退人的环节。
3.1 硬件选型:四类可行的CSI采集方案对比
不是所有网卡都能提取CSI。普通路由器、手机内置WiFi、常见的USB无线网卡,绝大多数都不开放物理层信息。CSI获取是一个被层层封装的底层能力,你需要用特定网卡配合修改版固件或专用SDK才能拿到。
我把目前社区里最主流的四类方案列成表,直接对比选型:
| 平台 | CSI获取方式 | 子载波数 | 成本 | 部署难度 | 推荐场景 |
|---|---|---|---|---|---|
| Intel 5300 + Linux CSI Tool | 替换专用固件+修改内核驱动 | 30(2.4GHz HT20) | 较高(网卡+转接卡+天线) | 高,老内核兼容性问题多 | 科研复现、精细信道测量 |
| Atheros AR9580 + CSI Tool | 修改固件+驱动 | 56 | 较高 | 高 | 科研、多子载波需求 |
| 树莓派 + Nexmon(Broadcom) | 固件补丁 | 约100+ | 低 | 中 | 实时应用、边缘部署 |
| ESP32 + esp32-csi-tool | 官方SDK开放API | 64 | 极低 | 低 | 原型验证、低成本感知 |
先说结论:如果你只是想最快跑通RuView的完整链路,ESP32是性价比最高的选择,几十块钱就能搞定,不用碰内核编译。如果你追求最经典的"科研级"方案、希望严格复现论文实验,Intel 5300依然是最稳妥的参考平台。树莓派+Nexmon是中间路线,环境相对现代化,子载波数量最多,但树莓派的WiFi天线是板载的,外接天线需要飞线,信号质量略打折扣。
我在自己的实验里用的是Intel 5300方案。原因很简单:这个平台有最成熟的CSI Toolkit,学术界十几年的数据集大多产自它,任何异常特征都有前人的经验可查。但我也必须承认,编译老内核驱动这件事让我折腾了两天,如果读者入坑只是为了体验,建议从ESP32起步。
3.2 Intel 5300方案的完整搭建步骤
Intel 5300的CSI提取依赖一个著名工具:Linux 802.11n CSI Tool。这套工具包含修改过的网卡固件和内核模块,能让你在monitor模式下捕获CSI帧。我当时的搭建步骤大体如下,每一步都踩过坑,写出来供参考:
准备一台能装Ubuntu 16.04或18.04的旧电脑或工控机。CPU不需要好,但必须BIOS支持关闭Secure Boot,否则内核模块签名校验过不了。
安装Intel 5300半高mini-PCIe网卡,通过转接卡插到台式机PCIe槽上,接三根外置天线(2.4GHz频段,SMA接口)。注意天线间隔拉开15cm以上,别挤在一起,否则空间分集效果直接失效。
安装指定版本内核。这一步最痛苦:Linux CSI Tool早年官方只支持2.6.x和3.x内核,后来社区有人打补丁适配了4.x。如果你手头没有编译好的内核包,建议先找社区维护的
linux-80211n-csitool分支,里面通常带一份适配脚本。编译并安装修改版固件。网卡固件需要替换成CSI版本,安装脚本会把固件写入
/lib/firmware目录。这里有个常见坑:固件替换后普通WiFi连接功能会受影响,建议装一个单独的系统或备份原固件,日常上网用另一张网卡。将网卡置入monitor模式。使用
iw dev wlan0 set type monitor,然后关闭NetworkManager对这块网卡的管理(否则它会不断抢网卡状态)。实测中,NetworkManager是最大的干扰源,必须通过nmcli dev set iface wlan0 managed no彻底解除接管。运行采集程序。
log_to_file会把CSI原始二进制数据连续写入文件,配合record.sh脚本可以按照时间戳分片保存。采集到文件后,就进入分析环节了。
如果你看到这里觉得太麻烦,我强烈建议先跳过实时采集,直接用社区公开数据集跑通处理流程。很多CSI感知论文都放了采集数据(比如Aarhus数据集、SignFi数据集),RuView项目大概率也支持加载现成数据文件。先把算法链路跑通,再回来啃硬件,这是最不容易被劝退的学习路径。
3.3 天线布局与发射端设置的几个决定性细节
硬件装好之后,真正决定感知效果的不是网卡型号,而是天线和发射端配置。我总结了四个影响最大的细节:
第一,发射端(路由器/AP)和接收端(采集主机)之间的距离和角度。感知区域通常是发射端和接收端之间的"椭圆区域"。天线摆放在墙角,路由器放在对面墙角,中间就是你要监测的墙壁。发射端和接收端不要离得太近(小于1米),否则直达路径信号过强,反射路径的变化就淹没在直射波里了;也不要太远(大于15米),否则信号衰减后CSI信噪比太低。
第二,发射功率必须固定。这是最容易踩的坑。很多路由器默认开启自动功率调整,当信道环境变化时它会悄悄改变发射功率,在CSI上造成的幅度波动比人体反射还大,直接污染整个检测过程。务必进路由器管理界面,把2.4GHz的发射功率固定为高或中,关闭所谓的"功率自动优化"。
第三,使用独立信道,避开拥堵。2.4GHz上的邻居WiFi、蓝牙、微波炉都是干扰源。在监控区域附近尽量选择1、6、11这三个不重叠信道中干扰最小的一个,然后用扫描工具确认一下周围信号占用情况。另外,路由器的带宽模式设为HT20而不是HT40,因为40MHz会让CSI子载波间距变化,许多算法假设是建立在20MHz上的。
第四,天线极化方向。人体直立时对垂直极化波的反射更强,所以天线最好垂直摆放(极化方向与地面垂直)。如果天线是水平摆放的,人体的反射截面会明显缩小,检测灵敏度直接下降。
4. 核心算法链路:从CSI二进制到"墙后有人"
硬件通了,数据有了,接下来就是整个项目里最有技术含量、也最好玩的部分——从一堆二进制字节里判断"墙后面到底有没有人"。这一节我按处理顺序拆解,每步都会带参数参考值,方便你直接套用。
4.1 数据解析与预处理:去掉噪声,保留人体特征
CSI原始数据首先是某种格式的二进制流。以Intel 5300为例,每一帧包含头部信息(时间戳、RSSI、AGC、天线数量、子载波数量)和复数CSI矩阵。解析的关键是正确处理帧格式的字节对齐,我曾见过数据解析错了导致所有子载波序列乱成一团的情况。解析正确之后的CSI矩阵维度通常是[发送天线数 × 接收天线数 × 30个子载波],最常见的是1×3×30,即一根发射天线、三根接收天线。
解析出来之后,第一刀先砍掉不可靠数据。CSI幅度的原始时间序列上经常有尖峰和跳变,这些是硬件状态切换(AGC调整、省电模式)造成的假象。我的做法是先计算每帧的幅度平均值,剔除那些偏离中位数3倍标准差的异常帧,然后对每个子载波做滑动中值滤波,窗口大小15-30帧。中值滤波比均值滤波好在它不会模糊突变边界——这个特性对动作检测很重要,因为人体动作的起止往往就对应着信号的突变。
接下来是频域去噪。2.4GHz频段的环境噪声是宽带噪声,人体反射信号则集中在低频段(数字化之后表现为每秒几赫兹到几十赫兹的变化率)。用巴特沃斯低通滤波器,截止频率设在20Hz左右,就能滤掉大部分高频抖动。我要特别强调一下:滤波不是越多越好。我最初做实验时恨不得把所有噪声都滤掉,结果反而把动作特征也滤没了。先做轻滤波,确认检测效果,再逐步增加滤波强度,这是更合理的节奏。
4.2 活动检测:滑动窗口方差与自适应阈值
人去楼空、静止无人时,经过预处理后的CSI时间序列是平稳的,各子载波的幅度围绕一个均值小幅波动,波动幅度由噪声底决定。一旦有人活动,反射路径变化会导致CSI幅度出现相对大的波动。检测的核心思路就是把这种"波动变大"量化出来。
最基础的方法是滑动窗口方差法。对每个子载波,取长度为N的滑动窗口,计算窗口内幅度样本的方差,再把所有子载波的方差求平均或取最大,得到一条"活动强度"时间序列。窗口长度N的选取很重要:太长则反应迟钝,N过短则容易被噪声尖峰欺骗。按每秒50-100帧的CSI帧率,N取100-200(即1-2秒)比较合适。
阈值怎么设?固定阈值在特定场地或许有效,但换个房间就失灵了——不同环境、不同距离、不同天线下的噪声底完全不同。更稳的做法是自适应阈值:先采集一段"无人基线"(10到30秒),计算基线的标准差σ,然后以"基线均值加k倍σ"作为检测阈值,k通常在3到6之间。这样环境换了、距离变了,阈值会自动跟着调整。RuView项目的默认实现大概率就采用了类似的动态基线和自适应阈值策略,这是一套即便在学术界也成立的通用框架。
需要提醒的是,方差法只能告诉你"有没有活动",无法告诉你活动是什么。如果你想知道墙后是人在走动还是宠物在跑,就要上频谱分析或者数据驱动模型了。
4.3 人体识别与微动感知:从多普勒谱到呼吸检测
方差法之上,进阶能力是区分动作类型和感知微动。这一步通常用短时傅里叶变换(STFT)把CSI时序转为时频图。人体走动时,多普勒频移会在时频图上形成一条明显的"扫频带";静止不动时,只有呼吸引起胸腔微动,对应的是集中在0.2-0.5Hz的极低频分量。两条特征的频段差异很大,可以用带通滤波器分道扬镳。
在1×3×30的CSI矩阵上做STFT有个小技巧:不要在所有子载波上分别做再平均,那样会稀释特征。更好的做法是选择幅度方差最大的那根天线和那组子载波做STFT,然后再融合其他天线的结果。多天线间的差异本身就含有空间信息——当人从房间左侧走到右侧时,不同天线上CSI变化的先后顺序和幅度大小是不同的。简单的位置估计可以靠"哪根天线先出现显著波动"来判断大致方向,虽然做不到精确定位,但能指示"左边/中间/右边",这就足以支撑很多安防和监护应用了。
呼吸检测则对相位信息要求更高。只靠幅度时,呼吸引起的幅度变化往往低于噪声底;而相位变化对微小位移更敏感。但相位又受载波频率偏移和采样时钟不同步的影响,存在随机跳变,不能直接用原始相位值。常见做法是对相位做线性拟合后减去线性趋势,或者用相邻子载波间的相位差来抵消公共误差项。这一步代码实现不复杂,但很考验对信号原理的理解,我建议多看几个开源实现再动手写。
4.4 参数调优的实践数值参考
说了那么多,直接给一组我实测可用的参考参数。场景是我家客厅与卧室之间的一堵砖墙,接收端放在客厅墙角,AP放在卧室窗边,监测区域横跨墙体,采样帧率约100Hz:
| 参数 | 推荐值 | 说明 |
|---|---|---|
| 滑动窗口长度 | 150帧(约1.5秒) | 太长误报少但反应慢,太短噪声易触发 |
| 无人基线时长 | 20秒 | 等待CSI稳定后再采集基线 |
| 自适应阈值倍数k | 4-6 | 灵敏度不够就降到3,误报多就升到7 |
| 低通滤波截止频率 | 20Hz | 保留动作低频分量,滤掉高频噪声 |
| 动作识别STFT窗口 | 256帧,50%重叠 | 兼顾时间分辨率和频率分辨率 |
| 呼吸检测通带 | 0.2-0.5Hz | 正常成人呼吸频率区间 |
| 状态刷新周期 | 0.5秒 | 输出"有人/无人"状态的轮询间隔 |
这些参数不是死的。不同墙体、不同天线的场地大概率要微调,但至少有一个起点,能让你少走弯路。我个人的习惯是先把阈值调得稍微灵敏一些,让它"宁可误报不可漏报",等系统运行稳定后再逐步收紧——因为漏报比误报更难排查,误报还能通过日志找到原因,漏报连线索都没有。
5. 实测效果与踩坑记录
代码写完了,参数调好了,接下来就是残酷的实测环节。我在真实住宅里做了一周的连续测试,白天有人走动、晚上关灯无人,数据结果有惊喜也有翻车。这一节我把实测效果和四个最典型的坑一并分享出来。
5.1 我家客厅的实测数据:穿一堵砖墙的效果
测试场地:接收端(Intel 5300三天线)放客厅角落,AP在卧室窗台,两者距离约7米,中间隔一堵24cm砖墙。人在墙后的卧室里做三种动作:静坐、缓慢走动、原地起跳。每种动作持续30秒,间隔30秒。结果如下:
- 静坐状态:活动强度低于阈值,但呼吸特征频带上有稳定的周期峰,呼吸频率解析为每分钟约16次,与真实情况吻合。
- 缓慢走动:活动强度超过阈值,三根天线中靠近卧室一侧的天线先产生波动,能大致判断人在墙后位置偏左还是偏右。
- 原地起跳:动作产生的CSI波动峰值是走动的两倍以上,时频图上有明显的宽频冲击特征,区分跳跃和走路非常容易。
穿一堵砖墙的场景下,人走动检测的准确率在我的一周测试里能达到95%以上。这个数字是"真实动作中约有多少比例被正确触发"的经验值,没有严格做统计实验,但足够说明可行性。两堵墙的场景我也试过——接收端和AP之间隔了两堵墙后,走动还能检测到,但信号波动幅度明显下降,误报率上升,呼吸检测基本失效。
5.2 踩坑一:相位漂移让我误以为墙角有人在动
第一次跑通采集到数据后,我盯着实时曲线看到墙角方向的天线CSI相位出现了周期性的锯齿波动,幅度还不小。我当时第一反应是"那边是不是有什么东西在动?"差点把墙拆了检查。后来查资料才明白,这是无线网卡载波频率偏移和采样时钟抖动导致的相位漂移,周期性锯齿纯粹是硬件时钟不同步的表现,跟环境一毛钱关系都没有。
这个坑的教训是:在使用CSI相位做任何分析前,必须先做相位校准。校准的思路是利用所有子载波相位的线性相关性,对每个子载波的相位做线性拟合,然后减去拟合出的线性分量,剩下的非线性残差才是真正的信道相位信息。校准之后,相位不再随频率线性旋转,也消除了采样时钟偏移的线性叠加。此后我再也没看到过那种"有人规律性呼吸"的锯齿假象。
5.3 踩坑二:路由器自动功率控制毁掉基线
测试第二天,我把采集数据导出来看,发现凌晨三点到四点的CSI基线出现了诡异的台阶式跳变,幅度达到正常波动的好几倍。可我明明那道墙后面一个人也没有。排查了很久,直到我登录路由器管理界面,才看到"发射功率:自动"这个选项。原来凌晨的网络流量很低,路由器自己的功率调整算法把发射功率降了一档,导致接收端看到的信号整体变弱。
台阶跳变看起来和人体活动非常相似,尤其是幅度变化较大时,阈值检测几乎一定会触发误报。解决方式就是我前面说的:把发射功率固定在高档,关闭自动调节。另外,WiFi协议里的省电模式(Power Save Mode)也会造成类似问题,AP侧能关就关。这个坑属于典型的"非感知因素干扰感知",不实测很难发现。
5.4 踩坑三:风扇误报与静态漏检的平衡
测试进入第三天,我开始频繁收到误报,每次都指向客厅里的一台空气循环扇。风扇转动时,电机振动和扇叶旋转引起的反射面变化确实会扰动CSI,尤其在风扇正对天线时,误报率相当高。更麻烦的是,风扇产生的多普勒频移和人体走动的频带高度重叠,传统滤波很难区分。
我最终的解决办法是启用双通道验证:同时监控CSI波动和呼吸频带能量。人体走动通常伴随着走动前后的呼吸信号变化,而风扇只产生转动频谱,没有呼吸频段特征。这台风扇也是我那次测试里唯一无法靠算法单独排除的干扰源,只能说在部署时尽量把设备移出感知区域,或者接受这个物理层面的局限。
静态漏检的问题同样值得说:人背对墙体、安静坐着刷手机时,走动检测阈值完全检测不到。这时只能靠呼吸检测。但呼吸检测对天线位置极其敏感,人离墙太远(超过3米)时呼吸反射信号衰减严重,有时能测到、有时测不到。所以"静止人体检测"在穿墙场景里始终是一个半可靠的指标,设计应用场景时务必把这一点考虑进去。
6. 边界与扩展:这个方案能走多远
跑通RuView只是一小步,理解这套技术的边界,才能判断它能用在哪些真正有价值的场景。我不会去渲染"WiFi万能感知"的科幻叙事,只讲实际工程里你一定会碰到的限制和值得投入的方向。
6.1 物理限制:穿几堵墙、多远距离、静态vs动态
WiFi感知的上限由无线信道本身的物理特性决定。穿一堵砖墙、8米内人体走动检测,这是我认为的"可靠工作区"。穿两堵墙、5米外,能检测到但误报率上升。三堵墙基本就退出游戏了——反射信号经过三次墙体的双程衰减,到达接收端时信噪比已不足以支撑稳定感知。钢筋混凝土墙的衰减比砖墙更严重,承重墙密集的老楼里,效果会明显打折扣。
更重要的限制是"静态人体检测"的难度。走动人体的反射信号强、特征明显,静止人体的反射基本淹没在噪声和静态多径里,只有呼吸引起的周期微动能提供线索,而呼吸检测对环境和距离极其敏感。如果你计划做"房间里有没有没人"这种存在性检测,务必提前用目标场景实测,别被演示视频里的理想效果带偏。
频率选择上也要有预期:2.4GHz穿墙好但分辨率有限,5GHz穿墙差但在无遮挡场景下精度更高。RuView这种项目默认跑2.4GHz是合理的,但如果你的部署场景是不穿墙的更近距离(比如隔着一扇门),可以试试5GHz频段的CSI,动作识别清晰度会有提升。
6.2 隐私边界与合规红线:无感监测不是偷窥
我必须花一段专门讲这个。WiFi穿墙感知最大的优势——不需要目标佩戴任何设备、无需摄像头、目标完全无感知——同时也是最大的伦理风险。这项技术如果被用于监视他人,性质极其恶劣,而且现实中很多国家的法律对无感采集周边环境信息有严格的限制。
我个人的态度和建议很简单:
- 这套技术只用于自己的住宅、自己管理的场所(比如自己的店铺内部安防),不要用于任何公共区域或他人私人空间。
- 如果系统检测到他人住宅内部的信号特征,应当主动屏蔽对应方向的天线敏感区,而不是"反向利用"。
- 开源项目存在的价值是教育和技术探索,不是为偷窥提供工具。转载、分享、讲解这套技术时,请务必把合规边界讲清楚。
从积极的角度看,WiFi感知的合规价值恰恰在于它的"无感"和"低侵入":不给被监护者(比如老人)佩戴任何设备,不需要安装摄像头侵犯隐私,只输出"有人/无人/跌倒"这类状态量,不保留可辨识身份的原始图像。这是养老监护场景里非常理想的技术形态。
6.3 后续扩展:跌倒检测、睡眠监测、多房间定位
如果你跑通了基础检测,下一步有几个方向我觉得特别值得投入:
第一个是跌倒检测。摔倒的动作特征是高速、宽频的多普勒冲击,和正常走动、坐下的信号特征差异很大。在卧室(一堵墙范围)内部署,老人卧室床边和卫生间洗手台前是两个最高价值的监测点。难点是环境中的重物掉落、宠物跳上跳下也会产生类似特征,需要采集足够多负样本才能做出可靠分类。
第二个是睡眠监测。把呼吸频率和翻身检测叠加起来,就能实现无穿戴的睡眠质量分析。原理上利用的是CSI对胸腔微动的敏感性,实现时难点在于长时间稳定采集和自动去噪——夜间空调、风扇、窗外车辆都会进入感知范围,需要做时变频率追踪才能保持呼吸信号锁定。
第三个是多房间定位。用多组天线同时采集不同方向的CSI,通过比较波动出现的时间先后和幅度强弱,可以把活动判别缩小到"哪个房间"。这个方法不需要每个房间都放接收机,成本低,适合独居老人的全屋安全监护。
还有更前沿一点的,比如把CSI特征输入轻量神经网络(CNN或Transformer)做动作类型识别,分类"走路/坐下/摔倒/挥手"。这类数据驱动方案需要较多的标注数据,但一旦训练完成,鲁棒性通常好于手工特征。
就我个人而言,我接下来最想把呼吸检测的算法再打磨一遍,目标是实现一整夜稳定的呼吸率追踪。WiFi感知这条路的潜力远不止"看穿墙"这个噱头,它本质上是把日常基础设施变成传感网络——如果有一天你家里随处可感知、但又完全无感知地保护着隐私,那这套技术就真正成熟了。