Source code for tensorbay.label.label_polygon

#!/usr/bin/env python3
#
# Copyright 2021 Graviti. Licensed under MIT License.
#

"""The implementation of the TensorBay polygon label."""

from typing import Any, Dict, Iterable, Optional, Type, TypeVar

from tensorbay.geometry import RLE, MultiPolygon, Polygon
from tensorbay.label.basic import SubcatalogBase, _LabelBase
from tensorbay.label.supports import AttributesMixin, CategoriesMixin, IsTrackingMixin
from tensorbay.utility import ReprType, attr_base, common_loads


[docs]class PolygonSubcatalog(SubcatalogBase, IsTrackingMixin, CategoriesMixin, AttributesMixin): """This class defines the subcatalog for polygon type of labels. Arguments: is_tracking: A boolean value indicates whether the corresponding subcatalog contains tracking information. Attributes: description: The description of the entire polygon subcatalog. categories: All the possible categories in the corresponding dataset stored in a :class:`~tensorbay.utility.name.NameList` with the category names as keys and the :class:`~tensorbay.label.supports.CategoryInfo` as values. category_delimiter: The delimiter in category values indicating parent-child relationship. attributes: All the possible attributes in the corresponding dataset stored in a :class:`~tensorbay.utility.name.NameList` with the attribute names as keys and the :class:`~tensorbay.label.attribute.AttributeInfo` as values. is_tracking: Whether the Subcatalog contains tracking information. Examples: *Initialization Method 1:* Init from ``PolygonSubcatalog.loads()`` method. >>> catalog = { ... "POLYGON": { ... "isTracking": True, ... "categories": [{"name": "0"}, {"name": "1"}], ... "attributes": [{"name": "gender", "enum": ["male", "female"]}], ... } ... } >>> PolygonSubcatalog.loads(catalog["POLYGON"]) PolygonSubcatalog( (is_tracking): True, (categories): NameList [...], (attributes): NameList [...] ) *Initialization Method 2:* Init an empty PolygonSubcatalog and then add the attributes. >>> from tensorbay.utility import NameList >>> from tensorbay.label import CategoryInfo, AttributeInfo >>> categories = NameList() >>> categories.append(CategoryInfo("a")) >>> attributes = NameList() >>> attributes.append(AttributeInfo("gender", enum=["female", "male"])) >>> polygon_subcatalog = PolygonSubcatalog() >>> polygon_subcatalog.is_tracking = True >>> polygon_subcatalog.categories = categories >>> polygon_subcatalog.attributes = attributes >>> polygon_subcatalog PolygonSubcatalog( (is_tracking): True, (categories): NameList [...], (attributes): NameList [...] ) """ def __init__(self, is_tracking: bool = False) -> None: SubcatalogBase.__init__(self) IsTrackingMixin.__init__(self, is_tracking)
[docs]class MultiPolygonSubcatalog(SubcatalogBase, IsTrackingMixin, CategoriesMixin, AttributesMixin): """This class defines the subcatalog for multiple polygon type of labels. Arguments: is_tracking: A boolean value indicates whether the corresponding subcatalog contains tracking information. Attributes: description: The description of the entire multiple polygon subcatalog. categories: All the possible categories in the corresponding dataset stored in a :class:`~tensorbay.utility.name.NameList` with the category names as keys and the :class:`~tensorbay.label.supports.CategoryInfo` as values. category_delimiter: The delimiter in category values indicating parent-child relationship. attributes: All the possible attributes in the corresponding dataset stored in a :class:`~tensorbay.utility.name.NameList` with the attribute names as keys and the :class:`~tensorbay.label.attribute.AttributeInfo` as values. is_tracking: Whether the Subcatalog contains tracking information. Examples: *Initialization Method 1:* Init from ``MultiPolygonSubcatalog.loads()`` method. >>> catalog = { ... "MULTI_POLYGON": { ... "isTracking": True, ... "categories": [{"name": "0"}, {"name": "1"}], ... "attributes": [{"name": "gender", "enum": ["male", "female"]}], ... } ... } >>> MultiPolygonSubcatalog.loads(catalog["MULTI_POLYGON"]) MultiPolygonSubcatalog( (is_tracking): True, (categories): NameList [...], (attributes): NameList [...] ) *Initialization Method 2:* Init an empty MultiPolygonSubcatalog and then add the attributes. >>> from tensorbay.label import CategoryInfo, AttributeInfo >>> multi_polygon_subcatalog = MultiPolygonSubcatalog() >>> multi_polygon_subcatalog.is_tracking = True >>> multi_polygon_subcatalog.add_category("a") >>> multi_polygon_subcatalog.add_attribute("gender", enum=["female", "male"]) >>> multi_polygon_subcatalog MultiPolyline2DSubcatalog( (is_tracking): True, (categories): NameList [...], (attributes): NameList [...] ) """ def __init__(self, is_tracking: bool = False) -> None: SubcatalogBase.__init__(self) IsTrackingMixin.__init__(self, is_tracking)
[docs]class RLESubcatalog(SubcatalogBase, IsTrackingMixin, CategoriesMixin, AttributesMixin): """This class defines the subcatalog for rle type of labels. Arguments: is_tracking: A boolean value indicating whether the corresponding subcatalog contains tracking information. Attributes: description: The description of the rle subcatalog. categories: All the possible categories in the corresponding dataset stored in a :class:`~tensorbay.utility.name.NameList` with the category names as keys and the :class:`~tensorbay.label.supports.CategoryInfo` as values. category_delimiter: The delimiter in category values indicating parent-child relationship. attributes: All the possible attributes in the corresponding dataset stored in a :class:`~tensorbay.utility.name.NameList` with the attribute names as keys and the :class:`~tensorbay.label.attribute.AttributeInfo` as values. is_tracking: Whether the Subcatalog contains tracking information. Examples: *Initialization Method 1:* Init from ``RLESubcatalog.loads()`` method. >>> catalog = { ... "RLE": { ... "isTracking": True, ... "categories": [{"name": "0"}, {"name": "1"}], ... "attributes": [{"name": "gender", "enum": ["male", "female"]}], ... } ... } >>> RLESubcatalog.loads(catalog["RLESubcatalog"]) RLESubcatalog( (is_tracking): True, (categories): NameList [...], (attributes): NameList [...] ) *Initialization Method 2:* Init an empty RLESubcatalog and then add the attributes. >>> from tensorbay.label import CategoryInfo, AttributeInfo >>> rle_subcatalog = RLESubcatalog() >>> rle_subcatalog.is_tracking = True >>> rle_subcatalog.add_category("a") >>> rle_subcatalog.add_attribute("gender", enum=["female", "male"]) >>> rle_subcatalog RLESubcatalog( (is_tracking): True, (categories): NameList [...], (attributes): NameList [...] ) """ def __init__(self, is_tracking: bool = False) -> None: SubcatalogBase.__init__(self) IsTrackingMixin.__init__(self, is_tracking)
[docs]class LabeledPolygon(_LabelBase, Polygon): """This class defines the concept of polygon label. :class:`LabeledPolygon` is the polygon type of label, which is often used for CV tasks such as semantic segmentation. Arguments: points: A list of 2D points representing the vertexes of the polygon. category: The category of the label. attributes: The attributs of the label. instance: The instance id of the label. Attributes: category: The category of the label. attributes: The attributes of the label. instance: The instance id of the label. Examples: >>> LabeledPolygon( ... [(1, 2), (2, 3), (1, 3)], ... category = "example", ... attributes = {"key": "value"}, ... instance = "123", ... ) LabeledPolygon [ Vector2D(1, 2), Vector2D(2, 3), Vector2D(1, 3) ]( (category): 'example', (attributes): {...}, (instance): '123' ) """ _T = TypeVar("_T", bound="LabeledPolygon") _repr_type = ReprType.SEQUENCE _repr_attrs = _LabelBase._repr_attrs _attrs_base: Polygon = attr_base(key="polygon") def __init__( self, points: Optional[Iterable[Iterable[float]]] = None, *, category: Optional[str] = None, attributes: Optional[Dict[str, Any]] = None, instance: Optional[str] = None, ): Polygon.__init__(self, points) # type: ignore[arg-type] _LabelBase.__init__(self, category, attributes, instance)
[docs] @classmethod def loads(cls: Type[_T], contents: Dict[str, Any]) -> _T: # type: ignore[override] """Loads a LabeledPolygon from a dict containing the information of the label. Arguments: contents: A dict containing the information of the polygon label. Returns: The loaded :class:`LabeledPolygon` object. Examples: >>> contents = { ... "polygon": [ ... {"x": 1, "y": 2}, ... {"x": 2, "y": 3}, ... {"x": 1, "y": 3}, ... ], ... "category": "example", ... "attributes": {"key": "value"}, ... "instance": "12345", ... } >>> LabeledPolygon.loads(contents) LabeledPolygon [ Vector2D(1, 2), Vector2D(2, 3), Vector2D(1, 3) ]( (category): 'example', (attributes): {...}, (instance): '12345' ) """ return common_loads(cls, contents)
[docs] def dumps(self) -> Dict[str, Any]: # type: ignore[override] """Dumps the current polygon label into a dict. Returns: A dict containing all the information of the polygon label. Examples: >>> labeledpolygon = LabeledPolygon( ... [(1, 2), (2, 3), (1, 3)], ... category = "example", ... attributes = {"key": "value"}, ... instance = "123", ... ) >>> labeledpolygon.dumps() { 'category': 'example', 'attributes': {'key': 'value'}, 'instance': '123', 'polygon': [{'x': 1, 'y': 2}, {'x': 2, 'y': 3}, {'x': 1, 'y': 3}], } """ return self._dumps()
[docs]class LabeledMultiPolygon(_LabelBase, MultiPolygon): # type: ignore[misc] """This class defines the concept of multiple polygon label. :class:`LabeledMultiPolygon` is the multipolygon type of label, which is often used for CV tasks such as semantic segmentation. Arguments: points: A list of 2D points representing the vertices of the polygon. category: The category of the label. attributes: The attributs of the label. instance: The instance id of the label. Attributes: category: The category of the label. attributes: The attributes of the label. instance: The instance id of the label. Examples: >>> LabeledMultiPolygon( ... [[(1.0, 2.0), (2.0, 3.0), (1.0, 3.0)], [(1.0, 4.0), (2.0, 3.0), (1.0, 8.0)]], ... category = "example", ... attributes = {"key": "value"}, ... instance = "12345", ... ) LabeledMultiPolygon [ Polygon [...], Polygon [...] ]( (category): 'example', (attributes): {...}, (instance): '12345' ) """ _T = TypeVar("_T", bound="LabeledMultiPolygon") _repr_type = ReprType.SEQUENCE _repr_attrs = _LabelBase._repr_attrs _attrs_base: MultiPolygon = attr_base(key="multiPolygon") def __init__( self, polygons: Optional[Iterable[Iterable[Iterable[float]]]] = None, *, category: Optional[str] = None, attributes: Optional[Dict[str, Any]] = None, instance: Optional[str] = None, ): MultiPolygon.__init__(self, polygons=polygons) _LabelBase.__init__(self, category, attributes, instance)
[docs] @classmethod def loads(cls: Type[_T], contents: Dict[str, Any]) -> _T: # type: ignore[override] """Loads a LabeledMultiPolygon from a list of dict containing the information of the label. Arguments: contents: A dict containing the information of the multipolygon label. Returns: The loaded :class:`LabeledMultiPolygon` object. Examples: >>> contents = { ... "multiPolygon": [ ... [ ... {"x": 1.0, "y": 2.0}, ... {"x": 2.0, "y": 3.0}, ... {"x": 1.0, "y": 3.0}, ... ], ... [{"x": 1.0, "y": 4.0}, {"x": 2.0, "y": 3.0}, {"x": 1.0, "y": 8.0}], ... ], ... "category": "example", ... "attributes": {"key": "value"}, ... "instance": "12345", ... } >>> LabeledMultiPolygon.loads(contents) LabeledMultiPolygon [ Polygon [...], Polygon [...] ]( (category): 'example', (attributes): {...}, (instance): '12345' ) """ return common_loads(cls, contents)
[docs] def dumps(self) -> Dict[str, Any]: # type: ignore[override] """Dumps the current multipolygon label into a dict. Returns: A dict containing all the information of the multipolygon label. Examples: >>> labeledmultipolygon = LabeledMultiPolygon( ... [[(1, 2), (2, 3), (1, 3)],[(1, 2), (2, 3), (1, 3)]], ... category = "example", ... attributes = {"key": "value"}, ... instance = "123", ... ) >>> labeledmultipolygon.dumps() { 'category': 'example', 'attributes': {'key': 'value'}, 'instance': '123', 'multiPolygon': [ [{'x': 1, 'y': 2}, {'x': 2, 'y': 3}, {'x': 1, 'y': 3}], [{"x": 1.0, "y": 4.0}, {"x": 2.0, "y": 3.0}, {"x": 1.0, "y": 8.0}] ] } """ return self._dumps()
[docs]class LabeledRLE(_LabelBase, RLE): # type: ignore[misc] """This class defines the concept of rle label. :class:`LabeledRLE` is the rle type of label, which is often used for CV tasks such as semantic segmentation. Arguments: rle: A rle format mask. category: The category of the label. attributes: The attributs of the label. instance: The instance id of the label. Attributes: category: The category of the label. attributes: The attributes of the label. instance: The instance id of the label. Examples: >>> LabeledRLE( ... [272, 2, 4, 4, 2, 9], ... category = "example", ... attributes = {"key": "value"}, ... instance = "12345", ... ) LabeledRLE [ 272, 2, ... ]( (category): 'example', (attributes): {...}, (instance): '12345' ) """ _T = TypeVar("_T", bound="LabeledRLE") _repr_type = ReprType.SEQUENCE _repr_attrs = _LabelBase._repr_attrs _attrs_base: RLE = attr_base(key="rle") def __init__( self, rle: Optional[Iterable[int]] = None, *, category: Optional[str] = None, attributes: Optional[Dict[str, Any]] = None, instance: Optional[str] = None, ): RLE.__init__(self, rle) _LabelBase.__init__(self, category, attributes, instance)
[docs] @classmethod def loads(cls: Type[_T], contents: Dict[str, Any]) -> _T: # type: ignore[override] """Loads a LabeledRLE from a dict containing the information of the label. Arguments: contents: A dict containing the information of the rle label. Returns: The loaded :class:`LabeledRLE` object. Examples: >>> contents = { ... "rle": [272, 2, 4, 4, 2, 9], ... "category": "example", ... "attributes": {"key": "value"}, ... "instance": "12345", ... } >>> LabeledRLE.loads(contents) LabeledRLE [ 272, 2, ... ]( (category): 'example', (attributes): {...}, (instance): '12345' ) """ return common_loads(cls, contents)
[docs] def dumps(self) -> Dict[str, Any]: # type: ignore[override] """Dumps the current rle label into a dict. Returns: A dict containing all the information of the rle label. Examples: >>> labeled_rle = LabeledRLE( ... [272, 2, 4, 4, 2, 9], ... category = "example", ... attributes = {"key": "value"}, ... instance = "123", ... ) >>> labeled_rle.dumps() { 'category': 'example', 'attributes': {'key': 'value'}, 'instance': '123', 'rle': [272, 2, 4, 4, 2, 9] } """ return self._dumps()