The Encord SDK is designed to offer a versatile and targeted approach to accessing label information. This approach allows for a more customized handling of label information, catering to various needs and scenarios in data processing.
The following table describes all values exported by the scripts on this page.
Key
Description
objectHash
The unique ID of the object instance. Two instances of the same object have different object hashes
Object name
The name of the object as defined in the Ontology. For example “Chicken”.
featureHash
The unique ID of the Ontology element. For example, the object “Chicken” in the Ontology. All instances have the same featureHash.
uid
The unique identifier for the object instance. Two instances of the same object have different uids.
Object color
The color used to label the object, as defined in the Ontology and seen in the Encord platform.
Ontology shape
The shape used to label the object, as defined in the Ontology. For example, polygon.
Classification name
The name of the Classification, as defined in the Ontology. For example “Day or night?”
Classification answer
The value of the Classification, as defined in the Ontology. For example “Day”
classificationHash
The unique identifier for the Classification instance.
Classification answer hash
The unique identifier for the Classification value
Attribute name
The name of the attribute, as defined in the Ontology. For example “Standing or sitting?”
Attribute answer
The name of the attribute value, as defined in the Ontology. For example “Sitting”
The following script prints a JSON file containing all the labels in your Project.
Make sure you substitute:
The <file-path-to-ssh-key> with the full path to your SSH private key.
The <project-id> with the hash of your Project.
The <file-path> with the file path to save the JSON file, with your labels.
# Import dependenciesfrom encord import EncordUserClientimport jsonSSH_PATH="<file-path-to-ssh-key>"PROJECT_ID="<project-id>"# 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_id> with the ID of the Project you want to export labels for.project = user_client.get_project(PROJECT_ID)# Get label rows for your Project.label_rows = project.list_label_rows_v2()# Create a list to store all label row dataall_label_rows =[]for label_row in label_rows:# Download label information label_row.initialise_labels()# Add the label data to the list all_label_rows.append(label_row.to_encord_dict())# Save the collected label rows data to a JSON fileoutput_file ="<file-path>label_rows.json"withopen(output_file,"w")asfile: json.dump(all_label_rows,file, indent=4)print(f"Label rows have been saved to {output_file}.")
The following scripts get the attributes for all labels in a Project, as well as the frames that the attributes appear on. Single images only have a single frame.
In the following scripts, ensure that you:
Replace <private_key_path> with the full path to your private key.
Replace <project_id> with the ID of the Project you want to export attributes for.
Replace <task_name> with the name of the data unit you want to export attributes for. Remove data_title_eq="<task_name>" if you want to export attributes for all tasks.
We recommend using the script for exporting all attributes if the Project uses an Ontology with nested attributes.
# Import dependenciesfrom encord import EncordUserClientfrom encord.objects.attributes import Attribute, TextAttributefrom encord.objects import ObjectInstance# Instantiate Encord client by substituting the path to your private keyuser_client = EncordUserClient.create_with_ssh_private_key( ssh_private_key_path="<private_key_path>")# Replace <project_id> with the ID of your Projectproject = user_client.get_project("<project_id>")# A function to extract and print essential information for all attributes, specifically handling text attributesdefprint_attributes(attribute: Attribute, object_instance: ObjectInstance, frame_number:int):ifisinstance(attribute, TextAttribute):print(f"Frame {frame_number+1}:")print(f"Text Attribute name: {attribute.title}")print(f"Text Attribute hash: {attribute.feature_node_hash}")# Retrieve text directly from object instance for the specific frame text_answer = object_instance.get_answer(attribute)print(f"Text Attribute Answer: {text_answer}")for label_row in project.list_label_rows_v2(data_title_eq="<task_name>"): label_row.initialise_labels()for object_instance in label_row.get_object_instances():for annotation in object_instance.get_annotations():# Now calling print_attributes per framefor attribute in object_instance.ontology_item.attributes: print_attributes(attribute, object_instance, annotation.frame)
The following scripts download and print the labels for a specified range of frames in videos.
Make sure you substitute:
The <private_key_path> with the full path to your private key.
The <project_id> with the ID of your Project.
The <task_name> with the name of the task you want to export labels for (if using the task-specific script).
The <start_frame_number> with the first frame of the range you want to export labels for.
The <end_frame_number> with the last frame of the range you want to export labels for.
To export labels for a single frame, make the <start_frame_number> the same as the <end_frame_number>. For example, to export labels on the 13th frame set <start_frame_number> = 13, and <end_frame_number> = 13.
# Import dependenciesfrom encord import EncordUserClientfrom encord.objects.ontology_element import OntologyElementfrom encord.objects.attributes import Attribute, Optionfrom encord.objects import ObjectInstancefrom collections.abc import Iterable# Instantiate Encord client by substituting the path to your private keyuser_client = EncordUserClient.create_with_ssh_private_key( ssh_private_key_path="<private_key_path>")# Replace <project_id> with the ID of your Projectproject = user_client.get_project("<project_id>")# A function to extract and print essential information for all attributesdefprint_attributes(attribute: Attribute, object_instance: ObjectInstance):print(f"Attribute name: {attribute.title}")print(f"Attribute hash: {attribute.feature_node_hash}")print(f"Attribute answer: {object_instance.get_answer(attribute)}")# Specify the label row you want to edit labels for.start_frame_number =<start_frame_number># Set the start of your desired frame rangeend_frame_number =<end_frame_number># Set the end of your desired frame range# Specify which task you want to export labels forfor label_row in project.list_label_rows_v2(data_title_eq="<task_name>"):# Download all labels label_row.initialise_labels()# Print essential label information for all objectsfor object_instance in label_row.get_object_instances():for annotation in object_instance.get_annotations():if start_frame_number <= annotation.frame <= end_frame_number:print("Frame: "+str(annotation.frame))print("objectHash: "+ object_instance.object_hash)print("Object name: "+ object_instance.object_name)print("featureHash: "+ object_instance.feature_hash)print("uid: "+str(object_instance.ontology_item.uid))print("Object color: "+ object_instance.ontology_item.color)print("Ontology shape: "+ object_instance.ontology_item.shape)print(f"Label location: {annotation.coordinates}")# Print all attributesfor attribute in object_instance.ontology_item.attributes: print_attributes(attribute, object_instance)# Print all essential classification information on specified framesfor classification_instance in label_row.get_classification_instances():for annotation in classification_instance.get_annotations():if start_frame_number <= annotation.frame <= end_frame_number:print("Classification hash: "+ classification_instance.classification_hash)print("Classification name: "+ classification_instance.classification_name)print("Feature hash: "+ classification_instance.feature_hash)print("Classification value: "+ classification_instance.get_answer().value)print("Classification answer hash: "+ classification_instance.get_answer().feature_node_hash)
The following scripts download and print the labels for specific frames in videos.
Make sure you substitute:
The <private_key_path> with the full path to your private key.
The <project_hash> with the hash of your Project.
The <task_name> with the name of the file (in Encord) you want to export labels for (if using the task-specific script).
Replace the numbers in the list [10, 20, 30, 40] with the frames you want to export labels for.
# Import dependenciesfrom encord import EncordUserClientfrom encord.objects.ontology_element import OntologyElementfrom encord.objects.attributes import Attribute, Optionfrom encord.objects import ObjectInstancefrom collections.abc import Iterable# Instantiate Encord clientuser_client = EncordUserClient.create_with_ssh_private_key( ssh_private_key_path="<private_key_path>")# Replace with the hash of your Projectproject = user_client.get_project("<project_hash>")# Function to extract and print essential information for all attributesdefprint_attributes(attribute: Attribute, object_instance: ObjectInstance):print(f"Attribute name: {attribute.title}")print(f"Attribute hash: {attribute.feature_node_hash}")print(f"Attribute answer: {object_instance.get_answer(attribute)}")# List of specific frames to be exportedspecific_frames =[10,20,30,40]# Replace with your specific frame numbersfor label_row in project.list_label_rows_v2(data_title_eq="<task_name>"):# Download all labels label_row.initialise_labels()# Print essential label information for all objectsfor object_instance in label_row.get_object_instances():for annotation in object_instance.get_annotations():if annotation.frame in specific_frames:print("Frame: "+str(annotation.frame))print("objectHash: "+ object_instance.object_hash)print("Object name: "+ object_instance.object_name)print("featureHash: "+ object_instance.feature_hash)print("uid: "+str(object_instance.ontology_item.uid))print("Object color: "+ object_instance.ontology_item.color)print("Ontology shape: "+ object_instance.ontology_item.shape)print(f"Label location: {annotation.coordinates}")# Print all attributesfor attribute in object_instance.ontology_item.attributes: print_attributes(attribute, object_instance)# Print essential classification information on specified framesfor classification_instance in label_row.get_classification_instances():for annotation in classification_instance.get_annotations():if annotation.frame in specific_frames:print("Classification hash: "+ classification_instance.classification_hash)print("Classification name: "+ classification_instance.classification_name)print("Feature hash: "+ classification_instance.feature_hash)print("Classification value: "+ classification_instance.get_answer().value)print("Classification answer hash: "+ classification_instance.get_answer().feature_node_hash)
ffmpeg can be used to save all frames with labels as an image, to be used in machine learning applications. The script below shows how this is done when exporting a list of non-consecutive frames from a specific video.
The <output_folder_path> with the full path to the output folder you want the output image files to be saved.
The <private_key_path> with the full path to your private key.
The <project_id> with the ID of your Project.
The <task_name> with the name of the file in Encord you want to export labels for.
The <path_to_your_video_file> with the full path to the video file you are exporting labels for.
Replace the numbers in the list [10, 20, 30, 40] with the frames you want to export labels for.
# Import dependenciesfrom encord import EncordUserClientfrom encord.objects.ontology_element import OntologyElementfrom encord.objects.attributes import Attribute, Optionfrom encord.objects import ObjectInstancefrom collections.abc import Iterableimport subprocessimport os# Specify the output folder path. Replace with your desired folder pathoutput_folder ="<output_folder_path>"# Create the output folder if it doesn't existifnot os.path.exists(output_folder): os.makedirs(output_folder)defextract_frame_to_image(video_file, frame_number, output_file):""" Uses FFmpeg to extract a specific frame from a video and saves it as an image.""" ffmpeg_command =['ffmpeg','-i', video_file,'-vf',f'select=eq(n\,{frame_number})','-vframes','1', output_file] subprocess.run(ffmpeg_command, check=True)# Instantiate Encord clientuser_client = EncordUserClient.create_with_ssh_private_key( ssh_private_key_path="<private_key_path>")# Replace with the ID of your Projectproject = user_client.get_project("<project_id>")# Function to extract and print essential information for all attributesdefprint_attributes(attribute: Attribute, object_instance: ObjectInstance):print(f"Attribute name: {attribute.title}")print(f"Attribute hash: {attribute.feature_node_hash}")print(f"Attribute answer: {object_instance.get_answer(attribute)}")# List of specific frames to be exported. Replace with your specific frame numbersspecific_frames =[10,20,30,40]# Path to the video file you are exporting labels forvideo_path ="<path_to_your_video_file>"for label_row in project.list_label_rows_v2(data_title_eq="<task_name>"):# Download all labels label_row.initialise_labels()# Print essential label information for all objectsfor object_instance in label_row.get_object_instances():for annotation in object_instance.get_annotations():if annotation.frame in specific_frames:print("Frame: "+str(annotation.frame))print("objectHash: "+ object_instance.object_hash)print("Object name: "+ object_instance.object_name)print("featureHash: "+ object_instance.feature_hash)print("uid: "+str(object_instance.ontology_item.uid))print("Object color: "+ object_instance.ontology_item.color)print("Ontology shape: "+ object_instance.ontology_item.shape)print(f"Label location: {annotation.coordinates}")# Define the output path for the image output_image_path = os.path.join(output_folder,f"frame_{annotation.frame}.png")# Extract and save the specific frame as an image extract_frame_to_image(video_path, annotation.frame, output_image_path)# Print all attributesfor attribute in object_instance.ontology_item.attributes: print_attributes(attribute, object_instance)# Print essential classification information on specified framesfor classification_instance in label_row.get_classification_instances():for annotation in classification_instance.get_annotations():if annotation.frame in specific_frames:print("Classification hash: "+ classification_instance.classification_hash)print("Classification name: "+ classification_instance.classification_name)print("Feature hash: "+ classification_instance.feature_hash)print("Classification value: "+ classification_instance.get_answer().value)print("Classification answer hash: "+ classification_instance.get_answer().feature_node_hash)
All label locations are exported as normalized coordinates ranging from 0 to 1. This means that the corners of the frame or image correspond to the coordinates (1,1), (1,0), (0,0), (0,1) regardless of frame dimensions.
To get the pixel values of any normalized coordinates, multiply them by the width or height of the label (given in pixels).
“x” and “h” coordinates of a label should be multiplied by the pixel width.
“y” and “w” coordinates of a label should be multiplied by the pixel height.
Consensus Projects introduce the concept of BRANCHES within the task workflow. A Consensus annotation task consists of a MAIN branch and one sub-branch for each Annotator. Each time an annotator saves or submits a task, the annotator creates their own branch on a task. The MAIN branch remains empty of labels until a reviewer specifies that a task is in consensus. When consensus is reached, the labels that are the best representative set move to the MAIN branch. To export all labels (labels generated for every branch on every data unit) from your Consensus Project, use include_all_branches=True.
Make sure you:
Substitute the <private_key_path> with the full path to your private key.
Substitute the <project_id> with the ID of your Project.
If you only want to export the MAIN branch, remove include_all_label_branches=True.
# Import dependenciesfrom encord import EncordUserClient# 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="<private_key_path>")# Specify Project. Replace <project_id> with the ID of the Project you want to export labels for.project = client.get_project("<project_id>")# 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)for label_row in label_rows:# Here we have the label row for the branch, but without labels themselves downloadedprint(f"Title: {label_row.data_title}, branch: {label_row.branch_name}")# And now we download the label content itself (bounding boxes and stuff) label_row.initialise_labels()# Print essential label information for all objectsfor 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 framefor 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_attributes(attribute, object_instance)# Print all essential classification informationfor 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 onfor annotation in classification_instance.get_annotations():print(f"Classification appears on frame: {annotation.frame}")
Use the bundle function to significantly improve export performance.
We strongly recommend NOT bundling more than 1000 operations at once, because bundling more than 1000 operations can reduce performance instead of improving performance.
In the following code, ensure you replace:
<private_key_path> with the full path to your private key.
<project-id> with the ID of the Project you want to export labels for.
#Perform label row operation before in this loop with the label row operations you want to perform.
Optionally, change the value of BUNDLE_SIZE to suit your needs. We strongly recommend NOT bundling more than 1000 operations at once, because bundling more than 1000 operations can reduce performance instead of improving performance.
# Import dependenciesfrom pathlib import Pathfrom encord import EncordUserClient, Projectfrom encord.objects import( Object, ObjectInstance, OntologyStructure,)from encord.objects.coordinates import BoundingBoxCoordinatesSSH_PATH ="<private-key-path>"PROJECT_ID ="<project-id>"# Authenticateuser_client: EncordUserClient = EncordUserClient.create_with_ssh_private_key(ssh_private_key_path=SSH_PATH)# Gets Project to export labelsproject: Project = user_client.get_project(PROJECT_ID)label_rows = project.list_label_rows_v2()BUNDLE_SIZE =100# Initialize label rows using bundleswith project.create_bundle(bundle_size=BUNDLE_SIZE)as bundle:for label_row in label_rows: label_row.initialise_labels(bundle=bundle)for label_row in label_rows:# Write any label row operation here. For example import, or export label rows. # Saving changes to label rows using bundleswith project.create_bundle(bundle_size=BUNDLE_SIZE)as bundle:for label_row in label_rows: label_row.save(bundle=bundle)