Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion labelbox/data/annotation_types/geometry/mask.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,13 @@ def geometry(self) -> Dict[str, Tuple[int, int, int]]:
external_polygons = self._extract_polygons_from_contours(
external_contours)
holes = self._extract_polygons_from_contours(holes)

if not external_polygons.is_valid:
external_polygons = external_polygons.buffer(0)

if not holes.is_valid:
holes = holes.buffer(0)

return external_polygons.difference(holes).__geo_interface__

def draw(self,
Expand All @@ -78,7 +85,6 @@ def draw(self,
np.ndarray representing only this object
as opposed to the mask that this object references which might have multiple objects determined by colors
"""

mask = self.mask.value
mask = np.alltrue(mask == self.color, axis=2).astype(np.uint8)

Expand Down
1 change: 0 additions & 1 deletion labelbox/data/serialization/coco/instance_dataset.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ def mask_to_coco_object_annotation(
# This is going to fill any holes into the multipolygon
# If you need to support holes use the panoptic data format
shapely = annotation.value.shapely.simplify(1).buffer(0)

if shapely.is_empty:
return

Expand Down
25 changes: 22 additions & 3 deletions labelbox/data/serialization/coco/panoptic_dataset.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,11 @@ def vector_to_coco_segment_info(canvas: np.ndarray,
annotation: ObjectAnnotation,
annotation_idx: int, image: CocoImage,
category_id: int):

shapely = annotation.value.shapely
if shapely.is_empty:
return

xmin, ymin, xmax, ymax = shapely.bounds
canvas = annotation.value.draw(height=image.height,
width=image.width,
Expand All @@ -40,6 +44,9 @@ def mask_to_coco_segment_info(canvas: np.ndarray, annotation,
color = id_to_rgb(annotation_idx)
mask = annotation.value.draw(color=color)
shapely = annotation.value.shapely
if shapely.is_empty:
return

xmin, ymin, xmax, ymax = shapely.bounds
canvas = np.where(canvas == (0, 0, 0), mask, canvas)
return SegmentInfo(id=annotation_idx,
Expand Down Expand Up @@ -70,20 +77,32 @@ def process_label(label: Label,
for annotation_idx, annotation in enumerate(annotations[class_name]):
categories[annotation.name] = hash_category_name(annotation.name)
if isinstance(annotation.value, Mask):
segment, canvas = (mask_to_coco_segment_info(
coco_segment_info = mask_to_coco_segment_info(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Questions around this.

  1. How can coco_segment_info be set to segment, canvas when it's only returning SegmentInfo object?
  2. When can coco_segment_info be None?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. mask_to_coco_segment_info returns both of those things. It is hard to read because canvas looks like it is part of the SegmentInfo object but it isn't
  2. coco_segment_info can be None if the annotation is invalid. Like an empty seg mask is exported for whatever reason.

canvas, annotation, class_idx + 1,
categories[annotation.name]))
categories[annotation.name])

if coco_segment_info is None:
# Filter out empty masks
continue

segment, canvas = coco_segment_info
segments.append(segment)
is_thing[annotation.name] = 0

elif isinstance(annotation.value, (Polygon, Rectangle)):
segment, canvas = vector_to_coco_segment_info(
coco_vector_info = vector_to_coco_segment_info(
canvas,
annotation,
annotation_idx=(class_idx if all_stuff else annotation_idx)
+ 1,
image=image,
category_id=categories[annotation.name])

if coco_segment_info is None:
# Filter out empty annotations
continue

segment, canvas = coco_vector_info
segments.append(segment)
is_thing[annotation.name] = 1 - int(all_stuff)

Expand Down