Example #1
0
 def clone(self, img_size=None, labels=None, img_tags=None, img_description=None, pixelwise_scores_labels=None):
     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))
Example #2
0
 def __init__(self,
              img_size,
              labels=None,
              img_tags=None,
              img_description="",
              pixelwise_scores_labels=None,
              custom_data=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, {})
Example #3
0
    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)
Example #4
0
    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, 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.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.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.executor = concurrent.futures.ThreadPoolExecutor()
        self.loop = asyncio.get_event_loop()
        # May want to catch other signals too
        signals = (signal.SIGHUP, signal.SIGTERM, signal.SIGINT, signal.SIGQUIT)
        for s in signals:
            self.loop.add_signal_handler(s, lambda s=s: asyncio.create_task(self._shutdown(signal=s)))
        # comment out the line below to see how unhandled exceptions behave
        self.loop.set_exception_handler(self.handle_exception)
 def clone(self,
           obj_classes: ObjClassCollection = None,
           img_tag_metas: TagMetaCollection = None,
           obj_tag_metas: TagMetaCollection = None):
     return ProjectMeta(
         obj_classes=take_with_default(obj_classes, self.obj_classes),
         img_tag_metas=take_with_default(img_tag_metas, self.img_tag_metas),
         obj_tag_metas=take_with_default(obj_tag_metas, self.obj_tag_metas))
Example #6
0
 def initialize(self, task_id, template, data=None, state=None):
     d = take_with_default(data, {})
     if "notifyDialog" not in d:
         d["notifyDialog"] = 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
Example #7
0
 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))
Example #8
0
 def clone(self, obj_classes: ObjClassCollection = None, tag_metas: TagMetaCollection = 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))
Example #9
0
 def clone(self,
           geometry: Geometry = None,
           obj_class: ObjClass = None,
           tags: TagCollection = None,
           description: str = None):
     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))
Example #10
0
 def __init__(self, img_size, labels=None, img_tags=None, img_description="", pixelwise_scores_labels=None):
     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 = []      # This field is not serialized. @TODO: create another class AnnotationExtended???
     self._add_labels_impl(self._pixelwise_scores_labels, take_with_default(pixelwise_scores_labels, []))
Example #11
0
 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,
              objects=None,
              figures=None,
              tags=None,
              description="",
              key=None):
     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 __init__(self,
              obj_classes=None,
              img_tag_metas=None,
              obj_tag_metas=None):
     self._obj_classes = take_with_default(obj_classes,
                                           ObjClassCollection())
     # TODO do we actualy need two sets of tags?
     self._img_tag_metas = take_with_default(img_tag_metas,
                                             TagMetaCollection())
     self._obj_tag_metas = take_with_default(obj_tag_metas,
                                             TagMetaCollection())
Example #14
0
    def clone(self, name: str = None, geometry_type: Geometry = None, color: List[int] = None) -> 'ObjClass':
        """
        Creates object duplicate. Defined arguments replace corresponding original values.

        Args:
            see __init__ method
        Returns:
            new instance of class
        """
        return ObjClass(name=take_with_default(name, self.name),
                        geometry_type=take_with_default(geometry_type, self.geometry_type),
                        color=take_with_default(color, self.color))
 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))
Example #16
0
    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)
Example #17
0
 def clone(self,
           name=None,
           value_type=None,
           possible_values=None,
           color=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))
Example #18
0
 def __init__(self, obj_classes=None, tag_metas=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())
Example #19
0
 def transform_labels(self, label_transform_fn, new_size=None):
     def _do_transform_labels(src_labels, label_transform_fn):
         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)
Example #20
0
    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, geometry: Geometry, obj_class: ObjClass, tags: TagCollection = None, description: str = ""):
     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()
Example #22
0
    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, [])
Example #23
0
 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,
              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())
Example #25
0
 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)
                           )
Example #26
0
 def draw_contour(self,
                  bitmap,
                  color=None,
                  thickness=1,
                  draw_tags=False,
                  tags_font=None):
     effective_color = take_with_default(color, self.obj_class.color)
     self.geometry.draw_contour(bitmap, effective_color, thickness)
     if draw_tags:
         self._draw_tags(bitmap, tags_font)
Example #27
0
    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())
Example #28
0
 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)
Example #29
0
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
Example #30
0
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