Skip to content

Commit 449f4a9

Browse files
committed
Ensure shapely coordinate consistency across Python versions
1 parent 50e045f commit 449f4a9

File tree

1 file changed

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

1 file changed

+33
-1
lines changed

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

Lines changed: 33 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,38 @@ 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 hasattr(result_geometry, 'geom_type') and result_geometry.geom_type == 'Polygon':
71+
from shapely.geometry import MultiPolygon
72+
result_geometry = MultiPolygon([result_geometry])
73+
74+
geometry_dict = result_geometry.__geo_interface__
75+
return self._normalize_coordinates(geometry_dict)
76+
77+
def _normalize_coordinates(self, geometry_dict):
78+
"""Normalize coordinates to ensure consistent tuple format across shapely versions"""
79+
80+
def ensure_tuple_coords(obj):
81+
"""Recursively ensure coordinate pairs are tuples"""
82+
if isinstance(obj, (list, tuple)):
83+
# Check if this is a coordinate pair [x, y]
84+
if len(obj) == 2 and all(isinstance(x, (int, float)) for x in obj):
85+
return (float(obj[0]), float(obj[1]))
86+
else:
87+
# Recursively process nested structures, preserving list/tuple types
88+
if isinstance(obj, list):
89+
return [ensure_tuple_coords(item) for item in obj]
90+
else:
91+
return tuple(ensure_tuple_coords(item) for item in obj)
92+
return obj
93+
94+
result = geometry_dict.copy()
95+
if 'coordinates' in result:
96+
result['coordinates'] = ensure_tuple_coords(result['coordinates'])
97+
return result
6698

6799
def draw(
68100
self,

0 commit comments

Comments
 (0)