← mouad el alj / motion-magnification [live] · no clip yet

motion-magnification

Cameras record motion too small for your eyes — the color shift of blood flow under skin, the millimeter sway of breathing. This demo amplifies a chosen temporal-frequency band until that motion is visible, entirely in your browser. It shares its transform core with the tensor-compression demo but uses none of the compression machinery: magnification only needs the DCT into the temporal-frequency domain, per-band gains, and the inverse DCT back.

SOURCE
The webcam records ~6 seconds at 15 fps (240p with WebGPU, 144p without) — the long window is what makes ~1 Hz signals resolvable. The stream never leaves this tab. Hold as still as you can.
Record a clip, then pick a band to amplify.
TEMPORAL SPECTRUM σ² energy per temporal frequency bin; the amplified band is highlighted.

Record a webcam clip or load the sample to begin.

recorded clip
reconstruction
RENDER TIME
AMPLIFIED BAND
RENDER PATH
FORWARD DCT
capture

The forward DCT runs once per clip and the transformed tensor stays resident on the GPU; dragging the amplification slider dispatches a single fused kernel, which is why it responds in real time.

Webcam capture, tiled decomposition, band amplification, and reconstruction all happen locally in this tab.

how it works

A ~6 second webcam clip becomes a [height, width, channel, frame] tensor. An orthonormal DCT along the channel and frame axes (Rust compiled to WASM, running once per clip in a worker) moves it into a frequency domain, where each temporal-frequency bin over 96 frames at 15 fps is spaced ~0.08 Hz apart. That's finer than the window's actual resolving power — with only 6.4 s of signal, telling two close frequencies apart really costs ~0.16 Hz — but it's enough spacing to place a ~1 Hz pulse a comfortable distance from its neighboring bins. That long, deliberately low-fps window is still the point: duration buys more frequency headroom here than extra pixels would.

Magnification is then just multiplication: every transform slice gets a gain, and a single fused WebGPU kernel applies the gains and inverts both DCTs in one pass. The transformed tensor is uploaded to the GPU once and stays resident, so dragging the slider re-runs only that kernel. This is the linear, color-amplification variant of Eulerian video magnification from MIT's 2012 work — a per-pixel temporal bandpass and gain, with no spatial pyramid — so it's simpler and noisier than the paper's full motion-magnification pipeline. Without WebGPU, a WASM fallback renders on the CPU at reduced resolution.

Honest caveats: pulse amplification needs decent lighting, a still subject, and a still camera; amplification also magnifies sensor noise, which is physics, not a bug. The webcam's own auto-exposure and white-balance can drift during the recording at frequencies that overlap the pulse and breathing bands, and nothing here locks them — some of what you see amplified may be the camera adjusting itself, not you. The sample video's short, low-fps clip only supports the slower bands. Everything runs locally — the webcam stream is stopped as soon as capture ends and never leaves the tab.

Bundled sample: Big Buck Bunny, © 2008 Blender Foundation / bigbuckbunny.org, licensed under CC BY 3.0; trimmed to three seconds and encoded at 1280×720 for this demo.

Webcam capture, tiled decomposition, band amplification, and reconstruction all happen locally in this tab. ← mouad el alj · email · cv