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.1-cp313-cp313-win_amd64.whl (17.5 MB view details)

Uploaded CPython 3.13Windows x86-64

evlib-0.13.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (18.5 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ x86-64

evlib-0.13.1-cp313-cp313-macosx_11_0_arm64.whl (16.4 MB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

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

Uploaded CPython 3.12Windows x86-64

evlib-0.13.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (18.5 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ x86-64

evlib-0.13.1-cp312-cp312-macosx_11_0_arm64.whl (16.4 MB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

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

Uploaded CPython 3.11Windows x86-64

evlib-0.13.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (18.5 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ x86-64

evlib-0.13.1-cp311-cp311-macosx_11_0_arm64.whl (16.4 MB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

File details

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

File metadata

  • Download URL: evlib-0.13.1-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.1-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 7283ab8f03af327423617dfb11f3a1f6444fd0fabfa77550c43bcfe65f889c86
MD5 d15bd1f8e7e472c64f8cce4e58111b50
BLAKE2b-256 c28d0871b1276d4444e36c3d78339009b5a86a98d1886cb0a515e68348bedab2

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for evlib-0.13.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 90a46274b8161be89acf4793d46a091ea96244ae9a8e237b7389523ca6d01064
MD5 4f9731368ee63ade53504c006f5c65f8
BLAKE2b-256 115bed02e717ed9b541d8d5ecb55b05066adc77401e3939be4ee68fecb3ed5ac

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for evlib-0.13.1-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 19df7bb991c0a69157e0e4fcc5bed8cf5b03084c97178aec0ed97880fcdac5eb
MD5 2fe9aba229d1cc723775df4046deed01
BLAKE2b-256 d8b282d035df3c55e0a61bda450df82c504ce7cd7a31f7b8b8580c8740a975aa

See more details on using hashes here.

File details

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

File metadata

  • Download URL: evlib-0.13.1-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.1-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 602ebf7ad88450ff6824078b2c77f069e914fbc5a057cd6d56d5df7aee900156
MD5 219e3445b1a0a70c5c25d6604879da5b
BLAKE2b-256 71bbb7a514edcaaa2e12c43b020653eb43876197f0cf19ed7cc3f8124327c287

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for evlib-0.13.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 2cb1e6ecc2eb57fb1d3439adb6c244a8db4f65a12009097d1b13531365617f3a
MD5 1f716029d2747885243b1831d094e023
BLAKE2b-256 c990ca7554d1e837a863baab0e0470952dcdf82cfe3ff37e485632cf00d288dc

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for evlib-0.13.1-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 667eb228f8fab6281c7d9883e1f692547ce8a42c91fc49c18d3ea5828b19e470
MD5 7d72ffd398a9f4df845865686660143c
BLAKE2b-256 60663a76d2e683a60ff0ae402fbde7db951c483af1389ca2e59103d5cfa05c6d

See more details on using hashes here.

File details

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

File metadata

  • Download URL: evlib-0.13.1-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.1-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 e1fff564f3d4ec54ad978be0902404200bceeced1cc0c8ac449eabe80a07529e
MD5 fb9f8a46b60cd0f8c6cf0442b8b1c1dc
BLAKE2b-256 926662c4171120b7f8410f99dd9f176036f7e78a532ea0131a2470d798dae5e2

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for evlib-0.13.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 f214a642d6a17d4bde9c07f26c6378487ca7a93729e65355c923779ae6fcb6ac
MD5 9c5878d5e289a21233b638cc4216c753
BLAKE2b-256 a31df3c2b74df1aace36883432102ddc6343e9b72974852393797d15ffad0311

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for evlib-0.13.1-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 1d0d2102474016e4bcfa54257c4ece7c4aa682ae3b9b07c4dc71d4dae883bb3c
MD5 c790f4277f2d4d69a2b3dcc22ad50d1c
BLAKE2b-256 1b7fe7db73da16e09ec7714f79cecd2f85ed16497c0b80b622fa193a21c2d910

See more details on using hashes here.

Release history Release notifications | RSS feed

0.13.2

9 files

This release

0.13.1 This release

9 files

0.13.0

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