Back to Ruview

WiFlow Browser Trainer · calibrate → capture → train → infer, in your camera's frame

examples/through-wall/wiflow_browser.html

20962.9 KB
Original Source

empty-room baseline (ADR-151) — step OUT of the space

① detect ESP32 sensorsnot detected

② calibrate baseline (10 s)recalibrateget-ready countdown s

enable camera (to confirm room empty)

camera: off

baseline

CSI source—

statusNOT CALIBRATED

frames in baseline0

age—

The room's static WiFi channel is mostly constant. We capture ~10 s of the quiescent field (you OUT of the space) and compute a per-feature running mean + std (Welford) over the 410-d CSI vector. Afterwards every CSI vector is expressed as deviation from baseline : x_norm = (x − base_mean) / (base_std + ε) — applied consistently in capture, train, and infer. This makes a body's perturbation stand out from the static channel. You must calibrate before capturing.

laptop camera MediaPipe skeleton = GROUND TRUTH (the label)

stand still

enable laptop camera

camera: off

guided capture

CSI source—

CSI nodes—

pose visibility—

pass / activity— / —

this activity samples0

total samples0

est. time / samples—

last skip reason—

passes sec / activity get-ready s

● start guided recordingpauseskip activity ⏭clear dataset

export dataset (JSON)import dataset

per-pose coverage (balance the dataset)

A pair is recorded only when BOTH (a) a confident MediaPipe pose (mean visibility > 0.5) AND (b) a fresh live CSI frame (source==esp32) exist. We store the baseline-normalized CSI + the 17 keypoints, mirrored to IndexedDB so a refresh keeps them. The routine runs multiple interleaved passes through every activity, so a chronological held-out split contains the same activity mix as training (fixes the OOD split). Follow the prompt so every pose bucket fills up.

train (TensorFlow.js)

total samples0

train / val split— / — (chronological 80/20)

epoch0

train MSE—

val MSE—

held-out [email protected]

held-out [email protected]

held-out MPJPE—

mean-pose baseline [email protected]

epochs patience train modelstop

no model yet — calibrate, capture, then train.

The bar to beat is the mean-pose baseline (predict the train-mean pose for everything). A model that doesn't clear it has learned no usable CSI→pose signal — this page says so plainly. Inputs are standardized on the train split only (after baseline-normalization); the val split is the chronological last 20%, never trained on.

loss curve — train (amber) vs val (blue)

Idle.

WiFi-inferred pose CSI ONLY — no camera in the loop

hide camera (skeleton on black)enable camera

camera: off

no model loaded

live inference

CSI source—

CSI nodes—

presence—

infer fps—

measured held-out [email protected]

This skeleton is inferred from WiFi CSI only (baseline-normalized, then through the model). It is coarse — the held-out PCK above is the real number. It is drawn over the same laptop-camera frame it trained in, so it aligns with the image. Same person / room / session — not validated cross-day or through-wall.