Skip to main content

fastmask-seg

Unique colors, pixel counts, per-color boolean masks, and bounding boxes from segmentation masks stored as images.

import cv2
import numpy as np
import fastmask_seg as fms

image = cv2.imread("instance_mask.png")  # (H, W, 3) uint8, one solid color per instance

result = fms.unique_color_masks(image)
result.colors        # (K, 3) uint8 colors present, in BGR order because OpenCV loads BGR
result.color_counts  # (K,) int64 pixel count per color
result.masks         # (K, H, W) bool, one mask per color

road = fms.get_color_mask(image, color=np.array([128, 64, 128], np.uint8))  # (H, W) bool
boxes = fms.masks_to_bboxes(result.masks)  # (K, 4) int64 rows of (rmin, rmax, cmin, cmax)

The library targets instance and semantic segmentation masks, where each class or instance is one solid color. Its fast paths rely on what those images look like: few distinct colors in long runs of identical pixels.

Install

pip install fastmask-seg            # NumPy only
pip install "fastmask-seg[numba]"   # adds compiled kernels for 3-channel images

Requires Python 3.12+ and NumPy 2.0+. The numba extra gives the same results as NumPy, with color analysis 1.3-2x faster and masks of named colors 2-4x faster (details).

API

fm = fms.FastMask(image)             # computes on first access and caches, so later queries reuse the analysis
fm.unique_colors                     # (K, C) uint8 colors in the image's channel layout, ordered by color ID
fm.unique_color_ids                  # (K,) sorted color IDs
fm.unique_color_counts               # (K,) int64 pixel counts
fm.label_image                       # (H, W) index of each pixel's color in unique_color_ids
fm.color_id_image                    # (H, W) color ID of each pixel
fm.get_color_masks(colors=palette)   # ColorMasks(masks, num_masks), one mask per requested color
fm.get_color_masks()                 # every color in the image
fm.get_color_mask(color=c)           # one (H, W) bool mask
fm.iter_color_masks()                # one (H, W) mask at a time, for many colors on large images

# Each FastMask member is also a function that takes an image or a FastMask:
fms.unique_colors(image)
fms.get_color_masks(image, colors=palette)
fms.unique_color_masks(image)        # UniqueColorMasks(colors, color_ids, color_counts, masks, num_masks)

fms.masks_to_bboxes(masks)           # (K, 4) boxes of a (K, H, W) bool stack
fms.mask_to_bbox(mask)               # (rmin, rmax, cmin, cmax) of one mask

fms.colors_to_color_ids(colors)      # (..., 3) or (..., 4) uint8 colors to uint32 IDs
fms.color_ids_to_colors(ids, fms.ColorFormat.COLOR)
fms.sort_colors(colors)              # colors in color ID order
  • Images are uint8 arrays of shape (H, W), (H, W, 3), or (H, W, 4), as cv2.imread or np.asarray(PIL.Image.open(...)) give them. In a grayscale image the gray value is the color.
  • Colors follow the image's channel order: BGR for OpenCV, RGB for Pillow. A color ID packs a color into one uint32 with channel 0 in the lowest byte.
  • Mask requests take colors= or color_ids=, and with neither they cover every color in the image. A color absent from the image gives an all-False mask.
  • Bounding boxes have exclusive ends, so mask[rmin:rmax, cmin:cmax] crops a mask to its pixels. An empty mask raises ValueError.
  • Functions and FastMask: a function given an image analyzes it from scratch on each call. Wrap the image in a FastMask to ask several questions about one image, and pass that object to the functions when you prefer their form.
  • Arguments are used as given. The docstrings state each required shape and dtype, and other inputs surface as NumPy errors or wrong results.

Processing many images

Allocate the mask buffer once and pass it as out=, so each image writes into memory the process already holds:

masks_buf = np.empty((64, H, W), dtype=bool)  # room for up to 64 colors per image

for path in paths:
    result = fms.unique_color_masks(cv2.imread(path), out=masks_buf)
    ...  # result.masks is masks_buf[:result.num_masks], overwritten by the next image

For a fixed class palette, pass the palette straight to get_color_masks(image, colors=palette, out=...); with the numba extra this is the fastest path. docs/performance.md covers the backends, the NumPy-path color_id_buffer, caching, and benchmarks.

Development

make dev     # uv sync --dev
make check   # ruff, isort, mypy --strict
make format  # isort + ruff format

License

MIT

Metadata

Release files for fastmask-seg 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for fastmask-seg 0.1.0
File Size Uploaded Provenance Actions
fastmask_seg-0.1.0.tar.gz 17.5 kB Without provenance Details for fastmask_seg-0.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for fastmask-seg 0.1.0
File Interpreter ABI Platform Actions
fastmask_seg-0.1.0-py3-none-any.whl Python 3 none any Details for fastmask_seg-0.1.0-py3-none-any.whl

Total release size: 36.7 kB

Release files / fastmask_seg-0.1.0.tar.gz

Download URL fastmask_seg-0.1.0.tar.gz
Size 17.5 kB
Tags Source
SHA-256 checksum
How to use checksums
89ee0b250a62f176331a027e02b0bf7cabd8a8b415fe3b791dd659f64bfe2f09
BLAKE2b-256 checksum
How to use checksums
ac615f6cbde12a323eb9d0309170236e7ff3b65599f51df96f0dbdaba6e3e3ae
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.9.4

Release files / fastmask_seg-0.1.0-py3-none-any.whl

Download URL fastmask_seg-0.1.0-py3-none-any.whl
Size 19.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d657902d0eac275f9ba5f41ab5458e0a32b298eb256b8d6895cafdb1ec0f8bd9
BLAKE2b-256 checksum
How to use checksums
e977c01078cad2d2fc4d74ba0197842a1f234a1186e2f07688f49c22a9956777
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.9.4

Security for fastmask-seg 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.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page