Cuboids
Basic This example includes the following:- Cuboid labeling
- Cuboid labeling
- Radio button options
- Checklist options
- Text input
# Import dependencies
from encord import EncordUserClient, Project
from encord.objects import Object
from encord.objects.coordinates import CuboidCoordinates
# User input
SSH_PATH = "/Users/chris-encord/ssh-private-key.txt" # Replace with the file path to your SSH private key
PROJECT_ID = "00000000-0000-0000-0000-000000000000" # Replace with the unique ID for the Project
BUNDLE_SIZE = 100
# Create user client using ssh key
user_client: EncordUserClient = EncordUserClient.create_with_ssh_private_key(
ssh_private_key_path=SSH_PATH,
# For US platform users use "https://api.us.encord.com"
domain="https://api.encord.com",
)
# Get project for which labels are to be added
project: Project = user_client.get_project(PROJECT_ID)
# Create radio button attribute for Person type
ontology_structure = project.ontology_structure
# Find a cuboid annotation object in the project ontology
cuboid_ontology_object: Object = ontology_structure.get_child_by_title(title="Person", type_=Object)
assert cuboid_ontology_object is not None, "Cuboid object 'Person' not found in ontology."
# Dictionary of labels per data unit and per frame with Person
pcd_labels = {
"scene-1094": {
0: {
"label_ref": "person_001",
"coordinates": CuboidCoordinates(
position=(9, 9, 9),
orientation=(0.11, 0.77, 0.33),
size=(0.2, 0.2, 0.2)
),
}
},
"scene-0916": {
0: [
{
"label_ref": "person_002",
"coordinates": CuboidCoordinates(
position=(0.4, 0.4, 0.4),
orientation=(0.0, 0.0, 0.4),
size=(0.1, 0.1, 0.1)
),
},
{
"label_ref": "person_003",
"coordinates": CuboidCoordinates(
position=(0.2, 0.2, 0.0),
orientation=(0.0, 0.0, 0.1),
size=(0.5, 0.5, 0.5)
),
},
{
"label_ref": "person_004",
"coordinates": CuboidCoordinates(
position=(0.2, 0.2, 0.0),
orientation=(0.0, 0.0, 0.1),
size=(0.7, 0.7, 0.7)
),
},
],
},
"scene-0796": {
0: {
"label_ref": "person_005",
"coordinates": CuboidCoordinates(
position=(0.4, 0.4, 0.0),
orientation=(0.0, 0.0, 0.4),
size=(0.12, 0.12, 0.12)
),
},
2: [
{
"label_ref": "person_006",
"coordinates": CuboidCoordinates(
position=(0.1, 0.1, 0.0),
orientation=(0.0, 0.0, 0.2),
size=(0.5, 0.5, 0.5)
),
},
{
"label_ref": "person_007",
"coordinates": CuboidCoordinates(
position=(0.1, 0.1, 0.0),
orientation=(0.0, 0.0, 0.2),
size=(0.0132, 0.0132, 0.0132)
),
},
{
"label_ref": "person_008",
"coordinates": CuboidCoordinates(
position=(0.2, 0.2, 0.0),
orientation=(0.0, 0.0, 0.1),
size=(0.8, 0.8, 0.8)
),
},
],
},
"scene-1100": {
0: {
"label_ref": "person_009",
"coordinates": CuboidCoordinates(
position=(0.4, 0.4, 0.0),
orientation=(0.0, 0.0, 0.4),
size=(0.012, 0.012, 0.012)
),
},
3: [
{
"label_ref": "person_010",
"coordinates": CuboidCoordinates(
position=(0.4, 0.4, 0.0),
orientation=(0.0, 0.0, 0.4),
size=(0.5, 0.5, 0.5)
),
},
{
"label_ref": "person_011",
"coordinates": CuboidCoordinates(
position=(0.3, 0.3, 0.0),
orientation=(0.0, 0.0, 0.3),
size=(0.13, 0.13, 0.13)
),
},
{
"label_ref": "person_012",
"coordinates": CuboidCoordinates(
position=(0.2, 0.2, 0.0),
orientation=(0.0, 0.0, 0.1),
size=(0.9, 0.9, 0.9)
),
},
],
},
"scene-0655": {
13: [
{
"label_ref": "person_013",
"coordinates": CuboidCoordinates(
position=(0.5, 0.5, 0.0),
orientation=(0.0, 0.0, 0.5),
size=(0.11, 0.11, 0.11)
),
},
{
"label_ref": "person_014",
"coordinates": CuboidCoordinates(
position=(0.2, 0.2, 0.0),
orientation=(0.0, 0.0, 0.2),
size=(0.6, 0.6, 0.6)
),
},
{
"label_ref": "person_015",
"coordinates": CuboidCoordinates(
position=(0.2, 0.2, 0.0),
orientation=(0.0, 0.0, 0.1),
size=(0.8, 0.8, 0.8)
),
},
],
14: [
{
"label_ref": "person_016",
"coordinates": CuboidCoordinates(
position=(0.5, 0.5, 0.0),
orientation=(0.0, 0.0, 0.5),
size=(0.3, 0.3, 0.3)
),
},
{
"label_ref": "person_014",
"coordinates": CuboidCoordinates(
position=(0.2, 0.2, 0.0),
orientation=(0.0, 0.0, 0.2),
size=(0.6, 0.6, 0.6)
),
},
{
"label_ref": "person_017",
"coordinates": CuboidCoordinates(
position=(0.2, 0.2, 0.0),
orientation=(0.0, 0.0, 0.1),
size=(0.8, 0.8, 0.8)
),
},
],
15: [
{
"label_ref": "person_016",
"coordinates": CuboidCoordinates(
position=(0.5, 0.5, 0.0),
orientation=(0.0, 0.0, 0.5),
size=(0.1, 0.1, 0.1)
),
},
{
"label_ref": "person_014",
"coordinates": CuboidCoordinates(
position=(0.2, 0.2, 0.0),
orientation=(0.0, 0.0, 0.2),
size=(0.6, 0.6, 0.6)
),
},
{
"label_ref": "person_017",
"coordinates": CuboidCoordinates(
position=(0.2, 0.2, 0.0),
orientation=(0.0, 0.0, 0.1),
size=(0.8, 0.8, 0.8)
),
},
],
},
}
# Initialize label rows
label_row_map = {}
with project.create_bundle(bundle_size=BUNDLE_SIZE) as bundle:
for data_title in pcd_labels.keys():
rows = project.list_label_rows_v2(data_title_eq=data_title)
if not rows:
print(f"Skipping: No label row found for {data_title}")
continue
lr = rows[0]
lr.initialise_labels(bundle=bundle)
label_row_map[data_title] = lr
# Create instances
label_rows_to_save = []
for data_title, frames in pcd_labels.items():
lr = label_row_map.get(data_title)
if not lr:
continue
instances_by_ref = {}
for frame_no, items in frames.items():
# normalize to list
items = items if isinstance(items, list) else [items]
for item in items:
ref = item["label_ref"]
coords = item["coordinates"]
if ref not in instances_by_ref:
instances_by_ref[ref] = cuboid_ontology_object.create_instance()
instances_by_ref[ref].set_for_frames(coordinates=coords, frames=frame_no)
# Add only instances that have at least one frame
for inst in instances_by_ref.values():
if inst.get_annotation_frames():
lr.add_object_instance(inst)
label_rows_to_save.append(lr)
# Save all label rows
with project.create_bundle(bundle_size=BUNDLE_SIZE) as bundle:
for lr in label_rows_to_save:
lr.save(bundle=bundle)
print(f"Saved label row for {lr.data_title}")
# Import dependencies
from encord import EncordUserClient, Project
from encord.objects import ChecklistAttribute, Object, ObjectInstance, Option, RadioAttribute, TextAttribute
from encord.objects.attributes import NumericAttribute
from encord.objects.coordinates import CuboidCoordinates
# User input
SSH_PATH = "/Users/chris-encord/ssh-private-key.txt" # Replace with the file path to your SSH private key
PROJECT_ID = "00000000-0000-0000-0000-000000000000" # Replace with the unique ID for the Project
BUNDLE_SIZE = 100
# Create user client using ssh key
user_client: EncordUserClient = EncordUserClient.create_with_ssh_private_key(
ssh_private_key_path=SSH_PATH,
# For US platform users use "https://api.us.encord.com"
domain="https://api.encord.com",
)
# Get project for which labels are to be added
project: Project = user_client.get_project(PROJECT_ID)
# Create radio button attribute for Person type
ontology_structure = project.ontology_structure
# Find a cuboid annotation object in the project ontology
cuboid_ontology_object: Object = ontology_structure.get_child_by_title(title="Person", type_=Object)
assert cuboid_ontology_object is not None, "Cuboid object 'Person' not found in ontology."
person_type_radio_attribute = ontology_structure.get_child_by_title(type_=RadioAttribute, title="Type?")
assert person_type_radio_attribute is not None, "Radio attribute 'Type?' not found in ontology."
# Create options for the radio buttons
adult_option = person_type_radio_attribute.get_child_by_title(type_=Option, title="Adult")
adolescent_option = person_type_radio_attribute.get_child_by_title(type_=Option, title="Adolescent")
child_option = person_type_radio_attribute.get_child_by_title(type_=Option, title="Child")
other_person_option = person_type_radio_attribute.get_child_by_title(type_=Option, title="Other Person type")
assert all([adult_option, adolescent_option, child_option, other_person_option]), (
"One or more Person type options are missing."
)
# Adult Qualities
adult_checklist_attribute = ontology_structure.get_child_by_title(type_=ChecklistAttribute, title="Adult Qualities?")
assert adult_checklist_attribute is not None, "Checklist attribute 'Adult Qualities?' not found."
adult_moving_option = adult_checklist_attribute.get_child_by_title(type_=Option, title="Moving")
adult_well_lit_option = adult_checklist_attribute.get_child_by_title(type_=Option, title="Well lit")
adult_fully_visible_option = adult_checklist_attribute.get_child_by_title(type_=Option, title="Fully visible")
assert all([adult_moving_option, adult_well_lit_option, adult_fully_visible_option]), (
"One or more Adult quality options are missing."
)
# Adolescent Qualities
adolescent_checklist_attribute = ontology_structure.get_child_by_title(
type_=ChecklistAttribute, title="Adolescent Qualities?"
)
assert adolescent_checklist_attribute is not None, "Checklist attribute 'Adolescent Qualities?' not found."
adolescent_moving_option = adolescent_checklist_attribute.get_child_by_title(type_=Option, title="Moving")
adolescent_well_lit_option = adolescent_checklist_attribute.get_child_by_title(type_=Option, title="Well lit")
adolescent_fully_visible_option = adolescent_checklist_attribute.get_child_by_title(type_=Option, title="Fully visible")
assert all([adolescent_moving_option, adolescent_well_lit_option, adolescent_fully_visible_option]), (
"One or more Adolescent quality options are missing."
)
# Child Qualities
child_checklist_attribute = ontology_structure.get_child_by_title(type_=ChecklistAttribute, title="Child Qualities?")
assert child_checklist_attribute is not None, "Checklist attribute 'Child Qualities?' not found."
child_moving_option = child_checklist_attribute.get_child_by_title(type_=Option, title="Moving")
child_well_lit_option = child_checklist_attribute.get_child_by_title(type_=Option, title="Well lit")
child_fully_visible_option = child_checklist_attribute.get_child_by_title(type_=Option, title="Fully visible")
assert all([child_moving_option, child_well_lit_option, child_fully_visible_option]), (
"One or more Child quality options are missing."
)
# Other Person Types
other_person_option_text_attribute = ontology_structure.get_child_by_title(
type_=TextAttribute, title="Specify Person type"
)
assert other_person_option_text_attribute is not None, "Text attribute 'Specify Person type' not found in ontology."
# Dictionary of labels per data unit and per frame with Person type specified, including quality options
pcd_labels = {
"scene-1094": {
0: {
"label_ref": "person_001",
"coordinates": CuboidCoordinates(position=(9, 9, 9), orientation=(0.11, 0.77, 0.33), size=(0.2, 0.2, 0.2)),
"person_type": "Adult",
"adult_quality_options": "Moving, Well lit",
}
},
"scene-0916": {
0: [
{
"label_ref": "person_002",
"coordinates": CuboidCoordinates(
position=(0.4, 0.4, 0.4), orientation=(0.0, 0.0, 0.4), size=(0.1, 0.1, 0.1)
),
"person_type": "Adolescent",
"adolescent_quality_options": "Moving, Well lit, Fully visible",
},
{
"label_ref": "person_003",
"coordinates": CuboidCoordinates(
position=(0.2, 0.2, 0.0), orientation=(0.0, 0.0, 0.1), size=(0.5, 0.5, 0.5)
),
"person_type": "Child",
"child_quality_options": "Moving",
},
{
"label_ref": "person_004",
"coordinates": CuboidCoordinates(
position=(0.2, 0.2, 0.0), orientation=(0.0, 0.0, 0.1), size=(0.7, 0.7, 0.7)
),
"person_type": "Other Person type",
"Specify Person type": "Person with a baby stroller",
},
],
},
"scene-0796": {
0: {
"label_ref": "person_005",
"coordinates": CuboidCoordinates(
position=(0.4, 0.4, 0.0), orientation=(0.0, 0.0, 0.4), size=(0.12, 0.12, 0.12)
),
"person_type": "Adult",
"adult_quality_options": "Moving, Well lit",
},
2: [
{
"label_ref": "person_006",
"coordinates": CuboidCoordinates(
position=(0.1, 0.1, 0.0), orientation=(0.0, 0.0, 0.2), size=(0.5, 0.5, 0.5)
),
"person_type": "Adolescent",
"adolescent_quality_options": "Fully visible",
},
{
"label_ref": "person_007",
"coordinates": CuboidCoordinates(
position=(0.1, 0.1, 0.0), orientation=(0.0, 0.0, 0.2), size=(0.0132, 0.0132, 0.0132)
),
"person_type": "Child",
"child_quality_options": "Moving",
},
{
"label_ref": "person_008",
"coordinates": CuboidCoordinates(
position=(0.2, 0.2, 0.0), orientation=(0.0, 0.0, 0.1), size=(0.8, 0.8, 0.8)
),
"person_type": "Other Person type",
"Specify Person type": "Person with a baby stroller",
},
],
},
"scene-1100": {
0: {
"label_ref": "person_009",
"coordinates": CuboidCoordinates(
position=(0.4, 0.4, 0.0), orientation=(0.0, 0.0, 0.4), size=(0.012, 0.012, 0.012)
),
"person_type": "Adult",
"adult_quality_options": "Moving",
},
3: [
{
"label_ref": "person_010",
"coordinates": CuboidCoordinates(
position=(0.4, 0.4, 0.0), orientation=(0.0, 0.0, 0.4), size=(0.5, 0.5, 0.5)
),
"person_type": "Adolescent",
"adolescent_quality_options": "Moving, Well lit, Fully visible",
},
{
"label_ref": "person_011",
"coordinates": CuboidCoordinates(
position=(0.3, 0.3, 0.0), orientation=(0.0, 0.0, 0.3), size=(0.13, 0.13, 0.13)
),
"person_type": "Child",
"child_quality_options": "Moving",
},
{
"label_ref": "person_012",
"coordinates": CuboidCoordinates(
position=(0.2, 0.2, 0.0), orientation=(0.0, 0.0, 0.1), size=(0.9, 0.9, 0.9)
),
"person_type": "Other Person type",
"Specify Person type": "Person with a baby stroller",
},
],
},
"scene-0655": {
13: [
{
"label_ref": "person_013",
"coordinates": CuboidCoordinates(
position=(0.5, 0.5, 0.0), orientation=(0.0, 0.0, 0.5), size=(0.11, 0.11, 0.11)
),
"person_type": "Child",
"child_quality_options": "Moving",
},
{
"label_ref": "person_014",
"coordinates": CuboidCoordinates(
position=(0.2, 0.2, 0.0), orientation=(0.0, 0.0, 0.2), size=(0.6, 0.6, 0.6)
),
"person_type": "Adult",
"adult_quality_options": "Moving, Well lit, Fully visible",
},
{
"label_ref": "person_015",
"coordinates": CuboidCoordinates(
position=(0.2, 0.2, 0.0), orientation=(0.0, 0.0, 0.1), size=(0.8, 0.8, 0.8)
),
"person_type": "Other Person type",
"Specify Person type": "Person walking a dog",
},
],
14: [
{
"label_ref": "person_016",
"coordinates": CuboidCoordinates(
position=(0.5, 0.5, 0.0), orientation=(0.0, 0.0, 0.5), size=(0.3, 0.3, 0.3)
),
"person_type": "Child",
"child_quality_options": "Moving",
},
{
"label_ref": "person_014",
"coordinates": CuboidCoordinates(
position=(0.2, 0.2, 0.0), orientation=(0.0, 0.0, 0.2), size=(0.6, 0.6, 0.6)
),
"person_type": "Adult",
"adult_quality_options": "Moving, Well lit, Fully visible",
},
{
"label_ref": "person_017",
"coordinates": CuboidCoordinates(
position=(0.2, 0.2, 0.0), orientation=(0.0, 0.0, 0.1), size=(0.8, 0.8, 0.8)
),
"person_type": "Other Person type",
"Specify Person type": "Person walking a dog",
},
],
15: [
{
"label_ref": "person_016",
"coordinates": CuboidCoordinates(
position=(0.5, 0.5, 0.0), orientation=(0.0, 0.0, 0.5), size=(0.1, 0.1, 0.1)
),
"person_type": "Child",
"child_quality_options": "Moving",
},
{
"label_ref": "person_014",
"coordinates": CuboidCoordinates(
position=(0.2, 0.2, 0.0), orientation=(0.0, 0.0, 0.2), size=(0.6, 0.6, 0.6)
),
"person_type": "Adult",
"adult_quality_options": "Moving, Well lit, Fully visible",
},
{
"label_ref": "person_017",
"coordinates": CuboidCoordinates(
position=(0.2, 0.2, 0.0), orientation=(0.0, 0.0, 0.1), size=(0.8, 0.8, 0.8)
),
"person_type": "Other Person type",
"Specify Person type": "Person walking a dog",
},
],
},
}
# Cache initialized label rows
label_row_map = {}
# Step 1: Initialize all label rows using a bundle
with project.create_bundle(bundle_size=BUNDLE_SIZE) as bundle:
for data_unit in pcd_labels.keys():
label_rows = project.list_label_rows_v2(data_title_eq=data_unit)
assert isinstance(label_rows, list), f"Expected list of label rows for '{data_unit}', got {type(label_rows)}"
if not label_rows:
print(f"Skipping: No label row found for {data_unit}")
continue
label_row = label_rows[0]
label_row.initialise_labels(bundle=bundle)
assert label_row.ontology_structure is not None, f"Ontology not initialized for label row: {data_unit}"
label_row_map[data_unit] = label_row # Cache initialized label row for later use
# Step 2: Process all frames/annotations and prepare label rows to save
label_rows_to_save = []
for data_unit, frame_coordinates in pcd_labels.items():
label_row = label_row_map.get(data_unit)
if not label_row:
print(f"Skipping: No initialized label row found for {data_unit}")
continue
object_instances_by_label_ref = {}
# Loop through the frames for the current data unit
for frame_number, items in frame_coordinates.items():
assert isinstance(frame_number, int), f"Frame number must be int, got {type(frame_number)}"
if not isinstance(items, list):
items = [items]
for item in items:
label_ref = item["label_ref"]
coord = item["coordinates"]
person_type = item["person_type"]
assert person_type in {
"Adult",
"Adolescent",
"Child",
"Other Person type",
}, f"Unexpected Person type '{person_type}' in data unit '{data_unit}'"
# Check if label_ref already exists for reusability
if label_ref not in object_instances_by_label_ref:
cuboid_object_instance: ObjectInstance = cuboid_ontology_object.create_instance()
assert cuboid_object_instance is not None, "Failed to create ObjectInstance"
object_instances_by_label_ref[label_ref] = cuboid_object_instance
checklist_attribute = None
# Set Person type attribute
if person_type == "Adult":
assert adult_option is not None, "Missing 'adult_option'"
cuboid_object_instance.set_answer(attribute=person_type_radio_attribute, answer=adult_option)
checklist_attribute = adult_checklist_attribute
elif person_type == "Adolescent":
assert adolescent_option is not None, "Missing 'adolescent_option'"
cuboid_object_instance.set_answer(attribute=person_type_radio_attribute, answer=adolescent_option)
checklist_attribute = adolescent_checklist_attribute
elif person_type == "Child":
assert child_option is not None, "Missing 'child_option'"
cuboid_object_instance.set_answer(attribute=person_type_radio_attribute, answer=child_option)
checklist_attribute = child_checklist_attribute
elif person_type == "Other Person type":
assert other_person_option is not None, "Missing 'other_person_option'"
cuboid_object_instance.set_answer(attribute=person_type_radio_attribute, answer=other_person_option)
text_answer = item.get("Specify Person type", "")
assert isinstance(text_answer, str), "'Specify Person type' must be a string"
cuboid_object_instance.set_answer(attribute=other_person_option_text_attribute, answer=text_answer)
# Set checklist attributes
checklist_answers = []
quality_key = f"{person_type.lower()}_quality_options"
quality_options = item.get(quality_key, "").split(", ")
for quality in quality_options:
if quality == "Moving":
checklist_answers.append(
adult_moving_option
if person_type == "Adult"
else adolescent_moving_option
if person_type == "Adolescent"
else child_moving_option
)
elif quality == "Well lit":
checklist_answers.append(
adult_well_lit_option
if person_type == "Adult"
else adolescent_well_lit_option
if person_type == "Adolescent"
else child_well_lit_option
)
elif quality == "Fully visible":
checklist_answers.append(
adult_fully_visible_option
if person_type == "Adult"
else adolescent_fully_visible_option
if person_type == "Adolescent"
else child_fully_visible_option
)
if checklist_attribute and checklist_answers:
cuboid_object_instance.set_answer(
attribute=checklist_attribute, answer=checklist_answers, overwrite=True
)
else:
# Reuse existing instance across frames
cuboid_object_instance = object_instances_by_label_ref[label_ref]
# Assign the object to the frame and track it
cuboid_object_instance.set_for_frames(coordinates=coord, frames=frame_number)
# Add object instances to label_row **only if they have frames assigned**
for cuboid_object_instance in object_instances_by_label_ref.values():
assert isinstance(cuboid_object_instance, ObjectInstance), "Expected ObjectInstance type"
if cuboid_object_instance.get_annotation_frames(): # Ensures it has at least one frame
label_row.add_object_instance(cuboid_object_instance)
label_rows_to_save.append(label_row)
# Step 3: Save all label rows using a bundle
with project.create_bundle(bundle_size=BUNDLE_SIZE) as bundle:
for label_row in label_rows_to_save:
assert label_row is not None, "Trying to save a None label row"
label_row.save(bundle=bundle)
print(f"Saved label row for {label_row.data_title}")
print("Labels with Person type radio buttons, checklist attributes, and text labels added for all data units.")
Polylines 3D
Basic This example includes the following:- Polyline 3D labeling
- Polyline 3D labeling
- Radio button options
- Checklist options
- Text input
# Import dependencies
from encord import EncordUserClient, Project
from encord.objects import Object
from encord.objects.coordinates import PointCoordinate3D, PolylineCoordinates
# User input
SSH_PATH = "/Users/chris-encord/ssh-private-key.txt" # Replace with the file path to your SSH private key
PROJECT_ID = "00000000-0000-0000-0000-000000000000" # Replace with the unique ID for the Project
BUNDLE_SIZE = 100
# Create user client using ssh key
user_client: EncordUserClient = EncordUserClient.create_with_ssh_private_key(
ssh_private_key_path=SSH_PATH,
# For US platform users use "https://api.us.encord.com"
domain="https://api.encord.com",
)
# Get project for which labels are to be added
project: Project = user_client.get_project(PROJECT_ID)
# Get the ontology
ontology_structure = project.ontology_structure
# Find a polyline annotation object in the project ontology
polyline_ontology_object: Object = ontology_structure.get_child_by_title(title="Object of Interest", type_=Object)
assert polyline_ontology_object is not None, "Polyline object 'Object of Interest' not found in ontology."
# Dictionary of labels per data unit and per frame with Object of Interest
pcd_labels = {
"scene-1094": {
0: {
"label_ref": "ooi_001",
"coordinates": PolylineCoordinates(
[
PointCoordinate3D(2.013, 2.02, 2.015),
PointCoordinate3D(3.033, 3.033, 3.033),
PointCoordinate3D(4.053, 4.023, 4.017),
PointCoordinate3D(0.043, 0.013, 0.043),
]
),
}
},
"scene-0916": {
0: [
{
"label_ref": "ooi_002",
"coordinates": PolylineCoordinates(
[
PointCoordinate3D(3.000, 2.300, 0.000),
PointCoordinate3D(3.300, 3.300, 0.000),
PointCoordinate3D(5.300, 3.300, 0.000),
PointCoordinate3D(4.300, 1.300, 0.000),
]
),
},
{
"label_ref": "ooi_003",
"coordinates": PolylineCoordinates(
[
PointCoordinate3D(4.300, 5.300, 0.000),
PointCoordinate3D(6.300, 6.300, 0.000),
PointCoordinate3D(8.300, 5.300, 0.000),
PointCoordinate3D(7.300, 4.300, 0.000),
]
),
},
{
"label_ref": "ooi_004",
"coordinates": PolylineCoordinates(
[
PointCoordinate3D(7.300, 2.300, 0.000),
PointCoordinate3D(9.300, 3.300, 0.000),
PointCoordinate3D(11.300, 2.300, 0.000),
PointCoordinate3D(10.300, 1.300, 0.000),
]
),
},
],
},
"scene-0796": {
0: {
"label_ref": "ooi_005",
"coordinates": PolylineCoordinates(
[
PointCoordinate3D(1.300, 2.300, 0.000),
PointCoordinate3D(3.300, 3.300, 0.000),
PointCoordinate3D(5.300, 2.300, 0.000),
PointCoordinate3D(4.300, 1.300, 0.000),
]
),
},
2: [
{
"label_ref": "ooi_006",
"coordinates": PolylineCoordinates(
[
PointCoordinate3D(1.300, 2.300, 0.000),
PointCoordinate3D(3.300, 3.300, 0.000),
PointCoordinate3D(5.300, 2.300, 0.000),
PointCoordinate3D(4.300, 1.300, 0.000),
]
),
},
{
"label_ref": "ooi_007",
"coordinates": PolylineCoordinates(
[
PointCoordinate3D(4.300, 5.300, 0.000),
PointCoordinate3D(6.300, 6.300, 0.000),
PointCoordinate3D(8.300, 5.300, 0.000),
PointCoordinate3D(7.300, 4.300, 0.000),
]
),
},
{
"label_ref": "ooi_008",
"coordinates": PolylineCoordinates(
[
PointCoordinate3D(7.300, 2.300, 0.000),
PointCoordinate3D(9.300, 3.300, 0.000),
PointCoordinate3D(11.300, 2.300, 0.000),
PointCoordinate3D(10.300, 1.300, 0.000),
]
),
},
],
},
"scene-1100": {
0: {
"label_ref": "ooi_009",
"coordinates": PolylineCoordinates(
[
PointCoordinate3D(1.300, 2.300, 0.000),
PointCoordinate3D(3.300, 3.300, 0.000),
PointCoordinate3D(5.300, 2.300, 0.000),
PointCoordinate3D(4.300, 1.300, 0.000),
]
),
},
3: [
{
"label_ref": "ooi_010",
"coordinates": PolylineCoordinates(
[
PointCoordinate3D(1.300, 2.300, 0.000),
PointCoordinate3D(3.300, 3.300, 0.000),
PointCoordinate3D(5.300, 2.300, 0.000),
PointCoordinate3D(4.300, 1.300, 0.000),
]
),
},
{
"label_ref": "ooi_011",
"coordinates": PolylineCoordinates(
[
PointCoordinate3D(4.300, 5.300, 0.000),
PointCoordinate3D(6.300, 6.300, 0.000),
PointCoordinate3D(8.300, 5.300, 0.000),
PointCoordinate3D(7.300, 4.300, 0.000),
]
),
},
{
"label_ref": "ooi_012",
"coordinates": PolylineCoordinates(
[
PointCoordinate3D(7.300, 2.300, 0.000),
PointCoordinate3D(9.300, 3.300, 0.000),
PointCoordinate3D(11.300, 2.300, 0.000),
PointCoordinate3D(10.300, 1.300, 0.000),
]
),
},
],
},
"scene-0655": {
103: [
{
"label_ref": "ooi_013",
"coordinates": PolylineCoordinates(
[
PointCoordinate3D(1.300, 2.300, 0.000),
PointCoordinate3D(3.300, 3.300, 0.000),
PointCoordinate3D(5.300, 2.300, 0.000),
PointCoordinate3D(4.300, 1.300, 0.000),
]
),
},
{
"label_ref": "ooi_014",
"coordinates": PolylineCoordinates(
[
PointCoordinate3D(4.300, 5.300, 0.000),
PointCoordinate3D(6.300, 6.300, 0.000),
PointCoordinate3D(8.300, 5.300, 0.000),
PointCoordinate3D(7.300, 4.300, 0.000),
]
),
},
{
"label_ref": "ooi_015",
"coordinates": PolylineCoordinates(
[
PointCoordinate3D(7.300, 2.300, 0.000),
PointCoordinate3D(9.300, 3.300, 0.000),
PointCoordinate3D(11.300, 2.300, 0.000),
PointCoordinate3D(10.300, 1.300, 0.000),
]
),
},
],
104: [
{
"label_ref": "ooi_016",
"coordinates": PolylineCoordinates(
[
PointCoordinate3D(1.300, 2.300, 0.000),
PointCoordinate3D(3.300, 3.300, 0.000),
PointCoordinate3D(5.300, 2.300, 0.000),
PointCoordinate3D(4.300, 1.300, 0.000),
]
),
},
{
"label_ref": "ooi_014",
"coordinates": PolylineCoordinates(
[
PointCoordinate3D(4.130, 5.230, 0.000),
PointCoordinate3D(6.130, 6.230, 0.000),
PointCoordinate3D(8.130, 5.230, 0.000),
PointCoordinate3D(7.130, 4.230, 0.000),
]
),
},
{
"label_ref": "ooi_017",
"coordinates": PolylineCoordinates(
[
PointCoordinate3D(7.300, 2.300, 0.000),
PointCoordinate3D(9.300, 3.300, 0.000),
PointCoordinate3D(11.300, 2.300, 0.000),
PointCoordinate3D(10.300, 1.300, 0.000),
]
),
},
],
105: [
{
"label_ref": "ooi_016",
"coordinates": PolylineCoordinates(
[
PointCoordinate3D(1.130, 2.230, 0.000),
PointCoordinate3D(3.130, 3.230, 0.000),
PointCoordinate3D(5.130, 2.230, 0.000),
PointCoordinate3D(4.130, 1.230, 0.000),
]
),
},
{
"label_ref": "ooi_014",
"coordinates": PolylineCoordinates(
[
PointCoordinate3D(4.330, 5.530, 0.000),
PointCoordinate3D(6.330, 6.530, 0.000),
PointCoordinate3D(8.330, 5.530, 0.000),
PointCoordinate3D(7.330, 4.530, 0.000),
]
),
},
{
"label_ref": "ooi_017",
"coordinates": PolylineCoordinates(
[
PointCoordinate3D(7.130, 2.230, 0.000),
PointCoordinate3D(9.130, 3.230, 0.000),
PointCoordinate3D(11.130, 2.230, 0.000),
PointCoordinate3D(10.130, 1.230, 0.000),
]
),
},
],
},
}
# Initialize label rows
label_row_map = {}
with project.create_bundle(bundle_size=BUNDLE_SIZE) as bundle:
for data_title in pcd_labels.keys():
rows = project.list_label_rows_v2(data_title_eq=data_title)
if not rows:
print(f"Skipping: No label row found for {data_title}")
continue
lr = rows[0]
lr.initialise_labels(bundle=bundle)
label_row_map[data_title] = lr
# Create instances
label_rows_to_save = []
for data_title, frames in pcd_labels.items():
lr = label_row_map.get(data_title)
if not lr:
continue
instances_by_ref = {}
for frame_no, items in frames.items():
# normalize to list
items = items if isinstance(items, list) else [items]
for item in items:
ref = item["label_ref"]
coords = item["coordinates"]
if ref not in instances_by_ref:
instances_by_ref[ref] = polyline_ontology_object.create_instance()
instances_by_ref[ref].set_for_frames(coordinates=coords, frames=frame_no)
# Add only instances that have at least one frame
for inst in instances_by_ref.values():
if inst.get_annotation_frames():
lr.add_object_instance(inst)
label_rows_to_save.append(lr)
# Save all label rows
with project.create_bundle(bundle_size=BUNDLE_SIZE) as bundle:
for lr in label_rows_to_save:
lr.save(bundle=bundle)
print(f"Saved label row for {lr.data_title}")
# Import dependencies
from pathlib import Path
from encord import EncordUserClient, Project
from encord.objects import (
ChecklistAttribute,
NumberAttribute,
Object,
ObjectInstance,
Option,
RadioAttribute,
TextAttribute,
)
from encord.objects.attributes import NumericAttribute
from encord.objects.coordinates import PointCoordinate3D, PolylineCoordinates
# User input
SSH_PATH = "/Users/chris-encord/ssh-private-key.txt" # Replace with the file path to your SSH private key
PROJECT_ID = "00000000-0000-0000-0000-000000000000" # Replace with the unique ID for the Project
BUNDLE_SIZE = 100
# Create user client using ssh key
user_client: EncordUserClient = EncordUserClient.create_with_ssh_private_key(
ssh_private_key_path=SSH_PATH,
# For US platform users use "https://api.us.encord.com"
domain="https://api.encord.com",
)
# Get project for which labels are to be added
project: Project = user_client.get_project(PROJECT_ID)
assert project is not None, "Project not found — check PROJECT_ID"
# Get ontology structure
ontology_structure = project.ontology_structure
assert ontology_structure is not None, "Ontology structure is missing in the project"
# Get polyline object for Object of Interest
polyline_ontology_object: Object = ontology_structure.get_child_by_title(title="Object of Interest", type_=Object)
assert polyline_ontology_object is not None, "Polyline object 'Object of Interest' not found in ontology"
# Get radio attribute for Object of Interest type
ooi_type_radio_attribute = ontology_structure.get_child_by_title(type_=RadioAttribute, title="Type?")
assert ooi_type_radio_attribute is not None, "Radio attribute 'Type?' not found in ontology"
# Get radio options
curb_option = ooi_type_radio_attribute.get_child_by_title(type_=Option, title="Curb")
assert curb_option is not None, "Option 'Curb' not found under radio attribute 'Type?'"
lane_divider_option = ooi_type_radio_attribute.get_child_by_title(type_=Option, title="Lane divider")
assert lane_divider_option is not None, "Option 'Lane divider' not found under radio attribute 'Type?'"
zebra_crossing_option = ooi_type_radio_attribute.get_child_by_title(type_=Option, title="Zebra crossing")
assert zebra_crossing_option is not None, "Option 'Zebra crossing' not found under radio attribute 'Type?'"
other_ooi_option = ooi_type_radio_attribute.get_child_by_title(type_=Option, title="Other")
assert other_ooi_option is not None, "Option 'Other' not found under radio attribute 'Type?'"
# Curb Qualities
curb_checklist_attribute = ontology_structure.get_child_by_title(type_=ChecklistAttribute, title="Qualities?")
assert curb_checklist_attribute is not None, "Checklist attribute 'Qualities?' not found"
curb_good_quality_option = curb_checklist_attribute.get_child_by_title(type_=Option, title="Good quality")
assert curb_good_quality_option is not None, "Option 'Good quality' not found under 'Qualities?'"
curb_well_lit_option = curb_checklist_attribute.get_child_by_title(type_=Option, title="Well lit")
assert curb_well_lit_option is not None, "Option 'Well lit' not found under 'Qualities?'"
curb_fully_visible_option = curb_checklist_attribute.get_child_by_title(type_=Option, title="Fully visible")
assert curb_fully_visible_option is not None, "Option 'Fully visible' not found under 'Curb Qualities?'"
# Lane divider Qualities
lane_divider_checklist_attribute = ontology_structure.get_child_by_title(
type_=ChecklistAttribute, title="Lane divider Qualities?"
)
assert lane_divider_checklist_attribute is not None, "Checklist attribute 'Lane divider Qualities?' not found"
lane_divider_good_quality_option = lane_divider_checklist_attribute.get_child_by_title(
type_=Option, title="Good quality"
)
assert lane_divider_good_quality_option is not None, "Option 'Good quality' not found under 'Lane divider Qualities?'"
lane_divider_well_lit_option = lane_divider_checklist_attribute.get_child_by_title(type_=Option, title="Well lit")
assert lane_divider_well_lit_option is not None, "Option 'Well lit' not found under 'Lane divider Qualities?'"
lane_divider_fully_visible_option = lane_divider_checklist_attribute.get_child_by_title(
type_=Option, title="Fully visible"
)
assert lane_divider_fully_visible_option is not None, "Option 'Fully visible' not found under 'Lane divider Qualities?'"
# Zebra crossing Qualities
zebra_crossing_checklist_attribute = ontology_structure.get_child_by_title(
type_=ChecklistAttribute, title="Zebra crossing Qualities?"
)
assert zebra_crossing_checklist_attribute is not None, "Checklist attribute 'Zebra crossing Qualities?' not found"
zebra_crossing_good_quality_option = zebra_crossing_checklist_attribute.get_child_by_title(
type_=Option, title="Good quality"
)
assert zebra_crossing_good_quality_option is not None, (
"Option 'Good quality' not found under 'Zebra crossing Qualities?'"
)
zebra_crossing_well_lit_option = zebra_crossing_checklist_attribute.get_child_by_title(type_=Option, title="Well lit")
assert zebra_crossing_well_lit_option is not None, "Option 'Well lit' not found under 'Zebra crossing Qualities?'"
zebra_crossing_fully_visible_option = zebra_crossing_checklist_attribute.get_child_by_title(
type_=Option, title="Fully visible"
)
assert zebra_crossing_fully_visible_option is not None, (
"Option 'Fully visible' not found under 'Zebra crossing Qualities?'"
)
# Other text attribute
other_ooi_option_text_attribute = ontology_structure.get_child_by_title(type_=TextAttribute, title="Specify type")
assert other_ooi_option_text_attribute is not None, "Text attribute 'Specify type' not found"
# Dictionary of labels per data unit and per frame with type specified, including quality options
pcd_labels = {
"scene-1094": {
0: {
"label_ref": "ooi_001",
"coordinates": PolylineCoordinates(
[
PointCoordinate3D(2.013, 2.02, 2.015),
PointCoordinate3D(3.033, 3.033, 3.033),
PointCoordinate3D(4.053, 4.023, 4.017),
PointCoordinate3D(5.043, 5.013, 5.043),
]
),
"ooi_type": "Curb",
"curb_quality_options": "Good quality, Well lit",
}
},
"scene-0916": {
0: [
{
"label_ref": "ooi_002",
"coordinates": PolylineCoordinates(
[
PointCoordinate3D(3.000, 2.300, 0.000),
PointCoordinate3D(3.300, 3.300, 0.000),
PointCoordinate3D(5.300, 3.300, 0.000),
PointCoordinate3D(4.300, 1.300, 0.000),
]
),
"ooi_type": "Lane divider",
"lane_divider_quality_options": "Good quality, Well lit, Fully visible",
},
{
"label_ref": "ooi_003",
"coordinates": PolylineCoordinates(
[
PointCoordinate3D(4.300, 5.300, 0.000),
PointCoordinate3D(6.300, 6.300, 0.000),
PointCoordinate3D(8.300, 5.300, 0.000),
PointCoordinate3D(7.300, 4.300, 0.000),
]
),
"ooi_type": "Zebra crossing",
"zebra_crossing_quality_options": "Good quality",
},
{
"label_ref": "ooi_004",
"coordinates": PolylineCoordinates(
[
PointCoordinate3D(7.300, 2.300, 0.000),
PointCoordinate3D(9.300, 3.300, 0.000),
PointCoordinate3D(11.300, 2.300, 0.000),
PointCoordinate3D(10.300, 1.300, 0.000),
]
),
"ooi_type": "Other",
"Type": "Cane",
},
],
},
"scene-0796": {
0: {
"label_ref": "ooi_005",
"coordinates": PolylineCoordinates(
[
PointCoordinate3D(1.300, 2.300, 0.000),
PointCoordinate3D(3.300, 3.300, 0.000),
PointCoordinate3D(5.300, 2.300, 0.000),
PointCoordinate3D(4.300, 1.300, 0.000),
]
),
"ooi_type": "Curb",
"curb_quality_options": "Good quality, Well lit",
},
2: [
{
"label_ref": "ooi_006",
"coordinates": PolylineCoordinates(
[
PointCoordinate3D(1.300, 2.300, 0.000),
PointCoordinate3D(3.300, 3.300, 0.000),
PointCoordinate3D(5.300, 2.300, 0.000),
PointCoordinate3D(4.300, 1.300, 0.000),
]
),
"ooi_type": "Lane divider",
"lane_divider_quality_options": "Fully visible",
},
{
"label_ref": "ooi_007",
"coordinates": PolylineCoordinates(
[
PointCoordinate3D(4.300, 5.300, 0.000),
PointCoordinate3D(6.300, 6.300, 0.000),
PointCoordinate3D(8.300, 5.300, 0.000),
PointCoordinate3D(7.300, 4.300, 0.000),
]
),
"ooi_type": "Zebra crossing",
"zebra_crossing_quality_options": "Good quality",
},
{
"label_ref": "ooi_008",
"coordinates": PolylineCoordinates(
[
PointCoordinate3D(7.300, 2.300, 0.000),
PointCoordinate3D(9.300, 3.300, 0.000),
PointCoordinate3D(11.300, 2.300, 0.000),
PointCoordinate3D(10.300, 1.300, 0.000),
]
),
"ooi_type": "Other",
"Type": "Cane",
},
],
},
"scene-1100": {
0: {
"label_ref": "ooi_009",
"coordinates": PolylineCoordinates(
[
PointCoordinate3D(1.300, 2.300, 0.000),
PointCoordinate3D(3.300, 3.300, 0.000),
PointCoordinate3D(5.300, 2.300, 0.000),
PointCoordinate3D(4.300, 1.300, 0.000),
]
),
"ooi_type": "Curb",
"curb_quality_options": "Good quality",
},
3: [
{
"label_ref": "ooi_010",
"coordinates": PolylineCoordinates(
[
PointCoordinate3D(1.300, 2.300, 0.000),
PointCoordinate3D(3.300, 3.300, 0.000),
PointCoordinate3D(5.300, 2.300, 0.000),
PointCoordinate3D(4.300, 1.300, 0.000),
]
),
"ooi_type": "Lane divider",
"lane_divider_quality_options": "Good quality, Well lit, Fully visible",
},
{
"label_ref": "ooi_011",
"coordinates": PolylineCoordinates(
[
PointCoordinate3D(4.300, 5.300, 0.000),
PointCoordinate3D(6.300, 6.300, 0.000),
PointCoordinate3D(8.300, 5.300, 0.000),
PointCoordinate3D(7.300, 4.300, 0.000),
]
),
"ooi_type": "Zebra crossing",
"zebra_crossing_quality_options": "Good quality",
},
{
"label_ref": "ooi_012",
"coordinates": PolylineCoordinates(
[
PointCoordinate3D(7.300, 2.300, 0.000),
PointCoordinate3D(9.300, 3.300, 0.000),
PointCoordinate3D(11.300, 2.300, 0.000),
PointCoordinate3D(10.300, 1.300, 0.000),
]
),
"ooi_type": "Other",
"Type": "Cane",
},
],
},
"scene-0655": {
13: [
{
"label_ref": "ooi_013",
"coordinates": PolylineCoordinates(
[
PointCoordinate3D(1.300, 2.300, 0.000),
PointCoordinate3D(3.300, 3.300, 0.000),
PointCoordinate3D(5.300, 2.300, 0.000),
PointCoordinate3D(4.300, 1.300, 0.000),
]
),
"ooi_type": "Zebra crossing",
"zebra_crossing_quality_options": "Good quality",
},
{
"label_ref": "ooi_014",
"coordinates": PolylineCoordinates(
[
PointCoordinate3D(4.300, 5.300, 0.000),
PointCoordinate3D(6.300, 6.300, 0.000),
PointCoordinate3D(8.300, 5.300, 0.000),
PointCoordinate3D(7.300, 4.300, 0.000),
]
),
"ooi_type": "Curb",
"curb_quality_options": "Good quality, Well lit, Fully visible",
},
{
"label_ref": "ooi_015",
"coordinates": PolylineCoordinates(
[
PointCoordinate3D(7.300, 2.300, 0.000),
PointCoordinate3D(9.300, 3.300, 0.000),
PointCoordinate3D(11.300, 2.300, 0.000),
PointCoordinate3D(10.300, 1.300, 0.000),
]
),
"ooi_type": "Other",
"Type": "Cane",
},
],
14: [
{
"label_ref": "ooi_016",
"coordinates": PolylineCoordinates(
[
PointCoordinate3D(1.300, 2.300, 0.000),
PointCoordinate3D(3.300, 3.300, 0.000),
PointCoordinate3D(5.300, 2.300, 0.000),
PointCoordinate3D(4.300, 1.300, 0.000),
]
),
"ooi_type": "Zebra crossing",
"zebra_crossing_quality_options": "Good quality",
},
{
"label_ref": "ooi_014",
"coordinates": PolylineCoordinates(
[
PointCoordinate3D(4.130, 5.230, 0.000),
PointCoordinate3D(6.130, 6.230, 0.000),
PointCoordinate3D(8.130, 5.230, 0.000),
PointCoordinate3D(7.130, 4.230, 0.000),
]
),
"ooi_type": "Curb",
"curb_quality_options": "Good quality, Well lit, Fully visible",
},
{
"label_ref": "ooi_017",
"coordinates": PolylineCoordinates(
[
PointCoordinate3D(7.300, 2.300, 0.000),
PointCoordinate3D(9.300, 3.300, 0.000),
PointCoordinate3D(11.300, 2.300, 0.000),
PointCoordinate3D(10.300, 1.300, 0.000),
]
),
"ooi_type": "Other",
"Type": "Cane",
},
],
15: [
{
"label_ref": "ooi_016",
"coordinates": PolylineCoordinates(
[
PointCoordinate3D(1.130, 2.230, 0.000),
PointCoordinate3D(3.130, 3.230, 0.000),
PointCoordinate3D(5.130, 2.230, 0.000),
PointCoordinate3D(4.130, 1.230, 0.000),
]
),
"ooi_type": "Zebra crossing",
"zebra_crossing_quality_options": "Good quality",
},
{
"label_ref": "ooi_014",
"coordinates": PolylineCoordinates(
[
PointCoordinate3D(4.330, 5.530, 0.000),
PointCoordinate3D(6.330, 6.530, 0.000),
PointCoordinate3D(8.330, 5.530, 0.000),
PointCoordinate3D(7.330, 4.530, 0.000),
]
),
"ooi_type": "Curb",
"curb_quality_options": "Good quality, Well lit, Fully visible",
},
{
"label_ref": "ooi_017",
"coordinates": PolylineCoordinates(
[
PointCoordinate3D(7.130, 2.230, 0.000),
PointCoordinate3D(9.130, 3.230, 0.000),
PointCoordinate3D(11.130, 2.230, 0.000),
PointCoordinate3D(10.130, 1.230, 0.000),
]
),
"ooi_type": "Other",
"Type": "Cane",
},
],
},
}
# Cache label rows after initialization
label_row_map = {}
# Step 1: Initialize all label rows using a bundle
with project.create_bundle(bundle_size=BUNDLE_SIZE) as bundle:
for data_unit in pcd_labels.keys():
label_rows = project.list_label_rows_v2(data_title_eq=data_unit)
assert isinstance(label_rows, list), f"Expected list of label rows for '{data_unit}', got {type(label_rows)}"
if not label_rows:
print(f"Skipping: No label row found for {data_unit}")
continue
label_row = label_rows[0]
label_row.initialise_labels(bundle=bundle)
assert label_row.ontology_structure is not None, f"Ontology not initialized for label row: {data_unit}"
label_row_map[data_unit] = label_row # Cache the initialized label row
# Step 2: Process all frame coordinates and prepare label rows for saving
label_rows_to_save = []
for data_unit, frame_coordinates in pcd_labels.items():
label_row = label_row_map.get(data_unit)
assert label_row is not None, f"Label row not initialized for {data_unit}"
object_instances_by_label_ref = {}
for frame_number, items in frame_coordinates.items():
assert isinstance(frame_number, int), f"Frame number must be int, got {type(frame_number)}"
if not isinstance(items, list):
items = [items]
for item in items:
label_ref = item["label_ref"]
coord = item["coordinates"]
ooi_type = item["ooi_type"]
assert ooi_type in {
"Curb",
"Lane divider",
"Zebra crossing",
"Other",
}, f"Unexpected type '{ooi_type}' in {data_unit}"
if label_ref not in object_instances_by_label_ref:
polyline_object_instance: ObjectInstance = polyline_ontology_object.create_instance()
assert polyline_object_instance is not None, "Failed to create ObjectInstance"
checklist_attribute = None
quality_options = []
# Assign radio and checklist attributes based on the type
if ooi_type == "Curb":
assert curb_option is not None, "Missing 'curb_option'"
polyline_object_instance.set_answer(attribute=ooi_type_radio_attribute, answer=curb_option)
checklist_attribute = curb_checklist_attribute
quality_options = [q.strip() for q in item.get("curb_quality_options", "").split(",") if q.strip()]
elif ooi_type == "Lane divider":
assert lane_divider_option is not None, "Missing 'lane_divider_option'"
polyline_object_instance.set_answer(attribute=ooi_type_radio_attribute, answer=lane_divider_option)
checklist_attribute = lane_divider_checklist_attribute
quality_options = [
q.strip() for q in item.get("lane_divider_quality_options", "").split(",") if q.strip()
]
elif ooi_type == "Zebra crossing":
assert zebra_crossing_option is not None, "Missing 'zebra_crossing_option'"
polyline_object_instance.set_answer(
attribute=ooi_type_radio_attribute, answer=zebra_crossing_option
)
checklist_attribute = zebra_crossing_checklist_attribute
quality_options = [
q.strip() for q in item.get("zebra_crossing_quality_options", "").split(",") if q.strip()
]
elif ooi_type == "Other":
assert other_ooi_option is not None, "Missing 'other_ooi_option'"
polyline_object_instance.set_answer(attribute=ooi_type_radio_attribute, answer=other_ooi_option)
text_answer = item.get("Type", "")
assert isinstance(text_answer, str), "'Type' must be a string"
polyline_object_instance.set_answer(attribute=other_ooi_option_text_attribute, answer=text_answer)
quality_options = []
# Process checklist options
checklist_answers = []
for quality in quality_options:
option = None
if quality == "Good quality":
option = (
curb_good_quality_option
if ooi_type == "Curb"
else lane_divider_good_quality_option
if ooi_type == "Lane divider"
else zebra_crossing_good_quality_option
if ooi_type == "Zebra crossing"
else None
)
elif quality == "Well lit":
option = (
curb_well_lit_option
if ooi_type == "Curb"
else lane_divider_well_lit_option
if ooi_type == "Lane divider"
else zebra_crossing_well_lit_option
if ooi_type == "Zebra crossing"
else None
)
elif quality == "Fully visible":
option = (
curb_fully_visible_option
if ooi_type == "Curb"
else lane_divider_fully_visible_option
if ooi_type == "Lane divider"
else zebra_crossing_fully_visible_option
if ooi_type == "Zebra crossing"
else None
)
if option:
checklist_answers.append(option)
else:
assert ooi_type == "Other", f"Invalid quality '{quality}' for type '{ooi_type}'"
if checklist_attribute and checklist_answers:
polyline_object_instance.set_answer(
attribute=checklist_attribute, answer=checklist_answers, overwrite=True
)
object_instances_by_label_ref[label_ref] = polyline_object_instance
else:
polyline_object_instance = object_instances_by_label_ref[label_ref]
# Assign coordinates for this frame
polyline_object_instance.set_for_frames(coordinates=coord, frames=frame_number)
# Add object instances to the label row if they have frames assigned
for polyline_object_instance in object_instances_by_label_ref.values():
assert isinstance(polyline_object_instance, ObjectInstance), "Expected ObjectInstance type"
if polyline_object_instance.get_annotation_frames():
label_row.add_object_instance(polyline_object_instance)
label_rows_to_save.append(label_row)
# Step 3: Save all label rows using a bundle
with project.create_bundle(bundle_size=BUNDLE_SIZE) as bundle:
for label_row in label_rows_to_save:
assert label_row is not None, "Trying to save a None label row"
label_row.save(bundle=bundle)
print(f"Saved label row for {label_row.data_title}")
print("Labels with radio buttons, checklist attributes, and text labels added for all data units.")
Keypoints 3D
Basic This example includes the following:- Keypoints 3D labeling
- Keypoint 3D labeling
- Radio button options
- Checklist options
- Text input
# Import dependencies
from encord import EncordUserClient, Project
from encord.objects import Object
from encord.objects.coordinates import PointCoordinate3D
# User input
SSH_PATH = "/Users/chris-encord/ssh-private-key.txt" # Replace with the file path to your SSH private key
PROJECT_ID = "00000000-0000-0000-0000-000000000000" # Replace with the unique ID for the Project
BUNDLE_SIZE = 100
# Create user client using ssh key
user_client: EncordUserClient = EncordUserClient.create_with_ssh_private_key(
ssh_private_key_path=SSH_PATH,
# For US platform users use "https://api.us.encord.com"
domain="https://api.encord.com",
)
# Get project for which labels are to be added
project: Project = user_client.get_project(PROJECT_ID)
# Create radio button attribute for Person type
ontology_structure = project.ontology_structure
# Find a keypoint annotation object in the project ontology
keypoint_ontology_object: Object = ontology_structure.get_child_by_title(title="Point of Interest", type_=Object)
assert keypoint_ontology_object is not None, "Keypoint object 'Point of Interest' not found in ontology."
# Dictionary of labels per data unit and per frame with Point of Interest
pcd_labels = {
"scene-1094": {
1: {
"label_ref": "poi_001",
"coordinates": PointCoordinate3D(x=0.01, y=0.02, z=0.03)
}
},
"scene-0916": {
1: [
{
"label_ref": "poi_002",
"coordinates": PointCoordinate3D(x=0.03, y=0.03, z=0.03)
},
{
"label_ref": "poi_003",
"coordinates": PointCoordinate3D(x=0.5, y=0.4, z=0.3)
},
{
"label_ref": "poi_004",
"coordinates": PointCoordinate3D(x=0.9, y=0.3, z=0.3)
},
],
},
"scene-0796": {
0: {
"label_ref": "poi_005",
"coordinates": PointCoordinate3D(x=0.05, y=0.02, z=0.03)
},
2: [
{
"label_ref": "poi_006",
"coordinates": PointCoordinate3D(x=0.3, y=0.3, z=0.3)
},
{
"label_ref": "poi_007",
"coordinates": PointCoordinate3D(x=0.4, y=0.5, z=0.3)
},
{
"label_ref": "poi_008",
"coordinates": PointCoordinate3D(x=0.11, y=0.2, z=0.3)
},
],
},
"scene-1100": {
0: {
"label_ref": "poi_009",
"coordinates": PointCoordinate3D(x=0.1, y=0.2, z=0.3)
},
3: [
{
"label_ref": "poi_010",
"coordinates": PointCoordinate3D(x=0.3, y=0.3, z=0.3)
},
{
"label_ref": "poi_011",
"coordinates": PointCoordinate3D(x=0.8, y=0.5, z=0.3)
},
{
"label_ref": "poi_012",
"coordinates": PointCoordinate3D(x=0.11, y=0.2, z=0.3)
},
],
},
"scene-0655": {
1: [
{
"label_ref": "poi_013",
"coordinates": PointCoordinate3D(x=0.2, y=0.1, z=0.3)
},
{
"label_ref": "poi_014",
"coordinates": PointCoordinate3D(x=0.6, y=0.6, z=0.3)
},
{
"label_ref": "poi_015",
"coordinates": PointCoordinate3D(x=0.10, y=0.1, z=0.3)
},
],
2: [
{
"label_ref": "poi_016",
"coordinates": PointCoordinate3D(x=0.4, y=0.1, z=0.3)
},
{
"label_ref": "poi_014",
"coordinates": PointCoordinate3D(x=0.8, y=0.5, z=0.3)
},
{
"label_ref": "poi_017",
"coordinates": PointCoordinate3D(x=0.11, y=0.2, z=0.3)
},
],
3: [
{
"label_ref": "poi_016",
"coordinates": PointCoordinate3D(x=0.5, y=0.2, z=0.3)
},
{
"label_ref": "poi_014",
"coordinates": PointCoordinate3D(x=0.7, y=0.4, z=0.3)
},
{
"label_ref": "poi_017",
"coordinates": PointCoordinate3D(x=0.9, y=0.3, z=0.3)
},
],
},
}
# Initialize label rows
label_row_map = {}
with project.create_bundle(bundle_size=BUNDLE_SIZE) as bundle:
for data_title in pcd_labels.keys():
rows = project.list_label_rows_v2(data_title_eq=data_title)
if not rows:
print(f"Skipping: No label row found for {data_title}")
continue
lr = rows[0]
lr.initialise_labels(bundle=bundle)
label_row_map[data_title] = lr
# Create instances
label_rows_to_save = []
for data_title, frames in pcd_labels.items():
lr = label_row_map.get(data_title)
if not lr:
continue
instances_by_ref = {}
for frame_no, items in frames.items():
# normalize to list
items = items if isinstance(items, list) else [items]
for item in items:
ref = item["label_ref"]
coords = item["coordinates"]
if ref not in instances_by_ref:
instances_by_ref[ref] = keypoint_ontology_object.create_instance()
instances_by_ref[ref].set_for_frames(coordinates=coords, frames=frame_no)
# Add only instances that have at least one frame
for inst in instances_by_ref.values():
if inst.get_annotation_frames():
lr.add_object_instance(inst)
label_rows_to_save.append(lr)
# Save all label rows
with project.create_bundle(bundle_size=BUNDLE_SIZE) as bundle:
for lr in label_rows_to_save:
lr.save(bundle=bundle)
print(f"Saved label row for {lr.data_title}")
# Import dependencies
from pathlib import Path
from encord import EncordUserClient, Project
from encord.objects import ChecklistAttribute, Object, ObjectInstance, Option, RadioAttribute, TextAttribute
from encord.objects.coordinates import PointCoordinate3D
# User input
SSH_PATH = "/Users/chris-encord/ssh-private-key.txt" # Replace with the file path to your SSH private key
PROJECT_ID = "00000000-0000-0000-0000-000000000000" # Replace with the unique ID for the Project
BUNDLE_SIZE = 100
# Create user client using ssh key
user_client: EncordUserClient = EncordUserClient.create_with_ssh_private_key(
ssh_private_key_path=SSH_PATH,
# For US platform users use "https://api.us.encord.com"
domain="https://api.encord.com",
)
# Get project for which labels are to be added
project: Project = user_client.get_project(PROJECT_ID)
assert project is not None, "Project not found — check PROJECT_ID"
# Get ontology structure
ontology_structure = project.ontology_structure
assert ontology_structure is not None, "Ontology structure is missing in the project"
# Get keypoint object for Point of Interest
keypoint_ontology_object: Object = ontology_structure.get_child_by_title(title="Point of Interest", type_=Object)
assert keypoint_ontology_object is not None, "Keypoint object 'Point of Interest' not found in ontology"
# Get radio attribute for Point of Interest type
poi_type_radio_attribute = ontology_structure.get_child_by_title(type_=RadioAttribute, title="Type?")
assert poi_type_radio_attribute is not None, "Radio attribute 'Type?' not found"
# Get radio options
sign_option = poi_type_radio_attribute.get_child_by_title(type_=Option, title="Sign")
assert sign_option is not None, "Option 'Sign' not found under radio attribute 'Type?'"
traffic_light_option = poi_type_radio_attribute.get_child_by_title(type_=Option, title="Traffic light")
assert traffic_light_option is not None, "Option 'Traffic light' not found under radio attribute 'Type?'"
other_poi_option = poi_type_radio_attribute.get_child_by_title(type_=Option, title="Other Point of Interest type")
assert other_poi_option is not None, "Option 'Other Point of Interest type' not found under radio attribute 'Type?'"
# Get checklist attributes and options for Sign
sign_checklist_attribute = ontology_structure.get_child_by_title(type_=ChecklistAttribute, title="Sign Qualities?")
assert sign_checklist_attribute is not None, "Checklist attribute 'Sign Qualities?' not found"
sign_well_positioned_option = sign_checklist_attribute.get_child_by_title(type_=Option, title="Well positioned")
assert sign_well_positioned_option is not None, "Option 'Well positioned' not found under 'Sign Qualities?'"
sign_good_visibility_option = sign_checklist_attribute.get_child_by_title(type_=Option, title="Good visibility")
assert sign_good_visibility_option is not None, "Option 'Good visibility' not found under 'Sign Qualities?'"
sign_good_condition_option = sign_checklist_attribute.get_child_by_title(
type_=Option, title="Good condition")
assert sign_good_condition_option is not None, "Option 'Good condition' not found under 'Sign Qualities?'"
# Get checklist attributes and options for Traffic light
traffic_light_checklist_attribute = ontology_structure.get_child_by_title(
type_=ChecklistAttribute, title="Traffic light Qualities?"
)
assert traffic_light_checklist_attribute is not None, "Checklist attribute 'Traffic light Qualities?' not found"
traffic_light_well_positioned_option = traffic_light_checklist_attribute.get_child_by_title(
type_=Option, title="Well positioned"
)
assert traffic_light_well_positioned_option is not None, "Option 'Well positioned' not found under 'Traffic light Qualities?'"
traffic_light_good_visibility_option = traffic_light_checklist_attribute.get_child_by_title(
type_=Option, title="Good visibility"
)
assert traffic_light_good_visibility_option is not None, "Option 'Good visibility' not found under 'Traffic light Qualities?'"
traffic_light_good_condition_option = traffic_light_checklist_attribute.get_child_by_title(type_=Option, title="Good condition")
assert traffic_light_good_condition_option is not None, "Option 'Good condition' not found under 'Traffic light Qualities?'"
# Get text attribute for specifying other Point of Interest types
other_poi_option_text_attribute = ontology_structure.get_child_by_title(
type_=TextAttribute, title="Specify Point of Interest type"
)
assert other_poi_option_text_attribute is not None, "Text attribute 'Specify Point of Interest type' not found"
# Dictionary of labels per data unit and per frame with Point of Interest type specified, including quality options
pcd_labels = {
"scene-1094": {
1: {
"label_ref": "poi_001",
"coordinates": PointCoordinate3D(x=0.01, y=0.02, z=0.03),
"poi_type": "Sign",
"sign_quality_options": "Well positioned, Good visibility, Good condition",
}
},
"scene-0916": {
1: [
{
"label_ref": "poi_002",
"coordinates": PointCoordinate3D(x=0.03, y=0.03, z=0.03),
"poi_type": "Traffic light",
"traffic_light_quality_options": "Well positioned, Good visibility, Good condition",
},
{
"label_ref": "poi_003",
"coordinates": PointCoordinate3D(x=0.5, y=0.4, z=0.3),
"poi_type": "Traffic light",
"traffic_light_quality_options": "Good visibility",
},
{
"label_ref": "poi_004",
"coordinates": PointCoordinate3D(x=0.9, y=0.3, z=0.3),
"poi_type": "Other Point of Interest type",
"Specify Point of Interest type": "Curb",
},
],
},
"scene-0796": {
0: {
"label_ref": "poi_005",
"coordinates": PointCoordinate3D(x=0.05, y=0.02, z=0.03),
"poi_type": "Sign",
"sign_quality_options": "Well positioned, Good visibility, Good condition",
},
2: [
{
"label_ref": "poi_006",
"coordinates": PointCoordinate3D(x=0.3, y=0.3, z=0.3),
"poi_type": "Sign",
"sign_quality_options": "Good condition",
},
{
"label_ref": "poi_007",
"coordinates": PointCoordinate3D(x=0.4, y=0.5, z=0.3),
"poi_type": "Sign",
"sign_quality_options": "Good visibility",
},
{
"label_ref": "poi_008",
"coordinates": PointCoordinate3D(x=0.11, y=0.2, z=0.3),
"poi_type": "Other Point of Interest type",
"Specify Point of Interest type": "Post box",
},
],
},
"scene-1100": {
0: {
"label_ref": "poi_009",
"coordinates": PointCoordinate3D(x=0.1, y=0.2, z=0.3),
"poi_type": "Traffic light",
"traffic_light_quality_options": "Well positioned, Good visibility, Good condition",
},
3: [
{
"label_ref": "poi_010",
"coordinates": PointCoordinate3D(x=0.3, y=0.3, z=0.3),
"poi_type": "Traffic light",
"traffic_light_quality_options": "Well positioned, Good visibility, Good condition",
},
{
"label_ref": "poi_011",
"coordinates": PointCoordinate3D(x=0.8, y=0.5, z=0.3),
"poi_type": "Traffic light",
"traffic_light_quality_options": "Good condition",
},
{
"label_ref": "poi_012",
"coordinates": PointCoordinate3D(x=0.11, y=0.2, z=0.3),
"poi_type": "Other Point of Interest type",
"Specify Point of Interest type": "Post box",
},
],
},
"scene-0655": {
1: [
{
"label_ref": "poi_013",
"coordinates": PointCoordinate3D(x=0.2, y=0.1, z=0.3),
"poi_type": "Sign",
"sign_quality_options": "Good condition",
},
{
"label_ref": "poi_014",
"coordinates": PointCoordinate3D(x=0.6, y=0.6, z=0.3),
"poi_type": "Sign",
"sign_quality_options": "Well positioned, Good visibility, Good condition",
},
{
"label_ref": "poi_015",
"coordinates": PointCoordinate3D(x=0.10, y=0.1, z=0.3),
"poi_type": "Other Point of Interest type",
"Specify Point of Interest type": "Curb",
},
],
2: [
{
"label_ref": "poi_016",
"coordinates": PointCoordinate3D(x=0.4, y=0.1, z=0.3),
"poi_type": "Sign",
"sign_quality_options": "Good condition",
},
{
"label_ref": "poi_014",
"coordinates": PointCoordinate3D(x=0.8, y=0.5, z=0.3),
"poi_type": "Sign",
"sign_quality_options": "Well positioned, Good visibility, Good condition",
},
{
"label_ref": "poi_017",
"coordinates": PointCoordinate3D(x=0.11, y=0.2, z=0.3),
"poi_type": "Other Point of Interest type",
"Specify Point of Interest type": "Post box",
},
],
3: [
{
"label_ref": "poi_016",
"coordinates": PointCoordinate3D(x=0.5, y=0.2, z=0.3),
"poi_type": "Sign",
"sign_quality_options": "Good condition",
},
{
"label_ref": "poi_014",
"coordinates": PointCoordinate3D(x=0.7, y=0.4, z=0.3),
"poi_type": "Sign",
"sign_quality_options": "Well positioned, Good visibility, Good condition",
},
{
"label_ref": "poi_017",
"coordinates": PointCoordinate3D(x=0.9, y=0.3, z=0.3),
"poi_type": "Other Point of Interest type",
"Specify Point of Interest type": "Post box",
},
],
},
}
# Cache label rows after initialization
label_row_map = {}
# Step 1: Initialize all label rows using a bundle
with project.create_bundle(bundle_size=BUNDLE_SIZE) as bundle:
for data_unit in pcd_labels.keys():
label_rows = project.list_label_rows_v2(data_title_eq=data_unit)
assert isinstance(label_rows, list), f"Expected list of label rows for '{data_unit}', got {type(label_rows)}"
if not label_rows:
print(f"Skipping: No label row found for {data_unit}")
continue
label_row = label_rows[0]
label_row.initialise_labels(bundle=bundle)
assert label_row.ontology_structure is not None, f"Ontology not initialized for label row: {data_unit}"
label_row_map[data_unit] = label_row # Cache the initialized label row
# Step 2: Process all frame coordinates and prepare label rows for saving
label_rows_to_save = []
for data_unit, frame_coordinates in pcd_labels.items():
label_row = label_row_map.get(data_unit)
assert label_row is not None, f"Label row not initialized for {data_unit}"
object_instances_by_label_ref = {}
for frame_number, items in frame_coordinates.items():
assert isinstance(frame_number, int), f"Frame number must be int, got {type(frame_number)}"
if not isinstance(items, list):
items = [items]
for item in items:
label_ref = item["label_ref"]
coord = item["coordinates"]
poi_type = item["poi_type"]
assert poi_type in {
"Sign",
"Traffic light",
"Other Point of Interest type",
}, f"Unexpected type '{poi_type}' in {data_unit}"
if label_ref not in object_instances_by_label_ref:
keypoint_object_instance: ObjectInstance = keypoint_ontology_object.create_instance()
assert keypoint_object_instance is not None, "Failed to create ObjectInstance"
checklist_attribute = None
quality_options = []
# Assign radio and checklist attributes based on the type
if poi_type == "Sign":
assert sign_option is not None, "Missing 'sign_type'"
keypoint_object_instance.set_answer(attribute=poi_type_radio_attribute, answer=sign_option)
checklist_attribute = sign_checklist_attribute
quality_options = [q.strip() for q in item.get("sign_quality_options", "").split(",") if q.strip()]
elif poi_type == "Traffic light":
assert traffic_light_option is not None, "Missing 'lane_divider_option'"
keypoint_object_instance.set_answer(attribute=poi_type_radio_attribute, answer=traffic_light_option)
checklist_attribute = traffic_light_checklist_attribute
quality_options = [
q.strip() for q in item.get("traffic_light_quality_options", "").split(",") if q.strip()
]
elif poi_type == "Other Point of Interest type":
assert other_poi_option is not None, "Missing 'other_ooi_option'"
keypoint_object_instance.set_answer(attribute=poi_type_radio_attribute, answer=other_poi_option)
text_answer = item.get("Type", "")
assert isinstance(text_answer, str), "'Type' must be a string"
keypoint_object_instance.set_answer(attribute=other_poi_option_text_attribute, answer=text_answer)
quality_options = []
# Process checklist options
checklist_answers = []
for quality in quality_options:
option = None
if quality == "Well positioned":
option = (
sign_well_positioned_option
if poi_type == "Sign"
else traffic_light_well_positioned_option
if poi_type == "Traffic light"
else None
)
elif quality == "Good visibility":
option = (
sign_good_visibility_option
if poi_type == "Sign"
else traffic_light_good_visibility_option
if poi_type == "Traffic light"
else None
)
elif quality == "Good condition":
option = (
sign_good_condition_option
if poi_type == "Sign"
else traffic_light_good_condition_option
if poi_type == "Traffic light"
else None
)
if option:
checklist_answers.append(option)
else:
assert poi_type == "Other Point of Interest type", f"Invalid quality '{quality}' for type '{poi_type}'"
if checklist_attribute and checklist_answers:
keypoint_object_instance.set_answer(
attribute=checklist_attribute, answer=checklist_answers, overwrite=True
)
object_instances_by_label_ref[label_ref] = keypoint_object_instance
else:
keypoint_object_instance = object_instances_by_label_ref[label_ref]
# Assign coordinates for this frame
keypoint_object_instance.set_for_frames(coordinates=coord, frames=frame_number)
# Add object instances to the label row if they have frames assigned
for keypoint_object_instance in object_instances_by_label_ref.values():
assert isinstance(keypoint_object_instance, ObjectInstance), "Expected ObjectInstance type"
if keypoint_object_instance.get_annotation_frames():
label_row.add_object_instance(keypoint_object_instance)
label_rows_to_save.append(label_row)
# Step 3: Save all label rows using a bundle
with project.create_bundle(bundle_size=BUNDLE_SIZE) as bundle:
for label_row in label_rows_to_save:
assert label_row is not None, "Trying to save a None label row"
label_row.save(bundle=bundle)
print(f"Saved label row for {label_row.data_title}")
print("Labels with radio buttons, checklist attributes, and text labels added for all data units.")
Segmentations
The following script demonstrates how to add segmentation labels to point cloud data using the Encord Python SDK. It assumes that you have a project with a point cloud dataset and an ontology that includes a segmentation object titled “Sidewalk”. The script creates segmentation instances for specified ranges of point indices in the point cloud files. If the scene was uploaded as shown in the example here, with one label space per frame, a space’s index in this list corresponds to its frame number.# Import dependencies
from encord import EncordUserClient, Project
from encord.objects import Object
from encord.objects.frames import Range
from encord.objects.spaces.range_space.point_cloud_space import PointCloudFileSpace
# User input
SSH_PATH = "/Users/chris-encord/ssh-private-key.txt" # Replace with the file path to your SSH private key
PROJECT_ID = "00000000-0000-0000-0000-000000000000" # Replace with the unique ID for the Project
BUNDLE_SIZE = 100
# Create user client using ssh key
user_client: EncordUserClient = EncordUserClient.create_with_ssh_private_key(
ssh_private_key_path=SSH_PATH,
# For US platform users use "https://api.us.encord.com"
domain="https://api.encord.com",
)
# Get project for which labels are to be added
project: Project = user_client.get_project(PROJECT_ID)
# Find a point-cloud segmentation object in the project ontology
ontology_structure = project.ontology_structure
segmentation_ontology_object: Object = ontology_structure.get_child_by_title(title="Sidewalk", type_=Object)
assert segmentation_ontology_object is not None, "Segmentation object 'Sidewalk' not found in ontology."
# Point-index ranges per data unit. Each entry becomes one segmentation instance owning
# the listed (start, end) inclusive point-index ranges in the uploaded point cloud.
# Ranges must be computed against the exact file registered on the platform - re-uploading,
# reordering, or decimating the cloud afterwards shifts every index.
pcd_segmentation_labels = {
"scene-1094": [
{
"label_ref": "sidewalk_001",
"ranges": [(0, 15234), (52000, 52980)],
},
{
"label_ref": "sidewalk_002",
"ranges": [(15235, 28110)],
},
],
"scene-0916": [
{
"label_ref": "sidewalk_003",
"ranges": [(0, 40233), (40500, 61022), (70000, 70999)],
},
],
}
# Initialize label rows
label_row_map = {}
with project.create_bundle(bundle_size=BUNDLE_SIZE) as bundle:
for data_title in pcd_segmentation_labels.keys():
rows = project.list_label_rows_v2(data_title_eq=data_title)
if not rows:
print(f"Skipping: No label row found for {data_title}")
continue
lr = rows[0]
lr.initialise_labels(bundle=bundle)
label_row_map[data_title] = lr
# Create instances
label_rows_to_save = []
for data_title, crowns in pcd_segmentation_labels.items():
lr = label_row_map.get(data_title)
if not lr:
continue
# Point-cloud segmentation instances live on the data unit's point-cloud space, not
# directly on the label row. Rather than constructing a space identifier, list every
# space on the row and pick out the point-cloud one, taking the first match.
# If the scene was uploaded as advised, with one label space per frame, a space's
# index in this list corresponds to its frame number - so index 0 is frame 0, which is what this example labels.
spaces = lr.get_spaces()
point_cloud_spaces = [s for s in spaces if isinstance(s, PointCloudFileSpace)]
assert len(point_cloud_spaces) > 0, f"No point cloud spaces found for {data_title}"
space = point_cloud_spaces[68]
for crown in crowns:
instance = segmentation_ontology_object.create_instance()
ranges = [Range(start=s, end=e) for s, e in crown["ranges"]]
space.put_object_instance(
object_instance=instance,
ranges=ranges,
confidence=1.0,
)
label_rows_to_save.append(lr)
# Save all label rows
with project.create_bundle(bundle_size=BUNDLE_SIZE) as bundle:
for lr in label_rows_to_save:
lr.save(bundle=bundle)
print(f"Saved label row for {lr.data_title}")

