def __init__(self, name: str, geometry_type: type, color: List[int] = None, geometry_config: dict = None, sly_id=None, hotkey: str = None): """ Class of objects (person, car, etc) with necessary properties: name, type of geometry (Polygon, Rectangle, ...) and RGB color. Only one class can be associated with Label. Args: name: string name of the class (person, car, apple, etc) geometry_type: type of the geometry. Geometry defines the shape for all Labels of this ObjClass: Polygon, Rectangle, Bitmap, Polyline, Point color: [R, G, B] geometry_config: additional settings of the geometry that is associated with ObjClass Returns: ObjClass instance """ self._name = name self._geometry_type = geometry_type self._color = random_rgb() if color is None else deepcopy(color) self._geometry_config = deepcopy(take_with_default( geometry_config, {})) self._sly_id = sly_id self._hotkey = take_with_default(hotkey, "") _validate_color(self._color)
def __init__(self, img_size, labels=None, img_tags=None, img_description="", pixelwise_scores_labels=None, custom_data=None, image_id=None): ''' The constructor for Annotation class. :param img_size(tuple): size of the image :param labels(list): list of Label class objects :param img_tags(list): list of image tags :param img_description(str): image description :param pixelwise_scores_labels(list) ''' if not isinstance(img_size, (tuple, list)): raise TypeError( '{!r} has to be a tuple or a list. Given type "{}".'.format( 'img_size', type(img_size))) self._img_size = tuple(img_size) self._img_description = img_description self._img_tags = take_with_default(img_tags, TagCollection()) self._labels = [] self._add_labels_impl(self._labels, take_with_default(labels, [])) self._pixelwise_scores_labels = [ ] # @TODO: store pixelwise scores as usual geometry labels self._add_labels_impl(self._pixelwise_scores_labels, take_with_default(pixelwise_scores_labels, [])) self._custom_data = take_with_default(custom_data, {}) self._image_id = image_id
def __init__(self, name: str, value_type: str, possible_values: List[str] = None, color: List[int]=None, sly_id=None, hotkey: str = None, applicable_to: str = None, applicable_classes: List[str]=None): """ :param name: str :param value_type: str (one of TagValueType fields) :param values: list of possible values (i.e. [str]) or None :param color: [R, G, B] """ if value_type not in SUPPORTED_TAG_VALUE_TYPES: raise ValueError("value_type = {!r} is unknown, should be one of {}" .format(value_type, SUPPORTED_TAG_VALUE_TYPES)) self._name = name self._value_type = value_type self._possible_values = possible_values self._color = random_rgb() if color is None else deepcopy(color) self._sly_id = sly_id self._hotkey = take_with_default(hotkey, "") self._applicable_to = take_with_default(applicable_to, TagApplicableTo.ALL) self._applicable_classes = take_with_default(applicable_classes, []) if self._applicable_to not in SUPPORTED_APPLICABLE_TO: raise ValueError("applicable_to = {!r} is unknown, should be one of {}" .format(self._applicable_to, SUPPORTED_APPLICABLE_TO)) if self._value_type == TagValueType.ONEOF_STRING: if self._possible_values is None: raise ValueError("TagValueType is ONEOF_STRING. List of possible values have to be defined.") if not all(isinstance(item, str) for item in self._possible_values): raise ValueError("TagValueType is ONEOF_STRING. All possible values have to be strings") elif self._possible_values is not None: raise ValueError("TagValueType is {!r}. possible_values variable have to be None".format(self._value_type)) _validate_color(self._color)
def clone(self, index=None, figures=None): ''' :param index: int :param figures: list :return: Frame class object ''' return self.__class__(index=take_with_default(index, self.index), figures=take_with_default(figures, self.figures))
def clone(self, obj_classes: ObjClassCollection = None, tag_metas: TagMetaCollection = None, project_type=None): ''' The function clone create copy of ProjectMeta with given Collections that stores ObjClass and TagMeta :param obj_classes: ObjClassCollection class object :param tag_metas: TagMetaCollection class object :return: ProjectMeta class object ''' return ProjectMeta(obj_classes=take_with_default(obj_classes, self.obj_classes), tag_metas=take_with_default(tag_metas, self.tag_metas), project_type=take_with_default(project_type, self.project_type))
def clone(self, frames_count=None, objects=None, frames=None, tags=None, description=""): 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))
def clone(self, objects=None, figures=None, tags=None, description=None): ''' :param objects: VideoObjectCollection :param figures: list of figures :param tags: VideoTagCollection :param description: str :return: PointcloudAnnotation class object ''' return PointcloudAnnotation( objects=take_with_default(objects, self.objects), figures=take_with_default(figures, self.figures), tags=take_with_default(tags, self.tags), description=take_with_default(description, self.description))
def __init__(self, logger=None, task_id=None, server_address=None, agent_token=None, ignore_errors=False, ignore_task_id=False): self._ignore_task_id = ignore_task_id self.logger = take_with_default(logger, default_logger) self._ignore_errors = ignore_errors self.task_id = take_with_default(task_id, int(os.environ["TASK_ID"])) self.server_address = take_with_default(server_address, os.environ[SERVER_ADDRESS]) self.agent_token = take_with_default(agent_token, os.environ[AGENT_TOKEN]) self.public_api = Api.from_env(ignore_task_id=self._ignore_task_id) self._app_url = self.public_api.app.get_url(self.task_id) self._session_dir = "/sessions/{}".format(self.task_id) self._template_path = None debug_app_dir = os.environ.get("DEBUG_APP_DIR", "") if debug_app_dir != "": self._session_dir = debug_app_dir mkdir(self.data_dir) self.cache_dir = os.path.join("/apps_cache") debug_cache_dir = os.environ.get("DEBUG_CACHE_DIR", "") if debug_cache_dir != "": self.cache_dir = debug_cache_dir mkdir(self.cache_dir) self.cache = FileCache(name="FileCache", storage_root=self.cache_dir) self.api = AgentAPI(token=self.agent_token, server_address=self.server_address, ext_logger=self.logger) self.api.add_to_metadata('x-task-id', str(self.task_id)) self.callbacks = {} self.periodic_items = {} self.processing_queue = queue.Queue() # (maxsize=self.QUEUE_MAX_SIZE) self.logger.debug('App is created', extra={ "task_id": self.task_id, "server_address": self.server_address }) self._ignore_stop_for_debug = False self._error = None self.stop_event = asyncio.Event() self.has_ui = False
def clone(self, geometry: Geometry = None, obj_class: ObjClass = None, tags: TagCollection = None, description: str = None): ''' The function clone make copy of the Label class object :return: Label class object ''' return self.__class__( geometry=take_with_default(geometry, self.geometry), obj_class=take_with_default(obj_class, self.obj_class), tags=take_with_default(tags, self.tags), description=take_with_default(description, self.description))
def __init__(self, frames_count=None, objects=None, frames=None, tags=None, description="", key=None): self._frames_count = frames_count self._description = description self._frames = take_with_default(frames, FrameCollection()) self._tags = take_with_default(tags, VideoTagCollection()) self._objects = take_with_default(objects, PointcloudObjectCollection()) self._key = take_with_default(key, uuid.uuid4())
def transform_labels(self, label_transform_fn, new_size=None): ''' The function transform_labels transform labels and change image size in current Annotation object and return the copy of the current Annotation object :param label_transform_fn: function for transform labels :param new_size: new image size :return: Annotation class object with new labels and image size ''' def _do_transform_labels(src_labels, label_transform_fn): # long easy to debug # result = [] # for label in src_labels: # result.extend(label_transform_fn(label)) # return result # short, hard-to-debug alternative return list( itertools.chain( *[label_transform_fn(label) for label in src_labels])) new_labels = _do_transform_labels(self._labels, label_transform_fn) new_pixelwise_scores_labels = _do_transform_labels( self._pixelwise_scores_labels, label_transform_fn) return self.clone(img_size=take_with_default(new_size, self.img_size), labels=new_labels, pixelwise_scores_labels=new_pixelwise_scores_labels)
def __init__(self, obj_classes=None, tag_metas=None, project_type=None): ''' :param obj_classes: Collection that stores ObjClass instances with unique names. :param tag_metas: Collection that stores TagMeta instances with unique names. ''' self._obj_classes = ObjClassCollection() if obj_classes is None else obj_classes self._tag_metas = take_with_default(tag_metas, TagMetaCollection()) self._project_type = project_type
def __init__(self, index, figures=None): ''' :param index: int :param figures: list of figures(point, rectangle etc) on the frame ''' self._index = index self._figures = take_with_default(figures, [])
def __init__(self, objects=None, figures=None, tags=None, description="", key=None): ''' :param objects: VideoObjectCollection :param figures: list of figures(Point, Cuboid, etc) :param tags: VideoTagCollection :param description: str :param key: uuid class object ''' self._description = description self._tags = take_with_default(tags, VideoTagCollection()) self._objects = take_with_default(objects, VideoObjectCollection()) self._figures = take_with_default(figures, []) self._key = take_with_default(key, uuid.uuid4())
def initialize(self, task_id, template, data=None, state=None): d = take_with_default(data, {}) if "notifyDialog" not in d: d["notifyDialog"] = None if "scrollIntoView" not in d: d["scrollIntoView"] = None s = take_with_default(state, {}) fields = [{ "field": TEMPLATE, "payload": template }, { "field": DATA, "payload": d }, { "field": STATE, "payload": s }] resp = self._api.task.set_fields(task_id, fields) return resp
def __init__(self, obj_class: ObjClass, tags: VideoTagCollection = None, key=None, class_id=None, labeler_login=None, updated_at=None, created_at=None): ''' :param obj_class: ObjClass class object :param tags: VideoTagCollection :param key: uuid class object ''' self.labeler_login = labeler_login self.updated_at = updated_at self.created_at = created_at self._obj_class = obj_class self._key = take_with_default(key, uuid.uuid4()) self._tags = take_with_default(tags, VideoTagCollection())
def resize(img: np.ndarray, ann: Annotation, size: tuple) -> (np.ndarray, Annotation): """ Resize the input image array and annotation to the given size. Args: img: Input image array. ann: Input annotation. size: Desired size (height, width) in pixels or -1. If one of values is -1 and "keep": true then for specific width height will be automatically computed to keep aspect ratio. Returns: A tuple containing resized image array and annotation. """ _validate_image_annotation_shape(img, ann) height = take_with_default(size[0], -1) # For backward capability width = take_with_default(size[1], -1) size = (height, width) new_size = sly_image.restore_proportional_size(in_size=ann.img_size, out_size=size) res_img = sly_image.resize(img, new_size) res_ann = ann.resize(new_size) return res_img, res_ann
def clone(self, name=None, value_type=None, possible_values=None, color=None, sly_id=None, hotkey=None, applicable_to=None, applicable_classes=None): ''' The function clone make copy of the TagMeta class object :return: TagMeta class object ''' return TagMeta(name=take_with_default(name, self.name), value_type=take_with_default(value_type, self.value_type), possible_values=take_with_default(possible_values, self.possible_values), color=take_with_default(color, self.color), sly_id=take_with_default(sly_id, self.sly_id), hotkey=take_with_default(hotkey, self.hotkey), applicable_to=take_with_default(applicable_to, self.applicable_to), applicable_classes=take_with_default(applicable_classes, self.applicable_classes))
def __init__(self, img_size, frames_count, objects=None, frames=None, tags=None, description="", key=None): ''' The constructor for VideoAnnotation class. :param img_size: size of the image(tuple or list of integers) :param frames_count: int :param objects: VideoObjectCollection :param frames: FrameCollection :param tags: VideoTagCollection :param description: str :param key: uuid class object ''' if not isinstance(img_size, (tuple, list)): raise TypeError('{!r} has to be a tuple or a list. Given type "{}".'.format('img_size', type(img_size))) self._img_size = tuple(img_size) self._frames_count = frames_count self._description = description self._tags = take_with_default(tags, VideoTagCollection()) self._objects = take_with_default(objects, VideoObjectCollection()) self._frames = take_with_default(frames, FrameCollection()) self._key = take_with_default(key, uuid.uuid4()) self.validate_figures_bounds()
def clone(self, meta=None, value=None, frame_range=None, key=None, sly_id=None, labeler_login=None, updated_at=None, created_at=None): ''' :param meta: Tag metadata :param value: There are 3 possible value types of value: ANY_NUMBER for numeric values, ANY_STRING for arbitrary string values, ONEOF_STRING for string values restricted to a given whitelist :param frame_range: tuple or list of integers :param key: uuid class object :return: VideoTag class object ''' return VideoTag(meta=take_with_default(meta, self.meta), value=take_with_default(value, self.value), frame_range=take_with_default(frame_range, self.frame_range), key=take_with_default(key, self.key), sly_id=take_with_default(sly_id, self.sly_id), labeler_login=take_with_default(labeler_login, self.labeler_login), updated_at=take_with_default(updated_at, self.updated_at), created_at=take_with_default(created_at, self.created_at))
def clone(self, video_object=None, geometry=None, frame_index=None, key=None, class_id=None, labeler_login=None, updated_at=None, created_at=None): return self.__class__( video_object=take_with_default(video_object, self.parent_object), geometry=take_with_default(geometry, self.geometry), frame_index=take_with_default(frame_index, self.frame_index), key=take_with_default(key, self._key), class_id=take_with_default(class_id, self.class_id), labeler_login=take_with_default(labeler_login, self.labeler_login), updated_at=take_with_default(updated_at, self.updated_at), created_at=take_with_default(created_at, self.created_at))
def __init__(self, video_object, geometry, frame_index, key=None, class_id=None, labeler_login=None, updated_at=None, created_at=None): self._video_object = video_object self._set_geometry_inplace(geometry) self._frame_index = frame_index self._key = take_with_default(key, uuid.uuid4()) self.class_id = class_id self.labeler_login = labeler_login self.updated_at = updated_at self.created_at = created_at
def __init__(self, geometry: Geometry, obj_class: ObjClass, tags: TagCollection = None, description: str = ""): ''' :param geometry: Geometry class of the object(point, rectangle, polygon, bitmap, line) :param obj_class: Class of objects (person, car, etc) with necessary properties: name, type of geometry (Polygon, Rectangle, ...) and RGB color. Only one class can be associated with Label. :param tags: TagCollection object :param description: description of the label ''' self._geometry = geometry self._obj_class = obj_class self._tags = take_with_default(tags, TagCollection()) self._description = description self._validate_geometry_type() self._validate_geometry()
def draw_contour(self, bitmap, color=None, thickness=1, draw_tags=False, tags_font=None): ''' The function draws the figure contour on a given label geometry bitmap :param bitmap: target image (np.ndarray) :param color: [R, G, B] :param thickness: thickness of the drawing contour ''' effective_color = take_with_default(color, self.obj_class.color) self.geometry.draw_contour(bitmap, effective_color, thickness, config=self.obj_class.geometry_config) if draw_tags: self._draw_tags(bitmap, tags_font)
def instance_crop(img: np.ndarray, ann: Annotation, class_title: str, save_other_classes_in_crop: bool = True, padding_config: dict = None) -> list: """ Crops objects of specified classes from image with configurable padding. Args: img: Input image array. ann: Input annotation. class_title: Name of class to crop. save_other_classes_in_crop: save non-target classes in each cropped annotation. padding_config: Dict with padding Returns: List of cropped [image, annotation] pairs. """ padding_config = take_with_default(padding_config, {}) _validate_image_annotation_shape(img, ann) results = [] img_rect = Rectangle.from_size(img.shape[:2]) if save_other_classes_in_crop: non_target_labels = [label for label in ann.labels if label.obj_class.name != class_title] else: non_target_labels = [] ann_with_non_target_labels = ann.clone(labels=non_target_labels) for label in ann.labels: if label.obj_class.name == class_title: src_fig_rect = label.geometry.to_bbox() new_img_rect = _rect_from_bounds(padding_config, img_w=src_fig_rect.width, img_h=src_fig_rect.height) rect_to_crop = new_img_rect.translate(src_fig_rect.top, src_fig_rect.left) crops = rect_to_crop.crop(img_rect) if len(crops) == 0: continue rect_to_crop = crops[0] image_crop = sly_image.crop(img, rect_to_crop) cropped_ann = ann_with_non_target_labels.relative_crop(rect_to_crop) label_crops = label.relative_crop(rect_to_crop) for label_crop in label_crops: results.append((image_crop, cropped_ann.add_label(label_crop))) return results
def __init__(self, meta, value=None, frame_range=None, key=None, sly_id=None, labeler_login=None, updated_at=None, created_at=None): ''' :param meta: Tag metadata: it include tag name, value type, and possible values for tags with enum values. When creating a new tag, the value is automatically cross-checked against the metadata to make sure the value is valid. :param value: There are 3 possible value types of value: ANY_NUMBER for numeric values, ANY_STRING for arbitrary string values, ONEOF_STRING for string values restricted to a given whitelist :param frame_range: tuple or list of integers :param key: uuid class object ''' super(VideoTag, self).__init__(meta, value=value, sly_id=sly_id, labeler_login=labeler_login, updated_at=updated_at, created_at=created_at) self._frame_range = None if frame_range is not None: if not isinstance(frame_range, (tuple, list)): raise TypeError('{!r} has to be a tuple or a list. Given type "{}".'.format(FRAME_RANGE, type(frame_range))) else: self._frame_range = list(frame_range) self._key = take_with_default(key, uuid.uuid4())
def clone(self, img_size=None, frames_count=None, objects=None, frames=None, tags=None, description=None): ''' :param img_size: size of the image(tuple or list of integers) :param frames_count: int :param objects: VideoObjectCollection :param frames: FrameCollection :param tags: VideoTagCollection :param description: str :return: VideoAnnotation class object ''' return VideoAnnotation(img_size=take_with_default(img_size, self.img_size), 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))
def clone(self, meta=None, value=None, sly_id=None, labeler_login=None, updated_at=None, created_at=None): ''' The function clone make copy of the Tag class object :return: Tag class object ''' return Tag(meta=take_with_default(meta, self.meta), value=take_with_default(value, self.value), sly_id=take_with_default(sly_id, self.sly_id), labeler_login=take_with_default(labeler_login, self.labeler_login), updated_at=take_with_default(updated_at, self.updated_at), created_at=take_with_default(created_at, self.created_at))
def clone(self, img_size=None, labels=None, img_tags=None, img_description=None, pixelwise_scores_labels=None, custom_data=None, image_id=None): ''' The function clone make copy of the Annotation class object :return: Annotation class object ''' return Annotation( img_size=take_with_default(img_size, self.img_size), labels=take_with_default(labels, self.labels), img_tags=take_with_default(img_tags, self.img_tags), img_description=take_with_default(img_description, self.img_description), pixelwise_scores_labels=take_with_default( pixelwise_scores_labels, self.pixelwise_scores_labels), custom_data=take_with_default(custom_data, self.custom_data), image_id=take_with_default(image_id, self.image_id))
def clone(self, obj_class: ObjClass = None, tags: VideoTagCollection = None, key=None, class_id=None, labeler_login=None, updated_at=None, created_at=None): ''' :param obj_class: ObjClass :param tags: VideoTagCollection :param key: uuid class object :return: VideoObject class object ''' return self.__class__( obj_class=take_with_default(obj_class, self.obj_class), key=take_with_default(key, self._key), tags=take_with_default(tags, self.tags), class_id=take_with_default(class_id, self.class_id), labeler_login=take_with_default(labeler_login, self.labeler_login), updated_at=take_with_default(updated_at, self.updated_at), created_at=take_with_default(created_at, self.created_at))