Ejemplo n.º 1
0
    def from_json(cls, data, project_meta: ProjectMeta):
        '''
        The function from_json convert Label from json format to Label class object. If there is no ObjClass from
        input json format in ProjectMeta, it generate RuntimeError error.
        :param data: input label in json format
        :param project_meta: ProjectMeta class object
        :return: Label class object
        '''
        obj_class_name = data[LabelJsonFields.OBJ_CLASS_NAME]
        obj_class = project_meta.get_obj_class(obj_class_name)
        if obj_class is None:
            raise RuntimeError(
                f'Failed to deserialize a Label object from JSON: label class name {obj_class_name!r} '
                f'was not found in the given project meta.')

        if obj_class.geometry_type is AnyGeometry:
            geometry_type_actual = GET_GEOMETRY_FROM_STR(
                data[GEOMETRY_TYPE] if GEOMETRY_TYPE in
                data else data[GEOMETRY_SHAPE])
            geometry = geometry_type_actual.from_json(data)
        else:
            geometry = obj_class.geometry_type.from_json(data)

        return cls(geometry=geometry,
                   obj_class=obj_class,
                   tags=TagCollection.from_json(data[LabelJsonFields.TAGS],
                                                project_meta.tag_metas),
                   description=data.get(LabelJsonFields.DESCRIPTION, ""))
Ejemplo n.º 2
0
def apply(augs,
          meta: ProjectMeta,
          img,
          ann: Annotation,
          segmentation_type='semantic'):
    # @TODO: save object tags

    # works for rectangles
    det_meta, det_mapping = meta.to_detection_task(convert_classes=False)
    det_ann = ann.to_detection_task(det_mapping)
    ia_boxes = det_ann.bboxes_to_imgaug()

    # works for polygons and bitmaps
    seg_meta, seg_mapping = meta.to_segmentation_task()
    seg_ann = ann.to_nonoverlapping_masks(seg_mapping)

    if segmentation_type == 'semantic':
        seg_ann = seg_ann.to_segmentation_task()
        class_to_index = {
            obj_class.name: idx
            for idx, obj_class in enumerate(seg_meta.obj_classes, start=1)
        }
        index_to_class = {v: k for k, v in class_to_index.items()}
    elif segmentation_type == 'instance':
        class_to_index = None
        index_to_class = {
            idx: label.obj_class.name
            for idx, label in enumerate(seg_ann.labels, start=1)
        }
    elif segmentation_type == 'panoptic':
        raise NotImplementedError

    ia_masks = seg_ann.masks_to_imgaug(class_to_index)

    res_meta = det_meta.merge(seg_meta)  # TagMetas should be preserved

    res_img, res_ia_boxes, res_ia_masks = _apply(augs, img, ia_boxes, ia_masks)
    res_ann = Annotation.from_imgaug(res_img,
                                     ia_boxes=res_ia_boxes,
                                     ia_masks=res_ia_masks,
                                     index_to_class=index_to_class,
                                     meta=res_meta)
    # add image tags
    res_ann = res_ann.clone(img_tags=ann.img_tags)
    return res_meta, res_img, res_ann
Ejemplo n.º 3
0
    def merge_metas(self, src_project_id, dst_project_id):
        '''
        Add metadata from given progect to given destination project
        :param src_project_id: int
        :param dst_project_id: int
        :return: merged project metainformation
        '''
        if src_project_id == dst_project_id:
            return self.get_meta(src_project_id)

        src_meta = ProjectMeta.from_json(self.get_meta(src_project_id))
        dst_meta = ProjectMeta.from_json(self.get_meta(dst_project_id))

        new_dst_meta = src_meta.merge(dst_meta)
        new_dst_meta_json = new_dst_meta.to_json()
        self.update_meta(dst_project_id, new_dst_meta.to_json())

        return new_dst_meta_json
Ejemplo n.º 4
0
 def to_json(self):
     return {
         "content": {
             "projectMeta": ProjectMeta().to_json(),
             "layout": [],
             "annotations": {}
         },
         "options": {}
     }
 def __init__(self, task_id, api: Api, v_model, project_meta: ProjectMeta):
     self._task_id = task_id
     self._api = api
     self._v_model = v_model
     self._project_meta = project_meta.clone()
     self._image_url = None
     self._ann = None
     self._options_initialized = False
     self.set_options()
Ejemplo n.º 6
0
    def from_json(cls,
                  data,
                  project_meta: ProjectMeta,
                  key_id_map: KeyIdMap = None):
        '''
        The function from_json convert PointcloudObject from json format to PointcloudObject class object. Raise error if object class name is not found in the given project meta
        :param data: input PointcloudObject in json format
        :param project_meta: ProjectMeta class object
        :param key_id_map: KeyIdMap class object
        :return: PointcloudObject class object
        '''
        obj_class_name = data[LabelJsonFields.OBJ_CLASS_NAME]
        obj_class = project_meta.get_obj_class(obj_class_name)
        if obj_class is None:
            raise RuntimeError(
                f'Failed to deserialize a object from JSON: class name {obj_class_name!r} '
                f'was not found in the given project meta.')

        object_id = data.get(ID, None)

        existing_key = None
        if object_id is not None and key_id_map is not None:
            existing_key = key_id_map.get_object_key(object_id)
        json_key = uuid.UUID(data[KEY]) if KEY in data else None
        if (existing_key
                is not None) and (json_key
                                  is not None) and (existing_key != json_key):
            raise RuntimeError(
                "Object id = {!r}: existing_key {!r} != json_key {!r}".format(
                    object_id, existing_key, json_key))

        if existing_key is not None:
            key = existing_key
        elif json_key is not None:
            key = json_key
        else:
            key = uuid.uuid4()

        if key_id_map is not None and existing_key is None:
            key_id_map.add_object(key, object_id)

        class_id = data.get(CLASS_ID, None)
        labeler_login = data.get(LABELER_LOGIN, None)
        updated_at = data.get(UPDATED_AT, None)
        created_at = data.get(CREATED_AT, None)

        return cls(obj_class=obj_class,
                   key=key,
                   tags=VideoTagCollection.from_json(
                       data[LabelJsonFields.TAGS], project_meta.tag_metas),
                   class_id=class_id,
                   labeler_login=labeler_login,
                   updated_at=updated_at,
                   created_at=created_at)
Ejemplo n.º 7
0
    def from_imgaug(cls,
                    img,
                    ia_boxes=None,
                    ia_masks=None,
                    index_to_class=None,
                    meta: ProjectMeta = None):
        if ((ia_boxes is not None) or (ia_masks is not None)) and meta is None:
            raise ValueError("Project meta has to be provided")

        labels = []
        if ia_boxes is not None:
            for ia_box in ia_boxes:
                obj_class = meta.get_obj_class(ia_box.label)
                if obj_class is None:
                    raise KeyError(
                        "Class {!r} not found in project meta".format(
                            ia_box.label))
                lbl = Label(
                    Rectangle(top=ia_box.y1,
                              left=ia_box.x1,
                              bottom=ia_box.y2,
                              right=ia_box.x2), obj_class)
                labels.append(lbl)

        if ia_masks is not None:
            if index_to_class is None:
                raise ValueError(
                    "mapping from index to class name is needed to transform masks to SLY format"
                )
            class_mask = ia_masks.get_arr()
            # mask = white_mask == 255
            (unique, counts) = np.unique(class_mask, return_counts=True)
            for index, count in zip(unique, counts):
                if index == 0:
                    continue
                mask = class_mask == index
                bitmap = Bitmap(data=mask[:, :, 0])
                restore_class = meta.get_obj_class(index_to_class[index])
                labels.append(Label(geometry=bitmap, obj_class=restore_class))

        return cls(img_size=img.shape[:2], labels=labels)
Ejemplo n.º 8
0
    def from_json(cls, data, project_meta):
        '''
        The function from_json convert annotation from json format to Annotation class object. If one of the labels
        of annotation in json format cannot be convert to Label class object it generate exception error.
        :param data: input annotation in json format
        :param project_meta: ProjectMeta class object
        :return: Annotation class object
        '''
        img_size_dict = data[AnnotationJsonFields.IMG_SIZE]
        img_height = img_size_dict[AnnotationJsonFields.IMG_SIZE_HEIGHT]
        img_width = img_size_dict[AnnotationJsonFields.IMG_SIZE_WIDTH]
        img_size = (img_height, img_width)
        try:
            labels = [
                Label.from_json(label_json, project_meta)
                for label_json in data[AnnotationJsonFields.LABELS]
            ]
        except Exception:
            logger.fatal(
                'Failed to deserialize annotation from JSON format. One of the Label objects could not be '
                'deserialized')
            raise

        custom_data = data.get(AnnotationJsonFields.CUSTOM_DATA, {})
        prob_labels = None
        if AnnotationJsonFields.PROBABILITY_LABELS in custom_data and \
                AnnotationJsonFields.PROBABILITY_CLASSES in custom_data:

            prob_classes = ObjClassCollection.from_json(
                custom_data[AnnotationJsonFields.PROBABILITY_CLASSES])

            # @TODO: tony, maybe link with project meta (add probability classes???)
            prob_project_meta = ProjectMeta(obj_classes=prob_classes)
            prob_labels = [
                Label.from_json(label_json, prob_project_meta) for label_json
                in custom_data[AnnotationJsonFields.PROBABILITY_LABELS]
            ]

            custom_data.pop(AnnotationJsonFields.PROBABILITY_CLASSES)
            custom_data.pop(AnnotationJsonFields.PROBABILITY_LABELS)

        image_id = data.get(AnnotationJsonFields.IMAGE_ID, None)

        return cls(img_size=img_size,
                   labels=labels,
                   img_tags=TagCollection.from_json(
                       data[AnnotationJsonFields.IMG_TAGS],
                       project_meta.tag_metas),
                   img_description=data.get(
                       AnnotationJsonFields.IMG_DESCRIPTION, ""),
                   pixelwise_scores_labels=prob_labels,
                   custom_data=custom_data,
                   image_id=image_id)
Ejemplo n.º 9
0
    def _do_single_img_inference(self, img, in_msg):
        in_project_meta = self._in_project_meta_from_msg(in_msg)
        ann_json = in_msg.get('annotation')
        if ann_json is not None:
            if in_project_meta is None:
                raise ValueError('In order to perform inference with annotation you must specify the appropriate'
                                 ' project meta.')
            ann = Annotation.from_json(ann_json, in_project_meta)
        else:
            in_project_meta = in_project_meta or ProjectMeta()
            ann = Annotation(img.shape[:2])

        inference_mode = self._make_inference_mode(in_msg.get(MODE, {}), in_project_meta)
        inference_result = inference_mode.infer_annotate(img, ann)
        return inference_result.to_json()
Ejemplo n.º 10
0
    def inference(self, id, img, ann=None, meta=None, mode=None, ext=None):
        data = {
            "request_type": "inference",
            "meta": meta or ProjectMeta().to_json(),
            "annotation": ann or None,
            "mode": mode or {},
        }
        img_data = sly_image.write_bytes(img, ext or '.jpg')
        encoder = MultipartEncoder({
            'id': str(id).encode('utf-8'),
            'data': json.dumps(data),
            'image': ("img", img_data, "")
        })

        response = self._api.post('models.infer',
                                  MultipartEncoderMonitor(encoder))
        return response.json()
Ejemplo n.º 11
0
        def post(self):
            args = self._parser.parse_args()

            meta = args[META]
            mode = args[MODE]

            data = {
                "request_type": GET_OUTPUT_META,
                "meta": json.loads(meta) if meta is not None else ProjectMeta().to_json(),
                "mode": json.loads(mode) if mode is not None else {}
            }

            response_json = self._model._final_processing(data)
            if 'out_meta' in response_json:
                return response_json['out_meta']
            if 'output_meta' in response_json:
                return response_json['output_meta']
            return response_json
Ejemplo n.º 12
0
 def get_output_meta(self, id, input_meta=None, inference_mode=None):
     data = {
         "request_type": "get_out_meta",
         "meta": input_meta or ProjectMeta().to_json(),
         "mode": inference_mode or {}
     }
     encoder = MultipartEncoder({
         'id': str(id).encode('utf-8'),
         'data': json.dumps(data)
     })
     response = self._api.post('models.infer',
                               MultipartEncoderMonitor(encoder))
     response_json = response.json()
     if 'out_meta' in response_json:
         return response_json['out_meta']
     if 'output_meta' in response_json:
         return response_json['output_meta']
     return response.json()
Ejemplo n.º 13
0
    def setUp(self):
        self._obj_class_gt = ObjClass(name='a', geometry_type=Rectangle)
        self._obj_class_pred = ObjClass(name='b', geometry_type=Rectangle)
        self._confidence_tag_meta = TagMeta(name='confidence', value_type=TagValueType.ANY_NUMBER)
        self._meta = ProjectMeta(
            obj_classes=ObjClassCollection([self._obj_class_gt, self._obj_class_pred]),
            tag_metas=TagMetaCollection([self._confidence_tag_meta]))

        # Will match self._pred_obj_1
        self._gt_obj_1 = Label(obj_class=self._obj_class_gt, geometry=Rectangle(0, 0, 10, 10))

        # Will match self._pred_obj_3
        self._gt_obj_2 = Label(obj_class=self._obj_class_gt, geometry=Rectangle(13, 13, 15, 15))

        # Will be a false negative
        self._gt_obj_3 = Label(obj_class=self._obj_class_gt, geometry=Rectangle(43, 43, 45, 45))

        # Will match self._gt_obj_1
        self._pred_obj_1 = Label(
            obj_class=self._obj_class_pred,
            geometry=Rectangle(0, 0, 9, 9),
            tags=TagCollection([Tag(meta=self._confidence_tag_meta, value=0.7)]))

        # Will be a false positive (self._pred_obj_1 has higher IoU).
        self._pred_obj_2 = Label(
            obj_class=self._obj_class_pred,
            geometry=Rectangle(0, 0, 8, 8),
            tags=TagCollection([Tag(meta=self._confidence_tag_meta, value=0.6)]))

        # Will match self._gt_obj_2
        self._pred_obj_3 = Label(
            obj_class=self._obj_class_pred,
            geometry=Rectangle(13, 13, 15, 15),
            tags=TagCollection([Tag(meta=self._confidence_tag_meta, value=0.1)]))

        # More false positives.
        self._pred_objs_fp = [
            Label(obj_class=self._obj_class_pred,
                  geometry=Rectangle(20, 20, 30, 30),
                  tags=TagCollection([Tag(meta=self._confidence_tag_meta, value=v / 100)]))
            for v in range(15, 85, 10)]

        self._metric_calculator = MAPMetric(class_mapping={'a': 'b'}, iou_threshold=0.5)
Ejemplo n.º 14
0
    def __init__(self,
                 task_id,
                 api: Api,
                 v_model,
                 project_meta: ProjectMeta,
                 col_number: int,
                 preview_info=False,
                 enable_zoom=False,
                 resize_on_zoom=False,
                 sync_views=False,
                 show_preview=True,
                 selectable=False,
                 opacity=0.5,
                 show_opacity_header=True,
                 fill_rectangle=False,
                 border_width=3):
        self._task_id = task_id
        self._api = api
        self._v_model = v_model
        self._project_meta = project_meta.clone()
        self._data = {}
        self.col_number = col_number
        self.preview_info = preview_info
        self._need_zoom = False
        self._with_title_url = False
        if not isinstance(self.col_number, int):
            raise ValueError("Columns number must be integer, not {}".format(
                type(self.col_number).__name__))

        self._options = {
            "enableZoom": enable_zoom,
            "syncViews": sync_views,
            "resizeOnZoom": resize_on_zoom,
            "showPreview": show_preview,
            "selectable": selectable,
            "opacity": opacity,
            "showOpacityInHeader": show_opacity_header,
            "fillRectangle": fill_rectangle,
            "borderWidth": border_width
        }
        self._options_initialized = False
Ejemplo n.º 15
0
    def _load_train_config(self):
        self._load_raw_model_config_json()

        self.class_title_to_idx = self.train_config[
            self.class_title_to_idx_key]
        logger.info('Read model internal class mapping',
                    extra={'class_mapping': self.class_title_to_idx})
        train_classes = ObjClassCollection.from_json(
            self.train_config[self.train_classes_key])
        logger.info('Read model out classes',
                    extra={'classes': train_classes.to_json()})

        # TODO: Factor out meta constructing from _load_train_config method.
        self._model_out_meta = ProjectMeta(obj_classes=train_classes,
                                           tag_metas=self._model_out_tags())
        # Make a separate [index] --> [class] map that excludes the 'special' classes that should not be in the`
        # final output.
        self.out_class_mapping = {
            idx: train_classes.get(title)
            for title, idx in self.class_title_to_idx.items()
            if train_classes.has_key(title)
        }
Ejemplo n.º 16
0
    def __init__(self, task_id, api: Api, v_model: str,
                 project_meta: ProjectMeta):
        self._task_id = task_id
        self._api = api
        self._v_model = v_model
        if self._v_model.startswith("data.") is False:
            new_v_model = v_model.replace('state.', 'data.', 1)
            raise KeyError(
                f"Data for this widget has to be stored in data field due to potential performance issues. "
                f"Please, change value of v_model argument "
                f"from {v_model} to {new_v_model} manually and also check html template"
            )

        self._project_meta = project_meta.clone()
        self._options = {
            "enableZoom": True,
            "syncViews": True,
            "showPreview": True,
            "selectable": True,
            "opacity": 0.5,
            "showOpacityInHeader": True,
            #"viewHeight": 450,
        }
        self._num_cols = 3

        self._gt_annotations = {}
        self._pred_annotations = {}
        self._order = []

        self._infos = {}
        self._min_time_index = None
        self._max_time_index = None
        self._active_time = None

        self._items_to_upload = {
            "gt": [],
            #"pred": {}
        }
Ejemplo n.º 17
0
    def __init__(self, task_id, api: Api, v_model, project_meta: ProjectMeta):
        self._task_id = task_id
        self._api = api
        self._v_model = v_model
        self._project_meta = project_meta.clone()

        self._left_title = None
        self._left_image_url = None
        self._left_ann = None

        self._right_title = None
        self._right_image_url = None
        self._right_ann = None

        self._options = {
            "enableZoom": True,
            "syncViews": True,
            "showPreview": False,
            "selectable": False,
            "opacity": 0.5,
            "showOpacityInHeader": True,
            # "viewHeight": 450,
        }
        self._options_initialized = False
Ejemplo n.º 18
0
    def from_json(cls,
                  data,
                  project_meta: ProjectMeta,
                  key_id_map: KeyIdMap = None):
        '''
        The function from_json convert VideoObject from json format to VideoObject class object. Raise error if object class name is not found in the given project meta
        :param data: input VideoObject in json format
        :param project_meta: ProjectMeta class object
        :param key_id_map: KeyIdMap class object
        :return: VideoObject class object
        '''
        obj_class_name = data[LabelJsonFields.OBJ_CLASS_NAME]
        obj_class = project_meta.get_obj_class(obj_class_name)
        if obj_class is None:
            raise RuntimeError(
                f'Failed to deserialize a object from JSON: class name {obj_class_name!r} '
                f'was not found in the given project meta.')

        key = uuid.UUID(data[KEY]) if KEY in data else uuid.uuid4()

        if key_id_map is not None:
            key_id_map.add_object(key, data.get(ID, None))

        class_id = data.get(CLASS_ID, None)
        labeler_login = data.get(LABELER_LOGIN, None)
        updated_at = data.get(UPDATED_AT, None)
        created_at = data.get(CREATED_AT, None)

        return cls(obj_class=obj_class,
                   key=key,
                   tags=VideoTagCollection.from_json(
                       data[LabelJsonFields.TAGS], project_meta.tag_metas),
                   class_id=class_id,
                   labeler_login=labeler_login,
                   updated_at=updated_at,
                   created_at=created_at)
Ejemplo n.º 19
0
 def _get_out_meta(self, in_msg):
     in_meta = self._in_project_meta_from_msg(in_msg) or ProjectMeta()
     inference_mode = self._make_inference_mode(in_msg.get(MODE, {}), in_meta)
     return inference_mode.out_meta
Ejemplo n.º 20
0
 def _in_project_meta_from_msg(in_msg):
     pr_meta_json = in_msg.get('meta')
     return ProjectMeta.from_json(pr_meta_json) if pr_meta_json is not None else None
Ejemplo n.º 21
0
def download_pointcloud_project(api,
                                project_id,
                                dest_dir,
                                dataset_ids=None,
                                download_items=True,
                                log_progress=False):
    LOG_BATCH_SIZE = 1

    key_id_map = KeyIdMap()

    project_fs = PointcloudProject(dest_dir, OpenMode.CREATE)

    meta = ProjectMeta.from_json(api.project.get_meta(project_id))
    project_fs.set_meta(meta)

    datasets_infos = []
    if dataset_ids is not None:
        for ds_id in dataset_ids:
            datasets_infos.append(api.dataset.get_info_by_id(ds_id))
    else:
        datasets_infos = api.dataset.get_list(project_id)

    for dataset in datasets_infos:
        dataset_fs = project_fs.create_dataset(dataset.name)
        pointclouds = api.pointcloud.get_list(dataset.id)

        ds_progress = None
        if log_progress:
            ds_progress = Progress('Downloading dataset: {!r}'.format(
                dataset.name),
                                   total_cnt=len(pointclouds))
        for batch in batched(pointclouds, batch_size=LOG_BATCH_SIZE):
            pointcloud_ids = [pointcloud_info.id for pointcloud_info in batch]
            pointcloud_names = [
                pointcloud_info.name for pointcloud_info in batch
            ]

            ann_jsons = api.pointcloud.annotation.download_bulk(
                dataset.id, pointcloud_ids)

            for pointcloud_id, pointcloud_name, ann_json in zip(
                    pointcloud_ids, pointcloud_names, ann_jsons):
                if pointcloud_name != ann_json[ApiField.NAME]:
                    raise RuntimeError(
                        "Error in api.video.annotation.download_batch: broken order"
                    )

                pointcloud_file_path = dataset_fs.generate_item_path(
                    pointcloud_name)
                if download_items is True:
                    api.pointcloud.download_path(pointcloud_id,
                                                 pointcloud_file_path)

                    related_images_path = dataset_fs.get_related_images_path(
                        pointcloud_name)
                    related_images = api.pointcloud.get_list_related_images(
                        pointcloud_id)
                    for rimage_info in related_images:
                        name = rimage_info[ApiField.NAME]

                        if not has_valid_ext(name):
                            new_name = get_file_name(
                                name)  # to fix cases like .png.json
                            if has_valid_ext(new_name):
                                name = new_name
                                rimage_info[ApiField.NAME] = name
                            else:
                                raise RuntimeError(
                                    'Something wrong with photo context filenames.\
                                                    Please, contact support')

                        rimage_id = rimage_info[ApiField.ID]

                        path_img = os.path.join(related_images_path, name)
                        path_json = os.path.join(related_images_path,
                                                 name + ".json")

                        api.pointcloud.download_related_image(
                            rimage_id, path_img)
                        dump_json_file(rimage_info, path_json)

                else:
                    touch(pointcloud_file_path)

                dataset_fs.add_item_file(pointcloud_name,
                                         pointcloud_file_path,
                                         ann=PointcloudAnnotation.from_json(
                                             ann_json, project_fs.meta,
                                             key_id_map),
                                         _validate_item=False)

            ds_progress.iters_done_report(len(batch))

    project_fs.set_key_id_map(key_id_map)
Ejemplo n.º 22
0
        def post(self):
            args = self._parser.parse_args()
            img_bytes = args[IMAGE].stream.read()
            img = sly_image.read_bytes(img_bytes)

            meta = args[META]
            ann = args[ANNOTATION]
            mode = args[MODE]

            data = {
                "request_type": INFERENCE,
                "meta": json.loads(meta.stream.read().decode("utf-8")) if meta is not None else ProjectMeta().to_json(),
                "annotation": json.loads(ann.stream.read().decode("utf-8")) if ann is not None else None,
                "mode": json.loads(mode.stream.read().decode("utf-8")) if mode is not None else {},
                'image_arr': img
            }
            return self._model._final_processing(data)
Ejemplo n.º 23
0
def download_video_project(api,
                           project_id,
                           dest_dir,
                           dataset_ids=None,
                           download_videos=True,
                           log_progress=False):
    '''
    Download project with given id in destination directory
    :param api: Api class object
    :param project_id: int
    :param dest_dir: str
    :param dataset_ids: list of integers
    :param download_videos: bool
    :param log_progress: bool
    '''
    LOG_BATCH_SIZE = 1

    key_id_map = KeyIdMap()

    project_fs = VideoProject(dest_dir, OpenMode.CREATE)

    meta = ProjectMeta.from_json(api.project.get_meta(project_id))
    project_fs.set_meta(meta)

    datasets_infos = []
    if dataset_ids is not None:
        for ds_id in dataset_ids:
            datasets_infos.append(api.dataset.get_info_by_id(ds_id))
    else:
        datasets_infos = api.dataset.get_list(project_id)

    for dataset in datasets_infos:
        dataset_fs = project_fs.create_dataset(dataset.name)
        videos = api.video.get_list(dataset.id)

        ds_progress = None
        if log_progress:
            ds_progress = Progress('Downloading dataset: {!r}'.format(
                dataset.name),
                                   total_cnt=len(videos))
        for batch in batched(videos, batch_size=LOG_BATCH_SIZE):
            video_ids = [video_info.id for video_info in batch]
            video_names = [video_info.name for video_info in batch]

            ann_jsons = api.video.annotation.download_bulk(
                dataset.id, video_ids)

            for video_id, video_name, ann_json in zip(video_ids, video_names,
                                                      ann_jsons):
                if video_name != ann_json[ApiField.VIDEO_NAME]:
                    raise RuntimeError(
                        "Error in api.video.annotation.download_batch: broken order"
                    )

                video_file_path = dataset_fs.generate_item_path(video_name)
                if download_videos is True:
                    api.video.download_path(video_id, video_file_path)
                else:
                    touch(video_file_path)

                dataset_fs.add_item_file(video_name,
                                         video_file_path,
                                         ann=VideoAnnotation.from_json(
                                             ann_json, project_fs.meta,
                                             key_id_map),
                                         _validate_item=False)

            ds_progress.iters_done_report(len(batch))

    project_fs.set_key_id_map(key_id_map)
Ejemplo n.º 24
0
def download_pointcloud_episode_project(api,
                                        project_id,
                                        dest_dir,
                                        dataset_ids=None,
                                        download_pcd=True,
                                        download_realated_images=True,
                                        download_annotations=True,
                                        log_progress=False,
                                        batch_size=10):
    key_id_map = KeyIdMap()
    project_fs = PointcloudEpisodeProject(dest_dir, OpenMode.CREATE)
    meta = ProjectMeta.from_json(api.project.get_meta(project_id))
    project_fs.set_meta(meta)

    datasets_infos = []
    if dataset_ids is not None:
        for ds_id in dataset_ids:
            datasets_infos.append(api.dataset.get_info_by_id(ds_id))
    else:
        datasets_infos = api.dataset.get_list(project_id)

    for dataset in datasets_infos:
        dataset_fs = project_fs.create_dataset(dataset.name)
        pointclouds = api.pointcloud_episode.get_list(dataset.id)

        if download_annotations:
            # Download annotation to project_path/dataset_path/annotation.json
            ann_json = api.pointcloud_episode.annotation.download(dataset.id)
            annotation = dataset_fs.annotation_class.from_json(
                ann_json, meta, key_id_map)
            dataset_fs.set_ann(annotation)

            # frames --> pointcloud mapping to project_path/dataset_path/frame_pointcloud_map.json
            frame_name_map = api.pointcloud_episode.get_frame_name_map(
                dataset.id)
            frame_pointcloud_map_path = dataset_fs.get_frame_pointcloud_map_path(
            )
            dump_json_file(frame_name_map, frame_pointcloud_map_path)

        # Download data
        if log_progress:
            ds_progress = Progress('Downloading dataset: {!r}'.format(
                dataset.name),
                                   total_cnt=len(pointclouds))

        for batch in batched(pointclouds, batch_size=batch_size):
            pointcloud_ids = [pointcloud_info.id for pointcloud_info in batch]
            pointcloud_names = [
                pointcloud_info.name for pointcloud_info in batch
            ]

            for pointcloud_id, pointcloud_name in zip(pointcloud_ids,
                                                      pointcloud_names):
                pointcloud_file_path = dataset_fs.generate_item_path(
                    pointcloud_name)
                if download_pcd is True:
                    api.pointcloud_episode.download_path(
                        pointcloud_id, pointcloud_file_path)
                else:
                    touch(pointcloud_file_path)

                if download_realated_images:
                    related_images_path = dataset_fs.get_related_images_path(
                        pointcloud_name)
                    related_images = api.pointcloud_episode.get_list_related_images(
                        pointcloud_id)
                    for rimage_info in related_images:
                        name = rimage_info[ApiField.NAME]
                        rimage_id = rimage_info[ApiField.ID]

                        path_img = os.path.join(related_images_path, name)
                        path_json = os.path.join(related_images_path,
                                                 name + ".json")

                        api.pointcloud_episode.download_related_image(
                            rimage_id, path_img)
                        dump_json_file(rimage_info, path_json)

                dataset_fs.add_item_file(pointcloud_name,
                                         pointcloud_file_path,
                                         _validate_item=False)
            if log_progress:
                ds_progress.iters_done_report(len(batch))

    project_fs.set_key_id_map(key_id_map)
Ejemplo n.º 25
0
 def update_project_meta(self, project_meta: ProjectMeta):
     self._project_meta = project_meta.clone()