fastlabelcontours
Fast direct contour extraction from 2D integer label images.
fastlabelcontours traces every nonzero label directly from one integer label map.
It does not create a full binary mask for each instance.
import numpy as np
from fastlabelcontours import contours
labels = np.array(
[[0, 7, 7],
[0, 7, 0],
[9, 9, 0]],
dtype=np.uint32,
)
result = contours(labels)
The result is a compact ragged representation:
ids: observed nonzero labels, sorted ascendingpoints: concatenated(x, y)pixel-edge verticescontour_offsets: slicespointsinto individual contourslabel_offsets: slices contours into labelsis_hole: marks inner boundaries
Contours are implicitly closed; the first point is not repeated. Coordinates follow exact pixel edges, so signed contour area sums to the number of pixels carrying each label. Diagonal-only contact does not merge components.
Why
A common implementation repeatedly materializes labels == label and calls a contour
routine once per instance. Even a better implementation still has to discover each
instance bounding box, crop it, materialize a binary mask, and invoke the contour tracer
once per object.
fastlabelcontours instead scans the label image once and traces label boundaries
directly in C++.
On a local 2048 x 2048 synthetic blob mask with 4096 instances:
| Method | Median time | Relative to fastlabelcontours |
|---|---|---|
fastlabelcontours |
~25 ms | 1.0x |
| SciPy bbox discovery + cropped OpenCV | ~55 ms | ~2.2x slower |
Rasterio features.shapes |
~105 ms | ~4.2x slower |
full-image labels == id + OpenCV per instance |
~4.95 s | ~199x slower |
The bbox-cropped OpenCV result is the most useful baseline: it avoids rescanning the full image for every label and still takes roughly twice as long in this workload. Exact results are machine- and data-dependent; run the included benchmark on your own masks.
Installation
pip install fastlabelcontours
Until wheels are published, install from source with a C++17 compiler:
pip install .
API
from fastlabelcontours import contours
result = contours(labels)
# contour i
points_i = result.points[result.contour_offsets[i] : result.contour_offsets[i + 1]]
# contours belonging to label j
first = result.label_offsets[j]
last = result.label_offsets[j + 1]
Inputs must be 2D NumPy arrays with dtype uint32 or uint64. Label 0 is background.
The public API copies non-contiguous inputs to contiguous storage before entering the C++
core.
Geometry semantics
- Coordinates are integer
(x, y)pixel-edge vertices, not pixel centers. - Contours are implicitly closed.
- Outer contours have positive signed area; holes have negative signed area.
is_holerecords the same distinction explicitly.- A label may have multiple disconnected outer contours.
- Connectivity is 4-connected, so diagonal-only contact does not merge components.
- No simplification is performed; the output represents exact raster boundaries.
Scope
fastlabelcontours deliberately stays narrow:
- 2D
uint32/uint64label images - background label
0 - CPU only
- NumPy as the only runtime dependency
- exact contours, including holes and disconnected components
- no polygon simplification or general geometry operations
Development
python -m pip install -e '.[dev,benchmark]'
pytest
ruff check .
mypy src/fastlabelcontours
python benchmarks/benchmark_contours.py --size 2048 --instances 4096
Build and validate release artifacts with:
python -m build
python -m twine check dist/*
cibuildwheel configuration for CPython 3.10-3.13 on Linux, macOS, and Windows is
included in pyproject.toml for producing binary wheels.
License
MIT
Metadata
Release files for fastlabelcontours 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 | Provenance | |
|---|---|---|---|---|
| fastlabelcontours-0.1.0.tar.gz | 14.3 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| fastlabelcontours-0.1.0-cp312-cp312-macosx_11_0_arm64.whl | CPython 3.12 | CPython 3.12 | macOS 11.0+ ARM64 | Details |
Total release size: 36.6 kB
Release files / fastlabelcontours-0.1.0.tar.gz
| Download URL | fastlabelcontours-0.1.0.tar.gz |
|---|---|
| Size | 14.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
00a3f7b8245f8585ea55dda6b49da23a6ac371c8ecdd95fd7f8a9e843a2175a8
|
|
BLAKE2b-256 checksum How to use checksums |
27c97e7489d72b66792c3e66a4f111fe1059691c827bd7df9116fdaec574f2e4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.23 {"installer":{"name":"uv","version":"0.11.23","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / fastlabelcontours-0.1.0-cp312-cp312-macosx_11_0_arm64.whl
| Download URL | fastlabelcontours-0.1.0-cp312-cp312-macosx_11_0_arm64.whl |
|---|---|
| Size | 22.2 kB |
| Tags | CPython 3.12 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
d13775aee6ae66d9acc7efb9d80a438f673ee79e592c4f0217845fd9b5c76aa3
|
|
BLAKE2b-256 checksum How to use checksums |
dbf9670fb4e9edde31b29404b9e65b3bb155b654681c3d7cbf690fe3d724cd73
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.23 {"installer":{"name":"uv","version":"0.11.23","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Security for fastlabelcontours 0.1.0
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.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.