pyevm
Eulerian Video Magnification — reveal invisible motion and colour changes in video.
Eulerian Video Magnification (EVM) is a computational technique that amplifies subtle, otherwise invisible variations in video — such as the colour flush of a heartbeat, the micro-vibrations of a bridge, or the barely perceptible breathing of a sleeping animal. pyevm provides clean, GPU-accelerated Python implementations of the three canonical EVM algorithms, plus a CLI and an interactive Streamlit app.
Showcase
| Original | Colour magnification | Motion magnification |
|---|---|---|
Algorithms
| Method | Best for | Reference |
|---|---|---|
| Color | Pulse detection, blood-flow visualisation | Wu et al. (2012) |
| Motion | Breathing, structural vibration | Wu et al. (2012) |
| Phase | Artifact-free motion magnification | Wadhwa et al. (2013) |
Installation
pip
pip install pyeulervid
uv
uv add pyeulervid
conda / pixi (conda-forge)
conda install -c conda-forge pyevm
pixi add pyevm
Optional: GPU-accelerated video I/O
torchcodec enables faster video decoding via FFmpeg. pip wheels are Linux-only; on Windows install via pixi (conda-forge provides Windows CUDA builds):
# pip / uv (Linux only)
pip install "pyeulervid[fast-io]"
uv add "pyeulervid[fast-io]"
# conda-forge — works on Windows + Linux + macOS
conda install -c conda-forge pyevm # torchcodec is included automatically
pixi add pyevm
Quick start
Python API
from pyevm import ColorMagnifier, MotionMagnifier, PhaseMagnifier
from pyevm.io.video import VideoReader, VideoWriter
reader = VideoReader("input.mp4")
# --- Batch mode (loads all frames into memory) ---
frames, fps = reader.read()
magnifier = ColorMagnifier(alpha=50, freq_low=0.4, freq_high=3.0)
result = magnifier.process(frames, fps)
VideoWriter("output.mp4", fps=fps).write(result)
# --- Streaming mode (O(1) memory — recommended for long/HD video) ---
magnifier = MotionMagnifier(alpha=20, freq_low=0.4, freq_high=3.0)
frame_stream, fps, n_frames = reader.stream()
output_stream = magnifier.process_stream(frame_stream, fps, n_frames=n_frames)
VideoWriter("output.mp4", fps=fps).write_stream(output_stream)
CLI
# Colour magnification
pyevm color input.mp4 output.mp4 --alpha 50 --freq-low 0.4 --freq-high 3.0
# Motion magnification
pyevm motion input.mp4 output.mp4 --alpha 20 --freq-low 0.4 --freq-high 3.0
# Phase-based magnification
pyevm phase input.mp4 output.mp4 --factor 10 --freq-low 0.4 --freq-high 3.0
# Inspect detected compute device
pyevm info
# Launch the interactive dashboard
pyevm dashboard
Add --debug to any command for verbose logging, including per-chunk timing breakdowns (pyramid build / filter / collapse) to identify performance bottlenecks.
Streamlit dashboard
pyevm dashboard
CLI reference
pyevm color
Amplifies subtle colour changes (e.g. skin-tone flush from pulse).
| Option | Default | Description |
|---|---|---|
--alpha |
50.0 |
Luminance amplification factor |
--freq-low |
0.4 |
Lower bandpass frequency (Hz) |
--freq-high |
3.0 |
Upper bandpass frequency (Hz) |
--n-levels |
6 |
Gaussian pyramid levels |
--chrom-attenuation |
0.1 |
Chrominance attenuation (0–1) |
--pyramid-level |
auto | Pyramid level to filter |
--filter |
ideal |
Filter type for batch mode; streaming always uses butterworth |
--chunk-size |
64 |
Frames per GPU batch (streaming mode) |
--max-frames |
— | Limit number of frames read |
--device |
auto | Compute device: cuda, mps, or cpu |
pyevm motion
Amplifies subtle physical motion (e.g. breathing, structural vibration).
| Option | Default | Description |
|---|---|---|
--alpha |
20.0 |
Amplification factor |
--freq-low |
0.4 |
Lower bandpass frequency (Hz) |
--freq-high |
3.0 |
Upper bandpass frequency (Hz) |
--n-levels |
6 |
Laplacian pyramid levels |
--lambda-c |
16.0 |
Spatial wavelength cutoff (px) |
--filter |
butterworth |
Filter type: butterworth or ideal |
--chunk-size |
64 |
Frames per GPU batch (streaming mode) |
--max-frames |
— | Limit number of frames read |
--device |
auto | Compute device: cuda, mps, or cpu |
pyevm phase
Artifact-free motion magnification via steerable pyramid phase decomposition.
| Option | Default | Description |
|---|---|---|
--factor |
10.0 |
Phase amplification factor |
--freq-low |
0.4 |
Lower bandpass frequency (Hz) |
--freq-high |
3.0 |
Upper bandpass frequency (Hz) |
--n-scales |
6 |
Pyramid scales |
--n-orientations |
8 |
Orientation bands per scale |
--sigma |
0.0 |
Spatial phase smoothing (0 = off) |
--filter |
ideal |
Filter type for batch mode; streaming always uses butterworth |
--attenuate |
off | Attenuate large motions (camera shake) instead of amplifying them (Fig. 11) |
--attenuate-mag |
π |
Attenuation threshold in radians |
--chunk-size |
64 |
Frames per GPU batch (64 ≈ 10 GB VRAM at 1080p) |
--max-frames |
— | Limit number of frames read |
--device |
auto | Compute device: cuda, mps, or cpu |
pyevm dashboard
Opens the interactive Streamlit dashboard in a browser. Requires streamlit to be installed (pip install streamlit).
| Option | Default | Description |
|---|---|---|
--max-upload-size |
5000 |
Maximum video upload size in MB |
--debug |
off | Enable verbose DEBUG logging |
pyevm info
Prints detected compute device, PyTorch version, and GPU details.
Hardware
pyevm automatically selects the best available compute device:
- CUDA — NVIDIA GPU
- MPS — Apple Silicon GPU
- CPU — fallback
Override with --device cuda, --device mps, or --device cpu.
References
- Wu, H.-Y., Rubinstein, M., Shih, E., Guttag, J., Durand, F., & Freeman, W. T. (2012). Eulerian Video Magnification for Revealing Subtle Changes in the World. ACM Transactions on Graphics, 31(4). PDF
- Wadhwa, N., Rubinstein, M., Durand, F., & Freeman, W. T. (2013). Phase-Based Video Motion Processing. ACM Transactions on Graphics, 32(4). PDF
Contributing
Bug reports and pull requests are welcome. Please open an issue first for any non-trivial changes.
License
Metadata
Release files for pyeulervid 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| pyeulervid-0.1.0.tar.gz | 390.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pyeulervid-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 433.2 kB
Release files / pyeulervid-0.1.0.tar.gz
| Download URL | pyeulervid-0.1.0.tar.gz |
|---|---|
| Size | 390.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ec283db08c690cb744a297354b53e8b707c32c3f43faef08c39e916ca3787ad1
|
|
BLAKE2b-256 checksum How to use checksums |
1fdb0a80dc5583d6e9386c11fd6cc19f00f7182067aa0bcb0857d7b0b5efc613
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Apr 13, 2026.
Transparency logRelease files / pyeulervid-0.1.0-py3-none-any.whl
| Download URL | pyeulervid-0.1.0-py3-none-any.whl |
|---|---|
| Size | 42.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
93a6c00501c0d65f90385acfdd8a2a066718a0a0d78f986e8629c3ae3b232f5c
|
|
BLAKE2b-256 checksum How to use checksums |
27f14d2575fdd5aacecef32fa363c6c588b1d5eb4082c6685be9327291f73679
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Apr 13, 2026.
Transparency log