Overview
To upload labels to a Consensus Project, you need to create a Consensus branch.
ALL Consensus branches start with encord-
.
Encord Format (Recommended)
- Supports multi-level nested classifications (radio, checklist, or free-form text) under objects or classifications.
- Handles all object types and classification.
COCO Format
Does not supports multiple levels of nested classifications (radio, checklist, or free-form text) under tools or classifications.
Confidence Score
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.
Label Branches
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.
Import Labels/Annotations to Consensus Projects
Import your labels to a Project in Annotate. Encord currently supports importing labels from the Encord format and from COCO.
Use branch_name
to create a Consensus label branch in label_rows_v2
for a data unit.
branch_name
MUST start with encord-
for Consensus branches.
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 (.).
This simple example imports a bounding box model to all data units in the Consensus branch.
import os
from encord import EncordUserClient, Project
from encord.objects import LabelRowV2, Object, OntologyStructure, ObjectInstance
from encord.objects.coordinates import BoundingBoxCoordinates, RotatableBoundingBoxCoordinates, PolygonCoordinates, PolylineCoordinates, PointCoordinate, BitmaskCoordinates
SSH_PATH = "file-path-to-your-ssh-key"
PROJECT_HASH = "unique-id-for-project"
CONSENSUS_BRANCH_NAME = "encord-<name-of-your-consensus-branch>"
assert SSH_PATH is not None, "SSH path cannot be None"
assert PROJECT_HASH is not None, "Project hash cannot be None"
user_client = EncordUserClient.create_with_ssh_private_key(
ssh_private_key_path=SSH_PATH
)
project = 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]
bundle = project.create_bundle()
for row in consensus_branch_rows:
row.initialise_labels(bundle=bundle)
bundle.execute()
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,
),
frames=0,
manual_annotation=False,
)
row.add_object_instance(inst)
row.save(bundle=bundle)
bundle.execute()
Import COCO Labels to Consensus Branches
The following code imports COCO labels as predictions for Active.
For more information on importing COCO labels into Encord, refer to our documentation.
Replace the following:
-
<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
import json
from pathlib import Path
from encord.utilities.coco.datastructure import FrameIndex
from encord import EncordUserClient
from encord.exceptions import OntologyError
SSH_PATH = "file-path-to-your-ssh-key"
PROJECT_HASH = "unique-id-for-project"
CONSENSUS_BRANCH_NAME = "encord-<name-of-your-consensus-branch>"
user_client: EncordUserClient = EncordUserClient.create_with_ssh_private_key(
ssh_private_key_path=SSH_PATH
)
project = user_client.get_project(PROJECT_HASH)
coco_file = Path("COCOimportfile.json")
labels_dict = json.loads(coco_file.read_text())
category_id_to_feature_hash = {}
ont_struct = project.ontology_structure
for 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.")
image_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
image_id_to_frame_index[img['id']] = FrameIndex(lr.data_hash, frame=frame_num)
project.import_coco_labels(
labels_dict,
category_id_to_feature_hash,
image_id_to_frame_index,
branch_name=CONSENSUS_BRANCH_NAME,
)
Verify Label Import
After importing your labels, verify that your labels imported.
The following code returns all labels and predictions on all branches.
from encord import EncordUserClient
import json
SSH_PATH = "file-path-of-your-ssh-key"
PROJECT_HASH = "unique-id-for-your-project"
user_client = EncordUserClient.create_with_ssh_private_key(
ssh_private_key_path=SSH_PATH
)
project = user_client.get_project(PROJECT_HASH)
label_rows = project.list_label_rows_v2(include_all_label_branches=True)
for label_row in label_rows:
print(f"Title: {label_row.data_title}, branch: {label_row.branch_name}")
label_row.initialise_labels()
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}")
for annotation in object_instance.get_annotations():
print(f"Frame {annotation.frame} -> {annotation.coordinates}")
for attribute in object_instance.ontology_item.attributes:
print (attribute, object_instance)
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}")
for annotation in classification_instance.get_annotations():
print(f"Classification appears on frame: {annotation.frame}")