Skip to content

Commit 8edfbb8

Browse files
committed
Ensure shapely coordinate consistency across Python versions
1 parent 50e045f commit 8edfbb8

File tree

1 file changed

+37
-1
lines changed
  • libs/labelbox/src/labelbox/data/annotation_types/geometry

1 file changed

+37
-1
lines changed

libs/labelbox/src/labelbox/data/annotation_types/geometry/mask.py

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ class Mask(Geometry):
3737

3838
@property
3939
def geometry(self) -> Dict[str, Tuple[int, int, int]]:
40+
# Extract mask contours and build geometry
4041
mask = self.draw(color=1)
4142
contours, hierarchy = cv2.findContours(
4243
image=mask, mode=cv2.RETR_TREE, method=cv2.CHAIN_APPROX_NONE
@@ -62,7 +63,42 @@ def geometry(self) -> Dict[str, Tuple[int, int, int]]:
6263
if not holes.is_valid:
6364
holes = holes.buffer(0)
6465

65-
return external_polygons.difference(holes).__geo_interface__
66+
# Get geometry result
67+
result_geometry = external_polygons.difference(holes)
68+
69+
# Ensure consistent MultiPolygon format across shapely versions
70+
if (
71+
hasattr(result_geometry, "geom_type")
72+
and result_geometry.geom_type == "Polygon"
73+
):
74+
result_geometry = MultiPolygon([result_geometry])
75+
76+
geometry_dict = result_geometry.__geo_interface__
77+
return self._normalize_coordinates(geometry_dict)
78+
79+
def _normalize_coordinates(self, geometry_dict):
80+
"""Normalize coordinates to ensure consistent tuple format across shapely versions"""
81+
82+
def ensure_tuple_coords(obj):
83+
"""Recursively ensure coordinate pairs are tuples"""
84+
if isinstance(obj, (list, tuple)):
85+
# Check if this is a coordinate pair [x, y]
86+
if len(obj) == 2 and all(
87+
isinstance(x, (int, float)) for x in obj
88+
):
89+
return (float(obj[0]), float(obj[1]))
90+
else:
91+
# Recursively process nested structures, preserving list/tuple types
92+
if isinstance(obj, list):
93+
return [ensure_tuple_coords(item) for item in obj]
94+
else:
95+
return tuple(ensure_tuple_coords(item) for item in obj)
96+
return obj
97+
98+
result = geometry_dict.copy()
99+
if "coordinates" in result:
100+
result["coordinates"] = ensure_tuple_coords(result["coordinates"])
101+
return result
66102

67103
def draw(
68104
self,

0 commit comments

Comments
 (0)