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.
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.
Copy
# Import dependenciesfrom typing import Listfrom encord import EncordUserClientfrom encord.objects import LabelRowV2# Authenticationuser_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 Projectproject = user_client.get_project("<project_hash>")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}")
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):
Copy
# Import dependenciesfrom typing import Listfrom encord import EncordUserClientfrom encord.objects import LabelRowV2, Object, ObjectInstance, OntologyStructurefrom encord.objects.coordinates import BoundingBoxCoordinates# Instantiate Encord client by replacing <private_key_path> with the path to your private keyuser_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 Projectproject = user_client.get_project("<project_hash>")# For simplicity, get only the first label rowfirst_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 rowontology_structure = first_label_row.ontology_structure# Gets the object instance we want to edit the label for. This example uses the firstfirst_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 boxfirst_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 boxfirst_label_row.save()
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.
Bounding box
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.
Copy
#Import dependenciesfrom typing import Listfrom encord import EncordUserClientfrom encord.objects import LabelRowV2, Object, ObjectInstance, OntologyStructurefrom encord.objects.coordinates import BoundingBoxCoordinates# Instantiate Encord client by replacing <private_key_path> with the path to your private keyuser_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 Projectproject = user_client.get_project("<project_hash>")# For simplicity, get only the first label rowfirst_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's Ontologyontology_structure: OntologyStructure = first_label_row.ontology_structurebox_ontology_object: Object = ontology_structure.get_child_by_title( title="person", type_=Object )# Instantiate an object instance from the box ontology nodebox_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 serverfirst_label_row.save()
Rotatable bounding box
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.
Copy
#Import dependenciesfrom typing import Listfrom encord import EncordUserClientfrom encord.objects import LabelRowV2, Object, ObjectInstance, OntologyStructurefrom encord.objects.coordinates import RotatableBoundingBoxCoordinates# Instantiate Encord client by replacing <private_key_path> with the path to your private keyuser_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 Projectproject = user_client.get_project("<project_hash>")# For simplicity, get only the first label rowfirst_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 ontologyontology_structure: OntologyStructure = first_label_row.ontology_structurerbb_ontology_object: Object = ontology_structure.get_child_by_title( title="person", type_=Object )# Instantiate an object instance from the rotatable bounding box ontology noderbb_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 serverfirst_label_row.save()
Polygon
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.
Copy
from typing import Listfrom encord import EncordUserClientfrom encord.objects import LabelRowV2, Object, ObjectInstance, OntologyStructurefrom encord.objects.coordinates import PolygonCoordinates, PointCoordinate# Instantiate Encord client by replacing <private_key_path> with the path to your private keyuser_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 Projectproject = user_client.get_project("<project_hash>")# For simplicity, get only the first label rowfirst_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 ontologyontology_structure: OntologyStructure = first_label_row.ontology_structurepolygon_ontology_object: Object = ontology_structure.get_child_by_title( title="person", type_=Object )# Instantiate an object instance from the polygon ontology nodepolygon_object_instance: ObjectInstance = polygon_ontology_object.create_instance()# The x,y coordinates of each polygon vertex are specified as followspolygon_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 serverfirst_label_row.save()
Polyline
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.
Copy
# Import dependenciesfrom typing import Listfrom encord import EncordUserClientfrom encord.objects import LabelRowV2, Object, ObjectInstance, OntologyStructurefrom encord.objects.coordinates import PolylineCoordinates, PointCoordinate# Instantiate Encord client by replacing <private_key_path> with the path to your private keyuser_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 Projectproject = user_client.get_project("<project_hash>")# For simplicity, get only the first label rowfirst_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 ontologyontology_structure: OntologyStructure = first_label_row.ontology_structurepolyline_ontology_object: Object = ontology_structure.get_child_by_title( title="snake", type_=Object )# Instantiate an object instance from the polyline ontology nodepolyline_object_instance: ObjectInstance = polyline_ontology_object.create_instance()# The x,y coordinates of each polyline vertex are specified as followspolyline_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 serverfirst_label_row.save()
Keypoint
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.
Copy
# Import dependenciesfrom typing import Listfrom encord import EncordUserClientfrom encord.objects import LabelRowV2, Object, ObjectInstance, OntologyStructurefrom encord.objects.coordinates import PointCoordinate# Instantiate Encord client by replacing <private_key_path> with the path to your private keyuser_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 Projectproject = user_client.get_project("<project_hash>")# For simplicity, get only the first label rowfirst_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 ontologyontology_structure: OntologyStructure = first_label_row.ontology_structurekeypoint_ontology_object: Object = ontology_structure.get_child_by_title( title="star", type_=Object )# Instantiate an object instance from the keypoint ontology nodekeypoint_object_instance: ObjectInstance = keypoint_ontology_object.create_instance()# The x,y coordinates of the keypoint are specified as followskeypoint_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 serverfirst_label_row.save()
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.
Copy
# Import dependenciesfrom typing import Listimport numpy as npfrom encord import EncordUserClientfrom encord.objects import LabelRowV2, Object, ObjectInstance, OntologyStructurefrom encord.objects.coordinates import BitmaskCoordinates# Instantiate Encord client by replacing <private_key_path> with the path to your private keyuser_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 Projectproject = user_client.get_project("<project_hash>")# For simplicity, get only the first label rowfirst_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 ontologyontology_structure: OntologyStructure = first_label_row.ontology_structurebitmask_ontology_object: Object = ontology_structure.get_child_by_title( title="Lung", type_=Object)# Instantiate an object instance from the bitmask ontology nodebitmask_object_instance: ObjectInstance = bitmask_ontology_object.create_instance()# The coordinates the bitmask are specified as followsbitmask_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 serverfirst_label_row.save()
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.
Bounding Box
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.
Copy
# Import dependenciesfrom typing import Listfrom encord import EncordUserClientfrom encord.objects import LabelRowV2, Object, ObjectInstance, OntologyStructurefrom encord.objects.coordinates import BoundingBoxCoordinates# Instantiate Encord client by replacing <private_key_path> with the path to your private keyuser_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 Projectproject = user_client.get_project("<project_hash>")# For simplicity, get only the first label rowfirst_label_row: LabelRowV2 = project.list_label_rows_v2()[0]# Download the existing labelsfirst_label_row.initialise_labels()# Retrieve the ontology structure and find the bounding box objectontology_structure: OntologyStructure = first_label_row.ontology_structurebox_ontology_object = ontology_structure.get_child_by_title( title="person", type_=Object)# Instantiate an object instance from the box ontology nodebox_object_instance: ObjectInstance = box_ontology_object.create_instance()# Coordinates for bounding boxes on frames 3, 4, and 5coordinates_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 framefor 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 rowfirst_label_row.add_object_instance(box_object_instance)# Save the updated labels back to the serverfirst_label_row.save()
Rotatable Bounding Box
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.
Copy
# 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()
Polygon
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.
Copy
# 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()
Polyline
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.
Copy
# Import dependenciesfrom typing import Listfrom encord import EncordUserClientfrom encord.objects import LabelRowV2, Object, ObjectInstance, OntologyStructurefrom encord.objects.coordinates import PolylineCoordinates, PointCoordinate# Instantiate Encord client by replacing <private_key_path> with the path to your private keyuser_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 Projectproject = user_client.get_project("<project_hash>")# For simplicity, get only the first label rowfirst_label_row: LabelRowV2 = project.list_label_rows_v2()[0]# Download the existing labelsfirst_label_row.initialise_labels()# Retrieve the ontology structure and find the polyline objectontology_structure: OntologyStructure = first_label_row.ontology_structurepolyline_ontology_object: Object = ontology_structure.get_child_by_title( title="snake", type_=Object)# Instantiate an object instance from the polyline ontology nodepolyline_object_instance: ObjectInstance = polyline_ontology_object.create_instance()# Define polyline coordinates for frames 3, 4, and 5coordinates_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 framefor 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 rowfirst_label_row.add_object_instance(polyline_object_instance)# Save the updated labels back to the serverfirst_label_row.save()
Keypoint
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.
Copy
# 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()
Bitmask
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.
Copy
# 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()
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.
Copy
# Import dependenciesfrom typing import Listfrom encord import EncordUserClientfrom encord.objects import LabelRowV2, Object, ObjectInstance, OntologyStructurefrom encord.objects.coordinates import BoundingBoxCoordinates# Instantiate Encord client by replacing <private_key_path> with the path to your private keyuser_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 Projectproject = 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 forfirst_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 rowontology_structure = first_label_row.ontology_structure# Gets the object instance we want to edit the label for. This example uses the firstfirst_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 boxfirst_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 abovefirst_object_instance.set_answer(attribute_option, overwrite=True)# Once you have updated labels and attributes, save your changesfirst_label_row.save()
The following example prints all object instance for a specified label row (data unit).
Copy
# Import dependenciesfrom typing import Listfrom encord import EncordUserClientfrom encord.objects import LabelRowV2, Object, ObjectInstance# Instantiate Encord client by replacing <private_key_path> with the path to your private keyuser_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 Projectproject = user_client.get_project("<project_hash>")# For simplicity, get only the first label rowfirst_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 instancesfor instance in all_object_instances: print(instance)# Optionally verify certain conditions are trueassert all_object_instances[0] == box_object_instanceassert all_object_instances[0].get_annotation(frame=0).manual_annotation is True
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.
Copy
# Import dependenciesfrom typing import Listfrom encord import EncordUserClientfrom encord.objects import LabelRowV2, Classification, ClassificationInstance, OntologyStructure# Instantiate Encord client by replacing <private_key_path> with the path to your private keyuser_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 Projectproject = user_client.get_project("<project_hash>")# For simplicity, get only the first label rowfirst_label_row: List[LabelRowV2] = project.list_label_rows_v2()[0]# Download the existing labels first_label_row.initialise_labels()# Get Ontology Structureontology_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 instancetext_classification_instance.set_answer(answer="Melancholy")# Select the frames where the classification instance is presenttext_classification_instance.set_for_frames(frames=0)# Add it to the label rowfirst_label_row.add_classification_instance(text_classification_instance)# Save labelsfirst_label_row.save()
Radio Button Classification
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.
Copy
# Import dependenciesfrom typing import Listfrom encord import EncordUserClientfrom encord.objects import LabelRowV2, Classification, Option, OntologyStructure# Instantiate Encord client by replacing <private_key_path> with the path to your private keyuser_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 Projectproject = user_client.get_project("<project_hash>")# For simplicity, get only the first label rowfirst_label_row: List[LabelRowV2] = project.list_label_rows_v2()[0]# Download the existing labels first_label_row.initialise_labels()# Get the Ontology structureontology_structure: OntologyStructure = first_label_row.ontology_structure# Assume that the following radio button classification exists in the Ontology.radio_ontology_classification: Classification = ( ontology_structure.get_child_by_title( title="Weather", type_=Classification ))radio_classification_option = radio_ontology_classification.get_child_by_title(title="Rainy",type_=Option)# Create classification instanceradio_classification_instance = radio_ontology_classification.create_instance()# Set the answer of the classification instanceradio_classification_instance.set_answer(radio_classification_option)# Select the frames where the classification instance is presentradio_classification_instance.set_for_frames(frames=0)# Add it to the label rowfirst_label_row.add_classification_instance(radio_classification_instance)# Save labelsfirst_label_row.save()
Checklist Classification
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.
Copy
# Import dependenciesfrom typing import Listfrom encord import EncordUserClientfrom encord.objects import LabelRowV2, Classification, ClassificationInstance, Option# Instantiate Encord client by replacing <private_key_path> with the path to your private keyuser_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 Projectproject = user_client.get_project("<project_hash>")# For simplicity, get only the first label rowfirst_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 Ontologymonkey_option = checklist_ontology_classification.get_child_by_title( title="Monkey", type_=Option)# Find the option you want to add in the Ontologyparrot_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 instancechecklist_classification_instance.set_answer([monkey_option, parrot_option])# Select the frames where the classification instance is presentchecklist_classification_instance.set_for_frames(frames=0)# Add it to the label rowfirst_label_row.add_classification_instance(checklist_classification_instance)# Save labelsfirst_label_row.save()
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.
Copy
# Import dependenciesfrom typing import Listfrom encord import EncordUserClientfrom encord.objects import LabelRowV2, Classification, ClassificationInstance, Option# Instantiate Encord client by replacing <private_key_path> with the path to your private keyuser_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 Projectproject = user_client.get_project("<project_hash>")# For simplicity, get only the first label rowfirst_label_row: List[LabelRowV2] = project.list_label_rows_v2()[0]# Download the existing labels first_label_row.initialise_labels()# Get the Ontology structureontology_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 labelobject_instance = first_label_row.get_object_instances()[0]# Find the attribute nameattribute = object_label.get_child_by_title("Description")# Set the answer for the attributeobject_instance.set_answer(attribute=attribute, answer="This is a picture of a whale")# Save labelsfirst_label_row.save()
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.
Nested Radio Attributes
Copy
# Import dependenciesfrom typing import Listfrom encord import EncordUserClientfrom encord.objects import LabelRowV2, Classification, ClassificationInstance, Option# Instantiate Encord client by replacing <private_key_path> with the path to your private keyuser_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 Projectproject = user_client.get_project("<project_hash>")# For simplicity, get only the first label rowfirst_label_row: List[LabelRowV2] = project.list_label_rows_v2()[0]# Download the existing labels first_label_row.initialise_labels()# Get the ontology structureontology_structure: OntologyStructure = first_label_row.ontology_structure# Find Object labelobject_label = ontology_structure.get_child_by_title( title="Whale", type_=Object)# Create object instance. We assume only 1 labelobject_instance = first_label_row.get_object_instances()[0]# Find the attributeobject_attribute = object_label.get_child_by_title("Colour")# Find the attribute option you want to setattribute_option = object_attribute.get_child_by_title( title="Blue", type_=Option)# Set the attribute optionobject_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 Ontologynested_radio_attribute_option = object_label.get_child_by_title( title="Pink", type_=Option)# Save labelsfirst_label_row.save()
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.
Learn more about relation attributes in Encord here.
Relation Attributes
Copy
# Import dependenciesfrom typing import Listfrom encord import EncordUserClientfrom encord.objects import LabelRowV2, Classification, ClassificationInstance, Option# Instantiate Encord client by replacing <private_key_path> with the path to your private keyuser_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 Projectproject = user_client.get_project("<project_hash>")# For simplicity, get only the first label rowfirst_label_row: List[LabelRowV2] = project.list_label_rows_v2()[0]# Download the existing labels first_label_row.initialise_labels()# Get the Ontology structureontology_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 labelobject_instance = first_label_row.get_object_instances()[0]# Find the attribute nameattribute = object_label.get_child_by_title("Description #relation")# Set the answer for the attributeobject_instance.set_answer(attribute=attribute, answer="This is a picture of a whale")# Save labelsfirst_label_row.save()
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.
Copy
# Import dependenciesfrom typing import Listfrom encord import EncordUserClientfrom encord.objects import LabelRowV2, Object, ObjectInstance, OntologyStructurefrom encord.objects.coordinates import PolygonCoordinates, PointCoordinate# Instantiate Encord client by replacing <private_key_path> with the path to your private keyuser_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 Projectproject = user_client.get_project("<project_hash>")# For simplicity, get only the first label rowfirst_label_row: LabelRowV2 = project.list_label_rows_v2()[0]# Download the existing labelsfirst_label_row.initialise_labels()# Find the object in the Ontologyperson_ontology_object: Object = ontology_structure.get_child_by_title( "Person", type_=Object)# Find the dynamic attribute in the Ontologyposition_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 5coordinates_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 framefor 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 rowfirst_label_row.add_object_instance(box_object_instance)# Assume the person is standing in frame 1person_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 3person_object_instance.set_answer( answer=position_attribute.get_child_by_title("Walking", type_=Option), frames=Range(start=1, end=3),)# Save labelsfirst_label_row.save()
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.