fastlabelops
Fast CPU primitives for integer instance masks. Requires Python 3.12+.
fastlabelops provides five small operations commonly needed around instance segmentation and
labeled images:
label_counts— count elements for each observed labelrelabel_sequential— compact arbitrary IDs to sequential labelsremove_small_objects— remove labeled objects at or below a size thresholdoverlap_counts— count only observed label-pair overlaps between two masksregionprops— compute a small set of common per-label properties in 2D
The package is deliberately low-level: NumPy arrays in, NumPy arrays out, one compiled C++ extension, no scikit-image dependency at runtime.
Installation
pip install fastlabelops
import numpy as np
from fastlabelops import (
label_counts,
overlap_counts,
regionprops,
relabel_sequential,
remove_small_objects,
)
labels = np.array(
[
[0, 17, 17],
[91, 0, 5002],
],
dtype=np.uint32,
)
ids, counts = label_counts(labels)
relabeled, n = relabel_sequential(labels)
filtered = remove_small_objects(labels, max_size=1)
props = regionprops(labels)
a_ids, b_ids, overlap = overlap_counts(labels, relabeled)
Label 0 is background throughout. Inputs already contain instance IDs; none of these functions
perform connected-component labeling.
label_counts
ids, counts = label_counts(labels, include_background=False)
Counts elements for each observed label ID. IDs are returned in ascending order and counts are
uint64. Background label 0 is excluded by default.
- supports
uint32anduint64 - arbitrary NumPy dimensionality
- accepts non-contiguous inputs
- memory scales with the number of observed labels, not
max(label) - with
include_background=True, the background row is emitted only when its count is nonzero
relabel_sequential
relabeled, n = relabel_sequential(labels, offset=0, in_place=False)
- supports
uint32anduint64 - arbitrary NumPy dimensionality
- deterministic first-occurrence relabeling
in_place=Truemutates a writable C-contiguous arrayoffset=Nstarts foreground labels atN + 1- memory scales with the number of observed labels, not
max(label)
remove_small_objects
filtered = remove_small_objects(labels, max_size=64, in_place=False)
Removes every nonzero label whose total size is less than or equal to max_size elements. Surviving
objects keep their original IDs. Disconnected regions carrying the same nonzero label are treated as
one instance.
- supports
uint32anduint64 - arbitrary NumPy dimensionality
in_place=Truemutates a writable C-contiguous arraymax_size=0is a no-op
overlap_counts
a_ids, b_ids, counts = overlap_counts(labels_a, labels_b, include_background=False)
Returns only label pairs that actually occur. By default, positions where either input is background
are ignored. Use include_background=True when full foreground/background contingency counts are
needed.
- same-shape inputs of arbitrary dimensionality
- supports
uint32anduint64, including mixed dtypes - deterministic first-occurrence pair ordering
- memory scales with observed label pairs, not a dense
(max_a + 1) x (max_b + 1)matrix
regionprops
props = regionprops(labels)
Currently 2D only and intentionally limited to:
label
area
bbox
centroid
area_bbox
Rows are sorted by ascending label. Bounding boxes use
(min_row, min_col, max_row_exclusive, max_col_exclusive). Arbitrary/gappy uint32 and
uint64 IDs are handled directly without relabeling first.
Performance
fastlabelops is CPU-only. On supported x86 CPUs, uint32 workloads automatically use AVX2 run
scanning where it helps; lightweight input sampling selects between SIMD and fallback paths.
Representative speedups versus common reference implementations on 2048²–4096² instance masks:
| Operation | vs scikit-image | vs NumPy | vs fastremap |
|---|---|---|---|
label_counts |
— | 9–16× | 4–7× |
relabel_sequential |
6–9× | — | 1.1–1.3× |
remove_small_objects |
4.5–5× | — | — |
overlap_counts |
38–55× | 26–33× | — |
regionprops |
95–97× | — | — |
overlap_counts and regionprops show the largest gains because the reference implementations
size internal structures by max(label) + 1, which is prohibitively expensive for gappy or
sparse IDs. fastlabelops sizes by observed labels, so sparse IDs cost the same as compact ones.
In the benchmarked sparse uint64 cases, scikit-image's remove_small_objects and regionprops
raised MemoryError when max(label) exceeded available memory.
Run the comparison benchmarks (requires scikit-image, scipy, and fastremap):
uv sync --dev
uv run examples/benchmark_label_counts.py
uv run examples/benchmark_relabel.py
uv run examples/benchmark_remove_small_objects.py
uv run examples/benchmark_overlap.py
uv run examples/benchmark_regionprops.py
The dependency-free benchmark matrix is also available:
uv run examples/benchmark_matrix.py
Development
uv sync --dev
uv run pytest
uv run ruff check src tests examples
uv run ruff format --check src tests examples
uv run mypy src tests examples
uv run pre-commit install
See examples/usage_example.py for a runnable example.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file fastlabelops-0.1.1.tar.gz.
File metadata
- Download URL: fastlabelops-0.1.1.tar.gz
- Upload date:
- Size: 32.4 kB
- Tags: Source
- Uploaded using 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}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dedcd6c27b03c6868c56cec8a5e4c021d3d8391385e10fd2874691d47efd3e05
|
|
| MD5 |
1049b6822d3e33ab1c6ef2b7d4260c6a
|
|
| BLAKE2b-256 |
a57b144af2be9450e6b7772bd073040123cd490bfb617ec1dab72e4cb1672806
|
File details
Details for the file fastlabelops-0.1.1-cp312-cp312-macosx_11_0_arm64.whl.
File metadata
- Download URL: fastlabelops-0.1.1-cp312-cp312-macosx_11_0_arm64.whl
- Upload date:
- Size: 47.0 kB
- Tags: CPython 3.12, macOS 11.0+ ARM64
- Uploaded using 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}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1aa862e05ff331ce48d40fe91326c4afc0c3b055011065a88b0ca87a4e1a47b8
|
|
| MD5 |
bae9dbb9cac1f0c536a59eca0d012dcf
|
|
| BLAKE2b-256 |
08bd8d9f14544508e09365b5d263752a3c3845cb2eb60b4f87a01fa2855b794d
|