Convert video files or webcam feeds into simulated event-camera (DVS) data using log-intensity differencing. A clean-room, dependency-light reimplementation of the core idea behind v2e/ESIM — no CUDA, no PyTorch, no pretrained models. Just NumPy, OpenCV, and h5py.
pip install eventify-dvsThe CLI entry point is eventify. With uv:
uv add eventify-dvs
uv run eventify --helpThree subcommands under the eventify entry point.
Opens the default camera and shows the event stream in an OpenCV window. Press q to quit. On macOS, grant camera permission to your terminal app first (System Settings → Privacy & Security → Camera).
# Defaults — 1280x720 @ 60 FPS
eventify webcam
# Snappy, high-sensitivity preview
eventify webcam --threshold 0.03 --accum-ms 40
# Different camera
eventify webcam --device 1| Flag | Default | Purpose |
|---|---|---|
--device |
0 |
Webcam device index |
--threshold |
0.05 |
Log-intensity event threshold |
--width |
1280 |
Requested capture width |
--height |
720 |
Requested capture height |
--fps |
60 |
Requested capture FPS |
--accum-ms |
80 |
Event accumulator half-life in ms |
--max-events |
8 |
Saturation ceiling for accumulated events per pixel |
eventify convert input.mp4 events.mp4
eventify convert input.mp4 events.mp4 --threshold 0.03| Flag | Default | Purpose |
|---|---|---|
input |
— | Path to source video |
output |
— | Path to write the rendered MP4 |
--threshold |
0.05 |
Log-intensity event threshold |
Emits binary-polarity DVS events to an HDF5 file compatible with the DVS128 Gesture dataset layout (Tonic / SpikingJelly loaders).
eventify export input.mp4 events.h5
eventify export input.mp4 events.h5 --sensor-size 128,128 --interp 4| Flag | Default | Purpose |
|---|---|---|
input |
— | Path to source video |
output |
— | Path to write the HDF5 events file |
--threshold |
0.05 |
Log-intensity event threshold |
--sensor-size |
source resolution | Override as W,H |
--interp |
0 |
Interpolated sub-frames between real frames |
import numpy as np
from eventify import (
frame_to_event_tuples,
video_to_event_stream,
interpolate_frames,
write_hdf5,
EVENT_DTYPE,
)
# Per-frame-pair event tuples
events = frame_to_event_tuples(prev, curr, prev_t_us=0, curr_t_us=1000)
# events["x"], events["y"], events["t"], events["p"] — p ∈ {0, 1}
# Full stream from a video file
chunks = list(video_to_event_stream("video.mp4", sensor_size=(128, 128), interp=4))
all_events = np.concatenate(chunks)
write_hdf5("out.h5", all_events, sensor_shape=(128, 128))-
frame_to_event_tuples(prev, curr, prev_t_us, curr_t_us, c_thresh=0.05, eps=1.0, sensor_size=None)— returns a NumPy structured array with dtypeEVENT_DTYPEand fields(x: i2, y: i2, t: i8, p: i1). Polarity is binary (0 = OFF, 1 = ON). A pixel whose log-delta spansKthresholds emitsKevents, uniformly staggered across the interval. -
video_to_event_stream(source, c_thresh=0.05, sensor_size=None, interp=0, capture_settings=None)— generator yielding one structured event array per (sub-)frame-pair. Timestamps are monotonic microseconds. -
interpolate_frames(prev, curr, n_intermediate)— linearly interpolatesn_intermediateframes between two endpoints, returning a list ofn_intermediate + 2frames. -
write_hdf5(path, events, sensor_shape)— writes events in the DVS-Gesture reprocessed layout:/events .attrs["sensor_shape"] (height, width) /xs i2 /ys i2 /ts i8 microseconds /ps i1 ∈ {0, 1} -
EVENT_DTYPE— NumPy structured dtype[("x", "<i2"), ("y", "<i2"), ("t", "<i8"), ("p", "<i1")].
uv run pytestMIT — see LICENSE.