A $0, laptop-only "reveal the invisible" art piece (part of the Unseen art project). Point the webcam at your face; it amplifies the otherwise-invisible color change of blood flowing under your skin so you watch your pulse, and shows a live BPM + waveform — all rendered on black. Pure Rust, real-time, from-scratch DSP.
| Part | State | How verified |
|---|---|---|
| Webcam capture (nokhwa/V4L2, warmup) | working | live: negotiates 1280x720@30, decodes RGB |
| 3-thread pipeline (capture/process/render) | working | headless snapshot + live run, no drops |
| Temporal band-pass (4th-order biquad cascade) | verified | unit tests: passes in-band, rejects out-of-band |
| rPPG BPM estimator (FFT + band-pass prefilter) | verified | unit tests: recovers 50/72/88/132 BPM ±3, gates low-SNR |
| BPM gate (prominence) + EMA tracker | verified | unit tests: drowned pulse gated; tracker smooths/holds |
| EVM color magnification + skin gate | verified | unit tests: static=unchanged, in-band=amplified, skin mask |
| EVM motion magnification (DoG) | verified | unit tests: static=unchanged, in-band feature amplified |
| Mode toggle (color / motion) | working | live run, key M, both stages kept warm |
| Hybrid render: vignette + bloom + waveform + BPM | working | live run renders, no panic; bloom visible |
11/11 unit tests pass (cargo test). The DSP + magnification cores are verified on synthetic
signals. The visual effect itself needs a real lit face in frame — verify it per below.
- Linux — developed and tested on Pop!_OS; capture goes through V4L2 (
/dev/video0) vianokhwa. nokhwa is cross-platform, so macOS/Windows may work, but they're untested. - A webcam, and a recent Rust toolchain (rustup).
- Good, steady light on your face. rPPG reads a ~1% skin-color change; in a dark room there's nothing to amplify. Face a lamp/window; avoid flicker and big movements.
git clone https://github.com/oneKn8/vitals && cd vitals
cargo run --release run # the live window (use --release for smooth 30fps)
cargo test # the DSP test suite
cargo run -- snapshot # dev: dump one composited frame to snapshot.png (no window)
cargo run -- probe # dev: dump one raw camera frame to probe.png| Key | Action |
|---|---|
M |
switch mode: PULSE (color flush) ↔ MOTION (amplified movement) |
Up / Down (or + / -) |
amplification alpha up / down |
Space |
freeze (stop adding magnification — compare to raw) |
F |
toggle fullscreen |
Esc / Q |
quit |
- Run it, sit ~50cm away, face inside the faint "align face here" box, well lit.
- Hold still ~10s. The BPM locks once enough signal is buffered; the red waveform along the bottom is your live pulse signal.
- Nudge alpha up until the flush across your face is visible but not noisy (start ~40).
Too high = blotchy noise;
Spacefreezes it so you can compare against raw.
camera -> downscale+mirror -> magnify -> vignette + bloom on black. Two magnify modes,
both fed every frame (so the toggle has no settling flash):
- Color/PULSE: per-pixel temporal band-pass in the heart-rate band, amplified, gated by a YCbCr skin mask (only the face flushes), upsampled and added back.
- MOTION: a Difference-of-Gaussians luminance band, temporally band-passed and amplified, exaggerating tiny movement.
In parallel, the mean green of a face ROI feeds an FFT-based rPPG estimator (zero-phase
band-pass prefilter, Hann window, parabolic peak, prominence gate, EMA-smoothed) for a stable
BPM + the waveform. Full design + rationale in DESIGN.md.
- wgpu HDR bloom — current bloom is a CPU bright-pass + blur (LDR); true HDR additive bloom wants the wgpu render backend (macroquad is GLES/no-HDR). Render layer is isolated.
- Face detection (
rustface) to auto-place the ROI instead of the fixed center box. - Hardware AE/WB lock — blocked by a panic in
v4l 0.14's control enumeration on this webcam; mitigated in software by the band-pass. Would need a rawVIDIOC_S_CTRLioctl.
Camera frames are processed in memory and never written to disk; only numeric features
leave the frame. (probe/snapshot are dev-only and dump a PNG, which is git-ignored.)
MIT © 2026 Shifat Islam Santo