@@ -22,9 +22,10 @@ class CompressedRle(TypedDict):
22
22
23
23
24
24
Rle = Union [CompressedRle , UncompressedRle ]
25
- Polygon = List [List [int ]]
25
+ Polygon = List [int ]
26
+ PolygonGroup = List [Polygon ]
26
27
BboxCoords = NamedTuple ("BboxCoords" , [("x" , int ), ("y" , int ), ("w" , int ), ("h" , int )])
27
- Segment = Union [Polygon , Rle ]
28
+ Segment = Union [PolygonGroup , Rle ]
28
29
29
30
BinaryMask = NewType ("BinaryMask" , np .ndarray )
30
31
IndexMask = NewType ("IndexMask" , np .ndarray )
@@ -234,7 +235,7 @@ def is_uncompressed_rle(obj: Segment) -> bool:
234
235
return isinstance (obj , dict ) and isinstance (obj .get ("counts" ), bytes )
235
236
236
237
237
- def is_polygon (obj : Segment ) -> bool :
238
+ def is_polygon_group (obj : Segment ) -> bool :
238
239
return (
239
240
isinstance (obj , list )
240
241
and isinstance (obj [0 ], list )
@@ -259,7 +260,7 @@ def crop_covered_segments(
259
260
ratio_tolerance : float = 0.001 ,
260
261
area_threshold : int = 1 ,
261
262
return_masks : bool = False ,
262
- ) -> List [Union [Optional [BinaryMask ], Polygon ]]:
263
+ ) -> List [Union [Optional [BinaryMask ], List [ Polygon ] ]]:
263
264
"""
264
265
Find all segments occluded by others and crop them to the visible part only.
265
266
Input segments are expected to be sorted from background to foreground.
@@ -314,13 +315,14 @@ def crop_covered_segments(
314
315
area_top = sum (mask_utils .area (rle_top ))
315
316
area_ratio = area_top / area_bottom
316
317
317
- # If a segment is already fully inside the top ones, stop accumulating the top
318
+ # If the top segment is (almost) fully inside the background one,
319
+ # we may need to skip it to avoid making a hole in the background object
318
320
if abs (area_ratio - iou ) < ratio_tolerance :
319
- break
321
+ continue
320
322
321
323
rles_top += rle_top
322
324
323
- if not rles_top and is_polygon (wrapped_segments [i ]) and not return_masks :
325
+ if not rles_top and is_polygon_group (wrapped_segments [i ]) and not return_masks :
324
326
output_segments .append (wrapped_segments [i ])
325
327
continue
326
328
@@ -334,7 +336,7 @@ def crop_covered_segments(
334
336
bottom_mask -= top_mask
335
337
bottom_mask [bottom_mask != 1 ] = 0
336
338
337
- if not return_masks and is_polygon (wrapped_segments [i ]):
339
+ if not return_masks and is_polygon_group (wrapped_segments [i ]):
338
340
output_segments .append (mask_to_polygons (bottom_mask , area_threshold = area_threshold ))
339
341
else :
340
342
if np .sum (bottom_mask ) < area_threshold :
0 commit comments