Repository navigation
fix(detection): handle empty polygons in filter_polygons_by_area and polygon_to_xyxy - #2761
Conversation
Done |
There was a problem hiding this comment.
🟡 Changes recommended
The user-visible fixes lack the changelog entry explicitly required by repository guidance.
1 open issue
What changed in this PR
Fixes empty-polygon crashes in Supervision’s detection utilities.
Changes:
- Treats empty polygons as zero-area inputs when filtering.
- Returns zero bounding boxes with preserved NumPy dtype.
- Adds regression cases for filtering, mixed inputs, and dtype preservation.
Code: 5/5; tests: 4/5; documentation: 3/5. Risk: 1/5. Assessment covers behavior, regression coverage, and repository conventions; tests were not rerun.
| File | Description |
|---|---|
| tests/detection/utils/test_polygons.py | Tests empty and mixed polygons with area constraints. |
| tests/detection/utils/test_converters.py | Tests empty inputs and bounding-box dtype preservation. |
| src/supervision/detection/utils/polygons.py | Guards empty polygons before coordinate reduction. |
| src/supervision/detection/utils/converters.py | Returns zero boxes for empty polygons and normalizes nonempty inputs. |
Review effort: Balanced
…o fix/empty-polygon-handling
filter_polygons_by_area and polygon_to_xyxy
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## develop #2761 +/- ##
=======================================
Coverage 94% 94%
=======================================
Files 83 83
Lines 13644 13650 +6
=======================================
+ Hits 12841 12848 +7
+ Misses 803 802 -1 🚀 New features to boost your workflow:
|
…d `polygon_to_xyxy` (#2761) * fix: handle empty polygons in filter_polygons_by_area and polygon_to_xyxy * fix: preserve array dtype for empty polygons in polygon_to_xyxy --------- Co-authored-by: Jirka Borovec <6035284+Borda@users.noreply.github.com>

Problem
sv.filter_polygons_by_areacrashes withValueError: zero-size array to reduction operation minimum which has no identitywhen any polygon in the input list has zero vertices (shape(0, 2)). This happens because_to_local_cv2_polygoncallspolygon.min(axis=0)unconditionally without checking for empty polygons.Similarly,
sv.polygon_to_xyxycrashes with the same reductionValueErrorwhen given an empty polygon instead of returning an all-zero bounding box matching Supervision's empty geometry convention (e.g. inmask_to_xyxy).Root cause
_to_local_cv2_polygon,polygon.min(axis=0)lacks a guard forlen(polygon) == 0. An empty polygon has area0.0in OpenCV (cv2.contourArea(np.empty((0, 2), dtype=np.float32)) == 0.0). Returning(np.empty((0, 2), dtype=np.float32), np.zeros(2, dtype=polygon.dtype))allowscv2.contourAreato evaluate0.0, sofilter_polygons_by_areafilters empty polygons cleanly according tomin_area/max_areawithout crashing.polygon_to_xyxy, callingnp.min(polygon, axis=0)on a zero-size array raisesValueError. Checkinglen(polygon) == 0and returningnp.zeros(4, dtype=output_dtype)produces an all-zeros box while preserving caller dtype.Change
src/supervision/detection/utils/polygons.py: added an empty-array check in_to_local_cv2_polygonto return(np.empty((0, 2), dtype=np.float32), np.zeros(2, dtype=polygon.dtype))whenlen(polygon) == 0.src/supervision/detection/utils/converters.py: added an empty-array check inpolygon_to_xyxyto returnnp.zeros(4, dtype=output_dtype)whenlen(polygon) == 0.tests/detection/utils/test_polygons.pyandtests/detection/utils/test_converters.pycovering empty polygons with area constraints and dtype preservation.Regression coverage
tests/detection/utils/test_polygons.py::test_filter_polygons_by_area: parameterized with empty polygon cases (min_area filter, max_area filter, and mixed empty + valid polygons).tests/detection/utils/test_converters.py::test_polygon_to_xyxy: parameterized withempty-polygon-intandempty-polygon-float32verifying all-zeros bounding box output and dtype preservation.Validation
pytest tests/detection/utils/test_polygons.py tests/detection/utils/test_converters.py— 221 passedpytest tests/detection tests/geometry— 2378 passed, 1 skippedgit diff --check— clean