用 Python 处理 Wi-Fi CSI:解析、清洗、热图与运动指标

2026-10-11 · 约 2 分钟

拿到 CSI 只是第一步;真正决定成败的是解析 → 清洗 → 特征这三步。本文给出可直接运行的最小实现。

1. 解析:先认清两种容器

容器 结构
UDP payload 24 字节头 + int16 I/Q 交错
抓包文件 每条记录前多 10 字节(double ts + uint16 len)
import struct
REC = struct.Struct("<dH")
HDR = struct.Struct("<I6sbBBBBBHHHH")
payload = HDR.size + 256 * 4          # 1048

def iter_records(path):
    with open(path, "rb") as f:
        while True:
            head = f.read(REC.size)
            if len(head) < REC.size:
                return
            _ts, length = REC.unpack(head)
            buf = f.read(length)
            if len(buf) < HDR.size:
                return
            ts, ta, rssi, snr, bw, ch, mode, _pad, n, tx, rx, chain = HDR.unpack_from(buf)
            iq = struct.unpack_from(f"<{n*2}h", buf, HDR.size)
            yield dict(ts=ts, ta=ta, rssi=rssi, snr=snr, n=n, tx=tx, rx=rx,
                       chain=chain, i=iq[0::2], q=iq[1::2])

样例数据:10 秒 / 256 子载波(可直接验证上面的解析器 [4])。

2. 清洗:相位为什么要校正

原始相位包含三部分:真实信道相位、CFO/SFO 造成的线性漂移、以及硬件相关的固定偏移。 不校正直接做 FFT,噪声会盖住呼吸/运动成分。常用三步:

  1. 去卷绕(np.unwrap);
  2. 线性拟合去斜率(去掉 CFO/SFO);
  3. 跨天线共轭乘 / CSI ratio(消除发射端相位噪声)。
import numpy as np

def sanitize_phase(phase):
    p = np.unwrap(phase)
    idx = np.arange(len(p))
    slope, intercept = np.polyfit(idx, p, 1)      # 线性漂移
    return p - (slope * idx + intercept)          # 去斜率 + 去常量

3. 特征:幅度热图与运动指标

amp = np.abs(i + 1j * q)                 # 每个子载波的幅度
heatmap = np.vstack(amplitude_rows)      # 形状 (测量数, 子载波数)

# 1 秒滚动运动指标:相邻测量之间的幅度变化
motion = np.abs(np.diff(heatmap, axis=0)).mean(axis=1)

本项目 10 分钟实测数据画出来的热图与运动曲线(原始抓包见数据集 [5]):

CSI 幅度热图

4. 常见坑

坑 表现 处理
帧率抖动 频谱出现假峰 以时间戳重采样,而非按序号
直接使用相位 结果全是噪声 先做 CFO/SFO 校正
组测量错位 4/8 条链被拆散 用 (ts, ta) 分组、chain_info bit15 判定结束
时间戳单位混淆 时间轴差 1000 倍 本项目 ts 是微秒

5. 下一步

参考与数据来源

本文的每条外部结论都标注来源与证据等级(分级标准);标注 E 级的是本项目可复现的实测数据。

  1. C 级 · 官方资料 Gi-z/CSIKit — Python CSI parsing and visualisation
    G. Zhang
    github.com/Gi-z/CSIKit · 核实: GitHub API 2026-10-11 (stars 307, MIT, last push 2025-02-19) · 支持 Atheros / Intel / Nexmon / ESP32 / FeitCSI / PicoScenes 多种格式。
  2. C 级 · 官方资料 citysu/csiread — fast Cython CSI parser
    S. Zhu
    github.com/citysu/csiread · 核实: GitHub API 2026-10-11 (stars 142, MIT, last push 2024-10-12)
  3. C 级 · 官方资料 xyanchen/WiFi-CSI-Sensing-Benchmark (SenseFi) — deep-learning benchmark
    X. Chen, et al.
    github.com/xyanchen/WiFi-CSI-Sensing-Benchmark · 核实: GitHub API 2026-10-11 (stars 638, MIT, last push 2023-11-06)
  4. E 级 · 本项目实测 Router CSI Lab — GL-MT6000 (MT7986) Wi-Fi CSI dataset, 10 s sample + 10 min capture
    Router CSI Lab · 2026
    csi.okwujun.pw/zh/datasets/ · 核实: CC BY 4.0, SHA-256 published; DOI (Zenodo) pending
  5. E 级 · 本项目实测 本项目 10 分钟实测抓包(57,293 条 / 600.0 s,SHA-256 00373f83…95e2)
    Router CSI Lab · 2026
    csi.okwujun.pw/zh/datasets/ · 核实: 分片重组逐字节校验通过(2026-10-11)