Skip to content

Use native segmentation parser and mask#304

Open
rolandocortez wants to merge 13 commits into
mainfrom
feat/86ca5v4v7-86ca5y69r-native-segmentation
Open

Use native segmentation parser and mask#304
rolandocortez wants to merge 13 commits into
mainfrom
feat/86ca5v4v7-86ca5y69r-native-segmentation

Conversation

@rolandocortez

@rolandocortez rolandocortez commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Purpose

Use native DepthAI segmentation components in depthai-nodes.

This PR updates the segmentation flow to use native dai.SegmentationMask and native dai.node.SegmentationParser where applicable, while preserving the existing host-side depthai-nodes parser for hostOnly=True.

It also aligns host parser background semantics with the native parser and fixes visualization of binary segmentation masks where class 0 is a valid foreground class and 255 is background.

Additionally, this PR adds the missing setStrides(...) setter to YOLOExtendedParser.

Specification

  • Removed the custom depthai_nodes.message.segmentation.SegmentationMask message.
  • Added explicit copy_message(dai.SegmentationMask) support.
  • Updated ParserGenerator to use native dai.node.SegmentationParser when parser_name == "SegmentationParser" and hostOnly=False.
  • Preserved depthai_nodes.node.parsers.segmentation.SegmentationParser for hostOnly=True.
  • Added RVC2 handling for native segmentation parser by setting it to run on host.
  • Added background_class support to the host SegmentationParser.
  • Updated host parser semantics to match native behavior:
    • background_class=True maps class 0 to 255.
    • Foreground class ids are preserved.
    • Single-channel/unassigned-class behavior still shifts correctly.
    • classes_in_one_layer=True ignores background_class.
  • Updated ApplyColormap handling for native dai.SegmentationMask:
    • 255 background maps to visual background index 0.
    • class 0 maps to a visible foreground index.
  • Added YOLOExtendedParser.setStrides(...) for manually setting YOLO output head strides.

Dependencies & Potential Impact

This depends on a DepthAI version exposing native dai.SegmentationMask and dai.node.SegmentationParser.

Potential impact is limited to segmentation parsing, segmentation mask copying, segmentation visualization paths, and the new YOLO parser strides setter API. The existing host segmentation parser path remains available through hostOnly=True.

Direct Visualizer rendering of binary dai.SegmentationMask values [0, 255] may not visibly color class 0; the ApplyColormap -> ImgFrameOverlay path handles this correctly.

Deployment Plan

No special deployment steps required.

Rollback: revert this PR.

Testing & Validation

  • Focused unit tests passed:
    • tests/unittests/test_messages/test_copy_message.py
    • tests/unittests/test_nodes/test_host_nodes/test_apply_colormap_node.py
  • Validated host SegmentationParser.run() directly with synthetic NN output.
  • Confirmed host background semantics match native parser behavior:
    • class 0 -> 255 when background_class=True
    • foreground class ids are preserved
    • single-channel/unassigned-class path still shifts correctly
    • classes_in_one_layer=True ignores background_class
  • Validated with the segmentation MRE on OAK-1 / RVC2:
    • DeepLab 512 host output no longer has foreground off-by-one compared with native parser.
    • DeepLab person host/native outputs produce valid [0, 255] masks.
    • ApplyColormap -> ImgFrameOverlay correctly visualizes binary masks where foreground class id is 0.
  • Validated YOLOExtendedParser.setStrides(...) locally:
    • accepts list and tuple stride values
    • rejects invalid, empty, non-integer, zero, and negative stride values
  • python -m compileall passed for touched parser files.

Note: For luxonis/mediapipe-selfie-segmentation:256x144, a dual-parser MRE feeding the same NeuralNetwork output to both parsers showed native dai.node.SegmentationParser emitting only [0], while the host depthai-nodes parser emitted [0, 255] for the same sequence numbers and mask shape. Since both parsers consumed the same NN output, this appears isolated to the native parser/model metadata path rather than the host parser changes in this PR.

AI Usage

Assisted-by: ChatGPT

Submitted code was reviewed by a human: YES

The author is taking the responsibility for the contribution: YES

Summary by CodeRabbit

  • New Features
    • Added native DepthAI dai.SegmentationMask support across parsing/remapping and ApplyColormap processing.
    • Introduced background_class for segmentation outputs.
    • Added setStrides support for extended YOLO parsing.
    • Updated documentation from removed segmentation-mask messaging to the new SnapData type.
  • Bug Fixes
    • Standardized segmentation masks to uint8, with consistent handling for empty/unassigned pixels.
  • Documentation
    • Updated parser and node docs to reference dai.SegmentationMask.
  • Tests
    • Updated stability/e2e and unit tests for the native mask API, including copy coverage.
  • Chores
    • Bumped workflow and dependency DepthAI versions to 3.7.1.

@rolandocortez rolandocortez requested a review from klemen1999 July 3, 2026 09:02
@github-actions github-actions Bot added the enhancement New feature or request label Jul 3, 2026
@coderabbitai

coderabbitai Bot commented Jul 3, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 8fa0c0a8-08c4-46c8-95a0-3620fc84d3ec

📥 Commits

Reviewing files that changed from the base of the PR and between c74ea5b and ea03305.

📒 Files selected for processing (6)
  • depthai_nodes/message/utils/copy_message.py
  • depthai_nodes/node/parser_generator.py
  • depthai_nodes/node/parsers/fastsam.py
  • depthai_nodes/node/parsers/segmentation.py
  • tests/stability_tests/check_messages.py
  • tests/utils/nodes/mocks/pipeline.py
💤 Files with no reviewable changes (1)
  • tests/stability_tests/check_messages.py
🚧 Files skipped from review as they are similar to previous changes (3)
  • depthai_nodes/node/parser_generator.py
  • depthai_nodes/message/utils/copy_message.py
  • depthai_nodes/node/parsers/segmentation.py

📝 Walkthrough

Walkthrough

This PR replaces the local segmentation-mask message path with dai.SegmentationMask, updates segmentation parsing and remapping to use uint8 masks with 255 sentinels, bumps DepthAI versions to 3.7.1, adds YOLOExtendedParser.setStrides, and updates message documentation to SnapData.

Changes

Native SegmentationMask migration

Layer / File(s) Summary
Creator and export changes for native SegmentationMask
depthai_nodes/message/creators/segmentation.py, depthai_nodes/message/__init__.py, depthai_nodes/node/README.md, tests/unittests/test_creators/test_segmentation.py, tests/utils/messages/creators/arrays.py
create_segmentation_message now uses depthai.SegmentationMask, requires uint8 masks, and writes masks via setCvMask; exports and tests were updated to match.
copy_message support for native SegmentationMask
depthai_nodes/message/utils/copy_message.py, tests/unittests/test_messages/test_copy_message.py
copy_message now clones native segmentation masks, including CV mask data and optional labels, and has a unit test for the new path.
ApplyColormap consumer update
depthai_nodes/node/apply_colormap.py, tests/unittests/test_nodes/test_host_nodes/test_apply_colormap_node.py
ApplyColormap accepts dai.SegmentationMask, remaps mask values before colormap application, and extends coverage for segmentation-mask inputs.
SegmentationParser background_class support and pipeline wiring
depthai_nodes/node/parser_generator.py, depthai_nodes/node/parsers/segmentation.py, tests/stability_tests/run_parser_test.py
ParserGenerator gets a dedicated SegmentationParser branch, SegmentationParser adds background_class handling and uint8 output normalization, and parser tests pass the host-only flag for that parser.
FastSAM mask sentinel and merge update
depthai_nodes/node/parsers/fastsam.py, depthai_nodes/node/parsers/utils/fastsam.py
FastSAM now uses dai.SegmentationMask in docs and initializes empty/merged masks with 255 as uint8.
Message remapping and type constants for dai.SegmentationMask
depthai_nodes/node/utils/message_remapping.py, depthai_nodes/node/utils/util_constants.py
Segmentation-mask remapping and message type bounds now operate on dai.SegmentationMask through getCvMask() and setCvMask().
Stability test helper update for native mask
tests/stability_tests/check_messages.py
Stability checks now validate native segmentation masks, normalize expected masks, and compare against getCvMask().

CI and dependency version bump

Layer / File(s) Summary
depthai version bump across workflows and requirements
.github/workflows/e2e_tests.yaml, .github/workflows/stability_tests.yaml, requirements.txt
Workflow defaults, job arguments, and the minimum depthai requirement now use version 3.7.1.

YOLOExtendedParser stride configuration

Layer / File(s) Summary
setStrides method addition
depthai_nodes/node/parsers/yolo.py
Adds a validated setter for configuring YOLO head strides.

SnapData documentation update

Layer / File(s) Summary
SnapData README entries
depthai_nodes/message/README.md
Replaces SegmentationMask README entries with SnapData message documentation.

Estimated code review effort: 4 (Complex) | ~60 minutes

Suggested reviewers: klemen1999, tersekmatija, dtronmans

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly reflects the main change: switching segmentation handling to native DepthAI parser and mask types.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/86ca5v4v7-86ca5y69r-native-segmentation

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
depthai_nodes/node/utils/message_remapping.py (1)

62-78: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Use a uint8 border sentinel here cv2.warpPerspective turns borderValue=-1 into 0 for uint8 masks, so remapped border pixels are labeled as class 0 instead of the unassigned sentinel used elsewhere (255). Set borderValue=255 or make it dtype-aware.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@depthai_nodes/node/utils/message_remapping.py` around lines 62 - 78, The
remapping logic in remap_segmentation_mask_array uses a borderValue that does
not preserve the unassigned class for uint8 masks, so border pixels get remapped
to class 0 instead of the sentinel used elsewhere. Update the
cv2.warpPerspective call to use a uint8-safe sentinel such as 255, or make the
borderValue depend on the segmentation_mask dtype, while keeping the existing
transformation and interpolation behavior unchanged.
depthai_nodes/node/utils/util_constants.py (1)

12-23: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Change UNASSIGNED_MASK_LABEL to 255 in mask remapping. depthai_nodes/node/utils/message_remapping.py still uses this constant as borderValue for cv2.warpPerspective, and -1 gets clipped to 0 for uint8 masks, not 255. That turns padded/unassigned pixels into class 0 instead of background.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@depthai_nodes/node/utils/util_constants.py` around lines 12 - 23, The mask
remapping background sentinel is wrong: UNASSIGNED_MASK_LABEL should be set to
255 so padded pixels stay as background instead of being clipped to 0 for uint8
masks. Update the constant in util_constants and keep message_remapping’s
cv2.warpPerspective borderValue usage aligned with that sentinel so unassigned
mask areas remain correctly marked.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/e2e_tests.yaml:
- Around line 114-115: The `exec hil_runner` command in the workflow is
interpolating `github.ref_name` directly into a shell string, which can allow
template/shell injection on the runner. Move `github.ref_name` and the other
`${{ }}` values used in `--docker-run-args` into step-level `env:` variables,
then reference them as shell variables inside the `run:` command. Keep the fix
localized to this workflow step so the `exec hil_runner` invocation no longer
embeds attacker-influenced values directly.

In `@depthai_nodes/node/parsers/fastsam.py`:
- Around line 380-382: The empty-detection fallback in merge_masks handling is
using an all-255 mask, which gets treated as active pixels and overwrites the
output instead of preserving the background/unassigned sentinel. Update the
no-results branch in fastsam.py around the results_masks initialization so the
fallback is zero-filled before calling merge_masks(), keeping the inactive path
truly inactive.

In `@depthai_nodes/node/parsers/segmentation.py`:
- Around line 47-58: The SegmentationParser currently skips the
`background_class` remap whenever `classes_in_one_layer` is true, so class 0
remains unchanged in that combination. Update the parsing logic in
`SegmentationParser` so the background remap is still applied when
`background_class` is enabled, even if `classes_in_one_layer` is set, or
explicitly validate/document that this flag combination is unsupported. Use the
`SegmentationParser` initializer and the class-remapping branch in its parse
flow to locate the change.

In `@depthai_nodes/node/utils/message_remapping.py`:
- Around line 81-92: remap_segmentation_mask currently rebuilds a new
dai.SegmentationMask but only transfers the CV mask, so labels metadata is lost.
Update remap_segmentation_mask in message_remapping.py to preserve labels the
same way copy_message.py does: read labels from the input segmentation_mask when
available, and set them on new_mask after setCvMask, using the same guarded
getLabels/setLabels pattern as the existing message-copy logic.

---

Outside diff comments:
In `@depthai_nodes/node/utils/message_remapping.py`:
- Around line 62-78: The remapping logic in remap_segmentation_mask_array uses a
borderValue that does not preserve the unassigned class for uint8 masks, so
border pixels get remapped to class 0 instead of the sentinel used elsewhere.
Update the cv2.warpPerspective call to use a uint8-safe sentinel such as 255, or
make the borderValue depend on the segmentation_mask dtype, while keeping the
existing transformation and interpolation behavior unchanged.

In `@depthai_nodes/node/utils/util_constants.py`:
- Around line 12-23: The mask remapping background sentinel is wrong:
UNASSIGNED_MASK_LABEL should be set to 255 so padded pixels stay as background
instead of being clipped to 0 for uint8 masks. Update the constant in
util_constants and keep message_remapping’s cv2.warpPerspective borderValue
usage aligned with that sentinel so unassigned mask areas remain correctly
marked.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: cb782501-6076-47ad-931e-5f93cb42ebc7

📥 Commits

Reviewing files that changed from the base of the PR and between 90b4974 and 5a93ce6.

📒 Files selected for processing (23)
  • .github/workflows/e2e_tests.yaml
  • .github/workflows/stability_tests.yaml
  • depthai_nodes/message/README.md
  • depthai_nodes/message/__init__.py
  • depthai_nodes/message/creators/segmentation.py
  • depthai_nodes/message/segmentation.py
  • depthai_nodes/message/utils/copy_message.py
  • depthai_nodes/node/README.md
  • depthai_nodes/node/apply_colormap.py
  • depthai_nodes/node/parser_generator.py
  • depthai_nodes/node/parsers/fastsam.py
  • depthai_nodes/node/parsers/segmentation.py
  • depthai_nodes/node/parsers/utils/fastsam.py
  • depthai_nodes/node/parsers/yolo.py
  • depthai_nodes/node/utils/message_remapping.py
  • depthai_nodes/node/utils/util_constants.py
  • requirements.txt
  • tests/stability_tests/check_messages.py
  • tests/unittests/test_creators/test_segmentation.py
  • tests/unittests/test_messages/test_copy_message.py
  • tests/unittests/test_messages/test_segmentation_msg.py
  • tests/unittests/test_nodes/test_host_nodes/test_apply_colormap_node.py
  • tests/utils/messages/creators/arrays.py
💤 Files with no reviewable changes (4)
  • depthai_nodes/message/init.py
  • depthai_nodes/message/segmentation.py
  • tests/unittests/test_messages/test_segmentation_msg.py
  • depthai_nodes/message/README.md

Comment thread .github/workflows/e2e_tests.yaml
Comment thread depthai_nodes/node/parsers/fastsam.py Outdated
Comment thread depthai_nodes/node/parsers/segmentation.py
Comment thread depthai_nodes/node/utils/message_remapping.py

@klemen1999 klemen1999 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Few comments but overall looks good

Comment thread depthai_nodes/message/utils/copy_message.py Outdated
Comment thread depthai_nodes/node/parsers/utils/fastsam.py
Comment thread depthai_nodes/node/parsers/fastsam.py Outdated
Comment thread depthai_nodes/node/parsers/segmentation.py Outdated
@klemen1999

Copy link
Copy Markdown
Collaborator

TODO: Before merge we need next DepthAI version released. This means that we need to wait with merge and update the requirements.txt

Comment thread depthai_nodes/node/parser_generator.py Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/stability_tests/run_parser_test.py`:
- Around line 93-96: The stability test currently forces SegmentationParser to
use the host-side path, so it never validates the native
dai.node.SegmentationParser flow. Update the test around parser_generator.build
in run_parser_test.py to add a separate SegmentationParser case or parameterize
hostOnly so both host-only and native segmentation parsing are exercised, while
keeping the existing parser_name-based logic for the other parsers.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ba14b24d-a601-46b7-846e-fc0328c0b379

📥 Commits

Reviewing files that changed from the base of the PR and between 5a93ce6 and c74ea5b.

📒 Files selected for processing (3)
  • depthai_nodes/node/parsers/fastsam.py
  • tests/stability_tests/check_messages.py
  • tests/stability_tests/run_parser_test.py
🚧 Files skipped from review as they are similar to previous changes (2)
  • tests/stability_tests/check_messages.py
  • depthai_nodes/node/parsers/fastsam.py

Comment thread tests/stability_tests/run_parser_test.py
@rolandocortez

Copy link
Copy Markdown
Contributor Author

Got it. Pushed the follow-up fixes and CI is green now. I fixed the stability failures from the native SegmentationMask migration, addressed the review comments around getLabels/setLabels, background_class handling, and setNNArchiveHead(head), and updated the parser mock to match the new ParserGenerator API usage.

Comment thread depthai_nodes/node/parsers/fastsam.py Outdated
Comment thread tests/stability_tests/check_messages.py Outdated
Comment thread tests/stability_tests/run_parser_test.py
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