feat(coco): read instance-segmentation datasets (polygon→SegmentationMask, identity tracks)#479
Merged
Merged
Conversation
Read COCO instance-segmentation datasets into the segmentation data model:
- coco.read_labels/read_labels_set/load_coco gain `segmentation_format`
("mask" default | "roi"). In "mask" mode, an annotation's polygon(s) are
rasterized into a single UserSegmentationMask at the image resolution
(multi-ring annotations collapse into one mask; degenerate rings with <3
vertices are skipped). "roi" keeps the prior vector UserROI behavior. RLE
segmentation is always read as a SegmentationMask. Polygons fall back to ROI
when the image entry lacks height/width.
- New `category_as_track` option: create one shared Track per COCO category
(named after the category) and assign it to that category's masks, ROIs,
bboxes, and keypoint instances lacking an explicit track id.
- _is_coco_data now detects keypoint-free detection/segmentation COCO (a JSON
object with images/annotations/categories arrays). Label Studio and
AlphaTracker exports are JSON arrays, so the dict signature does not collide.
- load_file forwards the new kwargs through to load_coco.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- test_coco.py: mask-default vs roi-mode reads, multi-polygon -> single mask (x/y extents), degenerate-ring skip, dims fallback, invalid segmentation_format, category_as_track (masks + bboxes + roi-mode ROIs, shared Track objects, .slp round-trip, off-by-default), load_file kwarg forwarding, and a keypoint-free COCO load_file + .slp round-trip. - test_main.py: keypoint-free segmentation COCO is classified as coco. - docs/formats/coco.md: segmentation handling + categories-as-identities. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #479 +/- ##
=======================================
Coverage 92.96% 92.97%
=======================================
Files 54 54
Lines 19421 19439 +18
Branches 4391 4394 +3
=======================================
+ Hits 18055 18073 +18
Misses 651 651
Partials 715 715 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Contributor
Docs PreviewPreview has been removed. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds first-class support for reading COCO instance-segmentation datasets (polygon or RLE) into the segmentation data model, and makes keypoint-free COCO datasets load through the normal auto-detection path. Previously, polygon
segmentationwas always read as a vectorUserROI(only RLE became aSegmentationMask), andload_file()could not auto-detect a COCO file that lacked keypoints.Key Changes
SegmentationMaskby default.coco.read_labels/read_labels_set/load_cocogain asegmentation_formatargument:"mask"(new default): each annotation's polygon(s) are rasterized into a singleUserSegmentationMaskat the image resolution. Multiple rings of one annotation collapse into one object mask."roi": keeps the previous behavior (oneUserROIper ring).SegmentationMask, regardless of the setting._is_coco_datanow recognizes detection/segmentation-only COCO (a JSON object withimages/annotations/categoriesarrays) instead of requiring keypoints. Label Studio and AlphaTracker exports are JSON arrays, so this dict-shaped signature does not collide with them.category_as_trackoption creates one sharedTrackper COCO category (named after the category) and assigns it to that category's masks, ROIs, bounding boxes, and keypoint instances (when they have no explicit track id). Useful for instance-segmentation datasets where the category encodes identity rather than object class. DefaultFalse.Example Usage
Masks round-trip through
.slp(RLE-compressedmask_rledataset), with category and identity-track preserved.API Changes
coco.read_labels(..., segmentation_format="mask", category_as_track=False)— new keyword args (back-compatible signature; behavior default changed for polygon segmentation, see below).coco.read_labels_set(...)andmain.load_coco(...)— same two new keyword args, forwarded through;load_file(..., segmentation_format=..., category_as_track=...)forwards them too.read_labelsraisesValueErrorfor an unknownsegmentation_format.Design Decisions
segmentationfield is the segmentation, so mapping it to theSegmentationMaskmodel is the more faithful default and is what exercises the segmentation pipeline end-to-end. The previous polygon→ROI behavior remains available viasegmentation_format="roi". The existing polygon-read test was updated and a roi-mode test added.imagesentry'sheight/width. If those are missing, the polygon falls back to anROI(there is no extent to rasterize into).Testing
tests/io/test_coco.py: mask-default vs roi-mode reads, multi-polygon→single mask (x and y extents), degenerate-ring skip, dims-fallback, invalidsegmentation_format,category_as_track(masks + bboxes + roi-mode ROIs, shared Track objects,.slpround-trip, off-by-default),load_filekwarg forwarding, and a keypoint-free COCOload_file+.slpround-trip.tests/io/test_main.pyfor keypoint-free segmentation COCO.ruff format/ruff checkclean; full test suite green.🤖 Generated with Claude Code