def test_can_crop_covered_segments(self): image_size = [7, 7] initial = [ [1, 1, 6, 1, 6, 6, 1, 6], # rectangle mask_tools.mask_to_rle( np.array([ [0, 0, 0, 0, 0, 0, 0], [0, 0, 1, 0, 1, 1, 0], [0, 1, 1, 0, 1, 1, 0], [0, 0, 0, 0, 0, 1, 0], [0, 1, 1, 0, 0, 1, 0], [0, 1, 1, 1, 1, 1, 0], [0, 0, 0, 0, 0, 0, 0], ])), [1, 1, 6, 6, 1, 6], # lower-left triangle ] expected = [ np.array([ [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0, 0], [0, 0, 0, 1, 0, 0, 0], [0, 0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0], ]), # half-covered np.array([ [0, 0, 0, 0, 0, 0, 0], [0, 0, 1, 0, 1, 1, 0], [0, 0, 0, 0, 1, 1, 0], [0, 0, 0, 0, 0, 1, 0], [0, 0, 0, 0, 0, 1, 0], [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0], ]), # half-covered mask_tools.rles_to_mask([initial[2]], *image_size), # unchanged ] computed = mask_tools.crop_covered_segments(initial, *image_size, ratio_tolerance=0, return_masks=True) self.assertEqual(len(initial), len(computed)) for i, (e_mask, c_mask) in enumerate(zip(expected, computed)): self.assertTrue(np.array_equal(e_mask, c_mask), '#%s: %s\n%s\n' % (i, e_mask, c_mask))
def find_instance_parts(self, group, img_width, img_height): boxes = [a for a in group if a.type == AnnotationType.bbox] polygons = [a for a in group if a.type == AnnotationType.polygon] masks = [a for a in group if a.type == AnnotationType.mask] anns = boxes + polygons + masks leader = anno_tools.find_group_leader(anns) bbox = anno_tools.max_bbox(anns) mask = None polygons = [p.points for p in polygons] if self._context._segmentation_mode == SegmentationMode.guess: use_masks = True == leader.attributes.get( 'is_crowd', find(masks, lambda x: x.label == leader.label) is not None) elif self._context._segmentation_mode == SegmentationMode.polygons: use_masks = False elif self._context._segmentation_mode == SegmentationMode.mask: use_masks = True else: raise NotImplementedError("Unexpected segmentation mode '%s'" % \ self._context._segmentation_mode) if use_masks: if polygons: mask = mask_tools.rles_to_mask(polygons, img_width, img_height) if masks: masks = (m.image for m in masks) if mask is not None: masks += chain(masks, [mask]) mask = mask_tools.merge_masks(masks) if mask is not None: mask = mask_tools.mask_to_rle(mask) polygons = [] else: if masks: mask = mask_tools.merge_masks(m.image for m in masks) polygons += mask_tools.mask_to_polygons(mask) mask = None return [leader, polygons, mask, bbox]
def merge_segments(cls, instance, img_width, img_height, include_polygons=False): polygons = [a for a in instance if a.type == AnnotationType.polygon] masks = [a for a in instance if a.type == AnnotationType.mask] if not polygons and not masks: return [] if not polygons and len(masks) == 1: return masks leader = find_group_leader(polygons + masks) instance = [] # Build the resulting mask mask = None if include_polygons and polygons: polygons = [p.points for p in polygons] mask = mask_tools.rles_to_mask(polygons, img_width, img_height) else: instance += polygons # keep unused polygons if masks: masks = (m.image for m in masks) if mask is not None: masks = chain(masks, [mask]) mask = mask_tools.merge_masks(masks) if mask is None: return instance mask = mask_tools.mask_to_rle(mask) mask = mask_utils.frPyObjects(mask, *mask['size']) instance.append( RleMask(rle=mask, label=leader.label, z_order=leader.z_order, id=leader.id, attributes=leader.attributes, group=leader.group)) return instance