Exemple #1
0
    def crop_segments(cls, segment_anns, img_width, img_height):
        segment_anns = sorted(segment_anns, key=lambda x: x.z_order)

        segments = []
        for s in segment_anns:
            if s.type == AnnotationType.polygon:
                segments.append(s.points)
            elif s.type == AnnotationType.mask:
                if isinstance(s, RleMask):
                    rle = s.rle
                else:
                    rle = mask_tools.mask_to_rle(s.image)
                segments.append(rle)

        segments = mask_tools.crop_covered_segments(
            segments, img_width, img_height)

        new_anns = []
        for ann, new_segment in zip(segment_anns, segments):
            fields = {'z_order': ann.z_order, 'label': ann.label,
                'id': ann.id, 'group': ann.group, 'attributes': ann.attributes
            }
            if ann.type == AnnotationType.polygon:
                if fields['group'] is None:
                    fields['group'] = cls._make_group_id(
                        segment_anns + new_anns, fields['id'])
                for polygon in new_segment:
                    new_anns.append(Polygon(points=polygon, **fields))
            else:
                rle = mask_tools.mask_to_rle(new_segment)
                rle = mask_utils.frPyObjects(rle, *rle['size'])
                new_anns.append(RleMask(rle=rle, **fields))

        return new_anns
Exemple #2
0
    def crop_segments(cls, instances, img_width, img_height):
        instances = sorted(instances, key=lambda x: x[0].z_order)

        segment_map = []
        segments = []
        for inst_idx, (_, polygons, mask, _) in enumerate(instances):
            if polygons:
                segment_map.extend(inst_idx for p in polygons)
                segments.extend(polygons)
            elif mask is not None:
                segment_map.append(inst_idx)
                segments.append(mask)

        segments = mask_tools.crop_covered_segments(segments, img_width,
                                                    img_height)

        for inst_idx, inst in enumerate(instances):
            new_segments = [
                s for si_id, s in zip(segment_map, segments)
                if si_id == inst_idx
            ]

            if not new_segments:
                inst[1] = []
                inst[2] = None
                continue

            if inst[1]:
                inst[1] = sum(new_segments, [])
            else:
                mask = mask_tools.merge_masks(new_segments)
                inst[2] = mask_tools.mask_to_rle(mask)

        return instances
Exemple #3
0
 def _to_rle(ann):
     if ann.type == AnnotationType.polygon:
         return mask_utils.frPyObjects([ann.points], h, w)
     elif isinstance(ann, RleMask):
         return [ann._rle]
     elif ann.type == AnnotationType.mask:
         return mask_utils.frPyObjects([mask_to_rle(ann.image)], h, w)
     else:
         raise TypeError("Unexpected arguments: %s, %s" % (a, b))
Exemple #4
0
    def _test_mask_to_rle(self, source_mask):
        rle_uncompressed = mask_tools.mask_to_rle(source_mask)

        from pycocotools import mask as mask_utils
        resulting_mask = mask_utils.frPyObjects(
            rle_uncompressed, *rle_uncompressed['size'])
        resulting_mask = mask_utils.decode(resulting_mask)

        self.assertTrue(np.array_equal(source_mask, resulting_mask),
            '%s\n%s\n' % (source_mask, resulting_mask))
Exemple #5
0
    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))
Exemple #6
0
    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]
Exemple #7
0
    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