Zigvid computes H0 and H1 zigzag persistence barcodes for binary videos. It implements the pipeline of [1], providing a highly parallelisable graph-based approach that avoids constructing cubical complexes and scales to high-resolution, high-frame-rate data. The barcode decomposition is based on the algorithm presented in [2].
The package provides a Rust library for building formigrams and computing barcodes, together with optional Python bindings built using PyO3 and maturin.
- Compute H0 and H1 zigzag persistence barcodes from image frame paths.
- Configure foreground color, 4- or 8-connectivity, and union/intersection frame composition.
- Use the Rust API directly or build a Python extension module with maturin.
- Parallelise frame-level work with a configurable thread count.
This repository is being prepared for public release. The core Rust API is functional, while packaging and convenience features are still under active development.
These features will be added:
- Support NumPy arrays as direct input for Python users.
- Provide pre-built wheels for installation via
pip.
Add Zigvid as a path dependency while developing locally:
[dependencies]
zigvid = { path = "../zigvid" }Compute H0 and H1 barcodes from a sequence of binary image frames:
use zigvid::{
binary_image::foreground_info::{
BinaryColor, CompositionType, Connectivity, ForegroundInfo,
},
binary_video::compute_barcode::{compute_zigzag_barcode_h0, compute_zigzag_barcode_h1},
};
let frames = vec![
"frames/frame_00000.png",
"frames/frame_00001.png",
"frames/frame_00002.png",
];
let foreground = ForegroundInfo {
color: BinaryColor::White,
connectivity: Connectivity::Eight,
composition_type: CompositionType::Union,
padding: None,
};
let number_of_cores = 4;
let h0_barcode = compute_zigzag_barcode_h0(&frames, foreground, number_of_cores);
// Uses Alexander duality under the hood
let h1_barcode = compute_zigzag_barcode_h1(&frames, foreground, number_of_cores);
println!("H0 barcode: {h0_barcode:?}");
println!("H1 barcode: {h1_barcode:?}");For H1, pass the same ForegroundInfo; compute_zigzag_barcode_h1 applies the required foreground/background inversion internally.
Run the self-contained example:
cargo run --example minimal_barcodeminimal_barcode writes temporary test frames before computing barcodes, so it does not require local generated data or benchmark files.
The Python package is built from the same Rust crate with maturin. From the repository root, create or activate a virtual environment, then install the extension in editable mode:
python -m pip install maturin
maturin developThen import zigvid from Python:
import zigvid
barcode = zigvid.compute_barcode_from_paths(
[
"frames/frame_00000.png",
"frames/frame_00001.png",
"frames/frame_00002.png",
],
foreground_color="white",
foreground_connectivity="8",
foreground_composition_type="union",
padding=None,
num_threads=-1,
dim=None,
)
print(barcode)dim=None computes both supported dimensions. Use dim=0 for H0 only or dim=1 for H1 only.
The return value is a dictionary containing h0 and/or h1. Each dimension contains NumPy arrays grouped by interval endpoint type:
oo: open-open intervalsoc: open-closed intervalsco: closed-open intervalscc: closed-closed intervals
Each array has shape (n, 2) and stores birth/death indices.
compute_barcode_from_paths accepts:
paths: ordered image frame paths.foreground_color:"white"or"black".foreground_connectivity:"4"or"8".foreground_composition_type:"union"or"intersection".padding:None,"none","white", or"black".num_threads:-1to use available parallelism, or a positive integer.dim:None,0, or1. IfNone, both H0 and H1 are computed.
Build a wheel instead of installing in editable mode:
maturin build --release[1] D. Lanners, From Frames to Features: Scalable Zigzag Persistence for Binary Video, 2026. [arXiv]
[2] T. K. Dey and T. Hou, Computing Zigzag Persistence on Graphs in Near-Linear Time, Proceedings of the 38th International Symposium on Computational Geometry (SoCG), 2022. [DOI]
Zigvid is licensed under the MIT License. See LICENSE.