Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
d67563e
feat: add CompactMask for memory-efficient crop-RLE mask storage
Borda Mar 2, 2026
77a0117
fix: resolve unresolved PR 2159 review suggestions
Borda Mar 2, 2026
ad6ceb7
fix: correct bounding box coordinates in CompactMask doctests
Borda Mar 2, 2026
a417abc
Merge branch 'develop' into debug/oom
Borda Mar 2, 2026
969e002
feat: implement memory-efficient IoU and NMS with CompactMask integra…
Borda Mar 2, 2026
d41fcf7
Merge branch 'debug/oom' of https://github.com/roboflow/supervision i…
Borda Mar 2, 2026
91742a2
Merge branch 'develop' into debug/oom
Borda Mar 10, 2026
13d0156
test: add extensive tests for CompactMask IoU, NMS, and InferenceSlic…
Borda Mar 10, 2026
490cc0a
fix(pre_commit): 🎨 auto format pre-commit hooks
pre-commit-ci[bot] Mar 10, 2026
75ed494
Merge branch 'develop' into debug/oom
Borda Mar 10, 2026
1f74014
fix(pre_commit): 🎨 auto format pre-commit hooks
pre-commit-ci[bot] Mar 10, 2026
eff23f6
feat(examples): add CompactMask demo and benchmark
Borda Mar 11, 2026
66917c2
Merge branch 'develop' into debug/oom
Borda Mar 11, 2026
b42bc46
feat(examples): expand CompactMask benchmark with new stages and metrics
Borda Mar 11, 2026
c1b2f26
feat(tests): add detailed CompactMask tests for NMM, centroids, holes…
Borda Mar 11, 2026
e0f4979
feat(compact_mask): add repack(), fix merge perf, and add parity tests
Borda Mar 11, 2026
b058368
fix(pre_commit): 🎨 auto format pre-commit hooks
pre-commit-ci[bot] Mar 11, 2026
3784110
Apply suggestions from code review
Borda Mar 11, 2026
9ff6096
fix(masks): handle empty crops by defaulting centroid to (0, 0)
Borda Mar 11, 2026
3b76858
Merge branch 'debug/oom' of https://github.com/roboflow/supervision i…
Borda Mar 11, 2026
33f1dcc
feat(compact_mask): add `bbox_xyxy` property and improve type annotat…
Borda Mar 11, 2026
2968028
Apply suggestions from code review
Borda Mar 11, 2026
e1a5df8
feat(compact_mask): enhance `with_offset` for clipping and add tests
Borda Mar 11, 2026
5b1c639
docs(compact_mask): unwrap prose and add per-operation speedup analysis
Borda Mar 11, 2026
9ee7fd0
perf(compact_mask): fast path in with_offset avoids decode/re-encode
Borda Mar 11, 2026
8c28649
fix(benchmark): count NMS mismatches and explain exact-vs-resize diff…
Borda Mar 11, 2026
b63130b
test(compact_mask): add 121 parametrised random-scenario parity tests
Borda Mar 11, 2026
2930e1b
refactor: rename single-char variables to descriptive names
Borda Mar 11, 2026
b747e24
fix(nms): remove resize-to-640 approximation from mask_non_max_suppre…
Borda Mar 12, 2026
b2234da
docs(compact_mask): update README with fresh benchmark results
Borda Mar 12, 2026
a0783de
refactor(benchmark): improve summary table logic, add CSV export
Borda Mar 12, 2026
3b88b6e
fix(pre_commit): 🎨 auto format pre-commit hooks
pre-commit-ci[bot] Mar 12, 2026
c52adeb
docs(compact_mask): update README with revised benchmark speedups and…
Borda Mar 12, 2026
03e3c77
Merge branch 'debug/oom' of https://github.com/roboflow/supervision i…
Borda Mar 12, 2026
437e7ee
fix(pre_commit): 🎨 auto format pre-commit hooks
pre-commit-ci[bot] Mar 12, 2026
12ccf4f
Merge branch 'develop' into debug/oom
Borda Mar 13, 2026
4241ff9
Merge branch 'develop' into debug/oom
Borda Mar 18, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
591 changes: 591 additions & 0 deletions examples/compact_mask/README.md

Large diffs are not rendered by default.

1,097 changes: 1,097 additions & 0 deletions examples/compact_mask/benchmark.py

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion examples/time_in_zone/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ Script to run object detection on an RTSP stream using the RF-DETR model.
- `--model_size`: RF-DETR backbone size to load — choose from 'nano', 'small', 'medium', 'base', or 'large' (default 'medium').
- `--device`: Compute device to run the model on ('cpu', 'mps', or 'cuda'; default 'cpu').
- `--classes`: Space-separated list of class IDs to track. Leave empty to track all classes.
- `--confidence_threshold`: Minimum confidence score for a detection to be kept, range 01 (default 0.3).
- `--confidence_threshold`: Minimum confidence score for a detection to be kept, range 0-1 (default 0.3).
- `--iou_threshold`: IOU threshold applied during non-max suppression (default 0.7).
- `--resolution`: Shortest-side input resolution supplied to the model. The script will round it to the nearest valid multiple (default 640).

Expand Down
2 changes: 2 additions & 0 deletions src/supervision/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
)
from supervision.dataset.formats.coco import get_coco_class_index_mapping
from supervision.dataset.utils import mask_to_rle, rle_to_mask
from supervision.detection.compact_mask import CompactMask
from supervision.detection.core import Detections
from supervision.detection.line_zone import (
LineZone,
Expand Down Expand Up @@ -161,6 +162,7 @@
"ColorAnnotator",
"ColorLookup",
"ColorPalette",
"CompactMask",
"ComparisonAnnotator",
"ConfusionMatrix",
"CropAnnotator",
Expand Down
26 changes: 22 additions & 4 deletions src/supervision/annotators/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,11 @@ def annotate(

colored_mask = np.array(scene, copy=True, dtype=np.uint8)

from supervision.detection.compact_mask import CompactMask

compact_mask = (
detections.mask if isinstance(detections.mask, CompactMask) else None
)
for detection_idx in np.flip(np.argsort(detections.area)):
color = resolve_color(
color=self.color,
Expand All @@ -443,8 +448,21 @@ def annotate(
if custom_color_lookup is None
else custom_color_lookup,
)
mask = np.asarray(detections.mask[detection_idx], dtype=bool)
colored_mask[mask] = color.as_bgr()
if compact_mask is not None:
# Paint only the bounding-box crop — avoids a full (H, W) alloc.
x1 = int(compact_mask.offsets[detection_idx, 0])
y1 = int(compact_mask.offsets[detection_idx, 1])
crop_m = compact_mask.crop(detection_idx)
crop_h, crop_w = crop_m.shape
colored_mask[y1 : y1 + crop_h, x1 : x1 + crop_w][crop_m] = (
color.as_bgr()
)
else:
mask = np.asarray(
detections.mask[detection_idx],
dtype=bool,
)
colored_mask[mask] = color.as_bgr()

cv2.addWeighted(
colored_mask, self.opacity, scene, 1 - self.opacity, 0, dst=scene
Expand Down Expand Up @@ -2900,8 +2918,8 @@ def annotate(self, scene: ImageType, detections: Detections) -> ImageType:
colored_mask[y1:y2, x1:x2] = scene[y1:y2, x1:x2]
else:
for mask in detections.mask:
mask = np.asarray(mask, dtype=bool)
colored_mask[mask] = scene[mask]
mask_bool = np.asarray(mask, dtype=bool)
colored_mask[mask_bool] = scene[mask_bool]

np.copyto(scene, colored_mask)
return scene
Expand Down
Loading
Loading