Wi-Fi CSI 跌倒检测:可用的低频特征、误报控制与证据边界
作者 Wu Jun · 更新于 2026-10-29 · 约 7 分钟
跌倒检测是 Wi-Fi 感知里商业价值很高的方向,也是最容易把「有剧烈变化」误写成「可靠识别跌倒」的方向。 WiFall 与 WiCare 证明了 CSI 可以捕获与跌倒相关的无线信号变化 [1] [2], 但这些论文的硬件、采样率、房间和受试者条件不能自动复制到一台约 12.64Hz 独立快照率的家用路由器上。
本文给出一个诚实的研究基线:利用慢运动包络、事件前上下文和事件后恢复期,先做「疑似跌倒事件」检测; 不声称医疗级准确性,也不把 8 条链记录当成 95Hz 微多普勒。
1. 先划清能力边界
| 任务 | 当前 GL-MT6000 路线 | 说明 |
|---|---|---|
| 检测明显运动 | 可以 | 幅度/相位随时间和子载波变化 |
| 检测突然的大幅事件 | 可以研究 | 但坐下、放包、关门也会产生大幅变化 |
| 提取事件级包络 | 可以 | 独立快照率约 12.64Hz |
| 恢复完整冲击微多普勒 | 不可以默认宣称 | 12.64Hz 的无模糊多普勒仅 ±6.32Hz |
| 医疗级跌倒识别 | 不可以 | 需要临床验证、风险管理与合规设备 |
| 自动呼救 | 不应由原型直接承诺 | 仍需人工复核与可靠告警链路 |
本项目 10 分钟抓包证明 256 子载波 CSI 能稳定采集,57,293 条链记录按 bit15 得到 7,609 个测量组, 独立快照率约 12.64Hz [3] [4]。它没有跌倒事件标签,因此不能用于计算 跌倒准确率。
2. 为什么不能把 95.5 条记录/秒当采样率
一次 CSI 测量最多包含 8 条 tx/rx 链记录,它们共享接近相同的时间点。8 条链提供空间/频率多样性, 不是 8 个连续时间采样。若把 57,293 条记录按 95.5Hz 串成相位序列,会产生两个错误:
- Nyquist 范围被人为扩大;
- 同时刻链路差异被误读为时间演化。
正确顺序是:
- 按
chain_infobit15 闭合测量; - 每个测量组选一条有效链或构造稳定的多链特征;
- 按
file_ts排序并重采样; - 明确报告独立快照率、最大空档与可用组比例。
12.64Hz 可以描述一次持续数百毫秒到数秒的身体运动包络,但不足以恢复 5GHz 下 1m/s 运动约 33Hz 的
真实步行微多普勒。算法必须针对这个限制设计,而不是靠改一个 FS=95 常量绕过。
3. 可解释的事件特征
跌倒不是一个孤立帧,而是一段事件:
事件前:有人走动/站立
事件中:短时大幅变化
事件后:坐下可能继续调整,跌倒后可能出现一段低运动期
因此特征应包含上下文与恢复期,而不是只看单个方差峰值。下面的代码假设 H 是每次测量选一条链后的
幅度矩阵,t 是对应时间戳,事件候选时刻为 event_t:
import numpy as np
def resample_rows(H, t, fs=20.0):
t = np.asarray(t, dtype=float)
order = np.argsort(t)
t, H = t[order], np.asarray(H)[order]
tu = np.arange(t[0], t[-1], 1.0 / fs)
Hu = np.column_stack([
np.interp(tu, t, H[:, i]) for i in range(H.shape[1])
])
return Hu, tu
def event_features(H, t, event_t, fs=20.0):
H, t = resample_rows(H, t, fs)
motion = np.abs(np.diff(H, axis=0)).mean(axis=1)
tm = t[1:]
pre = motion[(tm >= event_t - 8) & (tm < event_t - 2)]
event = motion[(tm >= event_t - 1) & (tm <= event_t + 1.5)]
post = motion[(tm > event_t + 1.5) & (tm <= event_t + 5)]
if min(len(pre), len(event), len(post)) < 10:
return None
baseline = float(np.median(pre))
peak = float(np.max(event))
quiet = float(np.mean(post))
# Low-frequency event-band share, not micro-Doppler.
x = event - event.mean()
power = np.abs(np.fft.rfft(x * np.hanning(len(x)))) ** 2
freqs = np.fft.rfftfreq(len(x), 1.0 / fs)
mask = (freqs >= 0.5) & (freqs <= 4.0)
return {
"pre_motion": baseline,
"event_peak": peak,
"peak_ratio": peak / (baseline + 1e-9),
"recovery_ratio": quiet / (peak + 1e-9),
"low_band_ratio": float(power[mask].sum() / (power.sum() + 1e-12)),
}
这里的 low_band_ratio 只是 0.5–4Hz 的运动能量占比,不是多普勒展宽。若要使用真实多普勒,必须先证明
硬件独立快照率足够,并引入已知速度/事件真值。
4. 从特征到状态机
建议先做简单状态机,而不是一上来用不可解释的深层模型:
- 事件前 2–8 秒出现持续行走/站立活动;
- 事件峰值显著高于同一 session 的静止基线;
- 事件上升沿足够陡,但允许 0.4–1.5 秒的人体动作时间;
- 事件后 1.5–5 秒运动低于峰值,形成恢复期;
- 触发后进入 30 秒不应期,避免同一事件重复告警;
- 输出
suspected_fall_event、证据字段和前后各 10 秒原始数据; - 由人工复核或受控规则决定是否告警。
阈值应来自你自己的带标签数据:
limits = {
"min_peak_ratio": 0, # calibrate from negatives
"max_recovery_ratio": 1, # calibrate from positives/negatives
"min_low_band_ratio": 0,
}
示例中的 0/1 只是占位,不能直接部署。必须用空房、坐下、放包、关门、宠物和模拟跌倒数据选择阈值, 并报告误报与漏报。
5. 采集协议
跌倒研究首先是人因与安全问题。只能使用软垫模拟跌倒,不应让受试者执行危险真实跌倒。
5.1 最小数据集
| 类别 | 建议事件数 | 作用 |
|---|---|---|
| 软垫模拟跌倒 | 每受试者 30–50 | 正样本;记录事件起点和恢复期 |
| 坐下 / 起立 | 30–50 | 最常见的相似负样本 |
| 放包 / 弯腰 | 30–50 | 大幅但非跌倒 |
| 正常行走 | 30–50 | 提供事件前上下文 |
| 关门 / 家电冲击 | 20–30 | 无人体上下文的突发负样本 |
| 空房 / 风扇 | 至少 2 小时 | 估计环境周期与空房误报 |
5.2 场景变量
- 至少 2 名受试者、2 个身高/体型范围和 2 个位置;
- 至少两种家具布局与两种链路方向;
- 记录 AP 高度、距离、朝向、信道、带宽、TX 功率;
- 记录 RSSI、SNR、独立快照率、最大空档和有效组比例;
- 事件标签包含起点、峰值、恢复时间和是否人工复核;
- 数据按 session 与受试者切分,不能把重叠窗口随机分到训练和测试集。
5.3 标签示例
session,subject,event_t,class,position,recovered_s,reviewed
s01,u01,2026-11-01T10:03:22Z,simulated_fall,p1,3.8,true
s01,u01,2026-11-01T10:06:10Z,sit,p1,,true
不要只保存处理后特征。保留原始 CSI、时间戳和质量统计,才能复核算法是否真的用了正确的数据。
6. 评估指标
跌倒事件极稀疏,单看 accuracy 没有意义。至少报告:
- 事件级 precision、recall、F1;
- 每类混淆矩阵:跌倒、坐下、放包、关门、空房;
- 每天误报次数;
- 漏报次数与检测延迟;
- 监测时长与有效覆盖率;
- 按受试者、房间、距离分组的结果;
- 置信区间与失败 session。
如果系统每天产生 20 次告警,即使离线 accuracy 是 95%,实际使用也会失败。养老场景首先关心的是误报负担 和人工复核成本。
7. 常见失败模式
| 现象 | 可能原因 | 处理 |
|---|---|---|
| 把坐下识别成跌倒 | 同样有大幅运动,恢复期差异小 | 加入事件前上下文与恢复期,增加负样本 |
| 每次关门都触发 | 突发能量没有人体空间/运动上下文 | 多链路一致性、持续性与前置活动门控 |
| 换房间全部失效 | 多径与距离变化 | 重新标定,按环境验证 |
| 同一事件重复告警 | 滑窗重叠 | 事件聚合与不应期 |
| 离线结果异常好 | 同 session 窗口泄漏 | 按受试者和日期切分 |
| 采样率看似 95Hz | 把并发链记录串成时间序列 | 按 bit15 组合并选链 |
| 宣称能识别所有跌倒 | 缺少真实与相似事件验证 | 改成"疑似事件",给出失败条件和人工复核 |
8. 证据与合规边界
WiFall 与 WiCare 等工作说明该方向有研究价值 [1] [2];CSI 特征体系可参考 系统综述 [5]。但这些论文不能替代你所在硬件、房间和人群上的验证。
产品措辞必须是:
- 「检测到疑似跌倒事件」,不是「确认跌倒」;
- 「研究/辅助功能」,不是「医疗器械」;
- 「通知人工复核」,不是自动承诺救护响应;
- 明确知情同意、数据保存、删除和关闭方式;
- 没有摄像头也属于监控,必须说明隐私影响。
9. 下一步需要的数据
本项目当前公开数据只能用于运动包络和解析器验证,不能证明跌倒准确率。真正下一步应采集:
- 至少 5 名受试者、2 个房间、3 个位置;
- 软垫模拟跌倒与坐下、放包、关门、宠物等负样本;
- 同步视频或人工事件标记作为真值,视频需获得同意并限制访问;
- 每次采集保存原始 CSI、固件版本、快照率和质量报告;
- 先建立事件级规则基线,再与机器学习模型比较。
10. 结论
- 当前约 12.64Hz 的独立快照率适合事件级运动包络,不足以恢复完整冲击微多普勒;
- 可用特征是事件前上下文、突发能量、恢复期和多链路一致性;
- 先做可解释规则和事件级指标,再考虑复杂模型;
- 每天误报次数、漏报与人工复核成本,比漂亮的离线 accuracy 更重要;
- 没有带标签数据与合规审查,就不能宣传医疗级跌倒检测。
相关:呼吸/心率检测 · Wi-Fi CSI 雷达边界 · 接入 Home Assistant
参考与数据来源
本文的每条外部结论都标注来源与证据等级(分级标准);标注 E 级的是本项目可复现的实测数据。
- B 级 · 同行评审
WiFall: Device-free fall detection by wireless networks
C. Han, K. R. R. Wu, Y. Wang · IEEE INFOCOM 2014 · 2014
doi:10.1109/infocom.2014.6847948 · 被引 201 · 核实: CrossRef API, 2026-10-11 · CSI 跌倒检测的开创性工作(被引 201 次)。 - B 级 · 同行评审
WiCare: Accidental Fall Detection for Elderly Care Using Passive Wi-Fi Sensing
K. Rishi, et al. · IEEE ICSC 2023 · 2023
doi:10.1109/icsc60394.2023.10441553 · 被引 2 · 核实: CrossRef API, 2026-10-11 · 养老场景的被动 Wi-Fi 跌倒检测(较新、被引少,作为方向性证据)。 - E 级 · 本项目实测
本项目 10 分钟实测抓包(57,293 条 / 600.0 s,SHA-256 00373f83…95e2)
Router CSI Lab · 2026
okwujun.pw/zh/datasets/ · 核实: 分片重组逐字节校验通过(2026-10-11) · 本地原始母片 SHA-256 为 00373f83…95e2;公开下载的是去标识派生文件,SHA-256 为 527466ce…a440,两者不可混用。 - E 级 · 本项目实测
Router CSI Toolkit — 采集/分析/守护脚本(MIT,公开仓库)
Router CSI Lab · 2026
github.com/jjjwu/router-csi-toolkit · 核实: GitHub API 于 2026-11-02 核实公开仓库、抓包质量预检、成功 CI 与 v0.1.3 Release;归档 SHA-256 为 59f144c0…adea7 · 公开版含无第三方依赖的抓包质量预检;网页端检查器使用同一容器定义和边界口径。 - A 级 · 标准/综述
WiFi Sensing with Channel State Information: A Survey
W. Ma, W. Zhou, X. Wang · ACM Computing Surveys · 2019
doi:10.1145/3310194 · 被引 857 · 核实: CrossRef API, 2026-10-11 · 领域内最常被引用的 CSI 感知综述(被引 857 次,核实于 CrossRef)。