Module datatap.droplet

This module provides classes for working with ML data. Specifically, it provides methods for creating new ML data objects, converting ML data objects to and from the JSON droplet format, and manipulating ML data objects.

Expand source code
"""
This module provides classes for working with ML data.  Specifically, it provides methods for creating new ML data
objects, converting ML data objects to and from the JSON droplet format, and manipulating ML data objects.
"""

from .bounding_box import BoundingBox, BoundingBoxJson
from .class_annotation import ClassAnnotation, ClassAnnotationJson
from .frame_annotation import FrameAnnotation, FrameAnnotationJson
from .image import Image, ImageJson
from .image_annotation import ImageAnnotation, ImageAnnotationJson
from .instance import Instance, InstanceJson
from .keypoint import Keypoint, KeypointJson
from .multi_instance import MultiInstance, MultiInstanceJson
from .segmentation import Segmentation, SegmentationJson
from .video import Video, VideoJson
from .video_annotation import VideoAnnotation, VideoAnnotationJson

__all__ = [
        "BoundingBox",
        "BoundingBoxJson",
        "ClassAnnotation",
        "ClassAnnotationJson",
        "FrameAnnotation",
        "FrameAnnotationJson",
        "Image",
        "ImageJson",
        "ImageAnnotation",
        "ImageAnnotationJson",
        "Instance",
        "InstanceJson",
        "Keypoint",
        "KeypointJson",
        "MultiInstance",
        "MultiInstanceJson",
        "Segmentation",
        "SegmentationJson",
        "Video",
        "VideoJson",
        "VideoAnnotation",
        "VideoAnnotationJson",
]

Sub-modules

datatap.droplet.attributes
datatap.droplet.bounding_box
datatap.droplet.class_annotation
datatap.droplet.frame_annotation
datatap.droplet.image
datatap.droplet.image_annotation
datatap.droplet.instance
datatap.droplet.keypoint
datatap.droplet.multi_instance
datatap.droplet.segmentation
datatap.droplet.video
datatap.droplet.video_annotation

Classes

class BoundingBox (rectangle: Rectangle, *, confidence: Optional[float] = None)

A BoundingBox represents the area within an image taken up by a detection, specified as an axis-aligned rectangle.

Expand source code
class BoundingBox:
        """
        A `BoundingBox` represents the area within an image taken up by a detection,
        specified as an axis-aligned rectangle.
        """

        rectangle: Rectangle
        """
        The area within the image where the corresponding detection appears.
        """

        confidence: Optional[float]
        """
        The confidence associated with this bounding box.
        """

        @staticmethod
        def from_json(json: BoundingBoxJson) -> BoundingBox:
                """
                Constructs a `BoundingBox` from a `BoundingBoxJson`.
                """
                return BoundingBox(
                        Rectangle.from_json(json["rectangle"]),
                        confidence = json.get("confidence")
                )

        def __init__(self, rectangle: Rectangle, *, confidence: Optional[float] = None):
                self.rectangle = rectangle
                self.confidence = confidence

                self.rectangle.assert_valid()

        def __repr__(self) -> str:
                return basic_repr("BoundingBox", self.rectangle, confidence = self.confidence)

        def __eq__(self, other: object) -> bool:
                if not isinstance(other, BoundingBox):
                        return NotImplemented
                return self.rectangle == other.rectangle and self.confidence == other.confidence

        def to_json(self) -> BoundingBoxJson:
                """
                Serializes this `BoundingBox` to a `BoundingBoxJson`.
                """
                json: BoundingBoxJson = {
                        "rectangle": self.rectangle.to_json()
                }

                if self.confidence is not None:
                        json["confidence"] = self.confidence

                return json

        def meets_confidence_threshold(self, threshold: float) -> bool:
                """
                Returns `True` if and only if the confidence of this bounding box is
                either unset or it is at least the given `threshold`.
                """
                return self.confidence is None or self.confidence >= threshold

Class variables

var confidence : Optional[float]

The confidence associated with this bounding box.

var rectangleRectangle

The area within the image where the corresponding detection appears.

Static methods

def from_json(json: BoundingBoxJson) ‑> BoundingBox

Constructs a BoundingBox from a BoundingBoxJson.

Expand source code
@staticmethod
def from_json(json: BoundingBoxJson) -> BoundingBox:
        """
        Constructs a `BoundingBox` from a `BoundingBoxJson`.
        """
        return BoundingBox(
                Rectangle.from_json(json["rectangle"]),
                confidence = json.get("confidence")
        )

Methods

def meets_confidence_threshold(self, threshold: float) ‑> bool

Returns True if and only if the confidence of this bounding box is either unset or it is at least the given threshold.

Expand source code
def meets_confidence_threshold(self, threshold: float) -> bool:
        """
        Returns `True` if and only if the confidence of this bounding box is
        either unset or it is at least the given `threshold`.
        """
        return self.confidence is None or self.confidence >= threshold
def to_json(self) ‑> BoundingBoxJson

Serializes this BoundingBox to a BoundingBoxJson.

Expand source code
def to_json(self) -> BoundingBoxJson:
        """
        Serializes this `BoundingBox` to a `BoundingBoxJson`.
        """
        json: BoundingBoxJson = {
                "rectangle": self.rectangle.to_json()
        }

        if self.confidence is not None:
                json["confidence"] = self.confidence

        return json
class BoundingBoxJson (*args, **kwargs)

The serialized JSON representation of a bounding box.

Expand source code
class BoundingBoxJson(_BoundingBoxJsonOptional, TypedDict):
        """
        The serialized JSON representation of a bounding box.
        """
        rectangle: RectangleJson

Ancestors

  • builtins.dict

Class variables

var confidence : float
var rectangle : Tuple[Tuple[float, float], Tuple[float, float]]
class ClassAnnotation (*, instances: Sequence[Instance], multi_instances: Sequence[MultiInstance] = [])

A ClassAnnotation represents the set of detections for a given class. These may either be individual instances, or "multi instances" that describe a visual clustering of the class.

Expand source code
class ClassAnnotation:
        """
        A `ClassAnnotation` represents the set of detections for a given
        class. These may either be individual instances, or "multi instances"
        that describe a visual clustering of the class.
        """

        instances: Sequence[Instance]
        """
        A sequence of individual instances of this class.
        """

        multi_instances: Sequence[MultiInstance]
        """
        A sequence of multi-instances of this class. An example of a
        multi instance would be a crowd of people (labeled as such).
        """

        @staticmethod
        def from_json(json: ClassAnnotationJson) -> ClassAnnotation:
                """
                Constructs a `ClassAnnotation` from a `ClassAnnotationJson`.
                """
                return ClassAnnotation(
                        instances = [Instance.from_json(instance) for instance in json["instances"]] if "instances" in json else [],
                        multi_instances = [MultiInstance.from_json(multi_instance) for multi_instance in json["multiInstances"]] if "multiInstances" in json else []
                )

        def __init__(self, *, instances: Sequence[Instance], multi_instances: Sequence[MultiInstance] = []):
                self.instances = instances
                self.multi_instances = multi_instances

        def filter_detections(
                self,
                *,
                instance_filter: Callable[[Instance], bool],
                multi_instance_filter: Callable[[MultiInstance], bool]
        ) -> ClassAnnotation:
                """
                Returns a new class annotation consisting only of the instances and
                multi-instances that meet the given constraints.
                """
                return ClassAnnotation(
                        instances = [
                                instance
                                for instance in self.instances
                                if instance_filter(instance)
                        ],
                        multi_instances = [
                                multi_instance
                                for multi_instance in self.multi_instances
                                if multi_instance_filter(multi_instance)
                        ]
                )

        def __repr__(self) -> str:
                return basic_repr("ClassAnnotation", instances = self.instances, multi_instances = self.multi_instances)

        def __eq__(self, other: object) -> bool:
                if not isinstance(other, ClassAnnotation):
                        return NotImplemented
                return self.instances == other.instances and self.multi_instances == other.multi_instances

        def __add__(self, other: ClassAnnotation) -> ClassAnnotation:
                if not isinstance(other, ClassAnnotation): # type: ignore - pyright complains about the isinstance check being redundant
                        return NotImplemented

                instances = list(self.instances) + list(other.instances)
                multi_instances = list(self.multi_instances) + list(other.multi_instances)

                return ClassAnnotation(
                        instances = instances,
                        multi_instances = multi_instances,
                )

        def to_json(self) -> ClassAnnotationJson:
                """
                Serializes this `ClassAnnotation` into a `ClassAnnotationJson`.
                """

                return {
                        "instances": [instance.to_json() for instance in self.instances],
                        "multiInstances": [multi_instance.to_json() for multi_instance in self.multi_instances]
                }

Class variables

var instances : Sequence[Instance]

A sequence of individual instances of this class.

var multi_instances : Sequence[MultiInstance]

A sequence of multi-instances of this class. An example of a multi instance would be a crowd of people (labeled as such).

Static methods

def from_json(json: ClassAnnotationJson) ‑> ClassAnnotation
Expand source code
@staticmethod
def from_json(json: ClassAnnotationJson) -> ClassAnnotation:
        """
        Constructs a `ClassAnnotation` from a `ClassAnnotationJson`.
        """
        return ClassAnnotation(
                instances = [Instance.from_json(instance) for instance in json["instances"]] if "instances" in json else [],
                multi_instances = [MultiInstance.from_json(multi_instance) for multi_instance in json["multiInstances"]] if "multiInstances" in json else []
        )

Methods

def filter_detections(self, *, instance_filter: Callable[[Instance], bool], multi_instance_filter: Callable[[MultiInstance], bool]) ‑> ClassAnnotation

Returns a new class annotation consisting only of the instances and multi-instances that meet the given constraints.

Expand source code
def filter_detections(
        self,
        *,
        instance_filter: Callable[[Instance], bool],
        multi_instance_filter: Callable[[MultiInstance], bool]
) -> ClassAnnotation:
        """
        Returns a new class annotation consisting only of the instances and
        multi-instances that meet the given constraints.
        """
        return ClassAnnotation(
                instances = [
                        instance
                        for instance in self.instances
                        if instance_filter(instance)
                ],
                multi_instances = [
                        multi_instance
                        for multi_instance in self.multi_instances
                        if multi_instance_filter(multi_instance)
                ]
        )
def to_json(self) ‑> ClassAnnotationJson

Serializes this ClassAnnotation into a ClassAnnotationJson.

Expand source code
def to_json(self) -> ClassAnnotationJson:
        """
        Serializes this `ClassAnnotation` into a `ClassAnnotationJson`.
        """

        return {
                "instances": [instance.to_json() for instance in self.instances],
                "multiInstances": [multi_instance.to_json() for multi_instance in self.multi_instances]
        }
class ClassAnnotationJson (*args, **kwargs)

The serialized JSON representation of a class annotation.

Expand source code
class ClassAnnotationJson(TypedDict, total = False):
        """
        The serialized JSON representation of a class annotation.
        """
        instances: Sequence[InstanceJson]
        multiInstances: Sequence[MultiInstanceJson]

Ancestors

  • builtins.dict

Class variables

var instances : Sequence[InstanceJson]
var multiInstances : Sequence[MultiInstanceJson]
class FrameAnnotation (*, classes: Mapping[str, ClassAnnotation])

A collection of class annotations that annotate a given image.

Expand source code
class FrameAnnotation:
        """
        A collection of class annotations that annotate a given image.
        """

        classes: Mapping[str, ClassAnnotation]
        """
        A mapping from class name to the annotations of that class.
        """

        @staticmethod
        def from_json(json: Mapping[str, Any]) -> FrameAnnotation:
                """
                Constructs an `FrameAnnotation` from an `FrameAnnotationJson`.
                """
                return FrameAnnotation(
                        classes = {
                                class_name: ClassAnnotation.from_json(json["classes"][class_name])
                                for class_name in json["classes"]
                        }
                )

        def __init__(
                self,
                *,
                classes: Mapping[str, ClassAnnotation],
        ):
                self.classes = classes

        def filter_detections(
                self,
                *,
                instance_filter: Callable[[Instance], bool],
                multi_instance_filter: Callable[[MultiInstance], bool]
        ) -> FrameAnnotation:
                """
                Returns a new image annotation consisting only of the instances and
                multi-instances that meet the given constraints.
                """
                return FrameAnnotation(
                        classes = {
                                class_name: class_annotation.filter_detections(
                                        instance_filter = instance_filter,
                                        multi_instance_filter = multi_instance_filter
                                )
                                for class_name, class_annotation in self.classes.items()
                        }
                )

        def apply_bounding_box_confidence_threshold(self, threshold: float) -> FrameAnnotation:
                """
                Returns a new image annotation consisting only of the instances and
                multi-instances that have bounding boxes which either do not have a
                confidence specified or which have a confience meeting the given
                threshold.
                """
                return self.filter_detections(
                        instance_filter = lambda instance: (
                                instance.bounding_box is not None
                                        and instance.bounding_box.meets_confidence_threshold(threshold)
                        ),
                        multi_instance_filter = lambda multi_instance: (
                                multi_instance.bounding_box is not None
                                        and multi_instance.bounding_box.meets_confidence_threshold(threshold)
                        )
                )

        def apply_segmentation_confidence_threshold(self, threshold: float) -> FrameAnnotation:
                """
                Returns a new image annotation consisting only of the instances and
                multi-instances that have segmentations which either do not have a
                confidence specified or which have a confience meeting the given
                threshold.
                """
                return self.filter_detections(
                        instance_filter = lambda instance: (
                                instance.segmentation is not None
                                        and instance.segmentation.meets_confidence_threshold(threshold)
                        ),
                        multi_instance_filter = lambda multi_instance: (
                                multi_instance.segmentation is not None
                                        and multi_instance.segmentation.meets_confidence_threshold(threshold)
                        )
                )

        def __repr__(self) -> str:
                return basic_repr(
                        "FrameAnnotation",
                        classes = self.classes
                )

        def __eq__(self, other: object) -> bool:
                if not isinstance(other, FrameAnnotation):
                        return NotImplemented
                return self.classes == other.classes

        def __add__(self, other: FrameAnnotation) -> FrameAnnotation:
                if not isinstance(other, FrameAnnotation): # type: ignore - pyright complains about the isinstance check being redundant
                        return NotImplemented

                classes: Dict[str, ClassAnnotation] = {}

                for key, value in self.classes.items():
                        classes[key] = value

                for key, value in other.classes.items():
                        if key in classes:
                                classes[key] += value
                        else:
                                classes[key] = value

                return FrameAnnotation(
                        classes = classes
                )

        def to_json(self) -> FrameAnnotationJson:
                """
                Serializes this image annotation into an `FrameAnnotationJson`.
                """
                json: FrameAnnotationJson = {
                        "classes": {
                                name: class_annotation.to_json()
                                for name, class_annotation in self.classes.items()
                        }
                }

                return json

Class variables

var classes : Mapping[str, ClassAnnotation]

A mapping from class name to the annotations of that class.

Static methods

def from_json(json: Mapping[str, Any]) ‑> FrameAnnotation

Constructs an FrameAnnotation from an FrameAnnotationJson.

Expand source code
@staticmethod
def from_json(json: Mapping[str, Any]) -> FrameAnnotation:
        """
        Constructs an `FrameAnnotation` from an `FrameAnnotationJson`.
        """
        return FrameAnnotation(
                classes = {
                        class_name: ClassAnnotation.from_json(json["classes"][class_name])
                        for class_name in json["classes"]
                }
        )

Methods

def apply_bounding_box_confidence_threshold(self, threshold: float) ‑> FrameAnnotation

Returns a new image annotation consisting only of the instances and multi-instances that have bounding boxes which either do not have a confidence specified or which have a confience meeting the given threshold.

Expand source code
def apply_bounding_box_confidence_threshold(self, threshold: float) -> FrameAnnotation:
        """
        Returns a new image annotation consisting only of the instances and
        multi-instances that have bounding boxes which either do not have a
        confidence specified or which have a confience meeting the given
        threshold.
        """
        return self.filter_detections(
                instance_filter = lambda instance: (
                        instance.bounding_box is not None
                                and instance.bounding_box.meets_confidence_threshold(threshold)
                ),
                multi_instance_filter = lambda multi_instance: (
                        multi_instance.bounding_box is not None
                                and multi_instance.bounding_box.meets_confidence_threshold(threshold)
                )
        )
def apply_segmentation_confidence_threshold(self, threshold: float) ‑> FrameAnnotation

Returns a new image annotation consisting only of the instances and multi-instances that have segmentations which either do not have a confidence specified or which have a confience meeting the given threshold.

Expand source code
def apply_segmentation_confidence_threshold(self, threshold: float) -> FrameAnnotation:
        """
        Returns a new image annotation consisting only of the instances and
        multi-instances that have segmentations which either do not have a
        confidence specified or which have a confience meeting the given
        threshold.
        """
        return self.filter_detections(
                instance_filter = lambda instance: (
                        instance.segmentation is not None
                                and instance.segmentation.meets_confidence_threshold(threshold)
                ),
                multi_instance_filter = lambda multi_instance: (
                        multi_instance.segmentation is not None
                                and multi_instance.segmentation.meets_confidence_threshold(threshold)
                )
        )
def filter_detections(self, *, instance_filter: Callable[[Instance], bool], multi_instance_filter: Callable[[MultiInstance], bool]) ‑> FrameAnnotation

Returns a new image annotation consisting only of the instances and multi-instances that meet the given constraints.

Expand source code
def filter_detections(
        self,
        *,
        instance_filter: Callable[[Instance], bool],
        multi_instance_filter: Callable[[MultiInstance], bool]
) -> FrameAnnotation:
        """
        Returns a new image annotation consisting only of the instances and
        multi-instances that meet the given constraints.
        """
        return FrameAnnotation(
                classes = {
                        class_name: class_annotation.filter_detections(
                                instance_filter = instance_filter,
                                multi_instance_filter = multi_instance_filter
                        )
                        for class_name, class_annotation in self.classes.items()
                }
        )
def to_json(self) ‑> FrameAnnotationJson

Serializes this image annotation into an FrameAnnotationJson.

Expand source code
def to_json(self) -> FrameAnnotationJson:
        """
        Serializes this image annotation into an `FrameAnnotationJson`.
        """
        json: FrameAnnotationJson = {
                "classes": {
                        name: class_annotation.to_json()
                        for name, class_annotation in self.classes.items()
                }
        }

        return json
class FrameAnnotationJson (*args, **kwargs)

The serialized JSON representation of an image annotation.

Expand source code
class FrameAnnotationJson(TypedDict):
        """
        The serialized JSON representation of an image annotation.
        """

        classes: Mapping[str, ClassAnnotationJson]

Ancestors

  • builtins.dict

Class variables

var classes : Mapping[str, ClassAnnotationJson]
class Image (*, uid: Optional[str] = None, paths: Sequence[str])

The Image class contains information about what image was labeled by a given annotation. It also includes utilities for loading and manipulating images.

Expand source code
class Image(Media):
        """
        The `Image` class contains information about what image was
        labeled by a given annotation. It also includes utilities
        for loading and manipulating images.
        """

        uid: Optional[str]
        """
        A unique ID for this image.
        """

        _pil_image: Optional[PIL.Image.Image]

        @staticmethod
        def from_json(json: ImageJson) -> Image:
                """
                Creates an `Image` from an `ImageJson`.
                """
                return Image(uid = json.get("uid", None), paths = json["paths"])

        @staticmethod
        def from_pil(pil_image: PIL.Image.Image) -> Image:
                """
                Creates an `Image` from an existing PIL Image. Note that an
                image created this way will not have any `paths` set, but will
                still be able to load the image via `get_pil_image`.
                """
                image = Image(
                        paths = [],
                )
                image._pil_image = pil_image
                return image

        def __init__(self, *, uid: Optional[str] = None, paths: Sequence[str]):
                super().__init__(paths = paths)
                self.uid = uid
                self._pil_image = None

        def __repr__(self) -> str:
                return basic_repr("Image", uid = self.uid, paths = self.paths)

        def __eq__(self, other: object) -> bool:
                if not isinstance(other, Image):
                        return NotImplemented
                return self.paths == other.paths

        # TODO(mdsavage): consider using functools.cache here if we upgrade to Python >= 3.9
        def get_pil_image(self, quiet: bool = False, attempts: int = 3, allow_local: bool = False) -> PIL.Image.Image:
                """
                Attempts to load the image specified by this reference. Resolution happpens in this order:

                1. Load from an internal cache (either from a previous load, or from `from_pil`)
                2. Try loading every path in order, returning once one loads

                Warning! `get_pil_image` may attempt to read from the local file system or from private
                networks. Please ensure that the annotation you are loading is trusted.
                """
                if self._pil_image is not None:
                        return self._pil_image

                return PIL.Image.open(self.load(quiet, attempts, allow_local))

        def to_json(self) -> ImageJson:
                """
                Serializes this `Image` into an `ImageJson`.
                """
                json: ImageJson = {
                        "paths": self.paths
                }

                if self.uid is not None:
                        json["uid"] = self.uid

                return json

Ancestors

  • datatap.droplet._media.Media

Class variables

var uid : Optional[str]

A unique ID for this image.

Static methods

def from_json(json: ImageJson) ‑> Image

Creates an Image from an ImageJson.

Expand source code
@staticmethod
def from_json(json: ImageJson) -> Image:
        """
        Creates an `Image` from an `ImageJson`.
        """
        return Image(uid = json.get("uid", None), paths = json["paths"])
def from_pil(pil_image: PIL.Image.Image) ‑> Image

Creates an Image from an existing PIL Image. Note that an image created this way will not have any paths set, but will still be able to load the image via get_pil_image.

Expand source code
@staticmethod
def from_pil(pil_image: PIL.Image.Image) -> Image:
        """
        Creates an `Image` from an existing PIL Image. Note that an
        image created this way will not have any `paths` set, but will
        still be able to load the image via `get_pil_image`.
        """
        image = Image(
                paths = [],
        )
        image._pil_image = pil_image
        return image

Methods

def get_pil_image(self, quiet: bool = False, attempts: int = 3, allow_local: bool = False) ‑> PIL.Image.Image

Attempts to load the image specified by this reference. Resolution happpens in this order:

  1. Load from an internal cache (either from a previous load, or from from_pil)
  2. Try loading every path in order, returning once one loads

Warning! get_pil_image may attempt to read from the local file system or from private networks. Please ensure that the annotation you are loading is trusted.

Expand source code
def get_pil_image(self, quiet: bool = False, attempts: int = 3, allow_local: bool = False) -> PIL.Image.Image:
        """
        Attempts to load the image specified by this reference. Resolution happpens in this order:

        1. Load from an internal cache (either from a previous load, or from `from_pil`)
        2. Try loading every path in order, returning once one loads

        Warning! `get_pil_image` may attempt to read from the local file system or from private
        networks. Please ensure that the annotation you are loading is trusted.
        """
        if self._pil_image is not None:
                return self._pil_image

        return PIL.Image.open(self.load(quiet, attempts, allow_local))
def to_json(self) ‑> ImageJson

Serializes this Image into an ImageJson.

Expand source code
def to_json(self) -> ImageJson:
        """
        Serializes this `Image` into an `ImageJson`.
        """
        json: ImageJson = {
                "paths": self.paths
        }

        if self.uid is not None:
                json["uid"] = self.uid

        return json
class ImageAnnotation (*, image: Image, classes: Mapping[str, ClassAnnotation], mask: Optional[Mask] = None, uid: Optional[str] = None, metadata: Optional[Mapping[str, Any]] = None)

A collection of class annotations that annotate a given image.

Expand source code
class ImageAnnotation:
        """
        A collection of class annotations that annotate a given image.
        """

        image: Image
        """
        The image being annotated.
        """

        classes: Mapping[str, ClassAnnotation]
        """
        A mapping from class name to the annotations of that class.
        """

        uid: Optional[str]
        """
        A unique identifier for this image annotation.
        """

        mask: Optional[Mask]
        """
        An optional region-of-interest mask to indicate that only
        features within the mask have been annotated.
        """

        metadata: Optional[Mapping[str, Any]]
        """
        An optional field for storing metadata on the annotation.
        """

        @staticmethod
        def from_json(json: Mapping[str, Any]) -> ImageAnnotation:
                """
                Constructs an `ImageAnnotation` from an `ImageAnnotationJson`.
                """
                return ImageAnnotation(
                        image = Image.from_json(json["image"]),
                        classes = {
                                class_name: ClassAnnotation.from_json(json["classes"][class_name])
                                for class_name in json["classes"]
                        },
                        mask = Mask.from_json(json["mask"]) if "mask" in json else None,
                        uid = json.get("uid"),
                        metadata = json.get("metadata")
                )

        def __init__(
                self,
                *,
                image: Image,
                classes: Mapping[str, ClassAnnotation],
                mask: Optional[Mask] = None,
                uid: Optional[str] = None,
                metadata: Optional[Mapping[str, Any]] = None
        ):
                self.image = image
                self.classes = classes
                self.mask = mask
                self.uid = uid
                self.metadata = metadata

        def filter_detections(
                self,
                *,
                instance_filter: Callable[[Instance], bool],
                multi_instance_filter: Callable[[MultiInstance], bool]
        ) -> ImageAnnotation:
                """
                Returns a new image annotation consisting only of the instances and
                multi-instances that meet the given constraints.
                """
                return ImageAnnotation(
                        image = self.image,
                        mask = self.mask,
                        classes = {
                                class_name: class_annotation.filter_detections(
                                        instance_filter = instance_filter,
                                        multi_instance_filter = multi_instance_filter
                                )
                                for class_name, class_annotation in self.classes.items()
                        },
                        uid = self.uid,
                        metadata = self.metadata
                )

        def apply_bounding_box_confidence_threshold(self, threshold: float) -> ImageAnnotation:
                """
                Returns a new image annotation consisting only of the instances and
                multi-instances that have bounding boxes which either do not have a
                confidence specified or which have a confience meeting the given
                threshold.
                """
                return self.filter_detections(
                        instance_filter = lambda instance: (
                                instance.bounding_box is not None
                                        and instance.bounding_box.meets_confidence_threshold(threshold)
                        ),
                        multi_instance_filter = lambda multi_instance: (
                                multi_instance.bounding_box is not None
                                        and multi_instance.bounding_box.meets_confidence_threshold(threshold)
                        )
                )

        def apply_segmentation_confidence_threshold(self, threshold: float) -> ImageAnnotation:
                """
                Returns a new image annotation consisting only of the instances and
                multi-instances that have segmentations which either do not have a
                confidence specified or which have a confience meeting the given
                threshold.
                """
                return self.filter_detections(
                        instance_filter = lambda instance: (
                                instance.segmentation is not None
                                        and instance.segmentation.meets_confidence_threshold(threshold)
                        ),
                        multi_instance_filter = lambda multi_instance: (
                                multi_instance.segmentation is not None
                                        and multi_instance.segmentation.meets_confidence_threshold(threshold)
                        )
                )

        def apply_metadata(self, metadata: Mapping[str, Any]) -> ImageAnnotation:
                """
                Returns a new image annotation with the supplied metadata.
                """
                return ImageAnnotation(
                        image = self.image,
                        mask = self.mask,
                        classes = self.classes,
                        uid = self.uid,
                        metadata = metadata
                )

        def __repr__(self) -> str:
                return basic_repr(
                        "ImageAnnotation",
                        uid = self.uid,
                        image = self.image,
                        mask = self.mask,
                        classes = self.classes,
                        metadata = self.metadata
                )

        def __eq__(self, other: object) -> bool:
                if not isinstance(other, ImageAnnotation):
                        return NotImplemented
                return self.image == other.image and self.classes == other.classes and self.mask == other.mask

        def __add__(self, other: ImageAnnotation) -> ImageAnnotation:
                if not isinstance(other, ImageAnnotation): # type: ignore - pyright complains about the isinstance check being redundant
                        return NotImplemented

                classes: Dict[str, ClassAnnotation] = {}

                for key, value in self.classes.items():
                        classes[key] = value

                for key, value in other.classes.items():
                        if key in classes:
                                classes[key] += value
                        else:
                                classes[key] = value

                return ImageAnnotation(
                        image = self.image,
                        classes = classes,
                        mask = self.mask,
                        uid = self.uid if self.uid is not None else other.uid,
                        metadata = self.metadata
                )

        def to_json(self) -> ImageAnnotationJson:
                """
                Serializes this image annotation into an `ImageAnnotationJson`.
                """
                json: ImageAnnotationJson = {
                        "kind": "ImageAnnotation",
                        "image": self.image.to_json(),
                        "classes": {
                                name: class_annotation.to_json()
                                for name, class_annotation in self.classes.items()
                        }
                }

                if self.mask is not None:
                        json["mask"] = self.mask.to_json()

                if self.uid is not None:
                        json["uid"] = self.uid

                if self.metadata is not None:
                        json["metadata"] = self.metadata

                return json

        def get_visualization_url(self) -> str:
                """
                Generates a URL on the dataTap platform that can be visited to view a
                visualization of this `ImageAnnotation`.
                """
                params = {
                        "annotation": json.dumps(self.to_json(), separators = (",", ":"))
                }

                return f"{Environment.BASE_URI}/visualizer/single#{urlencode(params, quote_via = quote)}"

        def get_comparison_url(self, other: ImageAnnotation) -> str:
                """
                Generates a URL on the dataTap platform that can be visited to view a
                visual comparison of this `ImageAnnotation` (which is treated as the
                "ground truth") and the `other` argument (which is treated as the
                "proposal").

                This method does not check that the two annotations agree on what image
                they are annotating, and will always use this `ImageAnnotation`'s
                image.
                """
                params = {
                        "groundTruth": json.dumps(self.to_json(), separators = (",", ":")),
                        "proposal": json.dumps(other.to_json(), separators = (",", ":"))
                }

                return f"{Environment.BASE_URI}/visualizer/compare#{urlencode(params, quote_via = quote)}"

Class variables

var classes : Mapping[str, ClassAnnotation]

A mapping from class name to the annotations of that class.

var imageImage

The image being annotated.

var mask : Optional[Mask]

An optional region-of-interest mask to indicate that only features within the mask have been annotated.

var metadata : Optional[Mapping[str, Any]]

An optional field for storing metadata on the annotation.

var uid : Optional[str]

A unique identifier for this image annotation.

Static methods

def from_json(json: Mapping[str, Any]) ‑> ImageAnnotation

Constructs an ImageAnnotation from an ImageAnnotationJson.

Expand source code
@staticmethod
def from_json(json: Mapping[str, Any]) -> ImageAnnotation:
        """
        Constructs an `ImageAnnotation` from an `ImageAnnotationJson`.
        """
        return ImageAnnotation(
                image = Image.from_json(json["image"]),
                classes = {
                        class_name: ClassAnnotation.from_json(json["classes"][class_name])
                        for class_name in json["classes"]
                },
                mask = Mask.from_json(json["mask"]) if "mask" in json else None,
                uid = json.get("uid"),
                metadata = json.get("metadata")
        )

Methods

def apply_bounding_box_confidence_threshold(self, threshold: float) ‑> ImageAnnotation

Returns a new image annotation consisting only of the instances and multi-instances that have bounding boxes which either do not have a confidence specified or which have a confience meeting the given threshold.

Expand source code
def apply_bounding_box_confidence_threshold(self, threshold: float) -> ImageAnnotation:
        """
        Returns a new image annotation consisting only of the instances and
        multi-instances that have bounding boxes which either do not have a
        confidence specified or which have a confience meeting the given
        threshold.
        """
        return self.filter_detections(
                instance_filter = lambda instance: (
                        instance.bounding_box is not None
                                and instance.bounding_box.meets_confidence_threshold(threshold)
                ),
                multi_instance_filter = lambda multi_instance: (
                        multi_instance.bounding_box is not None
                                and multi_instance.bounding_box.meets_confidence_threshold(threshold)
                )
        )
def apply_metadata(self, metadata: Mapping[str, Any]) ‑> ImageAnnotation

Returns a new image annotation with the supplied metadata.

Expand source code
def apply_metadata(self, metadata: Mapping[str, Any]) -> ImageAnnotation:
        """
        Returns a new image annotation with the supplied metadata.
        """
        return ImageAnnotation(
                image = self.image,
                mask = self.mask,
                classes = self.classes,
                uid = self.uid,
                metadata = metadata
        )
def apply_segmentation_confidence_threshold(self, threshold: float) ‑> ImageAnnotation

Returns a new image annotation consisting only of the instances and multi-instances that have segmentations which either do not have a confidence specified or which have a confience meeting the given threshold.

Expand source code
def apply_segmentation_confidence_threshold(self, threshold: float) -> ImageAnnotation:
        """
        Returns a new image annotation consisting only of the instances and
        multi-instances that have segmentations which either do not have a
        confidence specified or which have a confience meeting the given
        threshold.
        """
        return self.filter_detections(
                instance_filter = lambda instance: (
                        instance.segmentation is not None
                                and instance.segmentation.meets_confidence_threshold(threshold)
                ),
                multi_instance_filter = lambda multi_instance: (
                        multi_instance.segmentation is not None
                                and multi_instance.segmentation.meets_confidence_threshold(threshold)
                )
        )
def filter_detections(self, *, instance_filter: Callable[[Instance], bool], multi_instance_filter: Callable[[MultiInstance], bool]) ‑> ImageAnnotation

Returns a new image annotation consisting only of the instances and multi-instances that meet the given constraints.

Expand source code
def filter_detections(
        self,
        *,
        instance_filter: Callable[[Instance], bool],
        multi_instance_filter: Callable[[MultiInstance], bool]
) -> ImageAnnotation:
        """
        Returns a new image annotation consisting only of the instances and
        multi-instances that meet the given constraints.
        """
        return ImageAnnotation(
                image = self.image,
                mask = self.mask,
                classes = {
                        class_name: class_annotation.filter_detections(
                                instance_filter = instance_filter,
                                multi_instance_filter = multi_instance_filter
                        )
                        for class_name, class_annotation in self.classes.items()
                },
                uid = self.uid,
                metadata = self.metadata
        )
def get_comparison_url(self, other: ImageAnnotation) ‑> str

Generates a URL on the dataTap platform that can be visited to view a visual comparison of this ImageAnnotation (which is treated as the "ground truth") and the other argument (which is treated as the "proposal").

This method does not check that the two annotations agree on what image they are annotating, and will always use this ImageAnnotation's image.

Expand source code
def get_comparison_url(self, other: ImageAnnotation) -> str:
        """
        Generates a URL on the dataTap platform that can be visited to view a
        visual comparison of this `ImageAnnotation` (which is treated as the
        "ground truth") and the `other` argument (which is treated as the
        "proposal").

        This method does not check that the two annotations agree on what image
        they are annotating, and will always use this `ImageAnnotation`'s
        image.
        """
        params = {
                "groundTruth": json.dumps(self.to_json(), separators = (",", ":")),
                "proposal": json.dumps(other.to_json(), separators = (",", ":"))
        }

        return f"{Environment.BASE_URI}/visualizer/compare#{urlencode(params, quote_via = quote)}"
def get_visualization_url(self) ‑> str

Generates a URL on the dataTap platform that can be visited to view a visualization of this ImageAnnotation.

Expand source code
def get_visualization_url(self) -> str:
        """
        Generates a URL on the dataTap platform that can be visited to view a
        visualization of this `ImageAnnotation`.
        """
        params = {
                "annotation": json.dumps(self.to_json(), separators = (",", ":"))
        }

        return f"{Environment.BASE_URI}/visualizer/single#{urlencode(params, quote_via = quote)}"
def to_json(self) ‑> ImageAnnotationJson

Serializes this image annotation into an ImageAnnotationJson.

Expand source code
def to_json(self) -> ImageAnnotationJson:
        """
        Serializes this image annotation into an `ImageAnnotationJson`.
        """
        json: ImageAnnotationJson = {
                "kind": "ImageAnnotation",
                "image": self.image.to_json(),
                "classes": {
                        name: class_annotation.to_json()
                        for name, class_annotation in self.classes.items()
                }
        }

        if self.mask is not None:
                json["mask"] = self.mask.to_json()

        if self.uid is not None:
                json["uid"] = self.uid

        if self.metadata is not None:
                json["metadata"] = self.metadata

        return json
class ImageAnnotationJson (*args, **kwargs)

The serialized JSON representation of an image annotation.

Expand source code
class ImageAnnotationJson(_ImageAnnotationJsonOptional, TypedDict):
        """
        The serialized JSON representation of an image annotation.
        """

        kind: Literal["ImageAnnotation"]
        image: ImageJson
        classes: Mapping[str, ClassAnnotationJson]

Ancestors

  • builtins.dict

Class variables

var classes : Mapping[str, ClassAnnotationJson]
var imageImageJson
var kind : Literal['ImageAnnotation']
var mask : Sequence[Sequence[Tuple[float, float]]]
var metadata : Mapping[str, Any]
var uid : str
class ImageJson (*args, **kwargs)

The serialized JSON representation of an Image.

Expand source code
class ImageJson(_ImageJsonOptional, TypedDict):
        """
        The serialized JSON representation of an `Image`.
        """
        paths: Sequence[str]

Ancestors

  • builtins.dict

Class variables

var paths : Sequence[str]
var uid : str
class Instance (*, id: Optional[str] = None, bounding_box: Optional[BoundingBox] = None, segmentation: Optional[Segmentation] = None, keypoints: Optional[Mapping[str, Optional[Keypoint]]] = None, attributes: Optional[Mapping[str, AttributeValues]] = None)

A single appearance of an object of a particular class within a given image.

Expand source code
class Instance:
        """
        A single appearance of an object of a particular class within a given image.
        """

        id: Optional[str]
        """
        A unique id for this instance (within the context of its containing
        annotation).  Multiple instances with the same id should be interpreted
        to be the same object.
        """

        bounding_box: Optional[BoundingBox]
        """
        The bounding box of this instance.
        """

        segmentation: Optional[Segmentation]
        """
        The segmentation of this instance.
        """

        keypoints: Optional[Mapping[str, Optional[Keypoint]]]
        """
        A mapping from keypoint name to the keypoint within this instance.  If a key
        maps to `None`, then the annotation is reporting the _absence of_ that
        keypoint (i.e., that it is not visible in the image and does not have an
        inferrable position in the image).
        """

        attributes: Optional[Mapping[str, AttributeValues]]
        """
        A mapping from attribute name to value.
        """

        @staticmethod
        def from_json(json: InstanceJson) -> Instance:
                """
                Creates an `Instance` from an `InstanceJson`.
                """
                return Instance(
                        id = json.get("id"),
                        bounding_box = BoundingBox.from_json(json["boundingBox"]) if "boundingBox" in json else None,
                        segmentation = Segmentation.from_json(json["segmentation"]) if "segmentation" in json else None,
                        keypoints = {
                                name: Keypoint.from_json(keypoint) if keypoint is not None else None
                                for name, keypoint in json["keypoints"].items()
                        } if "keypoints" in json else None,
                        attributes = {
                                k: AttributeValues.from_json(v) for k, v in json["attributes"].items()
                        } if "attributes" in json else None
                )

        def __init__(
                self,
                *,
                id: Optional[str] = None,
                bounding_box: Optional[BoundingBox] = None,
                segmentation: Optional[Segmentation] = None,
                keypoints: Optional[Mapping[str, Optional[Keypoint]]] = None,
                attributes: Optional[Mapping[str, AttributeValues]] = None
        ):
                self.id = id
                self.bounding_box = bounding_box
                self.segmentation = segmentation
                self.keypoints = keypoints
                self.attributes = attributes

        def __repr__(self) -> str:
                return basic_repr(
                        "Instance",
                        id = self.id,
                        bounding_box = self.bounding_box,
                        segmentation = self.segmentation,
                        keypoints = self.keypoints,
                        attributes = self.attributes
                )

        def __eq__(self, other: object) -> bool:
                if not isinstance(other, Instance):
                        return NotImplemented
                return (
                        self.id == other.id
                        and self.bounding_box == other.bounding_box
                        and self.segmentation == other.segmentation
                        and self.keypoints == other.keypoints
                        and self.attributes == other.attributes
                )

        def to_json(self) -> InstanceJson:
                """
                Serializes an `Instance` into an `InstanceJson`.
                """
                json: InstanceJson = {}

                if self.id is not None:
                        json["id"] = self.id

                if self.bounding_box is not None:
                        json["boundingBox"] = self.bounding_box.to_json()

                if self.segmentation is not None:
                        json["segmentation"] = self.segmentation.to_json()

                if self.keypoints is not None:
                        keypoints: Dict[str, Optional[KeypointJson]] = {}

                        for name, keypoint in self.keypoints.items():
                                keypoints[name] = keypoint.to_json() if keypoint is not None else None

                        json["keypoints"] = keypoints

                if self.attributes is not None:
                        json["attributes"] = {
                                k: v.to_json() for k, v in self.attributes.items()
                        }

                return json

Class variables

var attributes : Optional[Mapping[str, AttributeValues]]

A mapping from attribute name to value.

var bounding_box : Optional[BoundingBox]

The bounding box of this instance.

var id : Optional[str]

A unique id for this instance (within the context of its containing annotation). Multiple instances with the same id should be interpreted to be the same object.

var keypoints : Optional[Mapping[str, Optional[Keypoint]]]

A mapping from keypoint name to the keypoint within this instance. If a key maps to None, then the annotation is reporting the absence of that keypoint (i.e., that it is not visible in the image and does not have an inferrable position in the image).

var segmentation : Optional[Segmentation]

The segmentation of this instance.

Static methods

def from_json(json: InstanceJson) ‑> Instance

Creates an Instance from an InstanceJson.

Expand source code
@staticmethod
def from_json(json: InstanceJson) -> Instance:
        """
        Creates an `Instance` from an `InstanceJson`.
        """
        return Instance(
                id = json.get("id"),
                bounding_box = BoundingBox.from_json(json["boundingBox"]) if "boundingBox" in json else None,
                segmentation = Segmentation.from_json(json["segmentation"]) if "segmentation" in json else None,
                keypoints = {
                        name: Keypoint.from_json(keypoint) if keypoint is not None else None
                        for name, keypoint in json["keypoints"].items()
                } if "keypoints" in json else None,
                attributes = {
                        k: AttributeValues.from_json(v) for k, v in json["attributes"].items()
                } if "attributes" in json else None
        )

Methods

def to_json(self) ‑> InstanceJson

Serializes an Instance into an InstanceJson.

Expand source code
def to_json(self) -> InstanceJson:
        """
        Serializes an `Instance` into an `InstanceJson`.
        """
        json: InstanceJson = {}

        if self.id is not None:
                json["id"] = self.id

        if self.bounding_box is not None:
                json["boundingBox"] = self.bounding_box.to_json()

        if self.segmentation is not None:
                json["segmentation"] = self.segmentation.to_json()

        if self.keypoints is not None:
                keypoints: Dict[str, Optional[KeypointJson]] = {}

                for name, keypoint in self.keypoints.items():
                        keypoints[name] = keypoint.to_json() if keypoint is not None else None

                json["keypoints"] = keypoints

        if self.attributes is not None:
                json["attributes"] = {
                        k: v.to_json() for k, v in self.attributes.items()
                }

        return json
class InstanceJson (*args, **kwargs)

The JSON serialization of an Instance.

Expand source code
class InstanceJson(TypedDict, total = False):
        """
        The JSON serialization of an `Instance`.
        """
        id: str
        boundingBox: BoundingBoxJson
        segmentation: SegmentationJson
        keypoints: Mapping[str, Optional[KeypointJson]]
        attributes: Mapping[str, AttributeValuesJson]

Ancestors

  • builtins.dict

Class variables

var attributes : Mapping[str, Union[Sequence[AttributeValueJson], str]]
var boundingBoxBoundingBoxJson
var id : str
var keypoints : Mapping[str, Optional[KeypointJson]]
var segmentationSegmentationJson
class Keypoint (point: Point, *, occluded: Optional[bool] = None, confidence: Optional[float] = None)

An object representing a specific keypoint in a particular instance.

Expand source code
class Keypoint:
        """
        An object representing a specific keypoint in a particular instance.
        """

        point: Point
        """
        The point in the image where this keypoint appears.
        """

        occluded: Optional[bool]
        """
        Whether this keypoint is occluded.

        If `False`, the keypoint is visible within the image.
        If `True`, the keypoint is not visible in the image because it is blocked by some other object,
        but has an inferrable position that would lie within the frame of the image.
        If `None`, then the data source did not differentiate between occluded and unoccluded keypoints.
        """

        confidence: Optional[float]
        """
        The confidence associated with this keypoint.
        """

        @staticmethod
        def from_json(json: KeypointJson) -> Keypoint:
                """
                Creates a `Keypoint` from a `KeypointJson`.
                """
                return Keypoint(
                        Point.from_json(json["point"]),
                        occluded = json.get("occluded"),
                        confidence = json.get("confidence")
                )

        def __init__(self, point: Point, *, occluded: Optional[bool] = None, confidence: Optional[float] = None):
                self.point = point
                self.occluded = occluded
                self.confidence = confidence

                self.point.assert_valid()

        def __repr__(self) -> str:
                return basic_repr("Keypoint", self.point, occluded = self.occluded, confidence = self.confidence)

        def __eq__(self, other: object) -> bool:
                if not isinstance(other, Keypoint):
                        return NotImplemented
                return self.point == other.point and self.occluded == other.occluded and self.confidence == other.confidence

        def to_json(self) -> KeypointJson:
                """
                Serializes this object into a `KeypointJson`.
                """
                json: KeypointJson = {
                        "point": self.point.to_json()
                }

                if self.occluded is not None:
                        json["occluded"] = self.occluded

                if self.confidence is not None:
                        json["confidence"] = self.confidence

                return json

Class variables

var confidence : Optional[float]

The confidence associated with this keypoint.

var occluded : Optional[bool]

Whether this keypoint is occluded.

If False, the keypoint is visible within the image. If True, the keypoint is not visible in the image because it is blocked by some other object, but has an inferrable position that would lie within the frame of the image. If None, then the data source did not differentiate between occluded and unoccluded keypoints.

var pointPoint

The point in the image where this keypoint appears.

Static methods

def from_json(json: KeypointJson) ‑> Keypoint

Creates a Keypoint from a KeypointJson.

Expand source code
@staticmethod
def from_json(json: KeypointJson) -> Keypoint:
        """
        Creates a `Keypoint` from a `KeypointJson`.
        """
        return Keypoint(
                Point.from_json(json["point"]),
                occluded = json.get("occluded"),
                confidence = json.get("confidence")
        )

Methods

def to_json(self) ‑> KeypointJson

Serializes this object into a KeypointJson.

Expand source code
def to_json(self) -> KeypointJson:
        """
        Serializes this object into a `KeypointJson`.
        """
        json: KeypointJson = {
                "point": self.point.to_json()
        }

        if self.occluded is not None:
                json["occluded"] = self.occluded

        if self.confidence is not None:
                json["confidence"] = self.confidence

        return json
class KeypointJson (*args, **kwargs)

The JSON serialization of a Keypoint.

Expand source code
class KeypointJson(_KeypointJsonOptional, TypedDict):
        """
        The JSON serialization of a `Keypoint`.
        """
        point: PointJson

Ancestors

  • builtins.dict

Class variables

var confidence : float
var occluded : bool
var point : Tuple[float, float]
class MultiInstance (*, bounding_box: Optional[BoundingBox] = None, segmentation: Optional[Segmentation] = None, count: Optional[int] = None)

An appearance of a group of objects of a particular class in a particular image.

There is not a strict definition as to when a group of instances should be categorized as a multi-instance. As such, when constructing a dataset, it is best to ensure that all of the DataSources agree on what constitutes a MultiInstance. These are most often used in public datasets when the cost of annotating every instance would be too high.

Expand source code
class MultiInstance:
        """
        An appearance of a group of objects of a particular class in a particular image.

        There is not a strict definition as to when a group of instances should be categorized as a multi-instance.
        As such, when constructing a dataset, it is best to ensure that all of the `DataSource`s agree on what
        constitutes a `MultiInstance`. These are most often used in public datasets when the cost of annotating
        every instance would be too high.
        """

        bounding_box: Optional[BoundingBox]
        """
        The bounding box of this multi-instance.
        """

        segmentation: Optional[Segmentation]
        """
        The segmentation of this multi-instance.
        """

        count: Optional[int]
        """
        A count of how many true instances are encapsulated in this multi-instance.
        """

        @staticmethod
        def from_json(json: MultiInstanceJson) -> MultiInstance:
                """
                Creates a `MultiInstance` from a `MultiInstanceJson`.
                """
                return MultiInstance(
                        bounding_box = BoundingBox.from_json(json["boundingBox"]) if "boundingBox" in json else None,
                        segmentation = Segmentation.from_json(json["segmentation"]) if "segmentation" in json else None,
                        count = json.get("count")
                )

        def __init__(
                self,
                *,
                bounding_box: Optional[BoundingBox] = None,
                segmentation: Optional[Segmentation] = None,
                count: Optional[int] = None
        ):
                self.bounding_box = bounding_box
                self.segmentation = segmentation
                self.count = count

        def __repr__(self) -> str:
                return basic_repr(
                        "MultiInstance",
                        bounding_box = self.bounding_box,
                        segmentation = self.segmentation,
                        count = self.count
                )

        def __eq__(self, other: object) -> bool:
                if not isinstance(other, MultiInstance):
                        return NotImplemented
                return self.bounding_box == other.bounding_box and self.segmentation == other.segmentation and self.count == other.count

        def to_json(self) -> MultiInstanceJson:
                """
                Serializes this object as a `MultiInstanceJson`.
                """
                json: MultiInstanceJson = {}

                if self.bounding_box is not None:
                        json["boundingBox"] = self.bounding_box.to_json()

                if self.segmentation is not None:
                        json["segmentation"] = self.segmentation.to_json()

                if self.count is not None:
                        json["count"] = self.count

                return json

Class variables

var bounding_box : Optional[BoundingBox]

The bounding box of this multi-instance.

var count : Optional[int]

A count of how many true instances are encapsulated in this multi-instance.

var segmentation : Optional[Segmentation]

The segmentation of this multi-instance.

Static methods

def from_json(json: MultiInstanceJson) ‑> MultiInstance
Expand source code
@staticmethod
def from_json(json: MultiInstanceJson) -> MultiInstance:
        """
        Creates a `MultiInstance` from a `MultiInstanceJson`.
        """
        return MultiInstance(
                bounding_box = BoundingBox.from_json(json["boundingBox"]) if "boundingBox" in json else None,
                segmentation = Segmentation.from_json(json["segmentation"]) if "segmentation" in json else None,
                count = json.get("count")
        )

Methods

def to_json(self) ‑> MultiInstanceJson

Serializes this object as a MultiInstanceJson.

Expand source code
def to_json(self) -> MultiInstanceJson:
        """
        Serializes this object as a `MultiInstanceJson`.
        """
        json: MultiInstanceJson = {}

        if self.bounding_box is not None:
                json["boundingBox"] = self.bounding_box.to_json()

        if self.segmentation is not None:
                json["segmentation"] = self.segmentation.to_json()

        if self.count is not None:
                json["count"] = self.count

        return json
class MultiInstanceJson (*args, **kwargs)

The JSON serialization of a MultiInstance.

Expand source code
class MultiInstanceJson(TypedDict, total = False):
        """
        The JSON serialization of a `MultiInstance`.
        """
        boundingBox: BoundingBoxJson
        segmentation: SegmentationJson
        count: int

Ancestors

  • builtins.dict

Class variables

var boundingBoxBoundingBoxJson
var count : int
var segmentationSegmentationJson
class Segmentation (mask: Mask, *, confidence: Optional[float] = None)

A Segmentation represents the area within an image taken up by a detection, specified as a Mask.

Expand source code
class Segmentation:
        """
        A `Segmentation` represents the area within an image taken up by a
        detection, specified as a `Mask`.
        """

        mask: Mask
        """
        The area within the image where the corresponding detection appears.
        """

        confidence: Optional[float]
        """
        The confidence associated with this segmentation.
        """

        @staticmethod
        def from_json(json: SegmentationJson) -> Segmentation:
                """
                Constructs a `Segmentation` from a `SegmentationJson`.
                """
                return Segmentation(
                        Mask.from_json(json["mask"]),
                        confidence = json.get("confidence")
                )

        def __init__(self, mask: Mask, *, confidence: Optional[float] = None):
                self.mask = mask
                self.confidence = confidence

                self.mask.assert_valid()

        def __repr__(self) -> str:
                return basic_repr("Segmentation", self.mask, confidence = self.confidence)

        def __eq__(self, other: object) -> bool:
                if not isinstance(other, Segmentation):
                        return NotImplemented
                return self.mask == other.mask and self.confidence == other.confidence

        def to_json(self) -> SegmentationJson:
                """
                Serializes this `Segmentation` to a `SegmentationJson`.
                """
                json: SegmentationJson = {
                        "mask": self.mask.to_json()
                }

                if self.confidence is not None:
                        json["confidence"] = self.confidence

                return json

        def meets_confidence_threshold(self, threshold: float) -> bool:
                """
                Returns `True` if and only if the confidence of this segmentation is
                either unset or is at least the given `threshold`.
                """
                return self.confidence is None or self.confidence >= threshold

Class variables

var confidence : Optional[float]

The confidence associated with this segmentation.

var maskMask

The area within the image where the corresponding detection appears.

Static methods

def from_json(json: SegmentationJson) ‑> Segmentation

Constructs a Segmentation from a SegmentationJson.

Expand source code
@staticmethod
def from_json(json: SegmentationJson) -> Segmentation:
        """
        Constructs a `Segmentation` from a `SegmentationJson`.
        """
        return Segmentation(
                Mask.from_json(json["mask"]),
                confidence = json.get("confidence")
        )

Methods

def meets_confidence_threshold(self, threshold: float) ‑> bool

Returns True if and only if the confidence of this segmentation is either unset or is at least the given threshold.

Expand source code
def meets_confidence_threshold(self, threshold: float) -> bool:
        """
        Returns `True` if and only if the confidence of this segmentation is
        either unset or is at least the given `threshold`.
        """
        return self.confidence is None or self.confidence >= threshold
def to_json(self) ‑> SegmentationJson

Serializes this Segmentation to a SegmentationJson.

Expand source code
def to_json(self) -> SegmentationJson:
        """
        Serializes this `Segmentation` to a `SegmentationJson`.
        """
        json: SegmentationJson = {
                "mask": self.mask.to_json()
        }

        if self.confidence is not None:
                json["confidence"] = self.confidence

        return json
class SegmentationJson (*args, **kwargs)

The serialized JSON representation of a segmentation.

Expand source code
class SegmentationJson(_SegmentationJsonOptional, TypedDict):
        """
        The serialized JSON representation of a segmentation.
        """
        mask: MaskJson

Ancestors

  • builtins.dict

Class variables

var confidence : float
var mask : Sequence[Sequence[Tuple[float, float]]]
class Video (*, uid: Optional[str] = None, paths: Optional[Sequence[str]] = None, frames: Optional[Sequence[Image]] = None)

The Video class contains information about what Video was labeled by a given annotation. It also includes utilities for loading and manipulating Videos.

Expand source code
class Video:
        """
        The `Video` class contains information about what Video was
        labeled by a given annotation. It also includes utilities
        for loading and manipulating Videos.
        """

        uid: Optional[str]
        """
        A unique ID for this Video.
        """

        paths: Optional[Sequence[str]]
        """
        A sequence of URIs where the media can be found. The loader
        will try them in order until it finds one it can load.

        Supported schemes include `http(s):`, `s3:`
        """

        frames: Optional[Sequence[Image]]
        """
        A sequence of images representing the video.
        """

        @staticmethod
        def from_json(json: VideoJson) -> Video:
                """
                Creates an `Video` from an `VideoJson`.
                """
                return Video(
                        uid = json.get("uid"),
                        paths = json.get("paths"),
                        frames = [Image.from_json(frame) for frame in json["frames"]] if "frames" in json else None
                )

        def __init__(
                self,
                *,
                uid: Optional[str] = None,
                paths: Optional[Sequence[str]] = None,
                frames: Optional[Sequence[Image]] = None
        ):
                self.uid = uid
                self.paths = paths
                self.frames = frames

        def __repr__(self) -> str:
                return basic_repr("Video", uid = self.uid, paths = self.paths, frames = self.frames)

        def __eq__(self, other: object) -> bool:
                if not isinstance(other, Video):
                        return NotImplemented
                return self.paths == other.paths

        def to_json(self) -> VideoJson:
                """
                Serializes this `Video` into an `VideoJson`.
                """
                json: VideoJson = {}

                if self.uid is not None:
                        json["uid"] = self.uid

                if self.paths is not None:
                        json["paths"] = self.paths

                if self.frames is not None:
                        json["frames"] = [frame.to_json() for frame in self.frames]

                return json

Class variables

var frames : Optional[Sequence[Image]]

A sequence of images representing the video.

var paths : Optional[Sequence[str]]

A sequence of URIs where the media can be found. The loader will try them in order until it finds one it can load.

Supported schemes include http(s):, s3:

var uid : Optional[str]

A unique ID for this Video.

Static methods

def from_json(json: VideoJson) ‑> Video

Creates an Video from an VideoJson.

Expand source code
@staticmethod
def from_json(json: VideoJson) -> Video:
        """
        Creates an `Video` from an `VideoJson`.
        """
        return Video(
                uid = json.get("uid"),
                paths = json.get("paths"),
                frames = [Image.from_json(frame) for frame in json["frames"]] if "frames" in json else None
        )

Methods

def to_json(self) ‑> VideoJson

Serializes this Video into an VideoJson.

Expand source code
def to_json(self) -> VideoJson:
        """
        Serializes this `Video` into an `VideoJson`.
        """
        json: VideoJson = {}

        if self.uid is not None:
                json["uid"] = self.uid

        if self.paths is not None:
                json["paths"] = self.paths

        if self.frames is not None:
                json["frames"] = [frame.to_json() for frame in self.frames]

        return json
class VideoAnnotation (*, video: Video, frames: Sequence[FrameAnnotation], uid: Optional[str] = None, metadata: Optional[Mapping[str, Any]] = None)

A collection of class annotations that annotate a given image.

Expand source code
class VideoAnnotation:
        """
        A collection of class annotations that annotate a given image.
        """

        video: Video
        """
        The video being annotated.
        """

        uid: Optional[str]
        """
        A unique identifier for this image annotation.
        """

        metadata: Optional[Mapping[str, Any]]
        """
        An optional field for storing metadata on the annotation.
        """

        @staticmethod
        def from_json(json: Mapping[str, Any]) -> VideoAnnotation:
                """
                Constructs an `VideoAnnotation` from an `VideoAnnotationJson`.
                """
                return VideoAnnotation(
                        video = Video.from_json(json["video"]),
                        frames = [FrameAnnotation.from_json(frame) for frame in json["frames"]],
                        uid = json.get("uid"),
                        metadata = json.get("metadata")
                )

        def __init__(
                self,
                *,
                video: Video,
                frames: Sequence[FrameAnnotation],
                uid: Optional[str] = None,
                metadata: Optional[Mapping[str, Any]] = None
        ):
                self.video = video
                self.frames = frames
                self.uid = uid
                self.metadata = metadata

        def filter_detections(
                self,
                *,
                instance_filter: Callable[[Instance], bool],
                multi_instance_filter: Callable[[MultiInstance], bool]
        ) -> VideoAnnotation:
                """
                Returns a new image annotation consisting only of the instances and
                multi-instances that meet the given constraints.
                """
                return VideoAnnotation(
                        video = self.video,
                        frames = [
                                frame.filter_detections(
                                        instance_filter = instance_filter,
                                        multi_instance_filter = multi_instance_filter
                                )
                                for frame in self.frames
                        ],
                        uid = self.uid,
                        metadata = self.metadata
                )

        def apply_bounding_box_confidence_threshold(self, threshold: float) -> VideoAnnotation:
                """
                Returns a new image annotation consisting only of the instances and
                multi-instances that have bounding boxes which either do not have a
                confidence specified or which have a confience meeting the given
                threshold.
                """
                return self.filter_detections(
                        instance_filter = lambda instance: (
                                instance.bounding_box is not None
                                        and instance.bounding_box.meets_confidence_threshold(threshold)
                        ),
                        multi_instance_filter = lambda multi_instance: (
                                multi_instance.bounding_box is not None
                                        and multi_instance.bounding_box.meets_confidence_threshold(threshold)
                        )
                )

        def apply_segmentation_confidence_threshold(self, threshold: float) -> VideoAnnotation:
                """
                Returns a new image annotation consisting only of the instances and
                multi-instances that have segmentations which either do not have a
                confidence specified or which have a confience meeting the given
                threshold.
                """
                return self.filter_detections(
                        instance_filter = lambda instance: (
                                instance.segmentation is not None
                                        and instance.segmentation.meets_confidence_threshold(threshold)
                        ),
                        multi_instance_filter = lambda multi_instance: (
                                multi_instance.segmentation is not None
                                        and multi_instance.segmentation.meets_confidence_threshold(threshold)
                        )
                )

        def apply_metadata(self, metadata: Mapping[str, Any]) -> VideoAnnotation:
                """
                Returns a new image annotation with the supplied metadata.
                """
                return VideoAnnotation(
                        video = self.video,
                        frames = self.frames,
                        uid = self.uid,
                        metadata = metadata
                )

        def __repr__(self) -> str:
                return basic_repr(
                        "VideoAnnotation",
                        uid = self.uid,
                        video = self.video,
                        frames = self.frames,
                        metadata = self.metadata
                )

        def __eq__(self, other: object) -> bool:
                if not isinstance(other, VideoAnnotation):
                        return NotImplemented
                return (
                        self.video == other.video
                        and self.frames == other.frames
                        and self.uid == other.uid
                        and self.metadata == other.metadata
                )

        def __add__(self, other: VideoAnnotation) -> VideoAnnotation:
                if not isinstance(other, VideoAnnotation): # type: ignore - pyright complains about the isinstance check being redundant
                        return NotImplemented

                if len(self.frames) != len(other.frames):
                        raise ValueError("Unable to merge VideoAnnotations with different number of frames")

                return VideoAnnotation(
                        video = self.video,
                        frames = [
                                frame1 + frame2
                                for frame1, frame2 in zip(self.frames, other.frames)
                        ],
                        uid = self.uid,
                        metadata = self.metadata
                )

        def to_json(self) -> VideoAnnotationJson:
                """
                Serializes this image annotation into an `VideoAnnotationJson`.
                """
                json: VideoAnnotationJson = {
                        "kind": "VideoAnnotation",
                        "video": self.video.to_json(),
                        "frames": [frame.to_json() for frame in self.frames]
                }

                if self.uid is not None:
                        json["uid"] = self.uid

                if self.metadata is not None:
                        json["metadata"] = self.metadata

                return json

Class variables

var metadata : Optional[Mapping[str, Any]]

An optional field for storing metadata on the annotation.

var uid : Optional[str]

A unique identifier for this image annotation.

var videoVideo

The video being annotated.

Static methods

def from_json(json: Mapping[str, Any]) ‑> VideoAnnotation

Constructs an VideoAnnotation from an VideoAnnotationJson.

Expand source code
@staticmethod
def from_json(json: Mapping[str, Any]) -> VideoAnnotation:
        """
        Constructs an `VideoAnnotation` from an `VideoAnnotationJson`.
        """
        return VideoAnnotation(
                video = Video.from_json(json["video"]),
                frames = [FrameAnnotation.from_json(frame) for frame in json["frames"]],
                uid = json.get("uid"),
                metadata = json.get("metadata")
        )

Methods

def apply_bounding_box_confidence_threshold(self, threshold: float) ‑> VideoAnnotation

Returns a new image annotation consisting only of the instances and multi-instances that have bounding boxes which either do not have a confidence specified or which have a confience meeting the given threshold.

Expand source code
def apply_bounding_box_confidence_threshold(self, threshold: float) -> VideoAnnotation:
        """
        Returns a new image annotation consisting only of the instances and
        multi-instances that have bounding boxes which either do not have a
        confidence specified or which have a confience meeting the given
        threshold.
        """
        return self.filter_detections(
                instance_filter = lambda instance: (
                        instance.bounding_box is not None
                                and instance.bounding_box.meets_confidence_threshold(threshold)
                ),
                multi_instance_filter = lambda multi_instance: (
                        multi_instance.bounding_box is not None
                                and multi_instance.bounding_box.meets_confidence_threshold(threshold)
                )
        )
def apply_metadata(self, metadata: Mapping[str, Any]) ‑> VideoAnnotation

Returns a new image annotation with the supplied metadata.

Expand source code
def apply_metadata(self, metadata: Mapping[str, Any]) -> VideoAnnotation:
        """
        Returns a new image annotation with the supplied metadata.
        """
        return VideoAnnotation(
                video = self.video,
                frames = self.frames,
                uid = self.uid,
                metadata = metadata
        )
def apply_segmentation_confidence_threshold(self, threshold: float) ‑> VideoAnnotation

Returns a new image annotation consisting only of the instances and multi-instances that have segmentations which either do not have a confidence specified or which have a confience meeting the given threshold.

Expand source code
def apply_segmentation_confidence_threshold(self, threshold: float) -> VideoAnnotation:
        """
        Returns a new image annotation consisting only of the instances and
        multi-instances that have segmentations which either do not have a
        confidence specified or which have a confience meeting the given
        threshold.
        """
        return self.filter_detections(
                instance_filter = lambda instance: (
                        instance.segmentation is not None
                                and instance.segmentation.meets_confidence_threshold(threshold)
                ),
                multi_instance_filter = lambda multi_instance: (
                        multi_instance.segmentation is not None
                                and multi_instance.segmentation.meets_confidence_threshold(threshold)
                )
        )
def filter_detections(self, *, instance_filter: Callable[[Instance], bool], multi_instance_filter: Callable[[MultiInstance], bool]) ‑> VideoAnnotation

Returns a new image annotation consisting only of the instances and multi-instances that meet the given constraints.

Expand source code
def filter_detections(
        self,
        *,
        instance_filter: Callable[[Instance], bool],
        multi_instance_filter: Callable[[MultiInstance], bool]
) -> VideoAnnotation:
        """
        Returns a new image annotation consisting only of the instances and
        multi-instances that meet the given constraints.
        """
        return VideoAnnotation(
                video = self.video,
                frames = [
                        frame.filter_detections(
                                instance_filter = instance_filter,
                                multi_instance_filter = multi_instance_filter
                        )
                        for frame in self.frames
                ],
                uid = self.uid,
                metadata = self.metadata
        )
def to_json(self) ‑> VideoAnnotationJson

Serializes this image annotation into an VideoAnnotationJson.

Expand source code
def to_json(self) -> VideoAnnotationJson:
        """
        Serializes this image annotation into an `VideoAnnotationJson`.
        """
        json: VideoAnnotationJson = {
                "kind": "VideoAnnotation",
                "video": self.video.to_json(),
                "frames": [frame.to_json() for frame in self.frames]
        }

        if self.uid is not None:
                json["uid"] = self.uid

        if self.metadata is not None:
                json["metadata"] = self.metadata

        return json
class VideoAnnotationJson (*args, **kwargs)

The serialized JSON representation of an video annotation.

Expand source code
class VideoAnnotationJson(_VideoAnnotationJsonOptional, TypedDict):
        """
        The serialized JSON representation of an video annotation.
        """

        kind: Literal["VideoAnnotation"]
        video: VideoJson
        frames: Sequence[FrameAnnotationJson]

Ancestors

  • builtins.dict

Class variables

var frames : Sequence[FrameAnnotationJson]
var kind : Literal['VideoAnnotation']
var metadata : Mapping[str, Any]
var uid : str
var videoVideoJson
class VideoJson (*args, **kwargs)

The serialized JSON representation of an Video.

Expand source code
class VideoJson(TypedDict, total = False):
        """
        The serialized JSON representation of an `Video`.
        """

        uid: str
        paths: Sequence[str]
        frames: Sequence[ImageJson]

Ancestors

  • builtins.dict

Class variables

var frames : Sequence[ImageJson]
var paths : Sequence[str]
var uid : str