Annotation

class Annotation[source]

Bases: object

Annotation for a single image. Annotation object is immutable.

Parameters
img_size : Tuple[int, int] or List[int, int]

Size of the image (height, width).

labels : List[Label]

List of Label objects.

img_tags : TagCollection or List[Tag]

TagCollection object or list of Tag objects.

img_description : str, optional

Image description.

Raises

TypeError, if image size is not tuple or list

Usage example
# Simple Annotation example
import supervisely as sly

height, width = 500, 700
ann = sly.Annotation((height, width))

# More complex Annotation example
# TagCollection
meta_lemon = sly.TagMeta('lemon_tag', sly.TagValueType.ANY_STRING)
tag_lemon = sly.Tag(meta_lemon, 'Hello')
tags = sly.TagCollection([tag_lemon])
# or tags = [tag_lemon]

# ObjClass
class_lemon = sly.ObjClass('lemon', sly.Rectangle)

# Label
label_lemon = sly.Label(sly.Rectangle(100, 100, 200, 200), class_lemon)

# Annotation
height, width = 300, 400
ann = sly.Annotation((height, width), [label_lemon], tags, 'example annotaion')
# 'points': {'exterior': [[100, 100], [200, 200]], 'interior': []}

# If Label geometry is out of image size bounds, it will be cropped
label_lemon = sly.Label(sly.Rectangle(100, 100, 700, 900), class_lemon)
height, width = 300, 400

ann = sly.Annotation((height, width), [label_lemon], tags, 'example annotaion')
# 'points': {'exterior': [[100, 100], [399, 299]], 'interior': []}

Methods

add_bg_object

add_label

Clones Annotation and adds a new Label.

add_labels

Clones Annotation and adds a new Labels.

add_pixelwise_score_label

Add label to the pixelwise_scores_labels and return the copy of the current Annotation object.

add_pixelwise_score_labels

Add_pixelwise_score_labels extend list of the labels of the pixelwise_scores_labels and return the copy of the current Annotation object.

add_tag

Clones Annotation and adds a new Tag.

add_tags

Clones Annotation and adds a new list of Tags.

bboxes_to_imgaug

Convert current annotation objects boxes to BoundingBoxesOnImage format.

clone

Makes a copy of Annotation with new fields, if fields are given, otherwise it will use fields of the original Annotation.

crop_labels

Crops Labels of the current Annotation.

delete_label

Clones Annotation with removed Label.

delete_tag

Clones Annotation with removed Tag.

delete_tag_by_name

Clones Annotation with removed Tag by it's name.

delete_tags

Clones Annotation with removed Tags.

delete_tags_by_name

Clones Annotation and removes Tags by their names.

discard_bindings

Remove binding keys from all labels.

draw

Draws current Annotation on image.

draw_class_idx_rgb

Draws current Annotation on render.

draw_contour

Draws geometry contour of Annotation on image.

draw_pretty

Draws current Annotation on image with contour.

filter_labels_by_classes

Filter annotation labels by given classes names.

filter_labels_by_min_side

Filters Labels of the current Annotation by side.

fliplr

Flips the current Annotation horizontally.

flipud

Flips the current Annotation vertically.

from_img_path

Creates empty Annotation from image.

from_imgaug

Create Annotation from image and SegmentationMapsOnImage, BoundingBoxesOnImage data or ProjectMeta.

from_json

Convert a json dict to Annotation.

get_bindings

Returns dictionary with bindings keys as keys and list of labels as values.

get_label_by_id

Get Label from current Annotation by sly_id.

is_empty

Check whether annotation contains labels or tags, or not.

load_json_file

Loads json file and converts it to Annotation.

masks_to_imgaug

Convert current annotation objects masks to SegmentationMapsOnImage format.

merge

Merge current Annotation with another Annotation.

relative_crop

Crops current Annotation and with image size (height, width) changes.

resize

Resizes current Annotation.

rotate

Rotates current Annotation.

scale

Scales current Annotation with the given factor.

stat_area

Get statistics about color area representation on the given render for the current Annotation.

stat_class_count

Get statistics about number of each class in Annotation.

to_detection_task

Convert Annotation classes geometries according to mapping dict and checking nonoverlapping masks.

to_indexed_color_mask

Draw current Annotation on image and save it in PIL format.

to_json

Convert the Annotation to a json dict.

to_nonoverlapping_masks

Create new annotation with non-overlapping labels masks.

to_segmentation_task

Convert Annotation classes by joining labels with same object classes to one label.

transform_labels

Transform labels and change image size in current Annotation object and return the copy of the current Annotation object.

Attributes

custom_data

image_id

Id of the image.

img_description

Image description.

img_size

Size of the image (height, width).

img_tags

Image tags.

labels

Labels on annotation.

pixelwise_scores_labels

add_bg_object(bg_obj_class)[source]
add_label(label)[source]

Clones Annotation and adds a new Label.

Parameters
label : Label

Label to be added.

Returns

New instance of Annotation

Return type

Annotation

Usage Example
import supervisely as sly

ann = sly.Annotation((300, 600))

# Create Label
class_kiwi = sly.ObjClass('kiwi', sly.Rectangle)
label_kiwi = sly.Label(sly.Rectangle(0, 0, 300, 300), class_kiwi)

# Add label to Annotation
# Remember that Annotation object is immutable, and we need to assign new instance of Annotation to a new variable
new_ann = ann.add_label(label_kiwi)
add_labels(labels)[source]

Clones Annotation and adds a new Labels.

Parameters
labels : List[Label]

List of Label objects to be added.

Returns

New instance of Annotation

Return type

Annotation

Usage Example
import supervisely as sly

ann = sly.Annotation((300, 600))

# Create Labels
class_kiwi = sly.ObjClass('kiwi', sly.Rectangle)
label_kiwi = sly.Label(sly.Rectangle(0, 0, 300, 300), class_kiwi)

class_lemon = sly.ObjClass('lemon', sly.Rectangle)
label_lemon = sly.Label(sly.Rectangle(0, 0, 500, 600), class_lemon)

# Add labels to Annotation
# Remember that Annotation object is immutable, and we need to assign new instance of Annotation to a new variable
new_ann = ann.add_labels([label_kiwi, label_lemon])
add_pixelwise_score_label(label)[source]

Add label to the pixelwise_scores_labels and return the copy of the current Annotation object. :type label: Label :param label: Label class object to be added :rtype: Annotation :return: Annotation class object with the new list of the pixelwise_scores_labels

add_pixelwise_score_labels(labels)[source]

Add_pixelwise_score_labels extend list of the labels of the pixelwise_scores_labels and return the copy of the current Annotation object. :type labels: List[Label] :param labels: list of the Label class objects to be added :rtype: Annotation :return: Annotation class object with the new list of the pixelwise_scores_labels

add_tag(tag)[source]

Clones Annotation and adds a new Tag.

Parameters
tag : Tag

Tag object to be added.

Returns

New instance of Annotation

Return type

Annotation

Usage Example
import supervisely as sly

ann = sly.Annotation((300, 600))

# Create Tag
meta_message = sly.TagMeta('Message', sly.TagValueType.ANY_STRING)
tag_message = sly.Tag(meta_message, 'Hello')

# Add Tag to Annotation
# Remember that Annotation object is immutable, and we need to assign new instance of Annotation to a new variable
new_ann = ann.add_tag(tag_message)
add_tags(tags)[source]

Clones Annotation and adds a new list of Tags.

Parameters
tags : List[Tag]

List of Tags to be added.

Returns

New instance of Annotation

Return type

Annotation

Usage Example
import supervisely as sly

ann = sly.Annotation((300, 600))

# Create Tags
meta_message = sly.TagMeta('Message', sly.TagValueType.ANY_STRING)
meta_alert = sly.TagMeta('Alert', sly.TagValueType.NONE)

tag_message = sly.Tag(meta_message, 'Hello')
tag_alert = sly.Tag(meta_alert)

# Add Tags to Annotation
# Remember that Annotation object is immutable, and we need to assign new instance of Annotation to a new variable
new_ann = ann.add_tags([tag_message, tag_alert])
bboxes_to_imgaug()[source]

Convert current annotation objects boxes to BoundingBoxesOnImage format.

Returns

BoundingBoxesOnImage, otherwise None

Return type

BoundingBoxesOnImage or NoneType

clone(img_size=None, labels=None, img_tags=None, img_description=None, pixelwise_scores_labels=None, custom_data=None, image_id=None)[source]

Makes a copy of Annotation with new fields, if fields are given, otherwise it will use fields of the original Annotation.

Parameters
img_size : Tuple[int, int] or List[int, int]

Size of the image (height, width).

labels : List[Label]

List of Label objects.

img_tags : TagCollection or List[Tag]

TagCollection object or list of Tag objects.

img_description : str, optional

Image description.

Returns

New instance of Annotation

Return type

Annotation

Usage Example
import supervisely as sly

ann = sly.Annotation((300, 400))

# Let's clone our Annotation with Label
class_kiwi = sly.ObjClass('kiwi', sly.Rectangle)
label_kiwi = sly.Label(sly.Rectangle(0, 0, 300, 300), class_kiwi)

# Assign cloned annotation to a new variable
ann_clone_1 = ann.clone(labels=[label_kiwi])

# Let's clone our Annotation with Label, TagCollection and description
meta_lemon = sly.TagMeta('lemon', sly.TagValueType.ANY_STRING)
tag_lemon = sly.Tag(meta_lemon, 'juicy')
tags = sly.TagCollection([tag_lemon])

# Assign cloned annotation to a new variable
ann_clone_2 = ann.clone(labels=[label_kiwi], img_tags=tags, img_description='Juicy')
crop_labels(rect)[source]

Crops Labels of the current Annotation.

Parameters
rect : Rectangle

Rectangle object for crop.

Returns

New instance of Annotation

Return type

Annotation

Usage Example
import supervisely as sly

address = 'https://app.supervise.ly/'
token = 'Your Supervisely API Token'
api = sly.Api(address, token)

# Get image and annotation from API
project_id = 888
image_id = 555555

meta_json = api.project.get_meta(project_id)
meta = sly.ProjectMeta.from_json(meta_json)

ann_info = api.annotation.download(image_id)
ann = sly.Annotation.from_json(ann_info.annotation, meta)

img = api.image.download_np(image_id)
new_img = copy.deepcopy(img)

# Draw Annotation on image before crop
ann.draw_pretty(img, thickness=3)

# Crop Labels for current Annotation
# Remember that Annotation object is immutable, and we need to assign new instance of Annotation to a new variable
cropped_ann = ann.crop_labels(sly.Rectangle(0, 0, 600, 700))

# Draw Annotation on image after crop
cropped_ann.draw_pretty(new_img, thickness=3)
https://i.imgur.com/6huO1se.jpg

Before

https://i.imgur.com/w2wR4h8.jpg

After

delete_label(label)[source]

Clones Annotation with removed Label.

Parameters
label : Label

Label to be deleted.

Raises

KeyError, if there is no deleted Label in current Annotation object

Returns

New instance of Annotation

Return type

Annotation

Usage Example
import supervisely as sly

ann = sly.Annotation((300, 600))

# Create Labels
class_kiwi = sly.ObjClass('kiwi', sly.Rectangle)
label_kiwi = sly.Label(sly.Rectangle(0, 0, 300, 300), class_kiwi)

class_lemon = sly.ObjClass('lemon', sly.Rectangle)
label_lemon = sly.Label(sly.Rectangle(0, 0, 500, 600), class_lemon)

# Add labels to Annotation
ann = ann.add_labels([label_kiwi, label_lemon])
print(len(ann.labels))
# Output: 2

# Run through all labels in Annotation objects
for label in ann.labels:
    if label.obj_class.name == 'lemon': # label obj_class name we want to delete
        # Remember that Annotation object is immutable, and we need to assign new instance of Annotation to a new variable
        new_ann = ann.delete_label(label)

print(len(new_ann.labels))
# Output: 1
delete_tag(tag)[source]

Clones Annotation with removed Tag.

Parameters
tag : Tag

Tag to be deleted.

Returns

New instance of Annotation

Return type

Annotation

Usage Example
import supervisely as sly

ann = sly.Annotation((300, 600))

meta_dog = sly.TagMeta('dog', sly.TagValueType.ANY_STRING)
meta_cat = sly.TagMeta('cat', sly.TagValueType.NONE)

tag_dog = sly.Tag(meta_dog, 'Woof!')
tag_cat = sly.Tag(meta_cat)

ann = ann.add_tags([tag_dog, tag_cat])
print(len(ann.img_tags))
# Output: 2

new_ann = ann.delete_tag(tag_dog)
print(len(new_ann.img_tags))
# Output: 1
delete_tag_by_name(tag_name)[source]

Clones Annotation with removed Tag by it’s name.

Parameters
tag_name : str

Tag name to be delete.

Returns

New instance of Annotation

Return type

Annotation

Usage Example
import supervisely as sly

ann = sly.Annotation((300, 600))

# Create Tag
meta_alert = sly.TagMeta('Alert', sly.TagValueType.ANY_STRING)
tag_alert = sly.Tag(meta_alert, 'Hello')

tag_ann = ann.add_tag(tag_alert)

# Delete Tag from Annotation
# Remember that Annotation object is immutable, and we need to assign new instance of Annotation to a new variable
new_ann = tag_ann.delete_tag_by_name('Alert')
delete_tags(tags)[source]

Clones Annotation with removed Tags.

Parameters
tags : List[Tag]

List of Tags to be deleted.

Returns

New instance of Annotation

Return type

Annotation

Usage Example
import supervisely as sly

ann = sly.Annotation((300, 600))

meta_message = sly.TagMeta('Message', sly.TagValueType.ANY_STRING)
meta_alert = sly.TagMeta('Alert', sly.TagValueType.NONE)

tag_message = sly.Tag(meta_message, 'Hello')
tag_alert = sly.Tag(meta_alert)

ann = ann.add_tags([tag_message, tag_alert])
print(len(ann.img_tags))
# Output: 2

new_ann = ann.delete_tags([tag_message, tag_alert])
print(len(new_ann.img_tags))
# Output: 0
delete_tags_by_name(tag_names)[source]

Clones Annotation and removes Tags by their names.

Parameters
tag_names : List[str]

List of Tags names to be deleted.

Returns

New instance of Annotation

Return type

Annotation

Usage Example
import supervisely as sly

ann = sly.Annotation((300, 600))

# Create Tags
meta_message = sly.TagMeta('Message', sly.TagValueType.ANY_STRING)
meta_alert = sly.TagMeta('Alert', sly.TagValueType.NONE)

tag_message = sly.Tag(meta_message, 'Hello')
tag_alert = sly.Tag(meta_alert)

# Add Tags to Annotation
tags_ann = ann.add_tags([tag_message, tag_alert])

# Delete Tags from Annotation
# Remember that Annotation object is immutable, and we need to assign new instance of Annotation to a new variable
new_ann = tags_ann.delete_tags_by_name(['Message', 'Alert'])
discard_bindings()[source]

Remove binding keys from all labels.

Return type

None

draw(bitmap, color=None, thickness=1, draw_tags=False, fill_rectangles=True, draw_class_names=False)[source]

Draws current Annotation on image. Modifies mask.

Parameters
bitmap : np.ndarray

Image.

color : List[int, int, int], optional

Drawing color in [R, G, B].

thickness : int, optional

Thickness of the drawing figure.

draw_tags : bool, optional

Determines whether to draw tags on bitmap or not.

fill_rectangles : int, optional

Choose False if you want to draw only contours of bboxes. By default, True.

draw_class_names : int, optional

Determines whether to draw class names on bitmap or not.

Returns

None

Return type

NoneType

Usage Example
import supervisely as sly

address = 'https://app.supervise.ly/'
token = 'Your Supervisely API Token'
api = sly.Api(address, token)

# Get image and annotation from API
project_id = 888
image_id = 555555

meta_json = api.project.get_meta(project_id)
meta = sly.ProjectMeta.from_json(meta_json)

ann_info = api.annotation.download(image_id)
ann = sly.Annotation.from_json(ann_info.annotation, meta)

img = api.image.download_np(image_id)

# Draw Annotation on image
ann.draw(img)
https://i.imgur.com/1W1Nfl1.jpg
draw_class_idx_rgb(render, name_to_index)[source]

Draws current Annotation on render.

Parameters
render : np.ndarray

Target render to draw classes.

name_to_index : dict

Dict where keys are class names and values are class indices to draw on render.

Usage Example
import supervisely as sly

address = 'https://app.supervise.ly/'
token = 'Your Supervisely API Token'
api = sly.Api(address, token)

# Get image and annotation from API
project_id = 888
image_id = 555555

meta_json = api.project.get_meta(project_id)
meta = sly.ProjectMeta.from_json(meta_json)

ann_info = api.annotation.download(image_id)
ann = sly.Annotation.from_json(ann_info.annotation, meta)

img = api.image.download_np(image_id)

# Draw Annotation on image
name_to_index = {'lemon': 90, 'kiwi': 195}
ann.draw_class_idx_rgb(img, name_to_index)
https://i.imgur.com/ACSaBgw.jpg
Return type

None

draw_contour(bitmap, color=None, thickness=1, draw_tags=False)[source]

Draws geometry contour of Annotation on image. Modifies mask.

Parameters
bitmap : np.ndarray

Image.

color : List[int, int, int], optional

Drawing color in [R, G, B].

thickness : int, optional

Thickness of the drawing figure.

draw_tags : bool, optional

Determines whether to draw tags on bitmap or not.

Returns

None

Return type

NoneType

Usage Example
import supervisely as sly

address = 'https://app.supervise.ly/'
token = 'Your Supervisely API Token'
api = sly.Api(address, token)

# Get image and annotation from API
project_id = 888
image_id = 555555

meta_json = api.project.get_meta(project_id)
meta = sly.ProjectMeta.from_json(meta_json)

ann_info = api.annotation.download(image_id)
ann = sly.Annotation.from_json(ann_info.annotation, meta)

img = api.image.download_np(image_id)

# Draw Annotation contour on image
ann.draw_contour(img)
https://i.imgur.com/F8KGZS4.jpg
draw_pretty(bitmap, color=None, thickness=None, opacity=0.5, draw_tags=False, output_path=None, fill_rectangles=True)[source]

Draws current Annotation on image with contour. Modifies mask.

Parameters
bitmap : np.ndarray

Image.

color : List[int, int, int], optional

Drawing color in [R, G, B].

thickness : int, optional

Thickness of the drawing figure.

opacity : float, optional

Opacity of the drawing figure.

draw_tags : bool, optional

Determines whether to draw tags on bitmap or not.

output_path : str, optional

Saves modified image to the given path.

Returns

None

Return type

NoneType

import supervisely as sly

address = 'https://app.supervise.ly/'
token = 'Your Supervisely API Token'
api = sly.Api(address, token)

# Get image and annotation from API
project_id = 888
image_id = 555555

meta_json = api.project.get_meta(project_id)
meta = sly.ProjectMeta.from_json(meta_json)

ann_info = api.annotation.download(image_id)
ann = sly.Annotation.from_json(ann_info.annotation, meta)

img = api.image.download_np(image_id)

# Draw pretty Annotation on image
ann.draw_pretty(img, thickness=3)

https://i.imgur.com/6huO1se.jpg
filter_labels_by_classes(keep_classes)[source]

Filter annotation labels by given classes names.

Parameters
keep_classes : List[str]

List with classes names.

Returns

New instance of Annotation

Return type

Annotation

import supervisely as sly

address = 'https://app.supervise.ly/'
token = 'Your Supervisely API Token'
api = sly.Api(address, token)

# Get image annotation from API
project_id = 7473
image_id = 2223200
meta_json = api.project.get_meta(project_id)
meta = sly.ProjectMeta.from_json(meta_json)
ann_info = api.annotation.download(image_id)
print(json.dumps(ann_info.annotation, indent=4))

# Output: {
#     "description": "",
#     "tags": [],
#     "size": {
#         "height": 800,
#         "width": 1067
#     },
#     "objects": [
#         {
#             "id": 57388829,
#             "classId": 121405,
#             "description": "",
#             "geometryType": "bitmap",
#             "labelerLogin": "alex",
#             "createdAt": "2022-01-02T08:06:05.183Z",
#             "updatedAt": "2022-01-02T08:07:12.219Z",
#             "tags": [],
#             "classTitle": "kiwi",
#             "bitmap": {
#                 "data": "eJyNlWs4lHkYxv/z8qp5NZuYSZes1KZm6CDSTuP0mh2ZWYdmULakdBUzkRqRrDG8M1vZZg8WIy...,
#                 "origin": [
#                     481,
#                     543
#                 ]
#             }
#         },
#         {
#             "id": 57388831,
#             "classId": 121404,
#             "description": "",
#             "geometryType": "bitmap",
#             "labelerLogin": "alex",
#             "createdAt": "2022-01-02T08:06:59.133Z",
#             "updatedAt": "2022-01-02T08:07:12.219Z",
#             "tags": [],
#             "classTitle": "lemon",
#             "bitmap": {
#                 "data": "eJwdV388k/sXfzwmz3TVNm3l94z5saQoXFSG+c26tM1GYjWUISWKK201SchvIcq30tX2rDuTdE...,
#                 "origin": [
#                     523,
#                     119
#                 ]
#             }
#         },
#         {
#             "id": 57388832,
#             "classId": 121405,
#             "description": "",
#             "geometryType": "bitmap",
#             "labelerLogin": "alex",
#             "createdAt": "2022-01-02T08:07:12.104Z",
#             "updatedAt": "2022-01-02T08:07:12.104Z",
#             "tags": [],
#             "classTitle": "kiwi",
#             "bitmap": {
#                 "data": "eJw1VglQU8kWTWISHzH6AzwwIEsSCBr2AApBloAJhB0eCEIYDJFN2WHACC7sRghbIAiIMuKj...,
#                 "origin": [
#                     773,
#                     391
#                 ]
#             }
#         }
#     ]
# }

ann = sly.Annotation.from_json(ann_info.annotation, meta)

# Let's filter 'lemon' class
keep_classes = ['lemon']
filter_ann = ann.filter_labels_by_classes(keep_classes)
print(json.dumps(filter_ann.to_json(), indent=4))

# Output: {
#     "description": "",
#     "size": {
#         "height": 800,
#         "width": 1067
#     },
#     "tags": [],
#     "objects": [
#         {
#             "classTitle": "lemon",
#             "description": "",
#             "tags": [],
#             "bitmap": {
#                 "origin": [
#                     523,
#                     119
#                 ],
#                 "data": "eJwBOAPH/IlQTkcNChoKAAAADUlIRFIAAAEsAAABCQEDAAAAFNKIswAAAAZQTFRFAAAA...,
#             },
#             "shape": "bitmap",
#             "geometryType": "bitmap",
#             "labelerLogin": "alex",
#             "updatedAt": "2022-01-02T08:07:12.219Z",
#             "createdAt": "2022-01-02T08:06:59.133Z",
#             "id": 57388831,
#             "classId": 121404
#         }
#     ],
#     "customBigData": {}
# }

filter_labels_by_min_side(thresh, filter_operator=<built-in function lt>, classes=None)[source]

Filters Labels of the current Annotation by side. If minimal side is smaller than Label threshold it will be ignored.

Parameters
thresh : int

Side threshold to filter.

filter_operator : operator

Type of filter operation.

classes : List[str]

List of Labels names to apply filter.

Returns

New instance of Annotation

Return type

Annotation

Usage Example
import supervisely as sly

address = 'https://app.supervise.ly/'
token = 'Your Supervisely API Token'
api = sly.Api(address, token)

# Get image and annotation from API
project_id = 888
image_id = 555555

meta_json = api.project.get_meta(project_id)
meta = sly.ProjectMeta.from_json(meta_json)

ann_info = api.annotation.download(image_id)
ann = sly.Annotation.from_json(ann_info.annotation, meta)

img = api.image.download_np(image_id)

# Filter Labels
# Remember that Annotation object is immutable, and we need to assign new instance of Annotation to a new variable
filtered_ann = ann.filter_labels_by_min_side(200)

# Draw filtered Annotation on image
filtered_ann.draw(img)
https://i.imgur.com/6huO1se.jpg

Before

https://i.imgur.com/uunTbPR.jpg

After

fliplr()[source]

Flips the current Annotation horizontally.

Returns

New instance of Annotation

Return type

Annotation

Usage Example
import supervisely as sly

address = 'https://app.supervise.ly/'
token = 'Your Supervisely API Token'
api = sly.Api(address, token)

# Get image and annotation from API
project_id = 888
image_id = 555555

meta_json = api.project.get_meta(project_id)
meta = sly.ProjectMeta.from_json(meta_json)

ann_info = api.annotation.download(image_id)
ann = sly.Annotation.from_json(ann_info.annotation, meta)

img = api.image.download_np(image_id)
new_img = copy.deepcopy(img)
new_img = sly.imaging.image.fliplr(new_img)

# Draw Annotation on image before horizontal flip
ann.draw_pretty(img, thickness=3)

# Flip
# Remember that Annotation object is immutable, and we need to assign new instance of Annotation to a new variable
fliplr_ann = ann.fliplr()

# Draw Annotation on image after horizontal flip
fliplr_ann.draw_pretty(new_img, thickness=3)
https://i.imgur.com/6huO1se.jpg

Before

https://i.imgur.com/AQSuqIN.jpg

After

flipud()[source]

Flips the current Annotation vertically.

Returns

New instance of Annotation

Return type

Annotation

Usage Example
import supervisely as sly

address = 'https://app.supervise.ly/'
token = 'Your Supervisely API Token'
api = sly.Api(address, token)

# Get image and annotation from API
project_id = 888
image_id = 555555

meta_json = api.project.get_meta(project_id)
meta = sly.ProjectMeta.from_json(meta_json)

ann_info = api.annotation.download(image_id)
ann = sly.Annotation.from_json(ann_info.annotation, meta)

img = api.image.download_np(image_id)
new_img = copy.deepcopy(img)
new_img = sly.imaging.image.flipud(new_img)

# Draw Annotation on image before vertical flip
ann.draw_pretty(img, thickness=3)

# Flip
# Remember that Annotation object is immutable, and we need to assign new instance of Annotation to a new variable
flipud_ann = ann.flipud()

# Draw Annotation on image after vertical flip
flipud_ann.draw_pretty(new_img, thickness=3)
https://i.imgur.com/6huO1se.jpg

Before

https://i.imgur.com/NVhvPDb.jpg

After

classmethod from_img_path(img_path)[source]

Creates empty Annotation from image.

Parameters
img_path : str

Path to the input image.

Returns

Annotation

Return type

Annotation

Usage Example
import supervisely as sly

img_path = "/home/admin/work/docs/my_dataset/img/example.jpeg"
ann = sly.Annotation.from_img_path(img_path)
classmethod from_imgaug(img, ia_boxes=None, ia_masks=None, index_to_class=None, meta=None)[source]

Create Annotation from image and SegmentationMapsOnImage, BoundingBoxesOnImage data or ProjectMeta.

Parameters
img : np.ndarray

Image in numpy format.

ia_boxes : List[BoundingBoxesOnImage], optional

List of BoundingBoxesOnImage data.

ia_masks : List[SegmentationMapsOnImage], optional

List of SegmentationMapsOnImage data.

index_to_class : Dict[int, str], optional

Dictionary specifying index match of class name.

meta : ProjectMeta, optional

ProjectMeta.

Raises

ValueError, if ia_boxes or ia_masks and meta is None

Raises

KeyError, if processed ObjClass not found in meta

Returns

Annotation object

Return type

Annotation

classmethod from_json(data, project_meta)[source]

Convert a json dict to Annotation. Read more about Supervisely format.

Parameters
data : dict

Annotation in json format as a dict.

project_meta : ProjectMeta

Input ProjectMeta.

Returns

Annotation object

Return type

Annotation

Raises

Exception

Usage example
import supervisely as sly

meta = sly.ProjectMeta()

ann_json = {
     "size": {
         "height": 500,
         "width": 700
     },
     "tags": [],
     "objects": []
}

ann = sly.Annotation.from_json(ann_json, meta)
get_bindings()[source]

Returns dictionary with bindings keys as keys and list of labels as values.

Returns

Dictionary with bindings keys as keys and list of labels as values.

Return type

Dict[str, List[Label]]

get_label_by_id(sly_id)[source]

Get Label from current Annotation by sly_id.

Parameters
sly_id : int

Label ID from Supervisely server.

Returns

Label or None

Return type

Label or NoneType

Usage Example
import supervisely as sly

address = 'https://app.supervise.ly/'
token = 'Your Supervisely API Token'
api = sly.Api(address, token)

# To get Label ID you must first access ProjectMeta
PROJECT_ID = 999

meta_json = api.project.get_meta(PROJECT_ID)
meta = sly.ProjectMeta.from_json(meta_json)

# Get desired image id to which label belongs to download annotation
image_id = 376728
ann_info = api.annotation.download(image_id)
ann_json = ann_info.annotation
ann = sly.Annotation.from_json(ann_json, meta)

# Get Label by it's ID
label_by_id = ann.get_label_by_id(sly_id=2263842)
print(label_by_id.to_json())
# Output: {
#     "classTitle":"kiwi",
#     "description":"",
#     "tags":[],
#     "points":{
#         "exterior":[
#             [481, 549],
#             [641, 703]
#         ],
#         "interior":[]
#     },
#     "labelerLogin":"cxnt",
#     "updatedAt":"2020-12-11T08:11:43.249Z",
#     "createdAt":"2020-12-10T09:38:57.969Z",
#     "id":2263842,
#     "classId":7370,
#     "geometryType":"rectangle",
#     "shape":"rectangle"
# }

# Returns None if Label ID doesn't exist on the given image ID
label_by_id = ann.get_label_by_id(sly_id=9999999)
# Output: None
is_empty()[source]

Check whether annotation contains labels or tags, or not.

Returns

True if annotation is empty, False otherwise.

Return type

bool

classmethod load_json_file(path, project_meta)[source]

Loads json file and converts it to Annotation.

Parameters
path : str

Path to the json file.

project_meta : ProjectMeta

Input ProjectMeta object.

Returns

Annotation object

Return type

Annotation

Usage example
import supervisely as sly

address = 'https://app.supervise.ly/'
token = 'Your Supervisely API Token'
api = sly.Api(address, token)

team_name = 'Vehicle Detection'
workspace_name = 'Cities'
project_name =  'London'

team = api.team.get_info_by_name(team_name)
workspace = api.workspace.get_info_by_name(team.id, workspace_name)
project = api.project.get_info_by_name(workspace.id, project_name)

meta = api.project.get_meta(project.id)

# Load json file
path = "/home/admin/work/docs/my_dataset/ann/annotation.json"
ann = sly.Annotation.load_json_file(path, meta)
masks_to_imgaug(class_to_index)[source]

Convert current annotation objects masks to SegmentationMapsOnImage format.

Parameters
class_to_index : dict

Dict matching class name to index.

Returns

SegmentationMapsOnImage, otherwise None

Return type

SegmentationMapsOnImage or NoneType

merge(other)[source]

Merge current Annotation with another Annotation.

Parameters
other : Annotation

Annotation to merge.

Returns

New instance of Annotation

Return type

Annotation

import supervisely as sly

# Create annotation
meta_lemon = sly.TagMeta('lemon_tag', sly.TagValueType.ANY_STRING)
tag_lemon = sly.Tag(meta_lemon, 'lemon')
tags_lemon = sly.TagCollection([tag_lemon])
class_lemon = sly.ObjClass('lemon', sly.Rectangle)
label_lemon = sly.Label(sly.Rectangle(100, 100, 200, 200), class_lemon)
height, width = 300, 400
ann_lemon = sly.Annotation((height, width), [label_lemon], tags_lemon)

# Create annotation to merge
meta_kiwi= sly.TagMeta('kiwi_tag', sly.TagValueType.ANY_STRING)
tag_kiwi = sly.Tag(meta_kiwi, 'kiwi')
tags_kiwi = sly.TagCollection([tag_kiwi])
class_kiwi = sly.ObjClass('kiwi', sly.Rectangle)
label_kiwi = sly.Label(sly.Rectangle(200, 100, 700, 200), class_kiwi)
height, width = 700, 500
ann_kiwi = sly.Annotation((height, width), [label_kiwi], tags_kiwi)

# Merge annotations
ann_merge = ann_lemon.merge(ann_kiwi)

for label in ann_merge.labels:
    print(label.obj_class.name)

# Output: lemon
# Output: kiwi

relative_crop(rect)[source]

Crops current Annotation and with image size (height, width) changes.

Parameters
rect : Rectangle

Rectangle object for crop.

Returns

New instance of Annotation

Return type

Annotation

Usage Example
import supervisely as sly

address = 'https://app.supervise.ly/'
token = 'Your Supervisely API Token'
api = sly.Api(address, token)

# Get image and annotation from API
project_id = 888
image_id = 555555

meta_json = api.project.get_meta(project_id)
meta = sly.ProjectMeta.from_json(meta_json)

ann_info = api.annotation.download(image_id)
ann = sly.Annotation.from_json(ann_info.annotation, meta)

img = api.image.download_np(image_id)
new_img = copy.deepcopy(img)
new_img = sly.imaging.image.crop(new_img, sly.Rectangle(200, 300, 600, 700))

# Draw Annotation on image before relative crop
ann.draw_pretty(img, thickness=3)

# Relative Crop Labels for current Annotation
# Remember that Annotation object is immutable, and we need to assign new instance of Annotation to a new variable
r_cropped_ann = ann.relative_crop(sly.Rectangle(200, 300, 600, 700))

# Draw Annotation on image after relative crop
r_cropped_ann.draw_pretty(new_img, thickness=3)
https://i.imgur.com/23UuNdJ.png

Before

https://i.imgur.com/8Z7xVxB.jpg

After

resize(out_size, skip_empty_masks=False)[source]

Resizes current Annotation.

Parameters
out_size : Tuple[int, int]

Desired output image size (height, width).

skip_empty_masks : bool

Skip the raising of the error when you have got an empty label mask after a resizing procedure.

Returns

New instance of Annotation

Return type

class

Annotation

Usage Example
import supervisely as sly

address = 'https://app.supervise.ly/'
token = 'Your Supervisely API Token'
api = sly.Api(address, token)

# Get image and annotation from API
project_id = 888
image_id = 555555

meta_json = api.project.get_meta(project_id)
meta = sly.ProjectMeta.from_json(meta_json)

ann_info = api.annotation.download(image_id)
ann = sly.Annotation.from_json(ann_info.annotation, meta)

img = api.image.download_np(image_id)
new_img = copy.deepcopy(img)
new_img = sly.imaging.image.resize(new_img, (100, 200))

# Draw Annotation on image before resize
ann.draw_pretty(img, thickness=3)

# Resize
# Remember that Annotation object is immutable, and we need to assign new instance of Annotation to a new variable
resized_ann = ann.resize((100, 200))

# Draw Annotation on image after resize
resized_ann.draw_pretty(new_img, thickness=3)
https://i.imgur.com/6huO1se.jpg

Before

https://i.imgur.com/RrvNMoV.jpg

After

rotate(rotator)[source]

Rotates current Annotation.

Parameters
rotator : ImageRotator

ImageRotator object.

Returns

New instance of Annotation

Return type

Annotation

Usage Example
import supervisely as sly
from supervisely.geometry.image_rotator import ImageRotator

address = 'https://app.supervise.ly/'
token = 'Your Supervisely API Token'
api = sly.Api(address, token)

# Get image and annotation from API
project_id = 888
image_id = 555555

meta_json = api.project.get_meta(project_id)
meta = sly.ProjectMeta.from_json(meta_json)

ann_info = api.annotation.download(image_id)
ann = sly.Annotation.from_json(ann_info.annotation, meta)

img = api.image.download_np(image_id)
new_img = copy.deepcopy(img)
new_img = sly.imaging.image.rotate(new_img, 10)

# Draw Annotation on image before rotation
ann.draw_pretty(img, thickness=3)

# Rotate Labels for current Annotation
# Remember that Annotation object is immutable, and we need to assign new instance of Annotation to a new variable
rotator = ImageRotator(annotation.img_size, 10)
rotated_ann = ann.rotate(rotator)

# Draw Annotation on image after rotation
rotated_ann.draw_pretty(new_img, thickness=3)
https://i.imgur.com/6huO1se.jpg

Before

https://i.imgur.com/ZQ47cXN.jpg

After

scale(factor)[source]

Scales current Annotation with the given factor.

Parameters
factor : float

Scale size.

Returns

New instance of Annotation

Return type

Annotation

Usage Example
import supervisely as sly

address = 'https://app.supervise.ly/'
token = 'Your Supervisely API Token'
api = sly.Api(address, token)

# Get image and annotation from API
project_id = 888
image_id = 555555

meta_json = api.project.get_meta(project_id)
meta = sly.ProjectMeta.from_json(meta_json)

ann_info = api.annotation.download(image_id)
ann = sly.Annotation.from_json(ann_info.annotation, meta)

img = api.image.download_np(image_id)
new_img = copy.deepcopy(img)
new_img = sly.imaging.image.scale(new_img, 0.55)

# Draw Annotation on image before rescale
ann.draw_pretty(img, thickness=3)

# Scale
# Remember that Annotation object is immutable, and we need to assign new instance of Annotation to a new variable
rescaled_ann = ann.scale(0.55)

# Draw Annotation on image after rescale
rescaled_ann.draw_pretty(new_img, thickness=3)
https://i.imgur.com/6huO1se.jpg

Before

https://i.imgur.com/Ze6uqZ8.jpg

After

classmethod stat_area(render, names, colors)[source]

Get statistics about color area representation on the given render for the current Annotation.

Parameters
render : np.ndarray

Target render.

names : List[str]

List of color names.

colors : List[List[int, int, int]]

List of [R, G, B] colors.

Returns

Colors area representation on the given render

Return type

dict

Raises

RuntimeError if len(names) != len(colors)

Usage Example
import supervisely as sly

address = 'https://app.supervise.ly/'
token = 'Your Supervisely API Token'
api = sly.Api(address, token)

# Get image and annotation from API
project_id = 888
image_id = 555555

meta_json = api.project.get_meta(project_id)
meta = sly.ProjectMeta.from_json(meta_json)

ann_info = api.annotation.download(image_id)
ann = sly.Annotation.from_json(ann_info.annotation, meta)

img = api.image.download_np(image_id)

class_names = []
class_colors = []
for label in ann.labels:
    class_names.append(label.obj_class.name)
    class_colors.append(label.obj_class.color)

ann.draw_pretty(img, thickness=3)

ann_stats = ann.stat_area(img, class_names, class_colors)
print(ann_stats)
# Output: {
#     "lemon":0.45548266166822865,
#     "kiwi":0.5697047797563262,
#     "unlabeled":98.97481255857544,
#     "height":800,
#     "width":1067,
#     "channels":3
# }

print(stat_area)
stat_class_count(class_names=None)[source]

Get statistics about number of each class in Annotation.

Parameters
class_names : List[str], optional

List of classes names.

Returns

Number of each class in Annotation and total number of classes

Return type

defaultdict

Usage Example
import supervisely as sly

# Create object classes
class_kiwi = sly.ObjClass('kiwi', sly.Rectangle)
class_lemon = sly.ObjClass('lemon', sly.Rectangle)

# Create labels
label_kiwi = sly.Label(sly.Rectangle(100, 100, 700, 900), class_kiwi)
label_lemon = sly.Label(sly.Rectangle(200, 200, 500, 600), class_lemon)
labels_arr = [label_kiwi, label_lemon]

# Create annotation
height, width = 300, 400
ann = sly.Annotation((height, width), labels_arr)

stat_class = ann.stat_class_count(['lemon', 'kiwi'])

# Output: defaultdict(<class 'int'>, {'lemon': 1, 'kiwi': 1, 'total': 2})
to_detection_task(mapping)[source]

Convert Annotation classes geometries according to mapping dict and checking nonoverlapping masks. Converting possible only to Bitmap or Rectangle.

Returns

New instance of Annotation

Return type

Annotation

import supervisely as sly

address = 'https://app.supervise.ly/'
token = 'Your Supervisely API Token'
api = sly.Api(address, token)

# Get image annotation from API
project_id = 7548
image_id = 2254942
meta_json = api.project.get_meta(project_id)
meta = sly.ProjectMeta.from_json(meta_json)
ann_info = api.annotation.download(image_id)
print(json.dumps(ann_info.annotation, indent=4))

# Output: {
#     "description": "",
#     "tags": [],
#     "size": {
#         "height": 800,
#         "width": 1067
#     },
#     "objects": [
#         {
#             "id": 56656282,
#             "classId": 122357,
#             "description": "",
#             "geometryType": "bitmap",
#             "labelerLogin": "alex",
#             "createdAt": "2021-10-15T11:01:40.805Z",
#             "updatedAt": "2021-10-15T11:01:40.805Z",
#             "tags": [],
#             "classTitle": "lemon",
#             "bitmap": {
#                 "data": "eJwBuwJE/YlQTkcNChoKAAAADUlIRFIAAAE3AAAApgEDAAAAhaFaIwAAAAZQTFRFAAAA...,
#                 "origin": [
#                     589,
#                     372
#                 ]
#             }
#         },
#         {
#             "id": 56656281,
#             "classId": 122356,
#             "description": "",
#             "geometryType": "polygon",
#             "labelerLogin": "alex",
#             "createdAt": "2021-10-15T13:22:58.178Z",
#             "updatedAt": "2021-10-15T13:22:58.178Z",
#             "tags": [],
#             "classTitle": "kiwi",
#             "points": {
#                 "exterior": [
#                     [
#                         719,
#                         115
#                     ],
#                   ...
#                     [
#                         732,
#                         123
#                     ]
#                 ],
#                 "interior": []
#             }
#         },
#         {
#             "id": 56656280,
#             "classId": 122356,
#             "description": "",
#             "geometryType": "polygon",
#             "labelerLogin": "alex",
#             "createdAt": "2021-10-15T13:22:58.178Z",
#             "updatedAt": "2021-10-15T13:22:58.178Z",
#             "tags": [],
#             "classTitle": "kiwi",
#             "points": {
#                 "exterior": [
#                     [
#                         250,
#                         216
#                     ],
#                   ...
#                     [
#                         278,
#                         212
#                     ]
#                 ],
#                 "interior": []
#             }
#         },
#         {
#             "id": 56656279,
#             "classId": 122356,
#             "description": "",
#             "geometryType": "polygon",
#             "labelerLogin": "alex",
#             "createdAt": "2021-10-15T13:22:58.177Z",
#             "updatedAt": "2021-10-15T13:22:58.177Z",
#             "tags": [],
#             "classTitle": "kiwi",
#             "points": {
#                 "exterior": [
#                     [
#                         554,
#                         581
#                     ],
#                   ...
#                     [
#                         560,
#                         587
#                     ]
#                 ],
#                 "interior": []
#             }
#         }
#     ]
# }

ann = sly.Annotation.from_json(ann_info.annotation, meta)

# Create mapping for classes converting. Let's convert classes to Rectangle.
mapping = {}
for label in ann.labels:
    if label.obj_class.name not in mapping:
        new_obj_class = sly.ObjClass(label.obj_class.name, Rectangle)
        mapping[label.obj_class] = new_obj_class

det_ann = ann.to_detection_task(mapping)
print(json.dumps(det_ann.to_json(), indent=4))

# Output: {
#     "description": "",
#     "size": {
#         "height": 800,
#         "width": 1067
#     },
#     "tags": [],
#     "objects": [
#         {
#             "classTitle": "lemon",
#             "description": "",
#             "tags": [],
#             "points": {
#                 "exterior": [
#                     [
#                         589,
#                         372
#                     ],
#                     [
#                         899,
#                         537
#                     ]
#                 ],
#                 "interior": []
#             },
#             "geometryType": "rectangle",
#             "shape": "rectangle"
#         },
#         {
#             "classTitle": "kiwi",
#             "description": "",
#             "tags": [],
#             "points": {
#                 "exterior": [
#                     [
#                         612,
#                         110
#                     ],
#                     [
#                         765,
#                         282
#                     ]
#                 ],
#                 "interior": []
#             },
#             "geometryType": "rectangle",
#             "shape": "rectangle"
#         },
#         {
#             "classTitle": "kiwi",
#             "description": "",
#             "tags": [],
#             "points": {
#                 "exterior": [
#                     [
#                         196,
#                         212
#                     ],
#                     [
#                         352,
#                         380
#                     ]
#                 ],
#                 "interior": []
#             },
#             "geometryType": "rectangle",
#             "shape": "rectangle"
#         },
#         {
#             "classTitle": "kiwi",
#             "description": "",
#             "tags": [],
#             "points": {
#                 "exterior": [
#                     [
#                         425,
#                         561
#                     ],
#                     [
#                         576,
#                         705
#                     ]
#                 ],
#                 "interior": []
#             },
#             "geometryType": "rectangle",
#             "shape": "rectangle"
#         }
#     ],
#     "customBigData": {}
# }

to_indexed_color_mask(mask_path, palette=1, colors=256)[source]

Draw current Annotation on image and save it in PIL format.

Parameters
mask_path : str

Saves image to the given path.

palette : Available palettes are WEB or ADAPTIVE, optional

Palette to use when converting image from mode “RGB” to “P”.

colors : int, optional

Number of colors to use for the ADAPTIVE palette.

Returns

None

Return type

NoneType

to_json()[source]

Convert the Annotation to a json dict. Read more about Supervisely format.

Returns

Json format as a dict

Return type

dict

Usage example
import supervisely as sly

ann = sly.Annotation((500, 700))
ann_json = ann.to_json()

print(ann_json)
# Output: {
#     "description": "",
#     "size": {
#         "height": 500,
#         "width": 700
#     },
#     "tags": [],
#     "objects": [],
#     "customBigData": {}
# }
to_nonoverlapping_masks(mapping)[source]

Create new annotation with non-overlapping labels masks. Convert classes to Bitmap or skip them.

Parameters
mapping : Dict[ObjClass, ObjClass]

Dict with ObjClasses for mapping.

Returns

New instance of Annotation

Return type

Annotation

import supervisely as sly

address = 'https://app.supervise.ly/'
token = 'Your Supervisely API Token'
api = sly.Api(address, token)

# Get image annotation from API
project_id = 7548
image_id = 2254937
meta_json = api.project.get_meta(project_id)
meta = sly.ProjectMeta.from_json(meta_json)
ann_info = api.annotation.download(image_id)
print(json.dumps(ann_info.annotation, indent=4))

# Output: {
#     "description": "",
#     "tags": [],
#     "size": {
#         "height": 800,
#         "width": 1067
#     },
#     "objects": [
#         {
#             "id": 56656282,
#             "classId": 122357,
#             "description": "",
#             "geometryType": "bitmap",
#             "labelerLogin": "alex",
#             "createdAt": "2021-10-15T11:01:40.805Z",
#             "updatedAt": "2021-10-15T11:01:40.805Z",
#             "tags": [],
#             "classTitle": "lemon",
#             "bitmap": {
#                 "data": "eJwBuwJE/YlQTkcNChoKAAAADUlIRFIAAAE3AAAApgEDAAAAhaFaIwAAAAZQTFRFAAAA...,
#                 "origin": [
#                     589,
#                     372
#                 ]
#             }
#         },
#         {
#             "id": 56656281,
#             "classId": 122356,
#             "description": "",
#             "geometryType": "polygon",
#             "labelerLogin": "alex",
#             "createdAt": "2021-10-15T13:22:58.178Z",
#             "updatedAt": "2021-10-15T13:22:58.178Z",
#             "tags": [],
#             "classTitle": "kiwi",
#             "points": {
#                 "exterior": [
#                     [
#                         719,
#                         115
#                     ],
#                   ...
#                     [
#                         732,
#                         123
#                     ]
#                 ],
#                 "interior": []
#             }
#         },
#         {
#             "id": 56656280,
#             "classId": 122356,
#             "description": "",
#             "geometryType": "polygon",
#             "labelerLogin": "alex",
#             "createdAt": "2021-10-15T13:22:58.178Z",
#             "updatedAt": "2021-10-15T13:22:58.178Z",
#             "tags": [],
#             "classTitle": "kiwi",
#             "points": {
#                 "exterior": [
#                     [
#                         250,
#                         216
#                     ],
#                   ...
#                     [
#                         278,
#                         212
#                     ]
#                 ],
#                 "interior": []
#             }
#         },
#         {
#             "id": 56656279,
#             "classId": 122356,
#             "description": "",
#             "geometryType": "polygon",
#             "labelerLogin": "alex",
#             "createdAt": "2021-10-15T13:22:58.177Z",
#             "updatedAt": "2021-10-15T13:22:58.177Z",
#             "tags": [],
#             "classTitle": "kiwi",
#             "points": {
#                 "exterior": [
#                     [
#                         554,
#                         581
#                     ],
#                   ...
#                     [
#                         560,
#                         587
#                     ]
#                 ],
#                 "interior": []
#             }
#         }
#     ]
# }

ann = sly.Annotation.from_json(ann_info.annotation, meta)

# Create mapping. Let's check 'kiwi' classes and skip 'lemon' classes.
mapping = {}
for label in ann.labels:
    if label.obj_class.name not in mapping:
        if label.obj_class.name == 'lemon':
            mapping[label.obj_class] = None
        else:
            new_obj_class = sly.ObjClass(label.obj_class.name, Bitmap)
            mapping[label.obj_class] = new_obj_class
nonoverlap_ann = ann.to_nonoverlapping_masks(mapping)
print(json.dumps(nonoverlap_ann.to_json(), indent=4))

# Output: {
#     "description": "",
#     "size": {
#         "height": 800,
#         "width": 1067
#     },
#     "tags": [],
#     "objects": [
#         {
#             "classTitle": "kiwi",
#             "description": "",
#             "tags": [],
#             "bitmap": {
#                 "origin": [
#                     187,
#                     396
#                 ],
#                 "data": "eJwBLALT/YlQTkcNChoKAAAADUlIRFIAAACuAAAAzgEDAAAAnTar9wAAAAZQTFRFAAAA...
#             },
#             "shape": "bitmap",
#             "geometryType": "bitmap"
#         },
#         {
#             "classTitle": "kiwi",
#             "description": "",
#             "tags": [],
#             "bitmap": {
#                 "origin": [
#                     365,
#                     385
#                 ],
#                 "data": "eJwB4gEd/olQTkcNChoKAAAADUlIRFIAAACbAAAAwgEDAAAAZC4i8AAAAAZQTFRFAAAA...
#             },
#             "shape": "bitmap",
#             "geometryType": "bitmap"
#         },
#         {
#             "classTitle": "kiwi",
#             "description": "",
#             "tags": [],
#             "bitmap": {
#                 "origin": [
#                     469,
#                     506
#                 ],
#                 "data": "eJwBHgLh/YlQTkcNChoKAAAADUlIRFIAAAC1AAAArQEDAAAAzBisHAAAAAZQTFRFAAAA...
#             },
#             "shape": "bitmap",
#             "geometryType": "bitmap"
#         }
#     ],
#     "customBigData": {}
# }
to_segmentation_task()[source]

Convert Annotation classes by joining labels with same object classes to one label. Applies to Bitmap only.

Returns

New instance of Annotation

Return type

Annotation

import supervisely as sly

address = 'https://app.supervise.ly/'
token = 'Your Supervisely API Token'
api = sly.Api(address, token)

# Get image annotation from API
project_id = 7473
image_id = 2223200
meta_json = api.project.get_meta(project_id)
meta = sly.ProjectMeta.from_json(meta_json)
ann_info = api.annotation.download(image_id)
print(json.dumps(ann_info.annotation, indent=4))

# Output: {
#     "description": "",
#     "tags": [],
#     "size": {
#         "height": 800,
#         "width": 1067
#     },
#     "objects": [
#         {
#             "id": 57388829,
#             "classId": 121405,
#             "description": "",
#             "geometryType": "bitmap",
#             "labelerLogin": "alex",
#             "createdAt": "2022-01-02T08:06:05.183Z",
#             "updatedAt": "2022-01-02T08:07:12.219Z",
#             "tags": [],
#             "classTitle": "kiwi",
#             "bitmap": {
#                 "data": "eJyNlWs4lHkYxv/z8qp5NZuYSZes1KZm6CDSTuP0mh2ZWYdmULakdBUzkRqRrDG8M1vZZg8W...,
#                 "origin": [
#                     481,
#                     543
#                 ]
#             }
#         },
#         {
#             "id": 57388831,
#             "classId": 121404,
#             "description": "",
#             "geometryType": "bitmap",
#             "labelerLogin": "alex",
#             "createdAt": "2022-01-02T08:06:59.133Z",
#             "updatedAt": "2022-01-02T08:07:12.219Z",
#             "tags": [],
#             "classTitle": "lemon",
#             "bitmap": {
#                 "data": "eJwdV388k/sXfzwmz3TVNm3l94z5saQoXFSG+c26tM1GYjWUISWKK201SchvIcq30tX2rD...,
#                 "origin": [
#                     523,
#                     119
#                 ]
#             }
#         },
#         {
#             "id": 57388832,
#             "classId": 121405,
#             "description": "",
#             "geometryType": "bitmap",
#             "labelerLogin": "alex",
#             "createdAt": "2022-01-02T08:07:12.104Z",
#             "updatedAt": "2022-01-02T08:07:12.104Z",
#             "tags": [],
#             "classTitle": "kiwi",
#             "bitmap": {
#                 "data": "eJw1VglQU8kWTWISHzH6AzwwIEsSCBr2AApBloAJhB0eCEIYDJFN2WHACC7sRghbIAiIMuKj...,
#                 "origin": [
#                     773,
#                     391
#                 ]
#             }
#         }
#     ]
# }

ann = sly.Annotation.from_json(ann_info.annotation, meta)
segm_ann = ann.to_segmentation_task()
print(json.dumps(segm_ann.to_json(), indent=4))

# Output: {
#     "description": "",
#     "size": {
#         "height": 800,
#         "width": 1067
#     },
#     "tags": [],
#     "objects": [
#         {
#             "classTitle": "kiwi",
#             "description": "",
#             "tags": [],
#             "bitmap": {
#                 "origin": [
#                     481,
#                     391
#                 ],
#                 "data": "eJwBagSV+4lQTkcNChoKAAAADUlIRFIAAAHpAAABOQEDAAAAjj5K+wAAAAZQTFRFAAAA...
#             },
#             "shape": "bitmap",
#             "geometryType": "bitmap"
#         },
#         {
#             "classTitle": "lemon",
#             "description": "",
#             "tags": [],
#             "bitmap": {
#                 "origin": [
#                     523,
#                     119
#                 ],
#                 "data": "eJwBOAPH/IlQTkcNChoKAAAADUlIRFIAAAEsAAABCQEDAAAAFNKIswAAAAZQTFRFAAAA...
#             },
#             "shape": "bitmap",
#             "geometryType": "bitmap"
#         }
#     ],
#     "customBigData": {}
# }

transform_labels(label_transform_fn, new_size=None)[source]

Transform labels and change image size in current Annotation object and return the copy of the current Annotation object. :param label_transform_fn: function for transform labels :type new_size: Optional[Tuple[int, int]] :param new_size: new image size :rtype: Annotation :return: Annotation class object with new labels and image size

property custom_data
property image_id

Id of the image.

Returns

Image id

Return type

int

Usage example
height, width = 300, 400
image_id = 12345
ann = sly.Annotation((height, width), image_id=image_id)
print(ann.image_id)
# Output: 12345
property img_description

Image description.

Returns

Image description

Return type

str

Usage example
ann = sly.Annotation((500, 700), img_description='Annotation for this image is empty')
print(ann.img_description)
# Output: Annotation for this image is empty
property img_size

Size of the image (height, width).

Returns

Image size

Return type

Tuple[int, int]

Usage example
height, width = 300, 400
ann = sly.Annotation((height, width))
print(ann.img_size)
# Output: (300, 400)
property img_tags

Image tags.

Returns

TagCollection object

Return type

TagCollection

Usage example
# Create TagCollection
meta_weather = sly.TagMeta('weather', sly.TagValueType.ANY_STRING)
tag_weather = sly.Tag(meta_weather, 'cloudy')
tags = sly.TagCollection([tag_weather])

ann = sly.Annotation((300, 400), img_tags=tags)
print(ann.img_tags)
# Output:
#   Tags:
#   +----------------+------------+--------+
#   |      Name      | Value type | Value  |
#   +----------------+------------+--------+
#   |     weather    | any_string | cloudy |
#   +----------------+------------+--------+
property labels

Labels on annotation.

Returns

Copy of list with image labels

Return type

List[Label]

Usage example
# Create Labels and add them to Annotation
class_kiwi = sly.ObjClass('kiwi', sly.Rectangle)
label_kiwi = sly.Label(sly.Rectangle(0, 0, 300, 300), class_kiwi)

class_lemon = sly.ObjClass('lemon', sly.Rectangle)
label_lemon = sly.Label(sly.Rectangle(0, 0, 500, 600), class_lemon)

labels_arr = [label_kiwi, label_lemon]

height, width = 300, 400
ann = sly.Annotation((height, width), labels_arr)

# Note that ann.labels return a COPY of list with image labels
class_potato = sly.ObjClass('potato', sly.Rectangle)
label_potato = sly.Label(sly.Rectangle(0, 0, 200, 400), class_potato)

ann.labels.append(label_potato)
print(len(ann.labels))
# Output: 2

ann_arr = ann.labels
ann_arr.append(label_potato)
print(len(ann_arr))
# Output: 3
property pixelwise_scores_labels