Source code for supervisely.geometry.point

# coding: utf-8


# docs
from __future__ import annotations

from typing import Dict, List, Optional, Tuple

import cv2

from supervisely._utils import unwrap_if_numpy
from supervisely.geometry.constants import (
    CLASS_ID,
    CREATED_AT,
    ID,
    LABELER_LOGIN,
    UPDATED_AT,
)
from supervisely.geometry.geometry import Geometry
from supervisely.geometry.image_rotator import ImageRotator
from supervisely.geometry.point_location import PointLocation
from supervisely.geometry.rectangle import Rectangle


[docs] class Point(Geometry): """2D point at (row, col). Immutable.""" def __init__( self, row: int, col: int, sly_id: Optional[int] = None, class_id: Optional[int] = None, labeler_login: Optional[int] = None, updated_at: Optional[str] = None, created_at: Optional[str] = None, ): """ Point geometry for a single :class:`~supervisely.annotation.label.Label`. :class:`~supervisely.geometry.point.Point` object is immutable. :param row: Position of Point on height. :type row: int or float :param col: Position of Point on width. :type col: int or float :param sly_id: Point ID in Supervisely server. :type sly_id: int, optional :param class_id: ID of ObjClass to which Point belongs. :type class_id: int, optional :param labeler_login: Login of the user who created Point. :type labeler_login: str, optional :param updated_at: Date and Time when Point was modified last. Date Format: Year:Month:Day:Hour:Minute:Seconds. Example: '2021-01-22T19:37:50.158Z'. :type updated_at: str, optional :param created_at: Date and Time when Point was created. Date Format is the same as in "updated_at" parameter. :type created_at: str, optional :Usage Example: .. code-block:: python import supervisely as sly row = 100 col = 200 figure = sly.Point(row, col) """ super().__init__( sly_id=sly_id, class_id=class_id, labeler_login=labeler_login, updated_at=updated_at, created_at=created_at, ) self._row = round(unwrap_if_numpy(row)) self._col = round(unwrap_if_numpy(col)) @property def row(self) -> int: """ Position of Point height. :returns: Height of Point. :rtype: int :Usage Example: .. code-block:: python print(figure.row) # Output: 100 """ return self._row @property def col(self) -> int: """ Position of Point width. :returns: Width of Point. :rtype: int :Usage Example: .. code-block:: python print(figure.col) # Output: 200 """ return self._col
[docs] @classmethod def from_point_location( cls, pt: PointLocation, sly_id: Optional[int] = None, class_id: Optional[int] = None, labeler_login: Optional[int] = None, updated_at: Optional[str] = None, created_at: Optional[str] = None, ) -> Point: """ Create Point from given :class:`~supervisely.geometry.point_location.PointLocation` object. :param pt: PointLocation to create Point from. :type pt: :class:`~supervisely.geometry.point_location.PointLocation` :param sly_id: Point ID in Supervisely server. :type sly_id: int, optional :param class_id: ID of ObjClass to which Point belongs. :type class_id: int, optional :param labeler_login: Login of the user who created :class:`~supervisely.geometry.point.Point`. :type labeler_login: str, optional :param updated_at: Date and Time when Point was modified last. Date Format: Year:Month:Day:Hour:Minute:Seconds. Example: '2021-01-22T19:37:50.158Z'. :type updated_at: str, optional :param created_at: Date and Time when Point was created. Date Format is the same as in "updated_at" parameter. :type created_at: str, optional :returns: :class:`~supervisely.geometry.point.Point` object :rtype: :class:`~supervisely.geometry.point.Point` :Usage Example: .. code-block:: python import supervisely as sly figure_loc = sly.PointLocation(100, 200) figure = sly.Point.from_point_location(figure_loc) """ return cls( row=pt.row, col=pt.col, sly_id=sly_id, class_id=class_id, labeler_login=labeler_login, updated_at=updated_at, created_at=created_at, )
@property def point_location(self) -> PointLocation: """ Get PointLocation from Point. :returns: PointLocation from Point. :rtype: :class:`~supervisely.geometry.point_location.PointLocation` :Usage Example: .. code-block:: python figure_loc = figure.point_location """ return PointLocation(row=self.row, col=self.col) @staticmethod def geometry_name(): """ """ return "point"
[docs] def crop(self, rect: Rectangle) -> List[Point]: """ Crops current Point. :param rect: Rectangle to crop Point from. :type rect: :class:`~supervisely.geometry.rectangle.Rectangle` :returns: List of Points from Rectangle. :rtype: List[:class:`~supervisely.geometry.point.Point`] :Usage Example: .. code-block:: python import supervisely as sly crop_figures = figure.crop(sly.Rectangle(1, 1, 300, 350)) """ return [self.clone()] if rect.contains_point_location(self.point_location) else []
[docs] def rotate(self, rotator: ImageRotator) -> Point: """ Rotates current Point. :param rotator: Class for object rotation. :type rotator: :class:`~supervisely.geometry.image_rotator.ImageRotator` :returns: Rotated Point. :rtype: :class:`~supervisely.geometry.point.Point` :Usage Example: .. code-block:: python import supervisely as sly from supervisely.geometry.image_rotator import ImageRotator # Remember that Point class object is immutable, and we need to assign new instance of Point to a new variable height, width = 300, 400 rotator = ImageRotator((height, width), 25) rotate_figure = figure.rotate(rotator) """ return self.from_point_location(self.point_location.rotate(rotator))
[docs] def resize(self, in_size: Tuple[int, int], out_size: Tuple[int, int]) -> Point: """ Resizes current Point. :param in_size: Input image size (height, width) to which belongs Point. :type in_size: Tuple[int, int] :param out_size: Desired output image size (height, width) to which belongs Point. :type out_size: Tuple[int, int] :returns: Resized Point. :rtype: :class:`~supervisely.geometry.point.Point` :Usage Example: .. code-block:: python # Remember that Point class object is immutable, and we need to assign new instance of Point to a new variable in_height, in_width = 300, 400 out_height, out_width = 600, 800 resize_figure = figure.resize((in_height, in_width), (out_height, out_width)) """ return self.from_point_location(self.point_location.resize(in_size, out_size))
[docs] def fliplr(self, img_size: Tuple[int, int]) -> Point: """ Flips current Point in horizontal. :param img_size: Input image size (height, width) to which belongs Point. :type img_size: Tuple[int, int] :returns: Flipped Point. :rtype: :class:`~supervisely.geometry.point.Point` :Usage Example: .. code-block:: python # Remember that Point class object is immutable, and we need to assign new instance of Point to a new variable height, width = 300, 400 fliplr_figure = figure.fliplr((height, width)) """ return self.from_point_location(self.point_location.fliplr(img_size))
[docs] def flipud(self, img_size: Tuple[int, int]) -> Point: """ Flips current Point in vertical. :param img_size: Input image size (height, width) to which belongs Point. :type img_size: Tuple[int, int] :returns: Flipped Point. :rtype: :class:`~supervisely.geometry.point.Point` :Usage Example: .. code-block:: python # Remember that Point class object is immutable, and we need to assign new instance of Point to a new variable height, width = 300, 400 flipud_figure = figure.flipud((height, width)) """ return self.from_point_location(self.point_location.flipud(img_size))
[docs] def scale(self, factor: float) -> Point: """ Scales current Point. :param factor: Scale parameter. :type factor: float :returns: Scaled Point. :rtype: :class:`~supervisely.geometry.point.Point` :Usage Example: .. code-block:: python # Remember that Point class object is immutable, and we need to assign new instance of Point to a new variable scale_figure = figure.scale(0.75) """ return self.from_point_location(self.point_location.scale(factor))
[docs] def translate(self, drow: int, dcol: int) -> Point: """ Translates current Point. :param drow: Horizontal shift. :type drow: int :param dcol: Vertical shift. :type dcol: int :returns: Translated Point. :rtype: :class:`~supervisely.geometry.point.Point` :Usage Example: .. code-block:: python # Remember that Point class object is immutable, and we need to assign new instance of Point to a new variable translate_figure = figure.translate(150, 350) """ return self.from_point_location(self.point_location.translate(drow, dcol))
def _draw_impl(self, bitmap, color, thickness=1, config=None): r = round(thickness / 2) # @TODO: relation between thickness and point radius - ??? cv2.circle(bitmap, (self.col, self.row), radius=r, color=color, thickness=cv2.FILLED) def _draw_contour_impl(self, bitmap, color, thickness=1, config=None): # @TODO: mb dummy operation for Point r = round((thickness + 1) / 2) cv2.circle(bitmap, (self.col, self.row), radius=r, color=color, thickness=cv2.FILLED) @property def area(self) -> float: """ Point area. :returns: Area of current Point, always 0.0 :rtype: float :Usage Example: .. code-block:: python print(figure.area) # Output: 0.0 """ return 0.0
[docs] def to_bbox(self) -> Rectangle: """ Create Rectangle object from current Point. :returns: Rectangle from Point. :rtype: :class:`~supervisely.geometry.rectangle.Rectangle` :Usage Example: .. code-block:: python rectangle = figure.to_bbox() """ return Rectangle(top=self.row, left=self.col, bottom=self.row, right=self.col)
[docs] def to_json(self) -> Dict: """ Convert the Point to a json dict. Read more about `Supervisely format <https://docs.supervisely.com/data-organization/00_ann_format_navi>`_. :returns: Point in json format as a dict. :rtype: dict :Usage Example: .. code-block:: python figure_json = figure.to_json() print(figure_json) # Output: { # "points": { # "exterior": [ # [200, 100] # ], # "interior": [] # } # } """ res = self.point_location.to_json() self._add_creation_info(res) return res
[docs] @classmethod def from_json(cls, data: Dict) -> Point: """ Convert a json dict to Point. Read more about `Supervisely format <https://docs.supervisely.com/data-organization/00_ann_format_navi>`_. :param data: Point in json format as a dict. :type data: dict :returns: Point from json. :rtype: :class:`~supervisely.geometry.point.Point` :Usage Example: .. code-block:: python import supervisely as sly figure_json = { "points": { "exterior": [[200, 100]], "interior": [] } } figure = sly.Point.from_json(figure_json) """ labeler_login = data.get(LABELER_LOGIN, None) updated_at = data.get(UPDATED_AT, None) created_at = data.get(CREATED_AT, None) sly_id = data.get(ID, None) class_id = data.get(CLASS_ID, None) return cls.from_point_location( PointLocation.from_json(data), sly_id=sly_id, class_id=class_id, labeler_login=labeler_login, updated_at=updated_at, created_at=created_at, )
[docs] @classmethod def allowed_transforms(cls): """ Returns the allowed transforms for the Point. """ from supervisely.geometry.any_geometry import AnyGeometry return [AnyGeometry]