fixed precision converting annotations with "force_mask=True"#1746
fixed precision converting annotations with "force_mask=True"#1746Borda merged 16 commits intoroboflow:developfrom
"force_mask=True"#1746Conversation
|
Hi @0xD4rky 👋🏻 thanks a lot for your interest in our library. It's true that the YOLO format requires normalization of box coordinates and masks, and loading and re-saving the dataset can lead to distortions, and we would like to minimize the level of these distortions. However, before we decide to introduce any changes to supervision datasets, I need to see that your proposed solution actually minimizes the distortions. The test you attached only shows that the masks processed in two different ways are different. However, there is no reference point to the source polygon. That is, we don't know if and by how much the output polygon differs from the input one. I would like to see a test where we have the source |
|
Thanks @SkalskiP for pointing out the need to verify that change. I forgot to add the verification to it. I created a sample label file to notice how polygon's coordinates used to change before the change and how does the change handle the polygon rounding. The below is the piece of code I used to analyze the changes in polygon's observed coordinates. We start with a known polygon in normalized YOLO coordinates. After loading and saving via
You can see how the processed polygon coordinates are similar to the original coordinates after we have taken the changes into consideration.
|
|
hello @SkalskiP please review the changes once you have time, thanks! |
sure, I undestabd that :) |
There was a problem hiding this comment.
Pull request overview
This PR attempts to fix precision loss when loading YOLO polygon annotations with force_mask=True. The issue occurs when normalized polygon coordinates are converted to pixel coordinates and back, causing rounding errors that result in misaligned masks. The proposed solution is to delay integer conversion until the last moment before calling cv2.fillPoly.
Changes:
- Modified
_polygons_to_masksfunction to inline the mask creation logic instead of callingpolygon_to_mask - Removed import of
polygon_to_maskfrom converters module - Added blank line in docstring formatting
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Add test_yolo_polygon_mask_precision_no_coord_drift verifying that load → save round-trip keeps coordinate drift under 0.005 normalised units [resolve roboflow#1] Review comment by @Borda (PR roboflow#1746): "could you pls add a test to demonstrate the previous issue and that your fix resolves it"
- Add test_polygons_to_masks_multiple_polygons_shape: verifies (N, H, W) output shape with fractional pixel coords and disjoint mask assertion - Add test_yolo_polygon_mask_precision_no_coord_drift: round-trip load/save with odd resolution (101x97) to ensure non-integer pixel coordinates [resolve roboflow#1] Review comment by @Borda (PR roboflow#1746): "could you pls add a test to demonstrate the previous issue and that your fix resolves it"
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## develop #1746 +/- ##
=======================================
Coverage 77% 77%
=======================================
Files 62 62
Lines 7640 7640
=======================================
+ Hits 5911 5919 +8
+ Misses 1729 1721 -8 🚀 New features to boost your workflow:
|
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
- Reuse polygon_to_mask in YOLO mask conversion - Align load_yolo_annotations Returns docstring indentation - Make polygon round-trip precision test mask-IoU based Co-authored-by: Codex <codex@openai.com>
… 0xD4rky/develop
…ixtures - Introduced `yolo_mask_round_trip_sample` pytest fixture for reusable test setup. - Split the regression test into separate checks (`loads_mask` and `round_trip_iou`) for clarity and improved readability.


Description
When we use supervision to load YOLO annotations with force_masks=True, it internally converts normalized polygon coordinates from your YOLO text files into pixel coordinates (multiplying by image width/height) and then back into normalized coordinates when saving them out. During this round-trip, integer casting or rounding may occur, causing slight shifts in the polygon coordinates. This leads to “crooked” or misaligned masks.
Type of change
Please delete options that are not relevant.
How has this change been tested, please provide a testcase or example of how you tested the change?
YOUR_ANSWER
Minimal Reproducible Code:
Docs
The Docs haven't been updated yet, I need to check the validity of the PR with the maintainers first!