Example #1
0
    def from_instance_masks(instance_masks,
                            instance_ids=None,
                            instance_labels=None):
        from datumaro.util.mask_tools import merge_masks

        if instance_ids is not None:
            assert len(instance_ids) == len(instance_masks)
        else:
            instance_ids = [None] * len(instance_masks)

        if instance_labels is not None:
            assert len(instance_labels) == len(instance_masks)
        else:
            instance_labels = [None] * len(instance_masks)

        instance_masks = sorted(zip(instance_masks, instance_ids,
                                    instance_labels),
                                key=lambda m: m[0].z_order)

        instance_mask = [
            m.as_instance_mask(id if id is not None else 1 + idx)
            for idx, (m, id, _) in enumerate(instance_masks)
        ]
        instance_mask = merge_masks(instance_mask)

        cls_mask = [m.as_class_mask(c) for m, _, c in instance_masks]
        cls_mask = merge_masks(cls_mask)
        return __class__(class_mask=cls_mask, instance_mask=instance_mask)
Example #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
Example #3
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]
Example #4
0
    def _find_instance_parts(self, group, img_width, img_height):
        boxes = [a for a in group if a.type == AnnotationType.bbox]
        masks = [a for a in group if a.type == AnnotationType.mask]

        anns = boxes + masks
        leader = find_group_leader(anns)
        bbox = max_bbox(anns)

        mask = None
        if self._save_masks:
            mask = merge_masks([m.image for m in masks])

        return [leader, mask, bbox]
Example #5
0
    def test_can_merge_masks(self):
        masks = [
            np.array([0, 2, 4, 0, 0, 1]),
            np.array([0, 1, 1, 0, 2, 0]),
            np.array([0, 0, 2, 3, 0, 0]),
        ]
        expected = \
            np.array([0, 1, 2, 3, 2, 1])

        actual = mask_tools.merge_masks(masks)

        self.assertTrue(np.array_equal(expected, actual),
            '%s\nvs.\n%s' % (expected, actual))
Example #6
0
    def _save_annotations(self, item, anno_dir):
        masks = [a for a in item.annotations if a.type == AnnotationType.mask]
        if not masks:
            return

        instance_ids = [int(a.attributes['track_id']) for a in masks]
        masks = sorted(zip(masks, instance_ids), key=lambda e: e[0].z_order)
        mask = merge_masks(
            (m.image, MotsPath.MAX_INSTANCES * (1 + m.label) + id)
            for m, id in masks)
        save_image(osp.join(anno_dir, item.id + '.png'),
                   mask,
                   create_dir=True,
                   dtype=np.uint16)
Example #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
Example #8
0
    def save_annotations(self, item):
        if not item.has_image:
            return

        ann_filename = item.id + CocoPath.PANOPTIC_EXT

        segments_info = list()
        masks = []
        next_id = self._min_ann_id
        for ann in item.annotations:
            if ann.type != AnnotationType.mask:
                continue

            if not ann.id:
                ann.id = next_id
                next_id += 1

            segment_info = {}
            segment_info['id'] = ann.id
            segment_info['category_id'] = cast(ann.label, int, -1) + 1
            segment_info['area'] = float(ann.get_area())
            segment_info['bbox'] = [float(p) for p in ann.get_bbox()]
            segment_info['iscrowd'] = cast(ann.attributes.get("is_crowd"), int,
                                           0)
            segments_info.append(segment_info)
            masks.append(ann)

        if not masks:
            return

        pan_format = mask_tools.merge_masks((m.image, m.id) for m in masks)
        save_image(osp.join(self._context._segmentation_dir, ann_filename),
                   mask_tools.index2bgr(pan_format),
                   create_dir=True)

        elem = {
            'image_id': self._get_image_id(item),
            'file_name': ann_filename,
            'segments_info': segments_info
        }
        self.annotations.append(elem)