Пример #1
0
    def apply(self):
        extractor = self._extractor

        images_dir = osp.join(self._save_dir, MotPath.IMAGE_DIR)
        os.makedirs(images_dir, exist_ok=True)
        self._images_dir = images_dir

        anno_dir = osp.join(self._save_dir, 'gt')
        os.makedirs(anno_dir, exist_ok=True)
        anno_file = osp.join(anno_dir, MotPath.GT_FILENAME)
        with open(anno_file, 'w', encoding="utf-8") as csv_file:
            writer = csv.DictWriter(csv_file, fieldnames=MotPath.FIELDS)

            track_id_mapping = {-1: -1}
            for idx, item in enumerate(extractor):
                log.debug("Converting item '%s'", item.id)

                frame_id = cast(item.id, int, 1 + idx)

                for anno in item.annotations:
                    if anno.type != AnnotationType.bbox:
                        continue

                    track_id = int(anno.attributes.get('track_id', -1))
                    if track_id not in track_id_mapping:
                        track_id_mapping[track_id] = len(track_id_mapping)
                    track_id = track_id_mapping[track_id]

                    writer.writerow({
                        'frame_id': frame_id,
                        'track_id': track_id,
                        'x': anno.x,
                        'y': anno.y,
                        'w': anno.w,
                        'h': anno.h,
                        'confidence': int(anno.attributes.get('ignored') != True),
                        'class_id': 1 + cast(anno.label, int, -2),
                        'visibility': float(
                            anno.attributes.get('visibility',
                                1 - float(
                                    anno.attributes.get('occluded', False)
                                )
                            )
                        )
                    })

                if self._save_images:
                    if item.has_image and item.image.has_data:
                        self._save_image(item, osp.join(self._images_dir,
                            '%06d%s' % (frame_id, self._find_image_ext(item))))
                    else:
                        log.debug("Item '%s' has no image", item.id)

        labels_file = osp.join(anno_dir, MotPath.LABELS_FILE)
        with open(labels_file, 'w', encoding='utf-8') as f:
            f.write('\n'.join(l.name
                for l in extractor.categories()[AnnotationType.label])
            )
Пример #2
0
 def _convert_label_categories(self, obj):
     converted = {
         'labels': [],
     }
     for label in obj.items:
         converted['labels'].append({
             'name': cast(label.name, str),
             'parent': cast(label.parent, str),
         })
     return converted
Пример #3
0
    def _convert_annotation(self, obj):
        assert isinstance(obj, Annotation)

        ann_json = {
            'id': cast(obj.id, int),
            'type': cast(obj.type.name, str),
            'attributes': obj.attributes,
            'group': cast(obj.group, int, 0),
        }
        return ann_json
Пример #4
0
 def _parse_attr(cls, value):
     if value == 'true':
         return True
     elif value == 'false':
         return False
     elif str(cast(value, int, 0)) == value:
         return int(value)
     elif str(cast(value, float, 0)) == value:
         return float(value)
     else:
         return value
Пример #5
0
    def save_categories(self, dataset):
        label_categories = dataset.categories().get(AnnotationType.label)
        if label_categories is None:
            return

        for idx, cat in enumerate(label_categories.items):
            self.categories.append({
                'id': 1 + idx,
                'name': cast(cat.name, str, ''),
                'supercategory': cast(cat.parent, str, ''),
            })
Пример #6
0
 def _is_float(value):
     if isinstance(value, str):
         casted = cast(value, float)
         if casted is not None:
             if cast(casted, str) == value:
                 return True
         return False
     elif isinstance(value, float):
         cast(value, float)
         return True
     return False
Пример #7
0
    def save_categories(self, dataset):
        label_categories = dataset.categories().get(AnnotationType.label)
        if label_categories is None:
            return

        for idx, cat in enumerate(label_categories.items):
            self.categories.append({
                'id': 1 + idx,
                'name': cast(cat.name, str, ''),
                'supercategory': cast(cat.parent, str, ''),
                'isthing': 0,  # TODO: can't represent this information yet
            })
Пример #8
0
        def _parse_attributes(attr_str):
            parsed = []
            if not attr_str:
                return parsed

            for attr in [a.strip() for a in cls._escape(attr_str).split(',')]:
                if not attr:
                    continue

                if '=' in attr:
                    name, value = attr.split('=', maxsplit=1)
                    if value.lower() in {'true', 'false'}:
                        value = value.lower() == 'true'
                    elif 1 < len(value) and value[0] == '"' and value[-1] == '"':
                        value = value[1:-1]
                    else:
                        for t in [int, float]:
                            casted = cast(value, t)
                            if casted is not None and str(casted) == value:
                                value = casted
                                break
                    if isinstance(value, str):
                        value = cls._unescape(value)
                    parsed.append((cls._unescape(name), value))
                else:
                    parsed.append((cls._unescape(attr), True))

            return parsed
Пример #9
0
    def _write_item(self, item, index):
        if not self._context._reindex:
            index = cast(item.attributes.get('frame'), int, index)
        image_info = OrderedDict([
            ("id", str(index)),
        ])
        filename = item.id + CvatPath.IMAGE_EXT
        image_info["name"] = filename
        if item.has_image:
            size = item.image.size
            if size:
                h, w = size
                image_info["width"] = str(w)
                image_info["height"] = str(h)

            if self._context._save_images:
                self._context._save_image(
                    item, osp.join(self._context._images_dir, filename))
        else:
            log.debug("Item '%s' has no image info", item.id)
        self._writer.open_image(image_info)

        for ann in item.annotations:
            if ann.type in {
                    AnnotationType.points, AnnotationType.polyline,
                    AnnotationType.polygon, AnnotationType.bbox
            }:
                self._write_shape(ann)
            elif ann.type == AnnotationType.label:
                self._write_tag(ann)
            else:
                continue

        self._writer.close_image()
Пример #10
0
    def _convert_label_object(self, obj):
        converted = self._convert_annotation(obj)

        converted.update({
            'label_id': cast(obj.label, int),
        })
        return converted
Пример #11
0
    def _write_item(self, item, index):
        image_info = OrderedDict([
            ("id", str(cast(item.id, int, index))),
        ])
        if item.has_image:
            size = item.image.size
            if size:
                h, w = size
                image_info["width"] = str(w)
                image_info["height"] = str(h)

            filename = item.image.filename
            if self._context._save_images:
                filename = self._save_image(item)
            image_info["name"] = filename
        else:
            log.debug("Item '%s' has no image info" % item.id)
        self._writer.open_image(image_info)

        for ann in item.annotations:
            if ann.type in {AnnotationType.points, AnnotationType.polyline,
                    AnnotationType.polygon, AnnotationType.bbox}:
                self._write_shape(ann)
            elif ann.type == AnnotationType.label:
                self._write_tag(ann)
            else:
                continue

        self._writer.close_image()
Пример #12
0
    def _convert_caption_object(self, obj):
        converted = self._convert_annotation(obj)

        converted.update({
            'caption': cast(obj.caption, str),
        })
        return converted
Пример #13
0
 def _get_image_id(self, item):
     image_id = self._image_ids.get(item.id)
     if image_id is None:
         image_id = cast(item.attributes.get('id'), int,
                         len(self._image_ids) + 1)
         self._image_ids[item.id] = image_id
     return image_id
Пример #14
0
    def _write_item_annotations(self, item):
        key_id_data = self._key_id_data

        item_id = cast(item.attributes.get('frame'), int)
        if item_id is None or self._context._reindex:
            item_id = len(key_id_data['videos']) + 1

        item_key = str(uuid.uuid4())
        key_id_data['videos'][item_key] = item_id

        item_user_info = {
            k: item.attributes.get(k, default_v)
            for k, default_v in self._default_user_info.items()
        }

        item_ann_data = {
            'description': item.attributes.get('description', ''),
            'key': item_key,
            'tags': [],
            'objects': [],
            'figures': [],
        }
        self._export_item_attributes(item, item_ann_data, item_user_info)
        self._export_item_annotations(item, item_ann_data, item_user_info)

        ann_path = osp.join(self._ann_dir, item.id + '.pcd.json')
        os.makedirs(osp.dirname(ann_path), exist_ok=True)
        dump_json_file(ann_path, item_ann_data, indent=True)
Пример #15
0
def match_dm_item(item, task_data, root_hint=None):
    is_video = task_data.meta['task']['mode'] == 'interpolation'

    frame_number = None
    if frame_number is None and item.has_image:
        frame_number = task_data.match_frame(item.image.path, root_hint)
    if frame_number is None:
        frame_number = task_data.match_frame(item.id, root_hint)
    if frame_number is None:
        frame_number = cast(item.attributes.get('frame', item.id), int)
    if frame_number is None and is_video:
        frame_number = cast(osp.basename(item.id)[len('frame_'):], int)

    if not frame_number in task_data.frame_info:
        raise Exception("Could not match item id: '%s' with any task frame" %
            item.id)
    return frame_number
Пример #16
0
    def _convert_bbox_object(self, obj):
        converted = self._convert_annotation(obj)

        converted.update({
            'label_id': cast(obj.label, int),
            'bbox': [float(p) for p in obj.get_bbox()],
        })
        return converted
Пример #17
0
    def _convert_polygon_object(self, obj):
        converted = self._convert_annotation(obj)

        converted.update({
            'label_id': cast(obj.label, int),
            'points': [float(p) for p in obj.points],
        })
        return converted
Пример #18
0
    def _convert_points_object(self, obj):
        converted = self._convert_annotation(obj)

        converted.update({
            'label_id': cast(obj.label, int),
            'points': [float(p) for p in obj.points],
            'visibility': [int(v.value) for v in obj.visibility],
        })
        return converted
Пример #19
0
 def _convert_cuboid_3d_object(self, obj):
     converted = self._convert_annotation(obj)
     converted.update({
         'label_id': cast(obj.label, int),
         'position': [float(p) for p in obj.position],
         'rotation': [float(p) for p in obj.rotation],
         'scale': [float(p) for p in obj.scale]
     })
     return converted
Пример #20
0
 def _save_image(self, item, index):
     if item.image.filename:
         frame_id = osp.splitext(item.image.filename)[0]
     else:
         frame_id = item.id
     frame_id = cast(frame_id, int, index)
     image_filename = '%06d%s' % (frame_id, MotPath.IMAGE_EXT)
     save_image(osp.join(self._images_dir, image_filename),
         item.image.data)
Пример #21
0
    def _convert_shape_object(self, obj):
        assert isinstance(obj, _Shape)
        converted = self._convert_annotation(obj)

        converted.update({
            'label_id': cast(obj.label, int),
            'points': [float(p) for p in obj.points],
            'z_order': obj.z_order,
        })
        return converted
Пример #22
0
    def convert_instance(self, instance, item):
        ann, polygons, mask, bbox = instance

        is_crowd = mask is not None
        if is_crowd:
            segmentation = {
                'counts': list(int(c) for c in mask['counts']),
                'size': list(int(c) for c in mask['size'])
            }
        else:
            segmentation = [list(map(float, p)) for p in polygons]

        area = 0
        if segmentation:
            if item.has_image:
                h, w = item.image.size
            else:
                # NOTE: here we can guess the image size as
                # it is only needed for the area computation
                w = bbox[0] + bbox[2]
                h = bbox[1] + bbox[3]

            rles = mask_utils.frPyObjects(segmentation, h, w)
            if is_crowd:
                rles = [rles]
            else:
                rles = mask_utils.merge(rles)
            area = mask_utils.area(rles)
        else:
            _, _, w, h = bbox
            segmentation = []
            area = w * h

        elem = {
            'id': self._get_ann_id(ann),
            'image_id': self._get_image_id(item),
            'category_id': cast(ann.label, int, -1) + 1,
            'segmentation': segmentation,
            'area': float(area),
            'bbox':
            [round(float(n), _COORDINATE_ROUNDING_DIGITS) for n in bbox],
            'iscrowd': int(is_crowd),
        }
        if 'score' in ann.attributes:
            try:
                elem['score'] = float(ann.attributes['score'])
            except Exception as e:
                log.warning("Item '%s': failed to convert attribute "
                            "'score': %e" % (item.id, e))
        if self._context._allow_attributes:
            attrs = self._convert_attributes(ann)
            if attrs:
                elem['attributes'] = attrs

        return elem
Пример #23
0
    def _parse_label_count(s: str) -> Tuple[str, int]:
        label, count = s.split(':', maxsplit=1)
        count = cast(count, int, default=None)

        if not label:
            raise argparse.ArgumentError(None, "Class name cannot be empty")
        if count is None or count < 0:
            raise argparse.ArgumentError(None,
                f"Class '{label}' count is invalid")

        return label, count
Пример #24
0
 def _convert_points_categories(self, obj):
     converted = {
         'items': [],
     }
     for label_id, item in obj.items.items():
         converted['items'].append({
             'label_id': int(label_id),
             'labels': [cast(label, str) for label in item.labels],
             'joints': [list(map(int, j)) for j in item.joints],
         })
     return converted
Пример #25
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)
Пример #26
0
 def _convert_points_categories(self, obj):
     converted = {
         'items': [],
     }
     for label_id, item in obj.items.items():
         converted['items'].append({
             'label_id':
             int(label_id),
             'labels': [cast(label, str) for label in item.labels],
             'adjacent': [int(v) for v in item.adjacent],
         })
     return converted
Пример #27
0
    def save_categories(self, dataset):
        label_categories = dataset.categories().get(AnnotationType.label)
        if label_categories is None:
            return
        point_categories = dataset.categories().get(AnnotationType.points)

        for idx, label_cat in enumerate(label_categories.items):
            cat = {
                'id': 1 + idx,
                'name': cast(label_cat.name, str, ''),
                'supercategory': cast(label_cat.parent, str, ''),
                'keypoints': [],
                'skeleton': [],
            }

            if point_categories is not None:
                kp_cat = point_categories.items.get(idx)
                if kp_cat is not None:
                    cat.update({
                        'keypoints': [str(l) for l in kp_cat.labels],
                        'skeleton': [list(map(int, j)) for j in kp_cat.joints],
                    })
            self.categories.append(cat)
Пример #28
0
def generate_next_name(names, basename, sep='.', suffix='', default=None):
    pattern = re.compile(r'%s(?:%s(\d+))?%s' % \
        tuple(map(re.escape, [basename, sep, suffix])))
    matches = [match for match in (pattern.match(n) for n in names) if match]

    max_idx = max([cast(match[1], int, 0) for match in matches], default=None)
    if max_idx is None:
        if default is not None:
            idx = sep + str(default)
        else:
            idx = ''
    else:
        idx = sep + str(max_idx + 1)
    return basename + idx + suffix
Пример #29
0
    def save_image_info(self, item, filename):
        h = 0
        w = 0
        if item.has_image and item.image.size:
            h, w = item.image.size

        self._data['images'].append({
            'id': self._get_image_id(item),
            'width': int(w),
            'height': int(h),
            'file_name': cast(filename, str, ''),
            'license': 0,
            'flickr_url': '',
            'coco_url': '',
            'date_captured': 0,
        })
Пример #30
0
    def _convert_mask_object(self, obj):
        converted = self._convert_annotation(obj)

        if isinstance(obj, RleMask):
            rle = obj.rle
        else:
            rle = mask_utils.encode(
                np.require(obj.image, dtype=np.uint8, requirements='F'))

        converted.update({
            'label_id': cast(obj.label, int),
            'rle': {
                # serialize as compressed COCO mask
                'counts': rle['counts'].decode('ascii'),
                'size': list(int(c) for c in rle['size']),
            }
        })
        return converted