Exemple #1
0
class LabeledBox2D(_LabelBase, Box2D):
    """This class defines the concept of 2D bounding box label.

    :class:`LabeledBox2D` is the 2D bounding box type of label,
    which is often used for CV tasks such as object detection.

    Arguments:
        xmin: The x coordinate of the top-left vertex of the labeled 2D box.
        ymin: The y coordinate of the top-left vertex of the labeled 2D box.
        xmax: The x coordinate of the bottom-right vertex of the labeled 2D box.
        ymax: The y coordinate of the bottom-right vertex of the labeled 2D box.
        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:
        >>> xmin, ymin, xmax, ymax = 1, 2, 4, 4
        >>> LabeledBox2D(
        ...     xmin,
        ...     ymin,
        ...     xmax,
        ...     ymax,
        ...     category="example",
        ...     attributes={"attr": "a"},
        ...     instance="12345",
        ... )
        LabeledBox2D(1, 2, 4, 4)(
          (category): 'example',
          (attributes): {...},
          (instance): '12345'
        )

    """

    _T = TypeVar("_T", bound="LabeledBox2D")

    _repr_type = ReprType.INSTANCE
    _repr_attrs = _LabelBase._repr_attrs

    _attrs_base: Box2D = attr_base(key="box2d")

    def __init__(
        self,
        xmin: float,
        ymin: float,
        xmax: float,
        ymax: float,
        *,
        category: Optional[str] = None,
        attributes: Optional[Dict[str, Any]] = None,
        instance: Optional[str] = None,
    ):
        Box2D.__init__(self, xmin, ymin, xmax, ymax)
        _LabelBase.__init__(self, category, attributes, instance)

    @classmethod
    def from_xywh(  # pylint: disable=arguments-differ
        cls: Type[_T],
        x: float,
        y: float,
        width: float,
        height: float,
        *,
        category: Optional[str] = None,
        attributes: Optional[Dict[str, Any]] = None,
        instance: Optional[str] = None,
    ) -> _T:
        """Create a :class:`LabeledBox2D` instance from the top-left vertex, the width and height.

        Arguments:
            x: X coordinate of the top left vertex of the box.
            y: Y coordinate of the top left vertex of the box.
            width: Length of the box along the x axis.
            height: Length of the box along the y axis.
            category: The category of the label.
            attributes: The attributs of the label.
            instance: The instance id of the label.

        Returns:
            The created :class:`LabeledBox2D` instance.

        Examples:
            >>> x, y, width, height = 1, 2, 3, 4
            >>> LabeledBox2D.from_xywh(
            ...     x,
            ...     y,
            ...     width,
            ...     height,
            ...     category="example",
            ...     attributes={"key": "value"},
            ...     instance="12345",
            ... )
            LabeledBox2D(1, 2, 4, 6)(
              (category): 'example',
              (attributes): {...},
              (instance): '12345'
            )

        """
        return cls(x,
                   y,
                   x + width,
                   y + height,
                   category=category,
                   attributes=attributes,
                   instance=instance)

    @classmethod
    def loads(cls: Type[_T], contents: Dict[str, Any]) -> _T:
        """Loads a LabeledBox2D from a dict containing the information of the label.

        Arguments:
            contents: A dict containing the information of the 2D bounding box label.

        Returns:
            The loaded :class:`LabeledBox2D` object.

        Examples:
            >>> contents = {
            ...     "box2d": {"xmin": 1, "ymin": 2, "xmax": 5, "ymax": 8},
            ...     "category": "example",
            ...     "attributes": {"key": "value"},
            ...     "instance": "12345",
            ... }
            >>> LabeledBox2D.loads(contents)
            LabeledBox2D(1, 2, 5, 8)(
              (category): 'example',
              (attributes): {...},
              (instance): '12345'
            )

        """
        return common_loads(cls, contents)

    def dumps(self) -> Dict[str, Any]:
        """Dumps the current 2D bounding box label into a dict.

        Returns:
            A dict containing all the information of the 2D box label.

        Examples:
            >>> xmin, ymin, xmax, ymax = 1, 2, 4, 4
            >>> labelbox2d = LabeledBox2D(
            ...     xmin,
            ...     ymin,
            ...     xmax,
            ...     ymax,
            ...     category="example",
            ...     attributes={"attr": "a"},
            ...     instance="12345",
            ... )
            >>> labelbox2d.dumps()
            {
                'category': 'example',
                'attributes': {'attr': 'a'},
                'instance': '12345',
                'box2d': {'xmin': 1, 'ymin': 2, 'xmax': 4, 'ymax': 4},
            }

        """
        return self._dumps()
Exemple #2
0
class LabeledPolyline2D(_LabelBase, Polyline2D):
    """This class defines the concept of polyline2D label.

    :class:`LabeledPolyline2D` is the 2D polyline type of label,
    which is often used for CV tasks such as lane detection.

    Arguments:
        points: A list of 2D points representing the vertexes of the 2D polyline.
        category: The category of the label.
        attributes: The attributes of the label.
        instance: The instance id of the label.
        beizer_point_types: The beizer point types of the label.

    Attributes:
        category: The category of the label.
        attributes: The attributes of the label.
        instance: The instance id of the label.
        beizer_point_types: The beizer point types of the label.

    Examples:
        >>> LabeledPolyline2D(
        ...     [(1, 2), (2, 4), (2, 1)],
        ...     category="example",
        ...     attributes={"key": "value"},
        ...     instance="123",
        ...     beizer_point_types="LLL",
        ... )
        LabeledPolyline2D [
          Vector2D(1, 2),
          Vector2D(2, 4),
          Vector2D(2, 1)
        ](
          (beizer_point_types): 'LLL',
          (category): 'example',
          (attributes): {...},
          (instance): '123'
        )

    """

    _T = TypeVar("_T", bound="LabeledPolyline2D")

    _repr_type = ReprType.SEQUENCE
    _repr_attrs = ("beizer_point_types", ) + _LabelBase._repr_attrs
    _attrs_base: Polyline2D = attr_base(key="polyline2d")
    beizer_point_types: str = attr(is_dynamic=True, key=camel)

    def __init__(
        self,
        points: Optional[Iterable[Iterable[float]]] = None,
        *,
        category: Optional[str] = None,
        attributes: Optional[Dict[str, Any]] = None,
        instance: Optional[str] = None,
        beizer_point_types: Optional[str] = None,
    ):
        Polyline2D.__init__(self, points)  # type: ignore[arg-type]
        _LabelBase.__init__(self, category, attributes, instance)
        if beizer_point_types:
            self.beizer_point_types = beizer_point_types

    @classmethod
    def loads(cls: Type[_T],
              contents: Dict[str, Any]) -> _T:  # type: ignore[override]
        """Loads a LabeledPolyline2D from a dict containing the information of the label.

        Arguments:
            contents: A dict containing the information of the 2D polyline label.

        Returns:
            The loaded :class:`LabeledPolyline2D` object.

        Examples:
            >>> contents = {
            ...     "polyline2d": [{'x': 1, 'y': 2}, {'x': 2, 'y': 4}, {'x': 2, 'y': 1}],
            ...     "category": "example",
            ...     "attributes": {"key": "value"},
            ...     "instance": "12345",
            ...     "beizer_point_types": "LLL",
            ... }
            >>> LabeledPolyline2D.loads(contents)
            LabeledPolyline2D [
              Vector2D(1, 2),
              Vector2D(2, 4),
              Vector2D(2, 1)
            ](
              (beizer_point_types): 'LLL',
              (category): 'example',
              (attributes): {...},
              (instance): '12345'
            )

        """
        return common_loads(cls, contents)

    def dumps(self) -> Dict[str, Any]:  # type: ignore[override]
        """Dumps the current 2D polyline label into a dict.

        Returns:
            A dict containing all the information of the 2D polyline label.

        Examples:
            >>> labeledpolyline2d = LabeledPolyline2D(
            ...     [(1, 2), (2, 4), (2, 1)],
            ...     category="example",
            ...     attributes={"key": "value"},
            ...     instance="123",
            ...     beizer_point_types="LLL",
            ... )
            >>> labeledpolyline2d.dumps()
            {
                'category': 'example',
                'attributes': {'key': 'value'},
                'instance': '123',
                'polyline2d': [{'x': 1, 'y': 2}, {'x': 2, 'y': 4}, {'x': 2, 'y': 1}],
                'beizerPointTypes': 'LLL',
            }

        """
        return self._dumps()
Exemple #3
0
class LabeledBox3D(_LabelBase, Box3D):
    """This class defines the concept of 3D bounding box label.

    :class:`LabeledBox3D` is the 3D bounding box type of label,
    which is often used for object detection in 3D point cloud.

    Arguments:
        size: Size of the 3D bounding box label in a sequence of [x, y, z].
        translation: Translation of the 3D bounding box label in a sequence of [x, y, z].
        rotation: Rotation of the 3D bounding box label in a sequence of [w, x, y, z]
            or a numpy quaternion object.
        transform_matrix: A 4x4 or 3x4 transformation matrix.
        category: Category of the 3D bounding box label.
        attributes: Attributs of the 3D bounding box label.
        instance: The instance id of the 3D bounding box label.

    Attributes:
        category: The category of the label.
        attributes: The attributes of the label.
        instance: The instance id of the label.
        size: The size of the 3D bounding box.
        transform: The transform of the 3D bounding box.

    Examples:
        >>> LabeledBox3D(
        ...     size=[1, 2, 3],
        ...     translation=(1, 2, 3),
        ...     rotation=(0, 1, 0, 0),
        ...     category="example",
        ...     attributes={"key": "value"},
        ...     instance="12345",
        ... )
        LabeledBox3D(
          (size): Vector3D(1, 2, 3),
          (translation): Vector3D(1, 2, 3),
          (rotation): quaternion(0, 1, 0, 0),
          (category): 'example',
          (attributes): {...},
          (instance): '12345'
        )

    """

    _T = TypeVar("_T", bound="LabeledBox3D")

    _repr_attrs = Box3D._repr_attrs + _LabelBase._repr_attrs

    _attrs_base: Box3D = attr_base(key="box3d")

    def __init__(
        self,
        size: Iterable[float],
        translation: Iterable[float] = (0, 0, 0),
        rotation: Transform3D.RotationType = (1, 0, 0, 0),
        *,
        transform_matrix: Optional[MatrixType] = None,
        category: Optional[str] = None,
        attributes: Optional[Dict[str, Any]] = None,
        instance: Optional[str] = None,
    ):
        Box3D.__init__(self,
                       size,
                       translation,
                       rotation,
                       transform_matrix=transform_matrix)
        _LabelBase.__init__(self, category, attributes, instance)

    def __rmul__(self: _T, other: Transform3D) -> _T:
        if isinstance(other, (Transform3D, quaternion)):
            labeled_box_3d = Box3D.__rmul__(self, other)
            if hasattr(self, "category"):
                labeled_box_3d.category = self.category
            if hasattr(self, "attributes"):
                labeled_box_3d.attributes = self.attributes
            if hasattr(self, "instance"):
                labeled_box_3d.instance = self.instance
            return labeled_box_3d

        return NotImplemented  # type: ignore[unreachable]

    @classmethod
    def loads(cls: Type[_T], contents: Dict[str, Any]) -> _T:
        """Loads a LabeledBox3D from a dict containing the information of the label.

        Arguments:
            contents: A dict containing the information of the 3D bounding box label.

        Returns:
            The loaded :class:`LabeledBox3D` object.

        Examples:
            >>> contents = {
            ...     "box3d": {
            ...         "size": {"x": 1, "y": 2, "z": 3},
            ...         "translation": {"x": 1, "y": 2, "z": 3},
            ...         "rotation": {"w": 1, "x": 0, "y": 0, "z": 0},
            ...     },
            ...     "category": "test",
            ...     "attributes": {"key": "value"},
            ...     "instance": "12345",
            ... }
            >>> LabeledBox3D.loads(contents)
            LabeledBox3D(
              (size): Vector3D(1, 2, 3),
              (translation): Vector3D(1, 2, 3),
              (rotation): quaternion(1, 0, 0, 0),
              (category): 'test',
              (attributes): {...},
              (instance): '12345'
            )

        """
        return common_loads(cls, contents)

    def dumps(self) -> Dict[str, Any]:
        """Dumps the current 3D bounding box label into a dict.

        Returns:
            A dict containing all the information of the 3D bounding box label.

        Examples:
            >>> labeledbox3d = LabeledBox3D(
            ...     size=[1, 2, 3],
            ...     translation=(1, 2, 3),
            ...     rotation=(0, 1, 0, 0),
            ...     category="example",
            ...     attributes={"key": "value"},
            ...     instance="12345",
            ... )
            >>> labeledbox3d.dumps()
            {
                'category': 'example',
                'attributes': {'key': 'value'},
                'instance': '12345',
                'box3d': {
                    'translation': {'x': 1, 'y': 2, 'z': 3},
                    'rotation': {'w': 0.0, 'x': 1.0, 'y': 0.0, 'z': 0.0},
                    'size': {'x': 1, 'y': 2, 'z': 3},
                },
            }

        """
        return self._dumps()
Exemple #4
0
class LabeledMultiPolyline2D(_LabelBase,
                             MultiPolyline2D):  # type: ignore[misc]
    """This class defines the concept of multiPolyline2D label.

    :class:`LabeledMultiPolyline2D` is the 2D multiple polyline type of label,
    which is often used for CV tasks such as lane detection.

    Arguments:
        polylines: A list of polylines.
        category: The category of the label.
        attributes: The attributes 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:
        >>> LabeledMultiPolyline2D(
        ...     [[[1, 2], [2, 3]], [[3, 4], [6, 8]]],
        ...     category="example",
        ...     attributes={"key": "value"},
        ...     instance="123",
        ... )
        LabeledPolyline2D [
          Polyline2D [...]
          Polyline2D [...]
        ](
          (category): 'example',
          (attributes): {...},
          (instance): '123'
        )

    """

    _T = TypeVar("_T", bound="LabeledMultiPolyline2D")

    _repr_type = ReprType.SEQUENCE
    _repr_attrs = _LabelBase._repr_attrs
    _attrs_base: MultiPolyline2D = attr_base(key="multiPolyline2d")

    def __init__(
        self,
        polylines: Optional[Iterable[Iterable[float]]] = None,
        *,
        category: Optional[str] = None,
        attributes: Optional[Dict[str, Any]] = None,
        instance: Optional[str] = None,
    ):
        MultiPolyline2D.__init__(self, polylines)  # type: ignore[arg-type]
        _LabelBase.__init__(self, category, attributes, instance)

    @classmethod
    def loads(cls: Type[_T],
              contents: Dict[str, Any]) -> _T:  # type: ignore[override]
        """Loads a LabeledMultiPolyline2D from a dict containing the information of the label.

        Arguments:
            contents: A dict containing the information of the 2D polyline label.

        Returns:
            The loaded :class:`LabeledMultiPolyline2D` object.

        Examples:
            >>> contents = {
            ...     "multiPolyline2d": [[{'x': 1, 'y': 1}, {'x': 1, 'y': 2}, {'x': 2, 'y': 2}],
                                        [{'x': 2, 'y': 3}, {'x': 3, 'y': 5}]],
            ...     "category": "example",
            ...     "attributes": {"key": "value"},
            ...     "instance": "12345",
            ... }
            >>> LabeledMultiPolyline2D.loads(contents)
            LabeledMultiPolyline2D [
              Polyline2D [...]
              Polyline2D [...]
            ](
              (category): 'example',
              (attributes): {...},
              (instance): '12345'
            )

        """
        return common_loads(cls, contents)

    def dumps(self) -> Dict[str, Any]:  # type: ignore[override]
        """Dumps the current 2D multiple polyline label into a dict.

        Returns:
            A dict containing all the information of the 2D polyline label.

        Examples:
            >>> labeledmultipolyline2d = LabeledMultiPolyline2D(
            ...     [[[1, 1], [1, 2], [2, 2]], [[2, 3], [3, 5]]],
            ...     category="example",
            ...     attributes={"key": "value"},
            ...     instance="123",
            ... )
            >>> labeledpolyline2d.dumps()
            {
                'category': 'example',
                'attributes': {'key': 'value'},
                'instance': '123',
                'polyline2d': [
                    [{'x': 1, 'y': 1}, {'x': 1, 'y': 2}, {'x': 2, 'y': 2}],
                    [{'x': 2, 'y': 3}, {'x': 3, 'y': 5}],
            }

        """
        return self._dumps()
class AttributeInfo(NameMixin, Items):
    """This class represents the information of an attribute.

    It refers to the `Json schema`_ method to describe an attribute.

    .. todo::
        The format of argument *type_* on the generated web page is incorrect.

    Arguments:
        name: The name of the attribute.
        type_: The type of the attribute value, could be a single type or multi-types.
            The type must be within the followings:

                - array
                - boolean
                - integer
                - number
                - string
                - null
                - instance

        enum: All the possible values of an enumeration attribute.
        minimum: The minimum value of number type attribute.
        maximum: The maximum value of number type attribute.
        items: The items inside array type attributes.
        parent_categories: The parent categories of the attribute.
        description: The description of the attribute.

    Attributes:
        type: The type of the attribute value, could be a single type or multi-types.
        enum: All the possible values of an enumeration attribute.
        minimum: The minimum value of number type attribute.
        maximum: The maximum value of number type attribute.
        items: The items inside array type attributes.
        parent_categories: The parent categories of the attribute.
        description: The description of the attribute.

    .. _Json schema: https://json-schema.org/

    Examples:
        >>> from tensorbay.label import Items
        >>> items = Items(type_="integer", enum=[1, 2, 3, 4, 5], minimum=1, maximum=5)
        >>> AttributeInfo(
        ...     name="example",
        ...     type_="array",
        ...     enum=[1, 2, 3, 4, 5],
        ...     items=items,
        ...     minimum=1,
        ...     maximum=5,
        ...     parent_categories=["parent_category_of_example"],
        ...     description="This is an example",
        ... )
        AttributeInfo("example")(
          (type): 'array',
          (enum): [
            1,
            2,
            3,
            4,
            5
          ],
          (minimum): 1,
          (maximum): 5,
          (items): Items(
            (type): 'integer',
            (enum): [...],
            (minimum): 1,
            (maximum): 5
          ),
          (parent_categories): [
            'parent_category_of_example'
          ]
        )

    """

    _T = TypeVar("_T", bound="AttributeInfo")

    _repr_attrs = Items._repr_attrs + ("parent_categories", )
    _repr_maxlevel = 2

    _attrs_base: Items = attr_base(key=None)
    parent_categories: List[str] = attr(is_dynamic=True, key=camel)

    def __init__(
        self,
        name: str,
        *,
        type_: _ArgType = "",
        enum: Optional[Iterable[_EnumElementType]] = None,
        minimum: Optional[float] = None,
        maximum: Optional[float] = None,
        items: Optional[Items] = None,
        parent_categories: Union[None, str, Iterable[str]] = None,
        description: str = "",
    ):
        NameMixin.__init__(self, name, description)
        Items.__init__(self,
                       type_=type_,
                       enum=enum,
                       minimum=minimum,
                       maximum=maximum,
                       items=items)

        if not parent_categories:
            return

        if isinstance(parent_categories, str):
            self.parent_categories = [parent_categories]
        else:
            self.parent_categories = list(parent_categories)

    @classmethod
    def loads(cls: Type[_T], contents: Dict[str, Any]) -> _T:
        """Load an AttributeInfo from a dict containing the attribute information.

        Arguments:
            contents: A dict containing the information of the attribute.

        Returns:
            The loaded :class:`AttributeInfo` object.

        Examples:
            >>> contents = {
            ...     "name": "example",
            ...     "type": "array",
            ...     "items": {"type": "boolean"},
            ...     "description": "This is an example",
            ...     "parentCategories": ["parent_category_of_example"],
            ... }
            >>> AttributeInfo.loads(contents)
            AttributeInfo("example")(
              (type): 'array',
              (items): Items(
                (type): 'boolean',
              ),
              (parent_categories): [
                'parent_category_of_example'
              ]
            )

        """
        return common_loads(cls, contents)

    def dumps(self) -> Dict[str, Any]:
        """Dumps the information of this attribute into a dict.

        Returns:
            A dict containing all the information of this attribute.

        Examples:
            >>> from tensorbay.label import Items
            >>> items = Items(type_="integer", minimum=1, maximum=5)
            >>> attributeinfo = AttributeInfo(
            ...     name="example",
            ...     type_="array",
            ...     items=items,
            ...     parent_categories=["parent_category_of_example"],
            ...     description="This is an example",
            ... )
            >>> attributeinfo.dumps()
            {
                'name': 'example',
                'description': 'This is an example',
                'type': 'array',
                'items': {'type': 'integer', 'minimum': 1, 'maximum': 5},
                'parentCategories': ['parent_category_of_example'],
            }

        """
        return self._dumps()
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)

    @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)

    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()
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)

    @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)

    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()
class LabeledKeypoints2D(_LabelBase, Keypoints2D):
    """This class defines the concept of 2D keypoints label.

    :class:`LabeledKeypoints2D` is the 2D keypoints type of label,
    which is often used for CV tasks such as human body pose estimation.

    Arguments:
        keypoints: A list of 2D keypoint.
        category: The category of the label.
        attributes: The attributes 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:
        >>> LabeledKeypoints2D(
        ...     [(1, 2), (2, 3)],
        ...     category="example",
        ...     attributes={"key": "value"},
        ...     instance="123",
        ... )
        LabeledKeypoints2D [
          Keypoint2D(1, 2),
          Keypoint2D(2, 3)
        ](
          (category): 'example',
          (attributes): {...},
          (instance): '123'
        )

    """

    _T = TypeVar("_T", bound="LabeledKeypoints2D")

    _repr_type = ReprType.SEQUENCE
    _repr_attrs = _LabelBase._repr_attrs
    _attrs_base: Keypoints2D = attr_base(key="keypoints2d")

    def __init__(
        self,
        keypoints: Optional[Iterable[Iterable[float]]] = None,
        *,
        category: Optional[str] = None,
        attributes: Optional[Dict[str, Any]] = None,
        instance: Optional[str] = None,
    ) -> None:
        Keypoints2D.__init__(self, keypoints)  # type: ignore[arg-type]
        _LabelBase.__init__(self, category, attributes, instance)

    @classmethod
    def loads(cls: Type[_T],
              contents: Dict[str, Any]) -> _T:  # type: ignore[override]
        """Loads a LabeledKeypoints2D from a dict containing the information of the label.

        Arguments:
            contents: A dict containing the information of the 2D keypoints label.

        Returns:
            The loaded :class:`LabeledKeypoints2D` object.

        Examples:
            >>> contents = {
            ...     "keypoints2d": [
            ...         {"x": 1, "y": 1, "v": 2},
            ...         {"x": 2, "y": 2, "v": 2},
            ...     ],
            ...     "category": "example",
            ...     "attributes": {"key": "value"},
            ...     "instance": "12345",
            ... }
            >>> LabeledKeypoints2D.loads(contents)
            LabeledKeypoints2D [
              Keypoint2D(1, 1, 2),
              Keypoint2D(2, 2, 2)
            ](
              (category): 'example',
              (attributes): {...},
              (instance): '12345'
            )

        """
        return common_loads(cls, contents)

    def dumps(self) -> Dict[str, Any]:  # type: ignore[override]
        """Dumps the current 2D keypoints label into a dict.

        Returns:
            A dict containing all the information of the 2D keypoints label.

        Examples:
            >>> labeledkeypoints2d = LabeledKeypoints2D(
            ...     [(1, 1, 2), (2, 2, 2)],
            ...     category="example",
            ...     attributes={"key": "value"},
            ...     instance="123",
            ... )
            >>> labeledkeypoints2d.dumps()
            {
                'category': 'example',
                'attributes': {'key': 'value'},
                'instance': '123',
                'keypoints2d': [{'x': 1, 'y': 1, 'v': 2}, {'x': 2, 'y': 2, 'v': 2}],
            }

        """
        return self._dumps()