Skip to content

feat: add compact RLE mask ingestion#2367

Open
Borda wants to merge 18 commits into
developfrom
perf-CMask/1
Open

feat: add compact RLE mask ingestion#2367
Borda wants to merge 18 commits into
developfrom
perf-CMask/1

Conversation

@Borda

@Borda Borda commented Jun 29, 2026

Copy link
Copy Markdown
Member

This pull request introduces support for returning segmentation masks as CompactMask objects in the detection pipeline, providing a more efficient and flexible mask representation. The changes allow users to opt-in to this new format via the compact_masks argument, affecting both mask decoding and the Detections.from_inference API. Several internal utilities and the main mask handling logic have been updated to support this feature.

New CompactMask support for segmentation masks:

  • src/supervision/detection/core.py: Added a compact_masks keyword argument to Detections.from_inference, allowing users to request segmentation masks as CompactMask objects instead of dense NumPy arrays. The argument is documented, and the call to process_roboflow_result is updated accordingly. [1] [2] [3]

  • src/supervision/detection/utils/internal.py: Updated process_roboflow_result to support the compact_masks argument. When enabled, segmentation masks are decoded and returned as CompactMask instances, either directly from COCO RLE or by converting dense masks. The function's return type and documentation are updated, and the mask construction logic is refactored to handle both dense and compact formats. [1] [2] [3] [4] [5] [6] [7]

Core CompactMask functionality and utilities:

  • src/supervision/detection/compact_mask.py:
    • Added new internal helpers for decoding COCO RLE (_coco_rle_counts_to_array) and trimming RLE columns (_rle_trim_col_runs).
    • Implemented CompactMask.from_coco_rle, enabling efficient construction of compact masks from COCO RLE payloads and bounding boxes without materializing dense arrays.
    • Minor bugfixes and type improvements, including proper use of cast for type safety in iteration and summation. [1] [2] [3] [4]

Type and import updates:

  • Updated imports and type annotations throughout the codebase to support the new CompactMask type and ensure type correctness.

These changes improve mask handling performance and flexibility, especially when working with large images or batches, while maintaining backward compatibility with existing dense mask workflows.


                                         CompactMask from_inference                                         
╭────────────────────────────┬───────────┬─────┬──────────┬───────┬───────┬─────────────┬─────────────┬────╮
│ src                        │ res       │ seg │ dense ms │ CM ms │     x │     peak MB │     mask MB │ ok │
├────────────────────────────┼───────────┼─────┼──────────┼───────┼───────┼─────────────┼─────────────┼────┤
│ people-walking.jpg         │ 1920x1080 │  14 │    20.48 │  4.61 │ 4.44x │  58.07/0.07 │  29.03/0.01 │ ✓  │
│ soccer.jpg                 │ 398x224   │   1 │     0.08 │  0.14 │ 0.59x │   0.18/0.02 │   0.09/0.00 │ ✓  │
│ vehicles.mp4#269           │ 3840x2160 │  59 │   396.23 │ 24.92 │   16x │ 978.79/0.13 │ 489.37/0.04 │ ✓  │
│ milk-bottling-plant.mp4#94 │ 1920x1080 │  12 │    19.44 │  3.94 │ 4.93x │  49.78/0.07 │  24.88/0.01 │ ✓  │
│ vehicles-2.mp4#637         │ 1920x1080 │  12 │    18.48 │  3.81 │ 4.85x │  49.78/0.07 │  24.88/0.01 │ ✓  │
│ grocery-store.mp4#501      │ 3840x2160 │  56 │   376.66 │ 23.86 │   16x │ 929.02/0.14 │ 464.49/0.04 │ ✓  │
│ subway.mp4#649             │ 2160x3840 │  45 │   345.71 │ 14.45 │   24x │ 746.53/0.12 │ 373.25/0.03 │ ✓  │
│ market-square.mp4#237      │ 2160x3840 │  59 │   454.17 │ 18.92 │   24x │ 978.79/0.13 │ 489.37/0.04 │ ✓  │
│ people-walking.mp4#170     │ 1920x1080 │  13 │    19.42 │  4.12 │ 4.71x │  53.93/0.07 │  26.96/0.01 │ ✓  │
│ beach-1.mp4#223            │ 3840x2160 │  55 │   367.12 │ 23.10 │   16x │ 912.43/0.14 │ 456.19/0.04 │ ✓  │
│ basketball-1.mp4#238       │ 1920x1080 │  15 │    22.17 │  4.20 │ 5.28x │  62.22/0.07 │  31.10/0.01 │ ✓  │
│ skiing.mp4#176             │ 1920x1080 │  15 │    22.70 │  4.20 │ 5.41x │  62.22/0.07 │  31.10/0.01 │ ✓  │
╰────────────────────────────┴───────────┴─────┴──────────┴───────┴───────┴─────────────┴─────────────┴────╯

Co-authored-by: Codex <codex@openai.com>
@codecov

codecov Bot commented Jun 29, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 90.62500% with 18 lines in your changes missing coverage. Please review.
✅ Project coverage is 83%. Comparing base (934da12) to head (e064c6e).

Additional details and impacted files
@@           Coverage Diff            @@
##           develop   #2367    +/-   ##
========================================
  Coverage       83%     83%            
========================================
  Files           69      69            
  Lines         9616    9771   +155     
========================================
+ Hits          7941    8095   +154     
- Misses        1675    1676     +1     
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@Borda Borda added the enhancement New feature or request label Jun 29, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds an opt-in pathway to keep segmentation masks in a compact RLE-backed representation (CompactMask) throughout Roboflow/Inference ingestion, reducing the need to materialize dense (N, H, W) boolean mask stacks.

Changes:

  • Added compact_masks keyword to Detections.from_inference(...) and plumbed it into Roboflow result parsing.
  • Extended process_roboflow_result(...) to optionally return CompactMask instead of dense masks.
  • Implemented CompactMask.from_coco_rle(...) plus supporting RLE utilities, and added tests covering the new behavior.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/supervision/detection/core.py Adds compact_masks option to Detections.from_inference and forwards it into Roboflow result parsing.
src/supervision/detection/utils/internal.py Adds compact_masks option to process_roboflow_result, returning masks as CompactMask when enabled.
src/supervision/detection/compact_mask.py Adds COCO RLE transcoding utilities and CompactMask.from_coco_rle(...) to avoid dense mask materialization.
tests/detection/utils/test_internal.py Adds tests verifying process_roboflow_result(..., compact_masks=True) returns CompactMask and preserves behavior.
tests/detection/test_core.py Adds tests for Detections.from_inference(..., compact_masks=True) representation change without pixel changes.
tests/detection/test_compact_mask.py Adds unit tests validating CompactMask.from_coco_rle(...) correctness and behavior.

Comment thread src/supervision/detection/utils/internal.py
Borda and others added 5 commits June 29, 2026 19:13
…oflow_result

- Batch COCO-RLE decode: defer per-prediction from_coco_rle calls to single
  post-loop call, eliminating O(N×W) per-prediction column-split overhead
- Mixed-batch alignment: drop all masks when only subset of predictions carry
  masks, matching tracker_id handling and preventing xyxy misalignment
- DoS guard: add _MAX_IMAGE_DIMENSION=32768 constant; raise ValueError when
  either image dimension exceeds limit in from_coco_rle
- Size-mismatch warning: emit logger.debug when compact_masks=True RLE size
  does not match image size, then fall back to dense decode
- int64 dtype fix: np.sum(counts, dtype=np.int64) prevents overflow on large masks
- Redundant outer int() removed from bbox clamp in from_coco_rle
- Sum invariant comment added to _rle_trim_col_runs
- Document that compact path drops True pixels outside the detection bbox;
  fix misleading pixel-invariance test docstring; add test asserting drop behavior

---
Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com>
…oflow_result

- 7 parametrized ValueError cases for from_coco_rle (zero-height, zero-width,
  xyxy-shape-mismatch, non-mapping-rle-item, missing-counts-key,
  counts-sum-mismatch, max-image-dimension-exceeded)
- bytes input path test for _coco_rle_counts_to_array via TestCcoRleCountsToArray
- polygon + compact_masks=True path asserts CompactMask returned
- box-only + compact_masks=True asserts None mask
- RLE size mismatch resize-fallback branch in dense path (rle_mask key)

---
Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com>
- _rle_split_cols: accept x_start/x_stop to skip columns outside crop (O(W)→O(crop_w))
- _rle_split_cols: .tolist() before loop to avoid numpy-scalar boxing overhead
- Detections.to_compact_masks(): explicit opt-in post-conversion method
- Extract _resolve_rle_mask helper; reduce process_roboflow_result branch count
- metrics: convert CompactMask to dense before cast in _detections_content
- Document _base48/_delta private symbol coupling in compact_mask.py imports
- Restrict CompactMask "more efficient" claim to memory footprint in module docstring
- Add pixel-layout annotation to from_coco_rle doctest example

---
Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com>
The __class__ constructor call in to_compact_masks() was missing
metadata=self.metadata; collection-level metadata would be silently
dropped on every conversion.

---
Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 6 comments.

Comment thread src/supervision/detection/utils/internal.py Outdated
Comment thread src/supervision/metrics/recall.py Outdated
Comment thread src/supervision/metrics/mean_average_recall.py Outdated
Comment thread src/supervision/metrics/f1_score.py Outdated
Comment thread tests/detection/test_compact_mask.py Outdated
Comment thread src/supervision/detection/core.py
Preserve CompactMask instances through mask metrics so mask_iou_batch can use the compact fast path.

Fix batched COCO RLE CompactMask slicing and add direct regression coverage for to_compact_masks and metric mask content.

Co-authored-by: Codex <codex@openai.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 12 out of 12 changed files in this pull request and generated 1 comment.

Comment thread src/supervision/detection/utils/internal.py Outdated
@Borda Borda requested a review from Copilot June 29, 2026 23:31

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 14 out of 14 changed files in this pull request and generated 1 comment.

Comment thread examples/compact_mask/README.md Outdated
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants