Source code for supervisely.pointcloud_annotation.pointcloud_episode_annotation

# coding: utf-8
from __future__ import annotations
import uuid
import json
from typing import Optional, Dict, List

from supervisely.project.project_meta import ProjectMeta
from supervisely._utils import take_with_default
from supervisely.api.module_api import ApiField
from supervisely.pointcloud_annotation.pointcloud_episode_object_collection import (
    PointcloudEpisodeObjectCollection,
)
from supervisely.video_annotation.constants import (
    FRAMES,
    DESCRIPTION,
    FRAMES_COUNT,
    TAGS,
    OBJECTS,
    KEY,
)
from supervisely.pointcloud_annotation.pointcloud_figure import PointcloudFigure
from supervisely.pointcloud_annotation.pointcloud_episode_frame_collection import (
    PointcloudEpisodeFrameCollection,
)
from supervisely.video_annotation.key_id_map import KeyIdMap
from supervisely.pointcloud_annotation.pointcloud_episode_tag_collection import (
    PointcloudEpisodeTagCollection,
)


[docs]class PointcloudEpisodeAnnotation: """ PointcloudEpisodeAnnotation for point cloud episodes. :class:`PointcloudEpisodeAnnotation<PointcloudEpisodeAnnotation>` object is immutable. :param frames_count: Number of PointcloudEpisodeFrame objects. :type frames_count: int, optional :param objects: PointcloudEpisodeObjectCollection object :type objects: PointcloudEpisodeObjectCollection, optional :param frames: PointcloudEpisodeFrameCollection object :type frames: PointcloudEpisodeFrameCollection, optional :param tags: PointcloudEpisodeTagCollection object :type tags: PointcloudEpisodeTagCollection, optional :param description: Description text :type description: str, optional :param key: uuid class object :type key: uuid.UUID, optional :Usage example: .. code-block:: python import supervisely as sly from supervisely.video_annotation.key_id_map import KeyIdMap # PointcloudEpisodeAnnotation example 1 pointcloud_episodes_ann = sly.PointcloudEpisodeAnnotation() print(pointcloud_episodes_ann.to_json()) # Output: { # "description": "", # "frames": [], # "framesCount": None, # "key": "494f67984d714c1eaf7a65e5df289ac6", # "objects": [], # "tags": [] # } # PointcloudEpisodeAnnotation example 2 pointcloud_id = 19481098 key_id_map = KeyIdMap() pcd_info = api.pointcloud_episode.get_info_by_id(pointcloud_id) project_meta_json = api.project.get_meta(pcd_info.project_id) project_meta = sly.ProjectMeta.from_json(project_meta_json) ann_json = api.pointcloud_episode.annotation.download(pcd_info.dataset_id) ann = sly.PointcloudEpisodeAnnotation.from_json( data=ann_json, project_meta=project_meta, key_id_map=key_id_map ) """ def __init__( self, frames_count: Optional[int] = None, objects: Optional[PointcloudEpisodeObjectCollection] = None, frames: Optional[PointcloudEpisodeFrameCollection] = None, tags: Optional[PointcloudEpisodeTagCollection] = None, description: Optional[str] = "", key: uuid.UUID = None, ) -> None: self._frames_count = frames_count self._description = description self._frames = take_with_default(frames, PointcloudEpisodeFrameCollection()) self._tags = take_with_default(tags, PointcloudEpisodeTagCollection()) self._objects = take_with_default(objects, PointcloudEpisodeObjectCollection()) self._key = take_with_default(key, uuid.uuid4())
[docs] def get_tags_on_frame(self, frame_index: int) -> PointcloudEpisodeTagCollection: """ Retrieve tags associated with a specific frame in a PointcloudEpisodeAnnotation. :param frame_index: The index of the frame for which tags need to be retrieved. :type frame_index: int :return: PointcloudEpisodeTagCollection containing the retrieved tags associated with the specified frame. :rtype: PointcloudEpisodeTagCollection :raises ValueError: If no frame with the given frame_index exists in the annotation. :Usage example: .. code-block:: python import supervisely as sly from supervisely.video_annotation.key_id_map import KeyIdMap key_id_map = KeyIdMap() pointcloud_id = 19481098 pcd_info = api.pointcloud_episode.get_info_by_id(pointcloud_id) project_meta_json = api.project.get_meta(pcd_info.project_id) project_meta = sly.ProjectMeta.from_json(project_meta_json) ann_json = api.pointcloud_episode.annotation.download(pcd_info.dataset_id) ann = sly.PointcloudEpisodeAnnotation.from_json( data=ann_json, project_meta=project_meta, key_id_map=key_id_map ) frame_index = 0 tags_on_frame = ann.get_tags_on_frame(frame_index) print(tags_on_frame) # Output: Tags: +-------+------------+-------+-------------+ | Name | Value type | Value | Frame range | +-------+------------+-------+-------------+ | color | any_string | red | [0, 0] | +-------+------------+-------+-------------+ """ frame = self._frames.get(frame_index, None) if frame is None: if frame_index < self.frames_count: return PointcloudEpisodeTagCollection([]) else: raise ValueError(f"No frame with index {frame_index} in annotation.") tags = [] for tag in self._tags: if frame_index >= tag.frame_range[0] and frame_index <= tag.frame_range[1]: tags.append(tag) return PointcloudEpisodeTagCollection(tags)
[docs] def get_objects_on_frame(self, frame_index: int) -> PointcloudEpisodeObjectCollection: """ Retrieve objects associated with a specific frame in a PointcloudEpisodeAnnotation. :param frame_index: The index of the frame for which objects need to be retrieved. :type frame_index: int :return: PointcloudEpisodeObjectCollection containing the retrieved objects associated with the specified frame. :rtype: :raises ValueError: If no frame with the given frame_index exists in the annotation. :Usage example: .. code-block:: python import supervisely as sly from supervisely.video_annotation.key_id_map import KeyIdMap key_id_map = KeyIdMap() pointcloud_id = 19481098 pcd_info = api.pointcloud_episode.get_info_by_id(pointcloud_id) project_meta_json = api.project.get_meta(pcd_info.project_id) project_meta = sly.ProjectMeta.from_json(project_meta_json) ann_json = api.pointcloud_episode.annotation.download(pcd_info.dataset_id) ann = sly.PointcloudEpisodeAnnotation.from_json( data=ann_json, project_meta=project_meta, key_id_map=key_id_map ) frame_index = 0 objects_on_frame = ann.get_objects_on_frame(frame_index) print(objects_on_frame.to_json()) # Output: # [ # { # "key": "687784c3d4d64ec4811948fec245514a", # "classTitle": "Tram", # "tags": [], # "labelerLogin": "almaz", # "updatedAt": "2023-03-16T06:38:44.934Z", # "createdAt": "2023-03-16T06:38:44.934Z" # }, # { # "key": "b8b23b6712444f0fbfb320b0b4acd09a", # "classTitle": "Car", # "tags": [], # "labelerLogin": "almaz", # "updatedAt": "2023-03-16T06:38:44.934Z", # "createdAt": "2023-03-16T06:38:44.934Z" # } # ] """ frame = self._frames.get(frame_index, None) if frame is None: if frame_index < self.frames_count: return PointcloudEpisodeObjectCollection([]) else: raise ValueError(f"No frame with index {frame_index} in annotation.") frame_objects = {} for fig in frame.figures: if fig.parent_object.key() not in frame_objects.keys(): frame_objects[fig.parent_object.key()] = fig.parent_object return PointcloudEpisodeObjectCollection(list(frame_objects.values()))
[docs] def get_figures_on_frame(self, frame_index: int) -> List[PointcloudFigure]: """ Retrieve figures associated with a specific frame in a PointcloudEpisodeAnnotation. :param frame_index: The index of the frame for which figures need to be retrieved. :type frame_index: int :return: List of PointcloudFigure objects containing the retrieved figures associated with the specified frame. :rtype: List[PointcloudFigure] :Usage example: .. code-block:: python import supervisely as sly from supervisely.video_annotation.key_id_map import KeyIdMap key_id_map = KeyIdMap() pointcloud_id = 19481098 pcd_info = api.pointcloud_episode.get_info_by_id(pointcloud_id) project_meta_json = api.project.get_meta(pcd_info.project_id) project_meta = sly.ProjectMeta.from_json(project_meta_json) ann_json = api.pointcloud_episode.annotation.download(pcd_info.dataset_id) ann = sly.PointcloudEpisodeAnnotation.from_json( data=ann_json, project_meta=project_meta, key_id_map=key_id_map ) frame_index = 0 figures_on_frame = ann.get_figures_on_frame(frame_index) print(figures_on_frame) # Output: # [<supervisely.pointcloud_annotation.pointcloud_figure.PointcloudFigure object at 0x7fc83895a4d0>, # <supervisely.pointcloud_annotation.pointcloud_figure.PointcloudFigure object at 0x7fc83895a810>, # <supervisely.pointcloud_annotation.pointcloud_figure.PointcloudFigure object at 0x7fc8389410d0>] """ frame = self._frames.get(frame_index, None) if frame is None: if frame_index < self.frames_count: return [] else: raise ValueError(f"No frame with index {frame_index} in annotation.") return frame.figures
[docs] def to_json(self, key_id_map: KeyIdMap = None) -> Dict: """ Convert PointcloudEpisodeAnnotation to JSON format. :param key_id_map: KeyIdMap object. :type key_id_map: KeyIdMap, optional :return: PointcloudEpisodeAnnotation in JSON format. :rtype: Dict :Usage example: .. code-block:: python import supervisely as sly pointcloud_id = 19481098 pcd_info = api.pointcloud_episode.get_info_by_id(pointcloud_id) project_path = "Downloads/pointcloud_api/project" sly.PointcloudEpisodeProject.download( api=api, project_id=pcd_info.project_id, dest_dir=project_path, dataset_ids=[pcd_info.dataset_id], download_pointclouds=True, ) project_fs = sly.PointcloudEpisodeProject(project_path, sly.OpenMode.READ) project_meta_json = api.project.get_meta(pcd_info.project_id) project_meta = sly.ProjectMeta.from_json(project_meta_json) ds = project_fs.datasets.items()[0]: ann = ds.get_ann(project_meta) print(ann.to_json()) # Output: # { # 'datasetId': 60988, # 'description': '', # 'frames': [{'figures': [{'classId': None, # 'createdAt': '2023-03-16T06:38:45.004Z', # 'description': '', # 'geometry': {'dimensions': {'x': 2.3652234, # 'y': 23.291742, # 'z': 3.326648}, # 'position': {'x': 86.29707472161449, # 'y': -14.472597682830635, # 'z': 0.8842007608554671}, # 'rotation': {'x': 0, # 'y': 0, # 'z': -1.6962800995995606}}, # 'geometryType': 'cuboid_3d', # 'id': 87536496, # 'labelerLogin': 'almaz', # 'objectId': 5531328, # 'updatedAt': '2023-03-16T06:38:45.004Z'}], # 'index': 0, # 'pointCloudId': 19481098}], # 'index': 1, # 'pointCloudId': 19481100}, # ...], # 'framesCount': 54, # 'objects': [{'classId': 666944, # 'classTitle': 'Car', # 'createdAt': '2023-03-16T06:38:44.934Z', # 'datasetId': 60988, # 'entityId': None, # 'id': 5531324, # 'labelerLogin': 'almaz', # 'tags': [], # 'updatedAt': '2023-03-16T06:38:44.934Z'}], # 'tags': [] # } """ res_json = { DESCRIPTION: self.description, KEY: self.key().hex, TAGS: self.tags.to_json(key_id_map), OBJECTS: self.objects.to_json(key_id_map), FRAMES_COUNT: self.frames_count, FRAMES: self.frames.to_json(key_id_map), } if key_id_map is not None: dataset_id = key_id_map.get_video_id(self.key()) if dataset_id is not None: res_json[ApiField.DATASET_ID] = dataset_id return res_json
[docs] @classmethod def from_json( cls, data: Dict, project_meta: ProjectMeta, key_id_map: Optional[KeyIdMap] = None ) -> PointcloudEpisodeAnnotation: """ Create a PointcloudEpisodeAnnotation object from a JSON representation. :param data: JSON data representing the PointcloudEpisodeAnnotation. :type data: Dict :param project_meta: Project metadata. :type project_meta: ProjectMeta :return: PointcloudEpisodeAnnotation object :rtype: :class:`PointcloudEpisodeAnnotation<PointcloudEpisodeAnnotation>` :Usage example: .. code-block:: python import supervisely as sly from supervisely.video_annotation.key_id_map import KeyIdMap key_id_map = KeyIdMap() pointcloud_id = 19481098 pcd_info = api.pointcloud_episode.get_info_by_id(pointcloud_id) project_meta_json = api.project.get_meta(pcd_info.project_id) project_meta = sly.ProjectMeta.from_json(project_meta_json) ann_json = api.pointcloud_episode.annotation.download(pcd_info.dataset_id) ann = sly.PointcloudEpisodeAnnotation.from_json( data=ann_json, project_meta=project_meta, key_id_map=key_id_map ) """ item_key = uuid.UUID(data[KEY]) if KEY in data else uuid.uuid4() if key_id_map is not None: key_id_map.add_video(item_key, data.get(ApiField.DATASET_ID, None)) description = data.get(DESCRIPTION, "") frames_count = data.get(FRAMES_COUNT, 0) tags = PointcloudEpisodeTagCollection.from_json( data[TAGS], project_meta.tag_metas, key_id_map ) objects = PointcloudEpisodeObjectCollection.from_json(data[OBJECTS], project_meta, key_id_map) frames = PointcloudEpisodeFrameCollection.from_json( data[FRAMES], objects, key_id_map=key_id_map ) return cls(frames_count, objects, frames, tags, description, item_key)
[docs] @classmethod def load_json_file( cls, path: str, project_meta: ProjectMeta, key_id_map: Optional[KeyIdMap] = None ) -> PointcloudEpisodeAnnotation: """ Loads json file and converts it to PointcloudEpisodeAnnotation. :param path: Path to the json file. :type path: str :param project_meta: Input :class:`ProjectMeta<supervisely.project.project_meta.ProjectMeta>`. :type project_meta: ProjectMeta :param key_id_map: KeyIdMap object. :type key_id_map: KeyIdMap, optional :return: PointcloudEpisodeAnnotation object :rtype: :class:`PointcloudEpisodeAnnotation<PointcloudEpisodeAnnotation>` :Usage example: .. code-block:: python import supervisely as sly address = 'https://app.supervise.ly/' token = 'Your Supervisely API Token' api = sly.Api(address, token) team_name = 'Vehicle Detection' workspace_name = 'Cities' project_name = 'London' project_id = 19441 project_meta_json = api.project.get_meta(project_id) project_meta = sly.ProjectMeta.from_json(project_meta_json) # Load json file path = "/home/admin/work/docs/my_dataset/ann/annotation.json" ann = sly.PointcloudEpisodeAnnotation.load_json_file(path, project_meta) """ with open(path) as fin: data = json.load(fin) return cls.from_json(data, project_meta, key_id_map)
[docs] def clone( self, frames_count: Optional[int] = None, objects: Optional[PointcloudEpisodeObjectCollection] = None, frames: Optional[PointcloudEpisodeFrameCollection] = None, tags: Optional[PointcloudEpisodeTagCollection] = None, description: Optional[str] = "", ) -> PointcloudEpisodeAnnotation: """ Makes a copy of PointcloudEpisodeAnnotation with new fields, if fields are given, otherwise it will use fields of the original PointcloudEpisodeAnnotation. :param frames_count: Number of PointcloudEpisodeFrame objects :type frames_count: int, optional :param objects: PointcloudEpisodeObjectCollection object :type objects: PointcloudEpisodeObjectCollection, optional :param frames: PointcloudEpisodeFrameCollection object :type frames: PointcloudEpisodeFrameCollection, optional :param tags: PointcloudEpisodeTagCollection object :type tags: PointcloudEpisodeTagCollection, optional :param description: Description text :type description: str, optional :return: PointcloudAnnotation class object :Usage example: .. code-block:: python import supervisely as sly from supervisely.video_annotation.key_id_map import KeyIdMap address = 'https://app.supervise.ly/' token = 'Your Supervisely API Token' api = sly.Api(address, token) key_id_map = KeyIdMap() pointcloud_id = 19481098 pcd_info = api.pointcloud_episode.get_info_by_id(pointcloud_id) project_meta_json = api.project.get_meta(pcd_info.project_id) project_meta = sly.ProjectMeta.from_json(project_meta_json) ann_json = api.pointcloud_episode.annotation.download(pcd_info.dataset_id) ann = sly.PointcloudAnnotation.from_json( data=ann_json, project_meta=project_meta, key_id_map=key_id_map ) obj_class_car = sly.ObjClass('car', sly.Cuboid) pointcloud_obj_car = sly.PointcloudEpisodeObject(obj_class_car) new_objects = ann.objects.add(pointcloud_obj_car) new_ann = ann.clone(objects=new_objects) print(new_ann.to_json()) # Output: # { # 'datasetId': 60988, # 'description': '', # 'frames': [{'figures': [{'classId': None, # 'createdAt': '2023-03-16T06:38:45.004Z', # 'description': '', # 'geometry': {'dimensions': {'x': 2.3652234, # 'y': 23.291742, # 'z': 3.326648}, # 'position': {'x': 86.29707472161449, # 'y': -14.472597682830635, # 'z': 0.8842007608554671}, # 'rotation': {'x': 0, # 'y': 0, # 'z': -1.6962800995995606}}, # 'geometryType': 'cuboid_3d', # 'id': 87536496, # 'labelerLogin': 'almaz', # 'objectId': 5531328, # 'updatedAt': '2023-03-16T06:38:45.004Z'}], # 'index': 0, # 'pointCloudId': 19481098}], # 'index': 1, # 'pointCloudId': 19481100}, # ...], # 'framesCount': 54, # 'objects': [{ # 'classId': 666944, # 'classTitle': 'Car', # 'createdAt': '2023-03-16T06:38:44.934Z', # 'datasetId': 60988, # 'entityId': None, # 'id': 5531324, # 'labelerLogin': 'almaz', # 'tags': [], # 'updatedAt': '2023-03-16T06:38:44.934Z'} # { # 'classTitle': 'Car', # 'createdAt': '2023-03-16T06:38:44.934Z', # 'key': 'fc149a8f3e3a413c807a6b4ba474645c', # 'labelerLogin': 'almaz', # 'tags': [], # 'updatedAt': '2023-03-16T06:38:44.934Z # }], # 'tags': [] # } # Output: { # "description": "", # "figures": [], # "key": "2cc443272aca4cfa9c4f404614938aa7", # "objects": [ # { # "classTitle": "Pole", # "createdAt": "2023-03-16T06:38:44.934Z", # "key": "eff2ec5e3cda47968f45bc51b36a0dc1", # "labelerLogin": "almaz", # "tags": [], # "updatedAt": "2023-03-16T06:38:44.934Z" # }, # { # "classTitle": "Tram", # "createdAt": "2023-03-16T06:38:44.934Z", # "key": "6baa92e09ceb413ba8fbfcfae74be1c7", # "labelerLogin": "almaz", # "tags": [], # "updatedAt": "2023-03-16T06:38:44.934Z" # }, # { # "classTitle": "car", # "key": "6b1bced23061437b8ddbcdd267548c96", # "tags": [] # } # ], # "tags": [] # } """ return PointcloudEpisodeAnnotation( frames_count=take_with_default(frames_count, self.frames_count), objects=take_with_default(objects, self.objects), frames=take_with_default(frames, self.frames), tags=take_with_default(tags, self.tags), description=take_with_default(description, self.description), )
@property def frames_count(self) -> int: """ Number of frames. :return: Frames count :rtype: :class:`int` :Usage example: .. code-block:: python import supervisely as sly frames_count = 15 video_ann = sly.PointcloudEpisodeAnnotation(frames_count=frames_count) print(video_ann.frames_count) # Output: 15 """ return self._frames_count @property def objects(self) -> PointcloudEpisodeObjectCollection: """ PointcloudEpisodeObject objects collection. :returns: PointcloudEpisodeObjectCollection object. :rtype: PointcloudEpisodeObjectCollection :Usage example: .. code-block:: python import supervisely as sly address = 'https://app.supervise.ly/' token = 'Your Supervisely API Token' api = sly.Api(address, token) project_id = 19441 project_meta_json = api.project.get_meta(project_id) project_meta = sly.ProjectMeta.from_json(project_meta_json) # Load json file path = "/home/admin/work/docs/my_dataset/ann/annotation.json" ann = sly.PointcloudEpisodeAnnotation.load_json_file(path, project_meta) objects = ann.objects """ return self._objects @property def frames(self) -> PointcloudEpisodeFrameCollection: """ PointcloudEpisodeFrameCollection collection. :return: PointcloudEpisodeFrameCollection object :rtype: :class:`PointcloudEpisodeFrameCollection<supervisely.pointcloud_episodes.pointcloud_episode_frame_collection.PointcloudEpisodeFrameCollection>` :Usage example: .. code-block:: python import supervisely as sly from supervisely.geometry.cuboid_3d import Cuboid3d, Vector3d from supervisely.pointcloud_annotation.pointcloud_episode_object_collection import PointcloudEpisodeObjectCollection obj_class_car = sly.ObjClass('car', Cuboid3d) pointcloud_obj_car = sly.PointcloudEpisodeObject(obj_class_car) objects = sly.PointcloudEpisodeObjectCollection([pointcloud_obj_car]) position, rotation, dimension = Vector3d(-3.4, 28.9, -0.7), Vector3d(0., 0, -0.03), Vector3d(1.8, 3.9, 1.6) cuboid = Cuboid3d(position, rotation, dimension) frame_index = 10 figure = sly.PointcloudFigure(pointcloud_obj_car, cuboid, frame_index=frame_index) frame = sly.PointcloudEpisodeFrame(frame_index, figures=[figure]) frames = sly.PointcloudEpisodeFrameCollection([frame]) pointcloud_episodes_ann = sly.PointcloudEpisodeAnnotation(frames_count, objects, frames) print(pointcloud_episodes_ann.frames.to_json()) # Output: # [ # { # "figures": [ # { # "geometry": { # "dimensions": { "x": 1.8, "y": 3.9, "z": 1.6 }, # "position": { "x": -3.4, "y": 28.9, "z": -0.7 }, # "rotation": { "x": 0.0, "y": 0, "z": -0.03 } # }, # "geometryType": "cuboid_3d", # "key": "030b9aafa97642e887e2be544ef7a7ee", # "objectKey": "95c473a6cff44afda127ffb40d2bac5b" # } # ], # "index": 0 # } # ] """ return self._frames @property def figures(self) -> List[PointcloudFigure]: """ PointcloudFigure objects. :returns: List of PointcloudFigure objects from PointcloudEpisodeAnnotation object. :rtype: list :Usage example: .. code-block:: python import supervisely as sly address = 'https://app.supervise.ly/' token = 'Your Supervisely API Token' api = sly.Api(address, token) project_id = 19441 project_meta_json = api.project.get_meta(project_id) project_meta = sly.ProjectMeta.from_json(project_meta_json) # Load json file path = "/home/admin/work/docs/my_dataset/ann/annotation.json" ann = sly.PointcloudEpisodeAnnotation.load_json_file(path, project_meta) for figure in ann.figures: print(figure.to_json()) # Output: # { # "geometry": { # "dimensions": { "x": 1.8, "y": 3.9, "z": 1.6 }, # "position": { "x": -3.4, "y": 28.9, "z": -0.7 }, # "rotation": { "x": 0.0, "y": 0, "z": -0.03 } # }, # "geometryType": "cuboid_3d", # "key": "01836c294c514250a11889f56cf210e9", # "objectKey": "737c4df19c0c4cccbc48cf69b72abe36" # } """ return self.frames.figures @property def tags(self) -> PointcloudEpisodeTagCollection: """ PointcloudEpisodeTag objects collection. :returns: PointcloudEpisodeTagCollection object. :rtype: PointcloudEpisodeTagCollection :Usage example: .. code-block:: python import supervisely as sly address = 'https://app.supervise.ly/' token = 'Your Supervisely API Token' api = sly.Api(address, token) project_id = 19441 project_meta_json = api.project.get_meta(project_id) project_meta = sly.ProjectMeta.from_json(project_meta_json) # Load json file path = "/home/admin/work/docs/my_dataset/ann/annotation.json" ann = sly.PointcloudEpisodeAnnotation.load_json_file(path, project_meta) tags = ann.tags """ return self._tags
[docs] def key(self) -> uuid.UUID: """ PointcloudEpisodeAnnotation key value. :returns: Key value of point cloud episodes annotation object. :rtype: str :Usage example: .. code-block:: python import supervisely as sly ann = sly.PointcloudEpisodeAnnotation() print(ann.key()) # Output: 93ab6292-c661-4a53-b407-85ed34f5b68a' """ return self._key
@property def description(self) -> str: """ Description text for PointcloudEpisodeAnnotation object. :return: PointcloudEpisodeAnnotation description :rtype: :class:`str` :Usage example: .. code-block:: python import supervisely as sly descr = 'example' ann = sly.PointcloudEpisodeAnnotation(description=descr) print(ann.description) # example """ return self._description
[docs] def is_empty(self) -> bool: """ Check whether point cloud episodes annotation contains objects or tags, or not. :returns: True if point cloud episodes annotation is empty, False otherwise. :rtype: :class:`bool` :Usage example: .. code-block:: python import supervisely as sly from supervisely.video_annotation.key_id_map import KeyIdMap address = 'https://app.supervise.ly/' token = 'Your Supervisely API Token' api = sly.Api(address, token) project_id = 18428 dataset_id = 60988 key_id_map = KeyIdMap() meta_json = api.project.get_meta(project_id) meta = sly.ProjectMeta.from_json(meta_json) ann_json = api.pointcloud_episode.annotation.download(dataset_id) ann = sly.PointcloudEpisodeAnnotation.from_json(ann_json, meta, key_id_map) print(ann.is_empty()) # False """ if len(self.objects) == 0 and len(self.tags) == 0: return True else: return False