Get Started
- 1. Prerequisites and Installation
- 2. Import cloud data
- 3. Set up your Project and team
- Export Labels
General
SDK Ref
- EncordUserClient
- Bundle
- CloudUploadSettings
- MetadataSchema
- FilterPreset
- Storage
- Labels
- Ontology
- Project
- Workflows and Stages
Index
Projects
Labels
Datasets
Working with Labels
The encord.objects.LabelRowV2 class is a wrapper around the Encord label row data format. It provides a convenient way to read, create, and manipulate labels.
View Label Details
The following code shows how to view details for label rows (data units). This example only prints the label_hash
and the date labels were created, but more details are available. To see all available label details, see the LabelRowV2 SDK Reference.
# Import dependencies
from typing import List
from encord import EncordUserClient
from encord.objects import LabelRowV2
# Authentication
user_client = EncordUserClient.create_with_ssh_private_key(
ssh_private_key_path="<private_key_path>"
)
label_rows: List[LabelRowV2] = project.list_label_rows_v2()
for label_row in label_rows:
print(f"Label hash: {label_row.label_hash}")
print(f"Label created at: {label_row.created_at}")
Label Basics
Key methods for working with labels in the SDK are initialise_labels() and save():
initialise_labels()
: Downloads the existing label information. This method must be called before performing any label operations using the SDK.save()
: Saves any changes made to the labels back to the server. This method must be called after completing label operations to ensure updates are stored.
The following example demonstrates how to use these methods to add a bounding box to a single data unit (label row):
# Import dependencies
from typing import List
from encord import EncordUserClient
from encord.objects import LabelRowV2, Object, ObjectInstance, OntologyStructure
from encord.objects.coordinates import BoundingBoxCoordinates
# Instantiate Encord client by replacing <private_key_path> with the path to your private key
user_client = EncordUserClient.create_with_ssh_private_key(
ssh_private_key_path="<private_key_path>"
)
# Specify the project. Replace <project_hash> with the hash of your Project
project = user_client.get_project("<project_hash>")
# For simplicity, get only the first label row
first_label_row: List[LabelRowV2] = project.list_label_rows_v2()[0]
# Download the existing labels
first_label_row.initialise_labels()
# Get the first object instance in the label row
ontology_structure = first_label_row.ontology_structure
# Gets the object instance we want to edit the label for. This example uses the first
first_obj_instance = first_label_row.get_object_instances()[0]
# Specifies which Ontology object to change labels for.
my_object = ontology_structure.get_child_by_title(title="Flower")
# This example changes the location of a bounding box
first_obj_instance.set_for_frames(
coordinates = BoundingBoxCoordinates(
height=0.1474,
width =0.1154,
top_left_x=0.1097,
top_left_y=0.3209
),
manual_annotation=False, overwrite=True
)
# Link the object instance to the label row.
first_label_row.add_object_instance(first_obj_instance)
# Saves the newly added bounding box
first_label_row.save()
Create Object Labels
Single Image or Frame
Creating and saving object instances is essential when importing annotations into Encord. Specify the label shape, the coordinates, and which frames the shape should occur on. For modalities without frames such as single images, ensure that frames=0
.
The following code adds a bounding box for the Ontology class person
to the first label row (data unit) of the specified Project. The object label is applied to the first frame.
#Import dependencies
from typing import List
from encord import EncordUserClient
from encord.objects import LabelRowV2, Object, ObjectInstance, OntologyStructure
from encord.objects.coordinates import BoundingBoxCoordinates
# Instantiate Encord client by replacing <private_key_path> with the path to your private key
user_client = EncordUserClient.create_with_ssh_private_key(
ssh_private_key_path="<private_key_path>"
)
# Specify the project. Replace <project_hash> with the hash of your Project
project = user_client.get_project("<project_hash>")
# For simplicity, get only the first label row
first_label_row: List[LabelRowV2] = project.list_label_rows_v2()[0]
# Download the existing labels
first_label_row.initialise_labels()
# Find a bounding box annotation object in the Project' Ontology
ontology_structure: OntologyStructure = label_row.ontology_structure
box_ontology_object: Object = ontology_structure.get_child_by_title(
title="person", type_=Object
)
# Instantiate an object instance from the box ontology node
box_object_instance: ObjectInstance = box_ontology_object.create_instance()
box_object_instance.set_for_frames(
coordinates=BoundingBoxCoordinates(
height=0.5,
width=0.5,
top_left_x=0.2,
top_left_y=0.2,
),
# Add the bounding box to the first frame
frames=0,
# There are multiple additional fields that can be set optionally:
manual_annotation=True,
)
# Link the object instance to the label row.
first_label_row.add_object_instance(box_object_instance)
# Upload the label to the server
first_label_row.save()
The following code adds a rotatable bounding box for the Ontology class person
to the first label row (data unit) of the specified Project. The object label is applied to the first frame.
#Import dependencies
from typing import List
from encord import EncordUserClient
from encord.objects import LabelRowV2, Object, ObjectInstance, OntologyStructure
from encord.objects.coordinates import RotatableBoundingBoxCoordinates
# Instantiate Encord client by replacing <private_key_path> with the path to your private key
user_client = EncordUserClient.create_with_ssh_private_key(
ssh_private_key_path="<private_key_path>"
)
# Specify the project. Replace <project_hash> with the hash of your Project
project = user_client.get_project("<project_hash>")
# For simplicity, get only the first label row
first_label_row: List[LabelRowV2] = project.list_label_rows_v2()[0]
# Download the existing labels
first_label_row.initialise_labels()
# Find a rotatable bounding box annotation object in the project ontology
ontology_structure: OntologyStructure = label_row.ontology_structure
rbb_ontology_object: Object = ontology_structure.get_child_by_title(
title="person", type_=Object
)
# Instantiate an object instance from the rotatable bounding box ontology node
rbb_object_instance: ObjectInstance = rbb_ontology_object.create_instance()
rbb_object_instance.set_for_frames(
coordinates=RotatableBoundingBoxCoordinates(
height=0.5,
width=0.5,
top_left_x=0.2,
top_left_y=0.2,
theta=305.7762
),
# Add the bounding box to the first frame
frames=0,
# There are multiple additional fields that can be set optionally:
manual_annotation=True,
)
# Link the object instance to the label row.
first_label_row.add_object_instance(rbb_object_instance)
# Upload the label to the server
first_label_row.save()
The following example adds a polygon for the Ontology class person
to the first label row (data unit) of the specified Project. The object label is applied to the first frame.
from typing import List
from encord import EncordUserClient
from encord.objects import LabelRowV2, Object, ObjectInstance, OntologyStructure
from encord.objects.coordinates import PolygonCoordinates, PointCoordinate
# Instantiate Encord client by replacing <private_key_path> with the path to your private key
user_client = EncordUserClient.create_with_ssh_private_key(
ssh_private_key_path="<private_key_path>"
)
# Specify the project. Replace <project_hash> with the hash of your Project
project = user_client.get_project("<project_hash>")
# For simplicity, get only the first label row
first_label_row: List[LabelRowV2] = project.list_label_rows_v2()[0]
# Download the existing labels
first_label_row.initialise_labels()
# Find a polygon annotation object in the project ontology
ontology_structure: OntologyStructure = label_row.ontology_structure
polygon_ontology_object: Object = ontology_structure.get_child_by_title(
title="person", type_=Object
)
# Instantiate an object instance from the polygon ontology node
polygon_object_instance: ObjectInstance = polygon_ontology_object.create_instance()
# The x,y coordinates of each polygon vertex are specified as follows
polygon_object_instance.set_for_frames(
coordinates=PolygonCoordinates(
[PointCoordinate(.32,.45), PointCoordinate(.59,.45), PointCoordinate(.137,.95), PointCoordinate(.137,.240)]
),
# Add the polygon to the first frame
frames=0,
# There are multiple additional fields that can be set optionally:
manual_annotation=True,
)
# Link the object instance to the label row.
first_label_row.add_object_instance(polygon_object_instance)
# Upload the label to the server
first_label_row.save()
The following example adds a polyline label for the Ontology class snake
to the first label row (data unit) of the specified Project. The object label is applied to the first frame.
# Import dependencies
from typing import List
from encord import EncordUserClient
from encord.objects import LabelRowV2, Object, ObjectInstance, OntologyStructure
from encord.objects.coordinates import PolylineCoordinates, PointCoordinate
# Instantiate Encord client by replacing <private_key_path> with the path to your private key
user_client = EncordUserClient.create_with_ssh_private_key(
ssh_private_key_path="<private_key_path>"
)
# Specify the project. Replace <project_hash> with the hash of your Project
project = user_client.get_project("<project_hash>")
# For simplicity, get only the first label row
first_label_row: List[LabelRowV2] = project.list_label_rows_v2()[0]
# Download the existing labels
first_label_row.initialise_labels()
# Find a polyline annotation object in the project ontology
ontology_structure: OntologyStructure = label_row.ontology_structure
polyline_ontology_object: Object = ontology_structure.get_child_by_title(
title="snake", type_=Object
)
# Instantiate an object instance from the polyline ontology node
polyline_object_instance: ObjectInstance = polyline_ontology_object.create_instance()
# The x,y coordinates of each polyline vertex are specified as follows
polyline_object_instance.set_for_frames(
coordinates=PolylineCoordinates(
[PointCoordinate(.32,.45), PointCoordinate(.59,.45), PointCoordinate(.137,.95), PointCoordinate(.137,.240)]
),
# Add the polyline to the first frame
frames=0,
# There are multiple additional fields that can be set optionally:
manual_annotation=True,
)
# Link the object instance to the label row.
first_label_row.add_object_instance(polyline_object_instance)
# Upload the label to the server
first_label_row.save()
The following example adds a bounding box for the Ontology class star
to the first label row (data unit) of the specified Project. The object label is applied to the first frame.
# Import dependencies
from typing import List
from encord import EncordUserClient
from encord.objects import LabelRowV2, Object, ObjectInstance, OntologyStructure
from encord.objects.coordinates import PointCoordinate
# Instantiate Encord client by replacing <private_key_path> with the path to your private key
user_client = EncordUserClient.create_with_ssh_private_key(
ssh_private_key_path="<private_key_path>"
)
# Specify the project. Replace <project_hash> with the hash of your Project
project = user_client.get_project("<project_hash>")
# For simplicity, get only the first label row
first_label_row: List[LabelRowV2] = project.list_label_rows_v2()[0]
# Download the existing labels
first_label_row.initialise_labels()
# Find a keypoint annotation object in the project ontology
ontology_structure: OntologyStructure = label_row.ontology_structure
keypoint_ontology_object: Object = ontology_structure.get_child_by_title(
title="star", type_=Object
)
# Instantiate an object instance from the keypoint ontology node
keypoint_object_instance: ObjectInstance = keypoint_ontology_object.create_instance()
# The x,y coordinates of the keypoint are specified as follows
keypoint_object_instance.set_for_frames(
coordinates=PointCoordinate(
x: .78
y: .239
),
# Add the keypoint to the first frame
frames=0,
# There are multiple additional fields that can be set optionally:
manual_annotation=True,
)
# Link the object instance to the label row.
first_label_row.add_object_instance(keypoint_object_instance)
# Upload the label to the server
first_label_row.save()
See our dedicated documentation to learn how to import Bitmask annotations into Encord.
The following example adds a bitmask for the Ontology class Lung
to the first label row (data unit) of the specified Project. The object label is applied to the first frame.
# Import dependencies
from typing import List
import numpy as np
from encord import EncordUserClient
from encord.objects import LabelRowV2, Object, ObjectInstance, OntologyStructure
from encord.objects.coordinates import BitmaskCoordinates
# Instantiate Encord client by replacing <private_key_path> with the path to your private key
user_client = EncordUserClient.create_with_ssh_private_key(
ssh_private_key_path="<private_key_path>"
)
# Specify the project. Replace <project_hash> with the hash of your Project
project = user_client.get_project("<project_hash>")
# For simplicity, get only the first label row
first_label_row: List[LabelRowV2] = project.list_label_rows_v2()[0]
# Download the existing labels
first_label_row.initialise_labels()
# Find a bitmask annotation object in the project ontology
ontology_structure: OntologyStructure = label_row.ontology_structure
bitmask_ontology_object: Object = ontology_structure.get_child_by_title(
title="Lung", type_=Object
)
# Instantiate an object instance from the bitmask ontology node
bitmask_object_instance: ObjectInstance = bitmask_ontology_object.create_instance()
# The coordinates the bitmask are specified as follows
bitmask_ontology_object_instance.set_for_frames(
# Create coordinates from provided numpy bitmask
coordinates=BitmaskCoordinates(numpy_coordinates),
# Add the bitmask to the first frame
frames=0,
manual_annotation=True,
)
# Link the object instance to the label row.
first_label_row.add_object_instance(bitmask_object_instance)
# Upload the label to the server
first_label_row.save()
Multiple Frames
When working with videos, an object instance may appear in multiple frames. For example, when tracking a car across frames, create a single object instance and place it on each frame where it appears. If objects are unique to each frame, create a new instance for each frame.
The following example places bounding boxes on frames 3,4 and 5 of the first label row (data unit) in a Project. Each bounding box is a person
object label.
# Import dependencies
from typing import List
from encord import EncordUserClient
from encord.objects import LabelRowV2, Object, ObjectInstance, OntologyStructure
from encord.objects.coordinates import BoundingBoxCoordinates
# Instantiate Encord client by replacing <private_key_path> with the path to your private key
user_client = EncordUserClient.create_with_ssh_private_key(
ssh_private_key_path="<private_key_path>"
)
# Specify the project. Replace <project_hash> with the hash of your Project
project = user_client.get_project("<project_hash>")
# For simplicity, get only the first label row
first_label_row: LabelRowV2 = project.list_label_rows_v2()[0]
# Download the existing labels
first_label_row.initialise_labels()
# Retrieve the ontology structure and find the bounding box object
ontology_structure: OntologyStructure = first_label_row.ontology_structure
box_ontology_object = ontology_structure.get_child_by_title(
title="person", type_=Object
)
# Instantiate an object instance from the box ontology node
box_object_instance: ObjectInstance = box_ontology_object.create_instance()
# Coordinates for bounding boxes on frames 3, 4, and 5
coordinates_per_frame = {
3: BoundingBoxCoordinates(
height=0.5,
width=0.5,
top_left_x=0.2,
top_left_y=0.2,
),
4: BoundingBoxCoordinates(
height=0.5,
width=0.5,
top_left_x=0.3,
top_left_y=0.3,
),
5: BoundingBoxCoordinates(
height=0.5,
width=0.5,
top_left_x=0.4,
top_left_y=0.4,
),
}
# Add the bounding boxes to the object instance for each frame
for frame_number, coordinates in coordinates_per_frame.items():
box_object_instance.set_for_frames(
coordinates=coordinates, frames=frame_number
)
# Link the object instance to the label row
first_label_row.add_object_instance(box_object_instance)
# Save the updated labels back to the server
first_label_row.save()
The following example places rotatable bounding boxes on frames 3,4 and 5 of the first label row (data unit) in a Project. Each rotatable bounding box is a person
object label.
# Import dependencies
from typing import List
from encord import EncordUserClient
from encord.objects import LabelRowV2, Object, ObjectInstance, OntologyStructure
from encord.objects.coordinates import RotatableBoundingBoxCoordinates
# Instantiate Encord client by replacing <private_key_path> with the path to your private key
user_client = EncordUserClient.create_with_ssh_private_key(
ssh_private_key_path="<private_key_path>"
)
# Specify the project. Replace <project_hash> with the hash of your Project
project = user_client.get_project("<project_hash>")
# For simplicity, get only the first label row
first_label_row: LabelRowV2 = project.list_label_rows_v2()[0]
# Download the existing labels
first_label_row.initialise_labels()
# Retrieve the ontology structure and find the bounding box object
ontology_structure: OntologyStructure = first_label_row.ontology_structure
box_ontology_object = ontology_structure.get_child_by_title(
title="person", type_=Object
)
# Instantiate an object instance from the box ontology node
box_object_instance: ObjectInstance = box_ontology_object.create_instance()
# Coordinates for bounding boxes on frames 3, 4, and 5
coordinates_per_frame = {
3: RotatableBoundingBoxCoordinates(
height=0.5,
width=0.5,
top_left_x=0.2,
top_left_y=0.2,
theta=305.7762
),
4: RotatableBoundingBoxCoordinates(
height=0.5,
width=0.5,
top_left_x=0.3,
top_left_y=0.3,
theta=306.7762
),
5: RotatableBoundingBoxCoordinates(
height=0.5,
width=0.5,
top_left_x=0.4,
top_left_y=0.4,
theta=325.7312
),
}
# Add the rotatable bounding boxes to the object instance for each frame
for frame_number, coordinates in coordinates_per_frame.items():
box_object_instance.set_for_frames(
coordinates=coordinates, frames=frame_number
)
# Link the object instance to the label row
first_label_row.add_object_instance(box_object_instance)
# Save the updated labels back to the server
first_label_row.save()
The following example places polygons on frames 3,4 and 5 of the first label row (data unit) in a Project. Each polygon is a person
object label.
# Import dependencies
from typing import List
from encord import EncordUserClient
from encord.objects import LabelRowV2, Object, ObjectInstance, OntologyStructure
from encord.objects.coordinates import PolygonCoordinates, PointCoordinate
# Instantiate Encord client by replacing <private_key_path> with the path to your private key
user_client = EncordUserClient.create_with_ssh_private_key(
ssh_private_key_path="<private_key_path>"
)
# Specify the project. Replace <project_hash> with the hash of your Project
project = user_client.get_project("<project_hash>")
# For simplicity, get only the first label row
first_label_row: LabelRowV2 = project.list_label_rows_v2()[0]
# Download the existing labels
first_label_row.initialise_labels()
# Retrieve the ontology structure and find the polygon object
ontology_structure: OntologyStructure = first_label_row.ontology_structure
polygon_ontology_object = ontology_structure.get_child_by_title(
title="person", type_=Object
)
# Instantiate an object instance from the polygon ontology node
polygon_object_instance: ObjectInstance = polygon_ontology_object.create_instance()
# Define polygon coordinates for frames 3, 4, and 5
coordinates_per_frame = {
3: PolygonCoordinates([
PointCoordinate(0.32, 0.45),
PointCoordinate(0.59, 0.45),
PointCoordinate(0.37, 0.95),
PointCoordinate(0.37, 0.24),
]),
4: PolygonCoordinates([
PointCoordinate(0.40, 0.50),
PointCoordinate(0.70, 0.50),
PointCoordinate(0.50, 0.90),
PointCoordinate(0.30, 0.30),
]),
5: PolygonCoordinates([
PointCoordinate(0.45, 0.55),
PointCoordinate(0.75, 0.55),
PointCoordinate(0.55, 0.85),
PointCoordinate(0.35, 0.35),
]),
}
# Add the polygons to the object instance for each frame
for frame_number, coordinates in coordinates_per_frame.items():
polygon_object_instance.set_for_frames(
coordinates=coordinates, frames=frame_number
)
# Link the object instance to the label row
first_label_row.add_object_instance(polygon_object_instance)
# Save the updated labels back to the server
first_label_row.save()
The following example places polylines on frames 3,4 and 5 of the first label row (data unit) in a Project. Each polyline is a snake
object label.
# Import dependencies
from typing import List
from encord import EncordUserClient
from encord.objects import LabelRowV2, Object, ObjectInstance, OntologyStructure
from encord.objects.coordinates import PolylineCoordinates, PointCoordinate
# Instantiate Encord client by replacing <private_key_path> with the path to your private key
user_client = EncordUserClient.create_with_ssh_private_key(
ssh_private_key_path="<private_key_path>"
)
# Specify the project. Replace <project_hash> with the hash of your Project
project = user_client.get_project("<project_hash>")
# For simplicity, get only the first label row
first_label_row: LabelRowV2 = project.list_label_rows_v2()[0]
# Download the existing labels
first_label_row.initialise_labels()
# Retrieve the ontology structure and find the polyline object
ontology_structure: OntologyStructure = first_label_row.ontology_structure
polyline_ontology_object: Object = ontology_structure.get_child_by_title(
title="snake", type_=Object
)
# Instantiate an object instance from the polyline ontology node
polyline_object_instance: ObjectInstance = polyline_ontology_object.create_instance()
# Define polyline coordinates for frames 3, 4, and 5
coordinates_per_frame = {
3: PolylineCoordinates([
PointCoordinate(0.32, 0.45),
PointCoordinate(0.59, 0.45),
PointCoordinate(0.37, 0.95),
PointCoordinate(0.37, 0.24),
]),
4: PolylineCoordinates([
PointCoordinate(0.40, 0.50),
PointCoordinate(0.70, 0.50),
PointCoordinate(0.50, 0.90),
PointCoordinate(0.30, 0.30),
]),
5: PolylineCoordinates([
PointCoordinate(0.45, 0.55),
PointCoordinate(0.75, 0.55),
PointCoordinate(0.55, 0.85),
PointCoordinate(0.35, 0.35),
]),
}
# Add the polylines to the object instance for each frame
for frame_number, coordinates in coordinates_per_frame.items():
polyline_object_instance.set_for_frames(
coordinates=coordinates, frames=frame_number
)
# Link the object instance to the label row
first_label_row.add_object_instance(polyline_object_instance)
# Save the updated labels back to the server
first_label_row.save()
The following example places keypoints on frames 3,4 and 5 of the first label row (data unit) in a Project. Each keypoint is a star
object label.
# Import dependencies
from typing import List
from encord import EncordUserClient
from encord.objects import LabelRowV2, Object, ObjectInstance, OntologyStructure
from encord.objects.coordinates import PointCoordinate
# Instantiate Encord client by replacing <private_key_path> with the path to your private key
user_client = EncordUserClient.create_with_ssh_private_key(
ssh_private_key_path="<private_key_path>"
)
# Specify the project. Replace <project_hash> with the hash of your Project
project = user_client.get_project("<project_hash>")
# For simplicity, get only the first label row
first_label_row: LabelRowV2 = project.list_label_rows_v2()[0]
# Download the existing labels
first_label_row.initialise_labels()
# Retrieve the ontology structure and find the keypoint object
ontology_structure: OntologyStructure = first_label_row.ontology_structure
keypoint_ontology_object: Object = ontology_structure.get_child_by_title(
title="star", type_=Object
)
# Instantiate an object instance from the keypoint ontology node
keypoint_object_instance: ObjectInstance = keypoint_ontology_object.create_instance()
# Define keypoint coordinates for frames 3, 4, and 5
coordinates_per_frame = {
3: PointCoordinate(x=0.78, y=0.239),
4: PointCoordinate(x=0.80, y=0.250),
5: PointCoordinate(x=0.82, y=0.260),
}
# Add the keypoints to the object instance for each frame
for frame_number, coordinates in coordinates_per_frame.items():
keypoint_object_instance.set_for_frames(
coordinates=coordinates, frames=frame_number
)
# Link the object instance to the label row
first_label_row.add_object_instance(keypoint_object_instance)
# Save the updated labels back to the server
first_label_row.save()
The following example places bitmasks on frames 3,4 and 5 of the first label row (data unit) in a Project. Each bitmask is a lung
object label.
# Import dependencies
from typing import List
import numpy as np
from encord import EncordUserClient
from encord.objects import LabelRowV2, Object, ObjectInstance, OntologyStructure
from encord.objects.coordinates import BitmaskCoordinates
# Instantiate Encord client by replacing <private_key_path> with the path to your private key
user_client = EncordUserClient.create_with_ssh_private_key(
ssh_private_key_path="<private_key_path>"
)
# Specify the project. Replace <project_hash> with the hash of your Project
project = user_client.get_project("<project_hash>")
# For simplicity, get only the first label row
first_label_row: LabelRowV2 = project.list_label_rows_v2()[0]
# Download the existing labels
first_label_row.initialise_labels()
# Retrieve the ontology structure and find the bitmask object
ontology_structure: OntologyStructure = first_label_row.ontology_structure
bitmask_ontology_object: Object = ontology_structure.get_child_by_title(
title="Lung", type_=Object
)
# Instantiate an object instance from the bitmask ontology node
bitmask_object_instance: ObjectInstance = bitmask_ontology_object.create_instance()
# Define bitmask coordinates for frames 3, 4, and 5
coordinates_per_frame = {
3: BitmaskCoordinates(np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]], dtype=np.uint8)),
4: BitmaskCoordinates(np.array([[0, 1, 0], [1, 0, 1], [0, 1, 0]], dtype=np.uint8)),
5: BitmaskCoordinates(np.array([[1, 1, 1], [0, 0, 0], [1, 1, 1]], dtype=np.uint8)),
}
# Add the bitmasks to the object instance for each frame
for frame_number, coordinates in coordinates_per_frame.items():
bitmask_object_instance.set_for_frames(
coordinates=coordinates, frames=frame_number, manual_annotation=True
)
# Link the object instance to the label row
first_label_row.add_object_instance(bitmask_object_instance)
# Save the updated labels back to the server
first_label_row.save()
Edit labels
Editing labels after they have been created involves the following steps:
The script below shows how to update the location of an object’s bounding box, and attribute values. Ensure you substitute the following values:
<private_key_path>
with the full path to your private key.<project_hash>
with the name of the project you want to update labels in.<file_name>
with the name of the file / data unit you want to edit labels for.<object_name>
with the name of the object.<attribute_name>
with the name of the attribute.<option_name>
with the name of the radio button option of the attribute.
# Import dependencies
from typing import List
from encord import EncordUserClient
from encord.objects import LabelRowV2, Object, ObjectInstance, OntologyStructure
from encord.objects.coordinates import BoundingBoxCoordinates
# Instantiate Encord client by replacing <private_key_path> with the path to your private key
user_client = EncordUserClient.create_with_ssh_private_key(
ssh_private_key_path="<private_key_path>"
)
# Specify the project. Replace <project_hash> with the hash of your Project
project = user_client.get_project("<project_hash>")
# Specify the label row you want to edit labels for. This example takes the first label row
# Replace the <file_name.mp4> with the name of the file you want to change labels for
first_label_row = project.list_label_rows_v2(
data_title_eq="<file_name>"
)[0]
# Download the existing labels
first_label_row.initialise_labels()
# Get the first object instance in the label row
ontology_structure = first_label_row.ontology_structure
# Gets the object instance we want to edit the label for. This example uses the first
first_obj_instance = first_label_row.get_object_instances()[0]
# Specifies which Ontology object to change labels for
# Replace <object_name> with the name of your object. For example 'Flower'
my_object = ontology_structure.get_child_by_title(title="<object_name>")
# Sets coordinates for the specified object instance
# This example changes the location of a bounding box
first_obj_instance.set_for_frames(
coordinates = BoundingBoxCoordinates(
height=0.1474,
width =0.1154,
top_left_x=0.1097,
top_left_y=0.3209
),
# Overwrites if annotations are already present
manual_annotation=False, overwrite=True
)
# Selects a Radio button attribute
# Replace <attribute_name> with the name of the attribute you want to edit. For example 'Flower species'
my_attribute = my_object.get_child_by_title(title="<attribute_name>", type_=RadioAttribute)
# Selects the radio button option of the attribute
# Replace <option_name> with the name of the option. For example 'Sunflower'
attribute_option = my_attribute.get_child_by_title(title="<option_name>", type_= Option)
# Sets the attribute to the attribute_option defined above
first_object_instance.set_answer(attribute_option, overwrite=True)
# Once you have updated labels and attributes, save your changes
first_label_row.save()
View Object Instances
The following example prints all object instance for a specified label row (data unit).
# Import dependencies
from typing import List
from encord import EncordUserClient
from encord.objects import LabelRowV2, Object, ObjectInstance
# Instantiate Encord client by replacing <private_key_path> with the path to your private key
user_client = EncordUserClient.create_with_ssh_private_key(
ssh_private_key_path="<private_key_path>"
)
# Specify the project. Replace <project_hash> with the hash of your Project
project = user_client.get_project("<project_hash>")
# For simplicity, get only the first label row
first_label_row: List[LabelRowV2] = project.list_label_rows_v2()[0]
# Download the existing labels
first_label_row.initialise_labels()
# Check the get_object_instances optional filters for when you have many different object/classification instances.
all_object_instances: List[
ObjectInstance
] = first_label_row.get_object_instances()
# Print all object instances
for instance in all_object_instances:
print(instance)
# Optionally verify certain conditions are true
assert all_object_instances[0] == box_object_instance
assert all_object_instances[0].get_annotation(frame=0).manual_annotation is True
Create Classifications
The following example assumes the Ontology includes a text classification field named Mood
. In this example, the text classification for the first label row (data unit) in the Project is set to Melancholy
on the first frame.
- Replace
<private_key_path>
with the key to your private key for authentication. - Replace
<project_hash>
with the hash of your Project. - Replace the Classification names and answers to suit your needs.
# Import dependencies
from typing import List
from encord import EncordUserClient
from encord.objects import LabelRowV2, Classification, ClassificationInstance, OntologyStructure
# Instantiate Encord client by replacing <private_key_path> with the path to your private key
user_client = EncordUserClient.create_with_ssh_private_key(
ssh_private_key_path="<private_key_path>"
)
# Specify the Project. Replace <project_hash> with the hash of your Project
project = user_client.get_project("<project_hash>")
# For simplicity, get only the first label row
first_label_row: List[LabelRowV2] = project.list_label_rows_v2()[0]
# Download the existing labels
first_label_row.initialise_labels()
# Get Ontology Structure
ontology_structure: OntologyStructure = first_label_row.ontology_structure
# Assume that the following text classification exists in the Ontology.
text_ontology_classification: Classification = (
ontology_structure.get_child_by_title(
title="Mood", type_=Classification
)
)
text_classification_instance = text_ontology_classification.create_instance()
# Set the value of the classification instance
text_classification_instance.set_answer(answer="Melancholy")
# Select the frames where the classification instance is present
text_classification_instance.set_for_frames(frames=0)
# Add it to the label row
first_label_row.add_classification_instance(text_classification_instance)
# Save labels
first_label_row.save()
The example for single Radio Button Classifications assumes the Ontology includes a radio button classification named Weather
. In this example, the Radio button classification answer for the first label row (data unit) in the Project is set to Rainy
on the first frame.
The example for nested radio buttons assumes the Ontology includes a radio button classification called Visible
. The classification answer is set to Cat
and the nested radio attribute is set to Multiple
.
The following example assumes the Ontology includes a checklist classification field named What is visible?
. In this example, the text attribute for the first label row (data unit) in the project is set to Monkey
and Parrot
on the first frame.
# Import dependencies
from typing import List
from encord import EncordUserClient
from encord.objects import LabelRowV2, Classification, ClassificationInstance, Option
# Instantiate Encord client by replacing <private_key_path> with the path to your private key
user_client = EncordUserClient.create_with_ssh_private_key(
ssh_private_key_path="<private_key_path>"
)
# Specify the Project. Replace <project_hash> with the hash of your Project
project = user_client.get_project("<project_hash>")
# For simplicity, get only the first label row
first_label_row: List[LabelRowV2] = project.list_label_rows_v2()[0]
# Download the existing labels
first_label_row.initialise_labels()
# Assume that the following checklist classification exists in the Ontology.
checklist_ontology_classification: Classification = (
ontology_structure.get_child_by_title(
title="What is visible?", type_=Classification
)
)
# Find the option you want to add in the Ontology
monkey_option = checklist_ontology_classification.get_child_by_title(
title="Monkey",
type_=Option
)
# Find the option you want to add in the Ontology
parrot_option = checklist_ontology_classification.get_child_by_title(
title="Parrot",
type_=Option
)
checklist_classification_instance = checklist_ontology_classification.create_instance()
# Set the value of the classification instance
checklist_classification_instance.set_answer([monkey_option, parrot_option])
# Select the frames where the classification instance is present
checklist_classification_instance.set_for_frames(frames=0)
# Add it to the label row
first_label_row.add_classification_instance(checklist_classification_instance)
# Save labels
first_label_row.save()
Add attribute
The following scripts assume that an object label called Whale
has already been created. Each script retrieves the object instance and searches for the corresponding attribute within the Project’s Ontology. For radio buttons and checklists, the scripts also identify the relevant attribute options.
- Replace
<private_key_path>
with the key to your private key for authentication. - Replace
<project_hash>
with the hash of your Project. - Replace
Whale
with the name of your object. - Replace the attributes and attribute answers to suit your needs.
Nested Attributes
Radio button attributes can be nested. The following script assumes that an object label called Whale
has already been created. To learn how to create a new object instance see the section here.
Radio attributes can also be nested under classifications. See here to learn how to do this.
# Import dependencies
from typing import List
from encord import EncordUserClient
from encord.objects import LabelRowV2, Classification, ClassificationInstance, Option
# Instantiate Encord client by replacing <private_key_path> with the path to your private key
user_client = EncordUserClient.create_with_ssh_private_key(
ssh_private_key_path="<private_key_path>"
)
# Specify the Project. Replace <project_hash> with the hash of your Project
project = user_client.get_project("<project_hash>")
# For simplicity, get only the first label row
first_label_row: List[LabelRowV2] = project.list_label_rows_v2()[0]
# Download the existing labels
first_label_row.initialise_labels()
# Get the ontology structure
ontology_structure: OntologyStructure = first_label_row.ontology_structure
# Find Object label
object_label = ontology_structure.get_child_by_title(
title="Whale",
type_=Object
)
# Create object instance. We assume only 1 label
object_instance = first_label_row.get_object_instances()[0]
# Find the attribute
object_attribute = object_label.get_child_by_title("Colour")
# Find the attribute option you want to set
attribute_option = object_attribute.get_child_by_title(
title="Blue",
type_=Option
)
# Set the attribute option
object_instance.set_answer(attribute_option)
# Assume that the following radio button classification exists in the Ontology.
nested_radio_ontology_attribute: Classification = (
ontology_structure.get_child_by_title(
title="Any Other Colours?", type_=RadioAttribute
)
)
# Assume the following radio button nested attribute exists in the Ontology
nested_radio_attribute_option = object_label.get_child_by_title(
title="Pink",
type_=Option
)
# Save labels
first_label_row.save()
Relation Attributes
Relation attributes work the exact same way as text attributes, except that when an attribute is marked as Relation the string #relation
is appended to the attribute name.
# Import dependencies
from typing import List
from encord import EncordUserClient
from encord.objects import LabelRowV2, Classification, ClassificationInstance, Option
# Instantiate Encord client by replacing <private_key_path> with the path to your private key
user_client = EncordUserClient.create_with_ssh_private_key(
ssh_private_key_path="<private_key_path>"
)
# Specify the Project. Replace <project_hash> with the hash of your Project
project = user_client.get_project("<project_hash>")
# For simplicity, get only the first label row
first_label_row: List[LabelRowV2] = project.list_label_rows_v2()[0]
# Download the existing labels
first_label_row.initialise_labels()
# Get the Ontology structure
ontology_structure: OntologyStructure = first_label_row.ontology_structure
# Assume that the following text attribute exists in the Ontology.
object_label = ontology_structure.get_child_by_title(
title="Whale",
type_=Object
)
# Create object instance. We assume only 1 label
object_instance = first_label_row.get_object_instances()[0]
# Find the attribute name
attribute = object_label.get_child_by_title("Description #relation")
# Set the answer for the attribute
object_instance.set_answer(attribute=attribute, answer="This is a picture of a whale")
# Save labels
first_label_row.save()
Dynamic Attributes
Dynamic attributes are attributes for object instances where the answer can change in each frame. You can read more about them here.
The following example adds bounding boxes for the label Person
to three frames. It then sets the dynamic attribute Position
to Walking
and Standing
. Wherever you can set frames, you can either set a single integer, a Range, or a list of Ranges.
# Import dependencies
from typing import List
from encord import EncordUserClient
from encord.objects import LabelRowV2, Object, ObjectInstance, OntologyStructure
from encord.objects.coordinates import PolygonCoordinates, PointCoordinate
# Instantiate Encord client by replacing <private_key_path> with the path to your private key
user_client = EncordUserClient.create_with_ssh_private_key(
ssh_private_key_path="<private_key_path>"
)
# Specify the project. Replace <project_hash> with the hash of your Project
project = user_client.get_project("<project_hash>")
# For simplicity, get only the first label row
first_label_row: LabelRowV2 = project.list_label_rows_v2()[0]
# Download the existing labels
first_label_row.initialise_labels()
# Find the object in the Ontology
person_ontology_object: Object = ontology_structure.get_child_by_title(
"Person", type_=Object
)
# Find the dynamic attribute in the Ontology
position_attribute = person_ontology_object.get_child_by_title(
title="Position", # The options here are "Standing" or "Walking"
type_=RadioAttribute,
)
# Coordinates for bounding boxes on frames 3, 4, and 5
coordinates_per_frame = {
3: BoundingBoxCoordinates(
height=0.5,
width=0.5,
top_left_x=0.2,
top_left_y=0.2,
),
4: BoundingBoxCoordinates(
height=0.5,
width=0.5,
top_left_x=0.3,
top_left_y=0.3,
),
5: BoundingBoxCoordinates(
height=0.5,
width=0.5,
top_left_x=0.4,
top_left_y=0.4,
),
}
# Add the bounding box labels to the object instance for each frame
for frame_number, coordinates in coordinates_per_frame.items():
box_object_instance.set_for_frames(
coordinates=coordinates, frames=frame_number
)
# Link the object instance to the label row
first_label_row.add_object_instance(box_object_instance)
# Assume the person is standing in frame 1
person_object_instance.set_answer(
answer=position_attribute.get_child_by_title("Standing", type_=Option),
frames=0,
)
# Assume the person is walking in frames 2 and 3
person_object_instance.set_answer(
answer=position_attribute.get_child_by_title("Walking", type_=Option),
frames=Range(start=1, end=3),
)
# Save labels
first_label_row.save()
Exporting Labels
Exporting labels is a crucial operation in Encord. The SDK provides a flexible and customizable approach to downloading label information, meaning there is no single method for exporting labels. For comprehensive details and various examples, refer to our export documentation here.
Was this page helpful?