Skip to main content
evlib logo

evlib: Event Camera Data Processing Library

PyPI Version Python Versions Documentation Python Rust Platform License

An event camera processing library with a Rust backend and Python bindings, designed for scalable data processing with real-world event camera datasets.

Architecture

evlib keeps a thin Rust core and does all DataFrame work in Polars from Python:

  • Rust (evlib._evlib) handles only what cannot be expressed as DataFrame operations: binary format parsing (EVT2/EVT3/EVT2.1, AEDAT, AER, HDF5 with the ECF codec), construction of the Polars frame from decoded primitives, and the native dense scatter-add kernels that build RVT stacked-histogram representations (evlib.representations_rs.stacked_histogram_dense on the CPU, plus _cuda and _metal GPU kernels).
  • Python Polars handles all processing: loading filters, filtering (evlib.filtering), and representations (evlib.representations, evlib.rvt). Every query is a lazy Polars LazyFrame collected with a selectable engine, so the same code runs on the CPU streaming engine today and on the GPU via cudf-polars (collect(engine="gpu")) where CUDA is available.

evlib.load_events returns a LazyFrame and applies any time, spatial, or polarity filters as Polars expressions, so loading and filtering fuse into one GPU-collectable query.

Quick Start

xkcd

What are Event Cameras?

Event cameras (also called neuromorphic or dynamic vision sensors) operate asynchronously: each pixel independently reports brightness changes as they occur, rather than sampling frames at a fixed rate.

Each event is represented as a 4-tuple:

$$e = (x, y, t, p)$$

Where:

  • $x, y \in \mathbb{N}$: Pixel coordinates
  • $t \in \mathbb{R}^+$: Timestamp (microsecond precision)
  • $p \in {-1, +1}$ or ${0, 1}$: Polarity (brightness change direction)

An event fires when the logarithmic brightness change exceeds a threshold:

$$\log(L(x,y,t)) - \log(L(x,y,t_{\text{last}})) > \pm C$$

where $C$ is the contrast threshold. This yields microsecond temporal resolution, 120 dB+ dynamic range, and data sparsity proportional to scene motion.

For a deeper introduction, see the user guide.

event data visualisation

Basic Usage

import evlib

# Automatic format detection: returns a Polars LazyFrame
events = evlib.load_events("data/prophesee/samples/evt2/80_balls.raw")

df = events.collect(engine="streaming")
print(f"Loaded {len(df):,} events")
print(f"Resolution: {df['x'].max()} x {df['y'].max()}")
print(f"Duration:   {df['t'].max() - df['t'].min()}")

Chain Polars expressions for efficient filtering and representation extraction:

import evlib
import evlib.representations as evr
import polars as pl

events = evlib.load_events("data/prophesee/samples/hdf5/pedestrians.hdf5")

# Temporal + spatial + polarity filtering, lazily
filtered = events.filter(
    (pl.col("t").dt.total_microseconds() / 1_000_000).is_between(0.1, 0.5)
    & pl.col("x").is_between(100, 500)
    & (pl.col("polarity") == 1)
)

# Produce a stacked histogram ready for an RVT-style model
hist = evr.create_stacked_histogram(
    filtered.collect(),
    height=180, width=240,
    bins=5, window_duration_ms=50.0,
)

The transformation turns a raw asynchronous event stream into a dense, model-ready tensor. Below, the pedestrians sequence: on the left, 250ms of raw events (red +1, blue -1); on the right, the same window as a stacked histogram of five 50ms temporal bins, where the walking figures advance bin to bin:

evlib: pedestrians event stream transformed into a stacked-histogram representation, shown as five temporal bins

Both this and a fully reproducible 80_balls version (from the tracked EVT2 sample) are generated by python scripts/generate_representation_figures.py.

See the representations guide for voxel grids, time surfaces, and mixed density stacks.

RVT preprocessing backends

evlib.rvt.process_sequence(...) reproduces the RVT stacked-histogram preprocessing pipeline and offers four interchangeable backends via backend=:

  • "polars": Polars on the CPU, or on the cudf GPU engine when you pass an engine= of "gpu" or a pl.GPUEngine(...).
  • "rust": Rust dense scatter-add on the CPU.
  • "cuda": a custom CUDA scatter-add kernel on an NVIDIA GPU. It loads the nvcc-built librvt_scatter.so via the EVLIB_CUDA_LIB environment variable.
  • "metal": a Metal scatter-add kernel on Apple Silicon. Build it with CC=clang maturin develop --features metal.

The underlying native kernels are exposed directly as evlib.representations_rs.stacked_histogram_dense (CPU), stacked_histogram_dense_cuda, and stacked_histogram_dense_metal.

Performance

evlib is bit-validated against the reference implementations it competes with: RVT (PyTorch), tonic, OpenEB, and dv_processing. On the gen4_1mpx validation set (18 sequences, RTX 4090), the RVT preprocessing output matches RVT torch exactly bar a single roughly 1e-10 boundary quirk, and the timings are:

  • evlib CUDA: 283.6s, slightly ahead of RVT torch-GPU at 286.3s (parity-plus, about 1.01x).
  • evlib Rust-CPU: 406.2s, 1.32x faster than RVT torch-CPU at 534.2s.
  • evlib CUDA is 1.88x faster than RVT torch-CPU.

For the standalone representations (20M events, versus tonic NumPy): voxel_grid 1.35x, event_frame 2.9x, time_surface 2.1x.

The Polars GPU engine is not a free win for single operations, and the CUDA-versus-RVT-GPU margin is parity-plus rather than a large speedup. The biggest margins are evlib's CPU backends and the standalone representations.

[!Note]

State of the GPU and Metal work: the CUDA backend is the production GPU path and edges out RVT's torch-GPU pipeline. The Metal backend matches the CPU kernel exactly on an M2 Pro, but about 3x slower there: the workload is memory-bound and the M2 Pro's CPU cores win. Metal is a portability path (an on-device kernel where torch-CUDA cannot run), not a speed win on M2-class hardware; use backend="rust" for the fastest Apple-CPU path.

evlib vs RVT preprocessing on an RTX 4090: evlib is faster than RVT on both GPU and CPU, with matching output

More plots: the full five-backend chart rvt_final_time.png (and rvt_final_memory.png for peak memory), plus tonic_bench_time.png for the representations-versus-tonic comparison.

Full documentation: https://tallamjr.github.io/evlib/

Installation

# Basic install
pip install evlib

# With PyTorch integration
pip install evlib[pytorch]

From source (requires Rust nightly and maturin):

git clone https://github.com/tallamjr/evlib.git
cd evlib
uv venv --python 3.12 && source .venv/bin/activate
uv pip install -e ".[dev]"
maturin develop                    # default minimal build
maturin develop --features hdf5    # opt-in HDF5 support (Linux/macOS)

[!Warning]

Known issue: --features hdf5 fails against Homebrew HDF5 2.x. The Rust binding (hdf5-metno-sys 0.10.1) only supports HDF5 1.8/1.10/1.12/1.14 and panics on a 2.x header with Invalid H5_VERSION: "2.1.1". Homebrew now ships 2.x, and even its hdf5@1.14 formula currently resolves to 2.1.1, so there is no Homebrew-based fix. To build the feature, point HDF5_DIR at a genuine 1.8-1.14 install from another source, for example conda-forge:

conda install -c conda-forge "hdf5=1.14"
HDF5_DIR="$CONDA_PREFIX" maturin develop --features hdf5

The default build (no --features hdf5) is unaffected: read HDF5 via h5py, or use the EVT2/EVT3 readers (which need no HDF5 feature). On Windows, HDF5 is always read through h5py.

Distributable wheels are built with the opt-in extension-module feature, e.g. maturin build --release --features python,polars,arrow,extension-module. That feature is deliberately off by default so cargo test and maturin develop build and run without linking errors.

GPU scatter-add kernels are opt-in features. For the CUDA backend, build the nvcc kernel and point EVLIB_CUDA_LIB at the resulting librvt_scatter.so. For the Metal backend on Apple Silicon, build with CC=clang maturin develop --features metal.

HDF5 is opt-in on Linux/macOS and unavailable on Windows; use h5py directly for HDF5 I/O on Windows. Full details and platform-specific notes live in the installation guide.

Documentation

Complete documentation is published at https://tallamjr.github.io/evlib/:

Examples

Runnable examples live in examples/:

python examples/simple_example.py
python examples/filtering_demo.py
python examples/stacked_histogram_demo.py

# Jupyter notebooks
pytest --nbmake examples/

Benchmarks live in benchmarks/: the Python suite (bench_rvt_dataset.py, bench_tonic.py) at the top level, and the Rust criterion benches under benchmarks/rust/.

Development

# Tests (both run directly, no special flags needed)
pytest                        # Python (test suite only)
cargo test                    # Rust
pytest --markdown-docs docs/  # doc examples (explicit)
pytest --nbmake examples/     # example notebooks (explicit)

# Formatting / linting
black python/ tests/ examples/
cargo fmt
ruff check python/ tests/
cargo clippy -- -D warnings

See CONTRIBUTING and the architecture overview for design details.

Community & Support

  • Issues: Report bugs and request features

xkcd

License

MIT License. See LICENSE.md for details.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

evlib-0.13.0-cp313-cp313-win_amd64.whl (17.5 MB view details)

Uploaded CPython 3.13Windows x86-64

evlib-0.13.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (16.6 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ x86-64

evlib-0.13.0-cp313-cp313-macosx_11_0_arm64.whl (15.0 MB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

evlib-0.13.0-cp312-cp312-win_amd64.whl (17.5 MB view details)

Uploaded CPython 3.12Windows x86-64

evlib-0.13.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (16.6 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ x86-64

evlib-0.13.0-cp312-cp312-macosx_11_0_arm64.whl (15.0 MB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

evlib-0.13.0-cp311-cp311-win_amd64.whl (17.5 MB view details)

Uploaded CPython 3.11Windows x86-64

evlib-0.13.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (16.6 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ x86-64

evlib-0.13.0-cp311-cp311-macosx_11_0_arm64.whl (15.0 MB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

File details

Details for the file evlib-0.13.0-cp313-cp313-win_amd64.whl.

File metadata

  • Download URL: evlib-0.13.0-cp313-cp313-win_amd64.whl
  • Upload date:
  • Size: 17.5 MB
  • Tags: CPython 3.13, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.11.15

File hashes

Hashes for evlib-0.13.0-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 004fcc127daea74b2a6510f92f13095a08ae0a6dfe6dc880b960f40de08a57b2
MD5 3d0950d29376a9311135f7263f3e1f5e
BLAKE2b-256 3db6fe4a501fff02e1685a6bfb38a4d7de6ff3ffa1a296c7f66c10e7c9761f25

See more details on using hashes here.

File details

Details for the file evlib-0.13.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for evlib-0.13.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 1228faa42b9ec681e11204d3b9e59751849d2dbe66522390ee72e0897290d450
MD5 b4b98249b4c620d795141931d2dfc7a6
BLAKE2b-256 58d1d90a3ec24c523370c0400e00edc784f62193348f1ec4a4b92538cf7124fe

See more details on using hashes here.

File details

Details for the file evlib-0.13.0-cp313-cp313-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for evlib-0.13.0-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 a3ccd248a5543183d9103e5c6feefcf2aedcdfdc7b33e19155731d06c122f4f2
MD5 7c1936498086296b1173bcc36438ca7c
BLAKE2b-256 432e2421fe0c531f40712a66b9440d23381707b6a19b13e556d8d1688466adc1

See more details on using hashes here.

File details

Details for the file evlib-0.13.0-cp312-cp312-win_amd64.whl.

File metadata

  • Download URL: evlib-0.13.0-cp312-cp312-win_amd64.whl
  • Upload date:
  • Size: 17.5 MB
  • Tags: CPython 3.12, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.11.15

File hashes

Hashes for evlib-0.13.0-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 d5bea03b09013460c2fbcfb65d75975928bd8966e9d14e055f3245612a299d62
MD5 13c3c63f075dadc2b2e056d30578db00
BLAKE2b-256 9b1504c39dafb7f8fcde8983800f52b12de9272205ffa54723182477bfec628d

See more details on using hashes here.

File details

Details for the file evlib-0.13.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for evlib-0.13.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 31a374b1e2e8dfd834f87e7bddcfaa410f1d177ff35e95188def4a77e933909e
MD5 9bfe322ec22e751b521a9dece31c7fea
BLAKE2b-256 d5a8bffc83a2962abdba38a47ff741157d712d923878512baffefb8d62c52132

See more details on using hashes here.

File details

Details for the file evlib-0.13.0-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for evlib-0.13.0-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 63c7402f7a50a4fb6c70c80bbc8ec221973b23b6c9a53642a87ac16c9803717c
MD5 c1c09ecc5a2eac25eda18341d05a96a9
BLAKE2b-256 e2e4eb98e34c81c19d78a6a74ce94a61583343fe3cea0fc5d1b5a9573e7a0e9a

See more details on using hashes here.

File details

Details for the file evlib-0.13.0-cp311-cp311-win_amd64.whl.

File metadata

  • Download URL: evlib-0.13.0-cp311-cp311-win_amd64.whl
  • Upload date:
  • Size: 17.5 MB
  • Tags: CPython 3.11, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.11.15

File hashes

Hashes for evlib-0.13.0-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 fe17dcd094c0feed1fa0e604688884389937a07adfb1091cfe2151271a095b32
MD5 c4d5a59bd6556e48a7ded7fd29a9311b
BLAKE2b-256 dd59d524bbc6b898c3dd9f412d8cd06cc5c595200e0acda1f63e935437667653

See more details on using hashes here.

File details

Details for the file evlib-0.13.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for evlib-0.13.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 21cac5a2ef9a3611f31795d557b70ec6730d3b0c24cabb0332d02a2485cd9532
MD5 6aa02ec00de59651fbd916200eb36550
BLAKE2b-256 8164e2aa1d457b91aa4774b560614ad10131ccb3ce980dcbde9d7a52b2717fec

See more details on using hashes here.

File details

Details for the file evlib-0.13.0-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for evlib-0.13.0-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 4d66f8daf190e0a9317f6e7cf7042c5565d46b6201e5e7610db9724abce218d2
MD5 f0c65e908005afaf53fd5ce96785ff2e
BLAKE2b-256 7f37e74c7b423142ba08f1cd62fed62887e1201986a1fc23f739fe63cbace597

See more details on using hashes here.

Release history Release notifications | RSS feed

0.13.2

9 files

0.13.1

9 files

This release

0.13.0 This release

9 files

0.12.0

9 files

0.9.0

9 files

0.8.7

9 files

0.7.18

9 files

0.7.17

9 files

0.6.0

6 files

0.5.15

6 files

0.5.14

6 files

0.5.13

6 files

0.5.12

6 files

0.5.11

6 files

0.5.10

6 files

0.5.9

3 files

0.5.8

5 files

0.5.7

4 files

0.5.2

6 files

0.5.0

6 files

0.4.10

6 files

0.4.8

6 files

0.4.3

6 files

0.4.2

6 files

0.2.45

6 files

0.2.44

6 files

0.2.43

6 files

0.2.4

2 files

0.2.3

2 files

0.1.26

3 files

0.1.25

4 files

0.1.24

4 files

0.1.23

4 files

0.1.10

1 file

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page