You can include confidence scores when uploading labels/annotations. Encord automatically calculates model metrics based on your label and prediction sets and assigned confidence scores.
When importing label/annotation sets into a Consensus Project, they are added as branches to individual label rows on your data units (images, videos, audio). Each data unit has the following:
A MAIN branch for ground truth annotations or pre-labels.
Optional Consensus branches and Prediction branches for different label/annotation or prediction sets.
Use branch_name to create a label branch in label_rows_v2 for a data unit.
Use branch_name to create a label branch in label_rows_v2 for a data unit.
branch_name supports alphanumeric characters (a-z, A-Z, 0-9) and is case sensitive
branch_name supports the following special characters: hyphens (-), underscores (_), and periods (.)
Bounding Box
Example 1
Imports a single bounding box (Cherry) to a single image (cherry_001.png).
Example 2:
Imports three instances (tracking an object across three sequential frames: 103, 104, and 105) of a bounding box (Cherry) to a video (Cherries_video.mp4).
Example 3
Imports three bounding boxes (Cherry) to a single image (cherry_001.png).
Example 4:
Imports three instances (tracking 3 different objects across three frames: object 1 - frames 103, 104, 105, object 2 - frames 206, 207, 208, and object 3 - frames 313, 315, 317) of three bounding boxes (Cherry) to a video (Cherries_video.mp4).
Copy
# Import dependenciesimport osfrom pathlib import Pathfrom encord import EncordUserClient, Projectfrom encord.objects import LabelRowV2, Object, OntologyStructure, ObjectInstancefrom encord.objects.coordinates import BoundingBoxCoordinates, RotatableBoundingBoxCoordinates, PolygonCoordinates, PolylineCoordinates, PointCoordinate, BitmaskCoordinates# ConfigurationSSH_PATH = "<file-path-to-ssh-private-key>"PROJECT_ID = "<unique-id-of-your-project>"CONSENSUS_BRANCH_NAME = "<name-of-your-label-branch>"ONTOLOGY_OBJECT_TITLE = "<name-of-ontology-object>" # Name of object label in your OntologyDATA_UNIT_TITLES = ["<data-unit-title-1>", "<data-unit-title-2>"] # List of specific data units# Ensure SSH path and project id are setassert SSH_PATH, "SSH path cannot be None"assert PROJECT_ID, "Project id cannot be None"# Authenticate with Encord using SSH keyuser_client = EncordUserClient.create_with_ssh_private_key( ssh_private_key_path=Path(SSH_PATH).read_text())# Get the project and list label rows for the label branchproject = user_client.get_project(PROJECT_ID)all_consensus_branch_rows = project.list_label_rows_v2(branch_name=CONSENSUS_BRANCH_NAME)# Filter label rows based on the specified data unit titlesconsensus_branch_rows = [ row for row in all_consensus_branch_rows if row.data_title in DATA_UNIT_TITLES]if not consensus_branch_rows: print("No matching data units found in the specified branch.")else: print("Data units found:", [row.data_title for row in consensus_branch_rows])# Retrieve the specified ontology object by titleontology_object = project.ontology_structure.get_child_by_title( title=ONTOLOGY_OBJECT_TITLE, type_=Object)# Initialize labels for each selected label row in the label branchwith project.create_bundle() as bundle: for row in consensus_branch_rows: row.initialise_labels(bundle=bundle)# Add bounding box labels to each filtered label rowfor row in consensus_branch_rows: # Instantiate an object instance for bounding box labels inst = ontology_object.create_instance() inst.set_for_frames( coordinates=BoundingBoxCoordinates( height=0.1, width=0.1, top_left_x=0.5, top_left_y=0.5, ), frames=0, # Apply to the specified frame manual_annotation=False, # Set to False as this is a label confidence=1, # Confidence of your label ) # Add the label instance to the label row row.add_object_instance(inst)with project.create_bundle() as bundle: # Save the row with labels within the bundle for row in consensus_branch_rows: row.save(bundle=bundle)
Rotatable Bounding Box
Example 1
Imports a single rotatable bounding box (Other type of fruit) to a single image (apple_001.png).
Example 2
Imports three instances (tracking an object across three sequential frames: 120, 121, and 122) of a bounding box (Other type of fruit) to a video (Cherries_video.mp4).
Example 3
Imports three rotatable bounding boxes (Other type of fruit) to a single image (apple_001.png).
Example 4:
Imports three instances (tracking 3 different objects across three frames: object 1 - frames 120, 121, 122, object 2 - frames 222, 224, 226, and object 3 - frames 321, 323, 325) of three rotatable bounding boxes (Other type of fruit) to a video (Cherries_video.mp4).
Copy
# Import dependenciesfrom pathlib import Pathfrom encord import EncordUserClient, Projectfrom encord.objects import Object, ObjectInstancefrom encord.objects.coordinates import RotatableBoundingBoxCoordinates# ConfigurationSSH_PATH = "<file-path-to-ssh-private-key>"PROJECT_ID = "<unique-id-for-project>"CONSENSUS_BRANCH_NAME = "<name-of-your-label-branch>"ONTOLOGY_OBJECT_TITLE = "<rotatable-bounding-box-class-title>"DATA_UNIT_TITLES = ["<data-unit-title-1>", "<data-unit-title-2>"] # Specify the data unit titles here# Authenticate with Encord using SSH keyuser_client = EncordUserClient.create_with_ssh_private_key( ssh_private_key_path=Path(SSH_PATH).read_text())# Get the project and list label rows for the label branchproject = user_client.get_project(PROJECT_ID)all_consensus_branch_rows = project.list_label_rows_v2(branch_name=CONSENSUS_BRANCH_NAME)# Filter label rows based on the specified data unit titlesconsensus_branch_rows = [ row for row in all_consensus_branch_rows if row.data_title in DATA_UNIT_TITLES]if not consensus_branch_rows: print("No matching data units found in the specified branch.")else: print("Data units found:", [row.data_title for row in consensus_branch_rows])# Retrieve the specified ontology object by titlerbb_ontology_object = project.ontology_structure.get_child_by_title( title=ONTOLOGY_OBJECT_TITLE, type_=Object)with project.create_bundle() as bundle: # Initialize labels for each selected label row in the label branch for label_row in consensus_branch_rows: label_row.initialise_labels(bundle=bundle)# Define rotatable bounding box coordinates and frame for each objectrotatable_bounding_box_labels = [ { "frame_number": 0, "coordinates": RotatableBoundingBoxCoordinates( height=0.3, width=0.2, top_left_x=0.1, top_left_y=0.1, theta=15 # Angle of rotation in degrees ), }, { "frame_number": 5, "coordinates": RotatableBoundingBoxCoordinates( height=0.25, width=0.25, top_left_x=0.15, top_left_y=0.15, theta=30 ), }, { "frame_number": 10, "coordinates": RotatableBoundingBoxCoordinates( height=0.2, width=0.3, top_left_x=0.2, top_left_y=0.2, theta=45 ), },]# Add rotatable bounding box labels to each filtered label rowfor label_row in consensus_branch_rows: for label in rotatable_bounding_box_labels: rbb_object_instance = rbb_ontology_object.create_instance() rbb_object_instance.set_for_frames( coordinates=label["coordinates"], frames=label["frame_number"], manual_annotation=False, # Mark as a label confidence=1.0 ) # Link the object instance to the label row label_row.add_object_instance(rbb_object_instance)with project.create_bundle() as bundle: for label_row in consensus_branch_rows: # Save the label row with the updated labels within the bundle label_row.save(bundle=bundle)
Polygons (Advanced)
Polygons can have simple and complex shapes, including being enclosed in one another, and encompassing separate regions. In each case the polygon’s coordinates are arranged in a different way.
Specifying coordinates for polygons uses this format:
Import a simple polygon using the recommended method.
Donut
Import a complex polygon with a hole in it.
Multiple Polygons
Import a complex polygon that is in multiple parts.
Donut with Object Inside
Imports a complex polygon that has a hole in it with another polygon inside.
Copy
# Import dependenciesfrom pathlib import Pathfrom encord import EncordUserClient, Projectfrom encord.objects import Object, ObjectInstancefrom encord.objects.coordinates import PolygonCoordinates, PointCoordinate# ConfigurationSSH_PATH = "/Users/chris-encord/sdk-ssh-private-key.txt"PROJECT_ID = "7d4ead9c-4087-4832-a301-eb2545e7d43b"CONSENSUS_BRANCH_NAME = "my-label-branch-I" # Specify your label branchONTOLOGY_OBJECT_TITLE = "Persimmon" # Name of object label in your Ontology# Define coordinates for each imageimage_annotations = { "cherry-002-dup-001.jpg": [ [ # Simple Polygon [PointCoordinate(1.000, 0.500), PointCoordinate(0.750, 0.933), PointCoordinate(0.250, 0.933), PointCoordinate(0.000, 0.500), PointCoordinate(0.250, 0.067), PointCoordinate(0.750, 0.067)] ] ], "cherry-002-dup-002.jpg": [ [ # Simple Polygon [PointCoordinate(0.900, 0.400), PointCoordinate(0.700, 0.850), PointCoordinate(0.300, 0.850), PointCoordinate(0.100, 0.400), PointCoordinate(0.300, 0.100), PointCoordinate(0.700, 0.100)] ] ],}# Ensure SSH path and project id are setassert SSH_PATH, "SSH path cannot be None"assert PROJECT_ID, "Project id cannot be None"# Authenticate with Encord using SSH keyuser_client = EncordUserClient.create_with_ssh_private_key( Path(SSH_PATH).read_text())# Get project and list label rows for the specified branchproject = user_client.get_project(PROJECT_ID)all_label_rows = project.list_label_rows_v2(branch_name=CONSENSUS_BRANCH_NAME)# Filter label rows based on images in `image_annotations`label_rows = [row for row in all_label_rows if row.data_title in image_annotations]if not label_rows: print("No matching label rows found for specified images in branch '{CONSENSUS_BRANCH_NAME}'.") exit()print("Processing label rows for:", [row.data_title for row in label_rows])with project.create_bundle() as bundle: # Prepare for labeling for label_row in label_rows: label_row.initialise_labels(bundle=bundle)for label_row in label_rows: image_title = label_row.data_title # Get the image title polygon_data = image_annotations.get(image_title, []) # Get associated polygons if not polygon_data: print(f"No polygon data found for {image_title}, skipping.") continue # Retrieve the specified ontology object by title polygon_ontology_object = project.ontology_structure.get_child_by_title( title=ONTOLOGY_OBJECT_TITLE, type_=Object ) # Iterate through each polygon in the image's annotation data for polygon in polygon_data: # Instantiate an object instance from the polygon ontology node polygon_object_instance = polygon_ontology_object.create_instance() # Set the coordinates for the polygon polygon_object_instance.set_for_frames( coordinates=PolygonCoordinates(polygon), frames=0, # Apply to the specified frame manual_annotation=True, # Set to True for manual annotation confidence=1.0, # Confidence of your label ) # Link the object instance to the label row label_row.add_object_instance(polygon_object_instance)with project.create_bundle() as bundle: for label_row in label_rows: # Save the label row with the polygon object instance within the bundle label_row.save(bundle=bundle)print("Label rows updated with polygon instances.")
DEPRECATED - Polygons
Example 1
Imports a single polygon (Persimmon) to a single image (persimmon_001.jpg).
Example 2
Imports three instances (tracking an object across three sequential frames: 143, 144, and 145) of a polygon (Persimmon) to a video (Cherries_video.mp4).
Example 3
Imports three polygons (Persimmon) to a single image (persimmon_001.jpg).
Example 4:
Imports three instances (tracking 3 different objects across three frames: object 1 - frames 153, 154, 155, object 2 - frames 242, 244, 246, and object 3 - frames 343, 345, 347) of three polygons (Persimmon) to a video (Cherries_video.mp4).
Copy
# Import dependenciesfrom pathlib import Pathfrom encord import EncordUserClient, Projectfrom encord.objects import Object, ObjectInstancefrom encord.objects.coordinates import PolygonCoordinates, PointCoordinate# ConfigurationSSH_PATH = "<file-path-to-ssh-private-key>"PROJECT_ID = "<project-unique-id>"CONSENSUS_BRANCH_NAME = "<name-of-your-label-branch>" # Specify the label branchDATA_UNIT_TITLE = "<name-of-data-unit>" # The title of the data unit (image or video)ONTOLOGY_OBJECT_TITLE = "<object-name>" # The ontology object title for the polygon# Create user client using SSH keyuser_client: EncordUserClient = EncordUserClient.create_with_ssh_private_key( Path(SSH_PATH).read_text())# Get the project and list label rows for the label branchproject: Project = user_client.get_project(PROJECT_ID)consensus_branch_rows = project.list_label_rows_v2( branch_name=CONSENSUS_BRANCH_NAME, # Use the label branch data_title_eq=DATA_UNIT_TITLE)if not consensus_branch_rows: print("No matching data units found in the specified branch.")else: print("Data units found:", [row.data_title for row in consensus_branch_rows])# Initialize labels for each selected label row in the label branchlabel_row = consensus_branch_rows[0]label_row.initialise_labels()# Find a polygon annotation object in the project ontologypolygon_ontology_object: Object = project.ontology_structure.get_child_by_title( title=ONTOLOGY_OBJECT_TITLE, type_=Object)# Instantiate an object instance from the polygon ontology nodepolygon_object_instance: ObjectInstance = polygon_ontology_object.create_instance()# Define the polygon coordinatespolygon_coordinates = PolygonCoordinates([ PointCoordinate(0.1, 0.2), PointCoordinate(0.3, 0.4), PointCoordinate(0.5, 0.6), PointCoordinate(0.7, 0.8)])# Set the polygon label for the specified framepolygon_object_instance.set_for_frames( coordinates=polygon_coordinates, frames=0, # Specify the frame number manual_annotation=False, # Mark as a label confidence=1.0 # Optional confidence score)# Link the object instance to the label rowlabel_row.add_object_instance(polygon_object_instance)# Save the label row label_row.save()
Polyline
Example 1
Imports a single polyline (Branch) to a single image (persimmon_001.jpg).
Example 2
Imports three instances (tracking an object across three sequential frames: 146, 147, and 148) of a polygon (Branch) to a video (Cherries_video.mp4).
Example 3
Imports three polylines (Branch) to a single image (persimmon_001.jpg).
Example 4:
Imports three instances (tracking 3 different objects across three frames: object 1 - frames 246, 247, 248, object 2 - frames 346, 347, 348, and object 3 - frames 446, 447, 448) of three polylines (Branch) to a video (Cherries_video.mp4).
Copy
# Import dependenciesfrom pathlib import Pathfrom encord import EncordUserClient, Projectfrom encord.objects import Object, ObjectInstancefrom encord.objects.coordinates import PolylineCoordinates, PointCoordinate# ConfigurationSSH_PATH = "<file-path-to-ssh-private-key>" # Path to your SSH private keyPROJECT_ID = "<project-unique-id>" # Unique project idCONSENSUS_BRANCH_NAME = "<your-label-branch-name>" # Specify your label branchDATA_UNIT_TITLE = "<name-of-data-unit>" # Specific data unit titleONTOLOGY_OBJECT_TITLE = "<object-name>" # Name of the polyline object in your ontology# Create user client using SSH keyuser_client: EncordUserClient = EncordUserClient.create_with_ssh_private_key( Path(SSH_PATH).read_text())# Get project for which labels are to be addedproject: Project = user_client.get_project(PROJECT_ID)# Specify the data unit to label in the given branchlabel_row = project.list_label_rows_v2( branch_name=CONSENSUS_BRANCH_NAME, # Filter by label branch data_title_eq=DATA_UNIT_TITLE)[0]# Initialize labels for the label row label_row.initialise_labels()# Find a polyline annotation object in the project ontologypolyline_ontology_object: Object = project.ontology_structure.get_child_by_title( title=ONTOLOGY_OBJECT_TITLE, 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(.x1, .y1), PointCoordinate(.x2, .y2), PointCoordinate(.x3, .y3), PointCoordinate(.13, .456)] ), # Add the polyline to the specified frame number frames=<frame-number>, # Replace with the actual frame number # There are multiple additional fields that can be set optionally: manual_annotation=True, confidence=1.0,)# Link the object instance to the label rowlabel_row.add_object_instance(polyline_object_instance)# Save the label row with the polyline instancelabel_row.save()print("Label row updated with polyline instance.")
Keypoint
Example 1
Imports a single keypoint (Pedicel) to a single image (blueberry_003.png).
Example 2
Imports three instances (tracking an object across three sequential frames: 143, 144, and 145) of a keypoint (Pedicel) to a video (Blueberries_video.mp4).
Example 3
Imports three keypoints (Pedicel) to a single image (blueberry_003.png).
Example 4:
Imports three instances (tracking 3 different objects across three frames: object 1 - frames 143, 144, 145, object 2 - frames 242, 244, 246, and object 3 - frames 343, 345, 347) of three keypoints (Pedicel) to a video (Blueberries_video.mp4).
Copy
# Import dependenciesfrom pathlib import Pathfrom encord import EncordUserClient, Projectfrom encord.objects import Object, ObjectInstancefrom encord.objects.coordinates import PointCoordinate# ConfigurationSSH_PATH = "<file-path-to-ssh-private-key>" # Path to your SSH private keyPROJECT_ID = "<project-unique-id>" # Unique project idCONSENSUS_BRANCH_NAME = "<your-label-branch-name>" # Specify your label branchDATA_UNIT_TITLE = "<name-of-data-unit>" # Specific data unit titleONTOLOGY_OBJECT_TITLE = "<object-name>" # Name of the keypoint object in your ontology# Create user client using SSH keyuser_client: EncordUserClient = EncordUserClient.create_with_ssh_private_key( Path(SSH_PATH).read_text())# Get project for which labels are to be addedproject: Project = user_client.get_project(PROJECT_ID)# Specify the data unit to label in the given branchlabel_row = project.list_label_rows_v2( branch_name=CONSENSUS_BRANCH_NAME, # Filter by label branch data_title_eq=DATA_UNIT_TITLE)[0]# Initialize labels for the label rowlabel_row.initialise_labels()# Find a keypoint annotation object in the project ontologykeypoint_ontology_object: Object = project.ontology_structure.get_child_by_title( title=ONTOLOGY_OBJECT_TITLE, 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=<value-for-x-axis>, # Replace with the actual value for the x-axis y=<value-for-y-axis> # Replace with the actual value for the y-axis ), # Add the keypoint to the specified frame number frames=<frame-number>, # Replace with the actual frame number # There are multiple additional fields that can be set optionally: manual_annotation=True, confidence=1.0,)# Link the object instance to the label rowlabel_row.add_object_instance(keypoint_object_instance)# Save the label row with the keypoint instancelabel_row.save()print("Label row updated with keypoint instance.")
Bitmask
Example 1:
Imports a single bitmask (Blueberry) to a single image (blueberry_003.jpg). For simplicity, the bitmask covers the entire image (image dimensions: 1254x836).
Example 2:
Imports three instances (tracking an object across three sequential frames: 156, 157, and 159) of a bitmask (Blueberry) to a video (Blueberries_video.mp4). For simplicity, the bitmask covers the entire frame (video dimensions: 1920x1080).
Example 3:
Imports three bitmasks (Blueberry) to a single image (blueberry_003.jpg). For simplicity, the bitmasks cover the entire image (image dimensions: 1254x836).
Example 4:
Imports three instances (tracking 3 different objects across three frames: object 1 - frames 156, 157, 158, object 2 - frames 256, 258, 259, and object 3 - frames 355, 357, 359) of three bitmasks (Blueberry) to a video (Blueberries_video.mp4). For simplicity, the bitmasks cover the entire frame (video dimensions: 1920x1080).
Copy
# Import dependenciesimport numpy as npfrom pathlib import Pathfrom encord import EncordUserClient, Projectfrom encord.objects import Object, ObjectInstancefrom encord.objects.coordinates import BitmaskCoordinates# ConfigurationSSH_PATH = "<file-path-to-ssh-private-key>" # Path to your SSH private keyPROJECT_ID = "<project-unique-id>" # Unique project idCONSENSUS_BRANCH_NAME = "<your-label-branch-name>" # Specify your label branchDATA_UNIT_TITLE = "<data-unit-name>" # Specific data unit titleONTOLOGY_OBJECT_TITLE = "<bitmask-object-name>" # Name of the bitmask object in your ontology# Prepare the mask itself.# For simplicity, we can just mask the whole image# Note: the size of the mask must be identical to the size of the imagenumpy_coordinates = np.ones((<y-axis-value>, <x-axis-value>)) # Replace with actual values# Ensure the image is in boolean formatnumpy_coordinates = numpy_coordinates.astype(bool)# Create user client using SSH keyuser_client: EncordUserClient = EncordUserClient.create_with_ssh_private_key( Path(SSH_PATH).read_text())# Get project for which labels are to be addedproject: Project = user_client.get_project(PROJECT_ID)# Specify the data unit to label in the given branchlabel_row = project.list_label_rows_v2( branch_name=CONSENSUS_BRANCH_NAME, # Filter by label branch data_title_eq=DATA_UNIT_TITLE)[0]# Initialize labels for the label row label_row.initialise_labels()# Find a bitmask annotation object in the project ontologybitmask_ontology_object: Object = project.ontology_structure.get_child_by_title( title=ONTOLOGY_OBJECT_TITLE, type_=Object)# Instantiate an object instance from the bitmask ontology nodebitmask_object_instance: ObjectInstance = bitmask_ontology_object.create_instance()# The coordinates for the bitmask are specified as followsbitmask_object_instance.set_for_frames( # Create coordinates from provided numpy bitmask coordinates=BitmaskCoordinates(numpy_coordinates), # Add the bitmask to the first frame frames=0, # There are multiple additional fields that can be set optionally: manual_annotation=True, confidence=1.0,)# Link the object instance to the label rowlabel_row.add_object_instance(bitmask_object_instance)# Save the label row with the bitmask instancelabel_row.save()print("Label row updated with bitmask instance.")
Object Primitives
Before you can import Object Primitive labels into Encord, the Object Primitive Template MUST exist in Encord. Use the UI to create the Object Primitive Template so you can visually inspect the Object Primitive.
Import Object Primitive labels
Example 1
Imports a single object primitive (Ontology object = Strawberry Object Primitive name = Triangle) to a single image (strawberries_10.jpg).
Example 2
Imports three instances (tracking an object across three sequential frames: 163, 164, and 165) of a object primitive (Ontology object = Strawberry Object Primitive name = Triangle) to a video (Cherries_video.mp4).
Example 3
Imports three object primitives (Ontology object = Strawberry Object Primitive name = Triangle) to a single image (strawberries_10.jpg).
Example 4
Imports three instances (tracking 3 different objects across three frames: object 1 - frames 173, 174, 175, object 2 - frames 183, 184, 185, and object 3 - frames 193, 194, 195) of three object primitives (Ontology object = Strawberry Object Primitive name = Triangle) to a video (Cherries_video.mp4).
Copy
# Import dependenciesfrom pathlib import Pathfrom encord import EncordUserClient, Projectfrom encord.objects import Object, ObjectInstancefrom encord.objects.coordinates import SkeletonCoordinate, SkeletonCoordinatesfrom encord.objects.skeleton_template import SkeletonTemplate# ConfigurationSSH_PATH = "<file-path-to-ssh-private-key>" # Path to your SSH private keyPROJECT_ID = "<project-unique-id>" # Unique project idCONSENSUS_BRANCH_NAME = "<your-label-branch-name>" # Specify your label branchDATA_UNIT_TITLE = "<name-of-data-unit>" # Specific data unit titleONTOLOGY_OBJECT_TITLE = "<name-of-object-in-ontology>" # Name of the object in your ontologySKELETON_TEMPLATE_NAME = "<name-of-object-primitive>" # Name of the skeleton template# Create user client using SSH keyuser_client: EncordUserClient = EncordUserClient.create_with_ssh_private_key( Path(SSH_PATH).read_text())# Get project for which labels are to be addedproject: Project = user_client.get_project(PROJECT_ID)# Specify the data unit to label in the given branchlabel_row = project.list_label_rows_v2( branch_name=CONSENSUS_BRANCH_NAME, # Filter by label branch data_title_eq=DATA_UNIT_TITLE)[0]# Initialize labels for the label rowlabel_row.initialise_labels()# Find a skeleton annotation object in the project ontologyskeleton_ontology_object: Object = project.ontology_structure.get_child_by_title( title=ONTOLOGY_OBJECT_TITLE, type_=Object)skeleton_template: SkeletonTemplate = project.ontology_structure.skeleton_templates[SKELETON_TEMPLATE_NAME]# Instantiate an object instance from the skeleton ontology nodeskeleton_object_instance: ObjectInstance = skeleton_ontology_object.create_instance()skeleton_hashes = [coord.feature_hash for coord in skeleton_template.skeleton.values()]skeleton_coordinates: SkeletonCoordinates = SkeletonCoordinates(values=[ SkeletonCoordinate( x=0.x0, y=0.y0, # Replace with actual coordinates name='point_0', color='#000000', value="point_0", feature_hash=skeleton_hashes[0] ), SkeletonCoordinate( x=0.x1, y=0.y1, # Replace with actual coordinates name='point_1', color='#000000', value="point_1", feature_hash=skeleton_hashes[1] ), SkeletonCoordinate( x=0.x2, y=0.y2, # Replace with actual coordinates name='point_2', color='#000000', value="point_2", feature_hash=skeleton_hashes[2] )], name="<name-of-object-primitive>" # Replace with the actual name)print(skeleton_coordinates)# The x,y coordinates of the skeleton are specified as followsskeleton_object_instance.set_for_frames( coordinates=skeleton_coordinates, # Add the skeleton to the image frames=0, # Additional fields that can be set optionally: manual_annotation=True, confidence=1.0,)# Link the object instance to the label rowlabel_row.add_object_instance(skeleton_object_instance)# Save the label row with the skeleton instancelabel_row.save()print("Label row updated with skeleton instance.")
Radio Button
Example 1:
Imports a radio button classification (Blueberry or Cherry?) to a single image (blueberry_003.jpg).
Example 2:
Imports a radio button classification (Blueberry or Cherry?) across a range of sequential frames: 193 to 197) to a video (Blueberries_video.mp4).
Copy
# Import dependenciesfrom __future__ import annotationsfrom pathlib import Pathfrom encord import EncordUserClient, Projectfrom encord.objects import Classificationfrom encord.objects.options import Option# ConfigurationSSH_PATH = "<file-path-to-ssh-private-key>" # Path to your SSH private keyPROJECT_ID = "<unique-project-id>" # Unique project idCONSENSUS_BRANCH_NAME = "<your-label-branch-name>" # Specify your label branchDATA_UNIT_TITLE = "<data-unit-name>" # Specific data unit titleONTOLOGY_OBJECT_TITLE = "<classification-name>" # Name of the classification in your ontologyRADIO_BUTTON_OPTION_TITLE = "<radio-button-option-title>" # Title of the radio button optionRADIO_BUTTON_OPTION = "<radio-button-option>" # Specify the answer for the radio button option# Create user client using SSH keyuser_client: EncordUserClient = EncordUserClient.create_with_ssh_private_key( Path(SSH_PATH).read_text())# Get project for which labels are to be addedproject: Project = user_client.get_project(PROJECT_ID)# Specify the data unit to apply classification in the given branchlabel_row = project.list_label_rows_v2( branch_name=CONSENSUS_BRANCH_NAME, # Filter by label branch data_title_eq=DATA_UNIT_TITLE)[0]# Initialize labels for the label row label_row.initialise_labels()# Find the radio classification in the project ontologyradio_ontology_classification: Classification = project.ontology_structure.get_child_by_title( title=ONTOLOGY_OBJECT_TITLE, type_=Classification,)# Find the specific radio button optionblueberry_option = radio_ontology_classification.get_child_by_title( title=RADIO_BUTTON_OPTION_TITLE, type_=Option)# Create an instance of the radio classificationradio_classification_instance = radio_ontology_classification.create_instance()# Set the answer for the classification instanceradio_classification_instance.set_answer( answer=RADIO_BUTTON_OPTION)# Set the classification for the specified frameradio_classification_instance.set_for_frames( # Add the classification to the image frames=0, # Additional fields that can be set optionally: manual_annotation=True, confidence=1.0,)# Link the classification instance to the label rowlabel_row.add_classification_instance(radio_classification_instance)# Save the label row with the classification instancelabel_row.save()print("Label row updated with classification instance.")
Checklist
Example 1:
Imports a checklist classification (Many types of fruit?) to a single image (apple_003.jpg). The selected items from the list are apple and kiwi.
Example 2:
Imports a checklist classification (Many types of fruit?) across a range of sequential frames: 193 to 197) to a video (Blueberries_video.mp4). The selected items from the list are apple and kiwi.
Copy
# Import dependenciesfrom __future__ import annotationsfrom pathlib import Pathfrom encord import EncordUserClient, Projectfrom encord.objects import Classificationfrom encord.objects.options import Option# ConfigurationSSH_PATH = "/Users/chris-encord/sdk-ssh-private-key.txt" # Path to your SSH private keyPROJECT_ID = "7d4ead9c-4087-4832-a301-eb2545e7d43b" # Unique project idCONSENSUS_BRANCH_NAME = "<your-label-branch-name>" # Specify your label branchDATA_UNIT_TITLE = "Blueberries_video.mp4" # Specific data unit titleONTOLOGY_OBJECT_TITLE = "Many types of fruit?" # Name of the classification in your ontologyAPPLE_OPTION_TITLE = "Apple" # Title of the apple optionKIWI_OPTION_TITLE = "Kiwi" # Title of the kiwi option# Create user client using SSH keyuser_client: EncordUserClient = EncordUserClient.create_with_ssh_private_key( Path(SSH_PATH).read_text())# Get project for which labels are to be addedproject: Project = user_client.get_project(PROJECT_ID)# Specify the data unit to add classification in the given branchlabel_row = project.list_label_rows_v2( branch_name=CONSENSUS_BRANCH_NAME, # Filter by label branch data_title_eq=DATA_UNIT_TITLE)[0]# Initialize labels for the label rowlabel_row.initialise_labels()# Find the checklist classification in the project ontologychecklist_ontology_classification: Classification = project.ontology_structure.get_child_by_title( title=ONTOLOGY_OBJECT_TITLE, type_=Classification,)# Find the specific options in the checklistapple_option = checklist_ontology_classification.get_child_by_title( title=APPLE_OPTION_TITLE, type_=Option)kiwi_option = checklist_ontology_classification.get_child_by_title( title=KIWI_OPTION_TITLE, type_=Option)# Create an instance of the checklist classificationchecklist_classification_instance = checklist_ontology_classification.create_instance()# Set the answers for the classification instancechecklist_classification_instance.set_answer( [apple_option, kiwi_option])# Set the classification for the specified framechecklist_classification_instance.set_for_frames( # Add the classification to the image frames=177, # Additional fields that can be set optionally: manual_annotation=True, confidence=1.0,)# Link the classification instance to the label rowlabel_row.add_classification_instance(checklist_classification_instance)# Save the label row with the classification instancelabel_row.save()print("Label row updated with checklist classification instance.")
This simple example imports a bounding box model label to all data units in the label branch.
Store labels Boilerplate
Copy
# Import dependenciesimport osfrom encord import EncordUserClient, Projectfrom encord.objects import LabelRowV2, Object, OntologyStructure, ObjectInstancefrom encord.objects.coordinates import BoundingBoxCoordinates, RotatableBoundingBoxCoordinates, PolygonCoordinates, PolylineCoordinates, PointCoordinate, BitmaskCoordinates# ConfigurationSSH_PATH = "file-path-to-your-ssh-key"PROJECT_ID = "unique-id-for-project"# Specify a label_rows_v2 branch name for your labels.CONSENSUS_BRANCH_NAME = "name-of-your-label-branch"assert SSH_PATH is not None, "SSH path cannot be None"assert PROJECT_ID is not None, "Project id cannot be None"# Authenticate with Encorduser_client = EncordUserClient.create_with_ssh_private_key( ssh_private_key_path=SSH_PATH)# Access the project and prepare the branch for labelsproject = user_client.get_project(PROJECT_ID)consensus_branch_rows = project.list_label_rows_v2(branch_name=CONSENSUS_BRANCH_NAME)if len(consensus_branch_rows) > 0: print("Branch is:", consensus_branch_rows[0].branch_name)ontology_object = project.ontology_structure.objects[0]with project.create_bundle() as bundle: for row in consensus_branch_rows: row.initialise_labels(bundle=bundle)for row in consensus_branch_rows: inst = ontology_object.create_instance() inst.set_for_frames( coordinates=BoundingBoxCoordinates( height=0.8, width=0.8, top_left_x=0.1, top_left_y=0.1, ), # Add the bounding box to the first frame frames=0, # There are multiple additional fields that can be set optionally: manual_annotation=False, ) row.add_object_instance(inst)with project.create_bundle() as bundle: for row in consensus_branch_rows: row.save(bundle=bundle)
This simple example imports a bounding box model label to all data units in the label branch.
Store labels Boilerplate
Copy
# Import dependenciesimport osfrom encord import EncordUserClient, Projectfrom encord.objects import LabelRowV2, Object, OntologyStructure, ObjectInstancefrom encord.objects.coordinates import BoundingBoxCoordinates, RotatableBoundingBoxCoordinates, PolygonCoordinates, PolylineCoordinates, PointCoordinate, BitmaskCoordinates# ConfigurationSSH_PATH = "file-path-to-your-ssh-key"PROJECT_HASH = "unique-id-for-project"# Specify a label_rows_v2 branch name for your labels.CONSENSUS_BRANCH_NAME = "name-of-your-label-branch"assert SSH_PATH is not None, "SSH path cannot be None"assert PROJECT_ID is not None, "Project ID cannot be None"# Authenticate with Encorduser_client = EncordUserClient.create_with_ssh_private_key( ssh_private_key_path=SSH_PATH)# Access the project and prepare the branch for labelsproject = user_client.get_project(PROJECT_HASH)consensus_branch_rows = project.list_label_rows_v2(branch_name=CONSENSUS_BRANCH_NAME)if len(consensus_branch_rows) > 0: print("Branch is:", consensus_branch_rows[0].branch_name)ontology_object = project.ontology_structure.objects[0]with project.create_bundle() as bundle: for row in consensus_branch_rows: row.initialise_labels(bundle=bundle)for row in consensus_branch_rows: inst = ontology_object.create_instance() inst.set_for_frames( coordinates=BoundingBoxCoordinates( height=0.8, width=0.8, top_left_x=0.1, top_left_y=0.1, ), # Add the bounding box to the first frame frames=0, # There are multiple additional fields that can be set optionally: manual_annotation=False, ) row.add_object_instance(inst)with project.create_bundle() as bundle: for row in consensus_branch_rows: row.save(bundle=bundle)
<private_key_path> with the file path to your SSH private key.
encord-<name-of-your-consensus-branch> with the name of your label branch.
<project_hash> with the Project ID for your Project.
COCOimportfile.json with the full path of the COCO file containing the predictions you want to import.
COCO Label import as Predictions
Copy
import jsonfrom pathlib import Pathfrom encord.utilities.coco.datastructure import FrameIndexfrom encord import EncordUserClientfrom encord.exceptions import OntologyError# Authenticate clientSSH_PATH = "file-path-to-your-ssh-key"# Specify a Project to import your predictions to. This Project must already exist in Encord.PROJECT_HASH = "unique-id-for-project"# Specify a label_rows_v2 branch name for your labels.CONSENSUS_BRANCH_NAME = "encord-<name-of-your-consensus-branch>"# Authenticate with Encord using the path to your private keyuser_client: EncordUserClient = EncordUserClient.create_with_ssh_private_key( ssh_private_key_path=SSH_PATH)# Replace with your project IDproject = user_client.get_project(PROJECT_ID)# Load the COCO annotations JSON file# Replace 'COCOimportfile.json' with the full path to your COCO filecoco_file = Path("COCOimportfile.json")labels_dict = json.loads(coco_file.read_text())# Build a mapping from COCO category IDs to the feature hashes in your Encord Ontology. category_id_to_feature_hash = {}ont_struct = project.ontology_structurefor coco_category in labels_dict["categories"]: try: ont_obj = ont_struct.get_child_by_title(coco_category["name"]) category_id_to_feature_hash[coco_category["id"]] = ont_obj.feature_node_hash except OntologyError: print(f"Could not match {coco_category['name']} in the Ontology. Import will crash if these are present.")# Build a mapping from COCO image IDs to Encord frame indices# This is only applicable for images, image groups, image sequences, videos, and DICOM seriesimage_id_to_frame_index = {}data_title_to_label_row = {lr.data_title: lr for lr in project.list_label_rows_v2(branch_name=CONSENSUS_BRANCH_NAME)}for img in labels_dict['images']: if "video_title" in img.keys(): lr = data_title_to_label_row[img["video_title"]] frame_num = int(img["file_name"].split('/')[-1].split(".")[0]) else: lr = data_title_to_label_row[img['image_title']] frame_num = 0 # Creates a mapping between the COCO image IDs and the corresponding frame indices in Encord # In this example, the target frame is 0 because the files in the sample project are single images image_id_to_frame_index[img['id']] = FrameIndex(lr.data_hash, frame=frame_num)# Import the COCO labels into Encordproject.import_coco_labels( labels_dict, category_id_to_feature_hash, image_id_to_frame_index, branch_name=CONSENSUS_BRANCH_NAME,)
After importing your labels, verify that your labels imported.
The following code returns all labels and predictions on all branches.
Copy
# Import dependenciesfrom encord import EncordUserClientimport jsonSSH_PATH = "file-path-of-your-ssh-key"PROJECT_HASH = "unique-id-for-your-project"# Instantiate client. Replace \<private_key_path> with the path to the file containing your private key.user_client = EncordUserClient.create_with_ssh_private_key( ssh_private_key_path=SSH_PATH)# Specify Project. Replace <project_hash> with the ID of the Project you want to export labels for.project = user_client.get_project(PROJECT_HASH)# Downloads a local copy of all the labels# Without the include_all_label_branches flag only the MAIN branch labels exportlabel_rows = project.list_label_rows_v2(include_all_label_branches=True) # Initialize label rows using bundleswith project.create_bundle() as bundle: for label_row in label_rows: label_row.initialise_labels(bundle=bundle)for label_row in label_rows: # Here we have the label row for the branch, but without labels themselves downloaded print(f"Title: {label_row.data_title}, branch: {label_row.branch_name}") # Print essential label information for all objects for object_instance in label_row.get_object_instances(): print (f"objectHash: {object_instance.object_hash}") print (f"Object name: {object_instance.object_name}") print (f"featureHash: {object_instance.feature_hash}") print (f"uid: {object_instance.ontology_item.uid}") print (f"Object color: {object_instance.ontology_item.color}") print (f"Ontology shape: {object_instance.ontology_item.shape}") # Print the frame number and the location of the object on the frame for annotation in object_instance.get_annotations(): print(f"Frame {annotation.frame} -> {annotation.coordinates}") # Print all attributes for attribute in object_instance.ontology_item.attributes: print (attribute, object_instance) # Print all essential classification information for classification_instance in label_row.get_classification_instances(): print (f"classificationHash: {classification_instance.classification_hash}") print (f"Classification name: {classification_instance.classification_name}") print (f"featureHash: {classification_instance.feature_hash}") print (f"Classification answer: {classification_instance.get_answer().value}") print (f"Classification answer hash: {classification_instance.get_answer().feature_node_hash}") # Print the frame number(s) that a classification appears on for annotation in classification_instance.get_annotations(): print(f"Classification appears on frame: {annotation.frame}")