Ontology SDK Basics
An Ontology, or labeling protocol, defines the concepts, relationships, and representations in your data. Ontologies are essential for creating object and frame labels by defining what is being labeled.Before you can apply Classifications to a Collection in Encord Active, the Classifications have to exist in an Ontology in Encord.
RadioAttribute). Checklists and text fields stop the nesting of attributes.
- Classification
- Radio button
- Radio button
- Radio button
- Radio button
- Radio button
- Radio button
- Radio button or Checklist or Text box
- Classification
- Radio button
- Radio button
- Checklist
- Classification
- Radio button
- Radio button
- Radio button
- Text box
Annotation Ontologies
Ontology with Annotation: Creates an Ontology (title=“My test Ontology”) with a single Bounding Box Object (“Cute cat”) in the structure. Workflow Project with Ontology and Annotations: Creates a Workflow Project (“Cats annotation project”) with a dataset (“MY_CAT_DATASET”) and an Ontology.
import logging
import time
from tqdm import tqdm
from encord import EncordUserClient
from encord.objects import Shape, Object, Option, OntologyStructure
from encord.objects.coordinates import BoundingBoxCoordinates
from encord.objects.attributes import RadioAttribute, ChecklistAttribute
user_client = EncordUserClient.create_with_ssh_private_key(
ssh_private_key_path='/Users/encord/.ssh/id_ed25519'
)
ontology_structure = OntologyStructure()
ontology_structure.add_object("Cute Cat", shape=Shape.BOUNDING_BOX)
cat_ontology = user_client.create_ontology(title="My test Ontology", structure=ontology_structure)
import logging
import time
from tqdm import tqdm
from encord import EncordUserClient
from encord.objects import Shape, Object, Option, OntologyStructure
from encord.objects.coordinates import BoundingBoxCoordinates
from encord.objects.attributes import RadioAttribute, ChecklistAttribute
requests_settings = RequestsSettings(
max_retries=10,
read_timeout=1800,
write_timeout=1800,
)
user_client = EncordUserClient.create_with_ssh_private_key(
ssh_private_key_path='/Users/encord/.ssh/id_ed25519'
)
# Now let's create a project for a cat dataset and provide annotations
MY_CAT_DATASET = '614bbb51-333a-48d0-9dc5-1e92873a5a44'
ONTOLOGY_HASH = 'd274a855-06cb-4f50-afac-eef176841b4c'
WORKFLOW_HASH = 'd330ff92-c397-4914-b056-ed6453f1af3c'
project_hash = user_client.create_project("Cats annotation project", ontology_hash=ONTOLOGY_HASH, dataset_hashes=[MY_CAT_DATASET], workflow_template_hash=WORKFLOW_HASH)
project = user_client.get_project(project_hash=project_hash)
label_row = project.list_label_rows_v2()[0]
label_row.initialise_labels()
# Use the cat_object from the other example, and this is how you find it
cat_object = project.ontology_structure.get_child_by_title("Cute Cat", type_=Object)
# Create instance of the object - a particular cat we want to label
cat_object_instance = cat_object.create_instance()
# Creating bounding box coordinates for a cat on a specific frame of specific media.
bounding_box_coordinates = BoundingBoxCoordinates(height=0.8, width=0.8, top_left_x=0.1, top_left_y=0.1)
# Setting these coordinates on a particular frame.
# Images have only one frame, so it doesn't need to be specified here
cat_object_instance.set_for_frames(bounding_box_coordinates)
# Attaching object instance to a particular label row
label_row.add_object_instance(cat_object_instance)
# Uploading created frame
label_row.save()
Skeleton (Primitive) Ontologies
Skeletons let you label complex structures, such as a human pose, as a set of connected points (a “primitive” object). Useadd_skeleton_object to add a skeleton object and its template to an Ontology in a single call. This method mints the object first and then reuses its feature_node_hash on the template, which is what the Label Editor needs to render the skeleton correctly.
Creating a skeleton object with
add_object and add_skeleton_template separately requires you to manually keep their feature_node_hash values in sync. Prefer add_skeleton_object unless you specifically need to reproduce an existing structure exactly (for example, matching uid or feature_node_hash values from an export).from encord import EncordUserClient
from encord.objects import OntologyStructure
from encord.objects.skeleton_template import SkeletonTemplate
from encord.orm.skeleton_template import SkeletonTemplateCoordinate
user_client = EncordUserClient.create_with_ssh_private_key(
ssh_private_key_path='<file-path-to-ssh-private-key>'
)
ontology_structure = OntologyStructure()
# Define a 3-point skeleton template ("Triangle") and the edges connecting its points
triangle_template = SkeletonTemplate(
name="Triangle",
width=100,
height=100,
skeleton={
"0": SkeletonTemplateCoordinate(x=0.30, y=0.30, name="point_0"),
"1": SkeletonTemplateCoordinate(x=0.45, y=0.30, name="point_1"),
"2": SkeletonTemplateCoordinate(x=0.35, y=0.45, name="point_2"),
},
skeleton_edges={
"0": {"1": {"color": "#00000"}},
"1": {"2": {"color": "#00000"}},
},
)
# Adds the skeleton object and its template as a linked pair, sharing one feature_node_hash
skeleton_object, skeleton_template = ontology_structure.add_skeleton_object(
name="Strawberries", skeleton_template=triangle_template
)
triangle_ontology = user_client.create_ontology(title="My skeleton Ontology", structure=ontology_structure)
# Prints the ontology hash
print(triangle_ontology.ontology_hash)
Classification Ontologies
- Standard Classifications are applied to individual frames.
- Global Classifications are applied to a whole file.
- Standard Classifications
- Global Classifications
from encord import EncordUserClient
from encord.objects import OntologyStructure
from encord.objects.attributes import RadioAttribute
user_client = EncordUserClient.create_with_ssh_private_key(
ssh_private_key_path='/Users/encord/.ssh/id_ed25519'
)
# Create a new ontology with Classifications
ontology_structure = OntologyStructure()
# Adding a Classification of type radio button
classification = ontology_structure.add_classification()
cat_colour = classification.add_attribute(RadioAttribute, "colour", required=True)
cat_colour.add_option("white")
cat_colour.add_option("black")
# Create a new ontology with Classifications
ontology = user_client.create_ontology("Radio Button Ontology", structure=ontology_structure)
print(f"created ontology {ontology.ontology_hash}")
from encord import EncordUserClient
from encord.objects import OntologyStructure
from encord.objects.attributes import ChecklistAttribute
user_client = EncordUserClient.create_with_ssh_private_key(
ssh_private_key_path='/Users/encord/.ssh/id_ed25519'
)
# Create a new ontology with Classifications
ontology_structure = OntologyStructure()
# Adding classification of a type checklist
new_classification = ontology_structure.add_classification()
new_checklist_attribute = new_classification.add_attribute(ChecklistAttribute, "Location")
# Adding options for the classification
new_checklist_attribute.add_option("Here")
new_checklist_attribute.add_option("There")
new_checklist_attribute.add_option("Everywhere")
# Create a new ontology with Classifications
ontology = user_client.create_ontology("Checklist Ontology", structure=ontology_structure)
print(f"created ontology {ontology.ontology_hash}")
from encord import EncordUserClient
from encord.objects import OntologyStructure
from encord.objects.attributes import NumericAttribute
user_client = EncordUserClient.create_with_ssh_private_key(
ssh_private_key_path='/Users/encord/.ssh/id_ed25519'
)
# Create a new Ontology with Classifications
ontology_structure = OntologyStructure()
# Adding a Number Classification
new_classification = ontology_structure.add_classification()
score_attribute = new_classification.add_attribute(NumericAttribute, "Score", required=True)
# Create a new ontology with Classifications
ontology = user_client.create_ontology(title="Ontology with numeric attributes", structure=ontology_structure)
print(f"created ontology {ontology.ontology_hash}")
from encord import EncordUserClient
from encord.objects import Shape, Object, Option, OntologyStructure
from encord.objects.coordinates import BoundingBoxCoordinates
from encord.objects.attributes import ChecklistAttribute
user_client = EncordUserClient.create_with_ssh_private_key(
ssh_private_key_path='/Users/encord/.ssh/id_ed25519'
)
# Create a new ontology with Classifications
ontology_structure = OntologyStructure()
# Adding a Classification of type text field
new_classification = ontology_structure.add_classification()
new_text_attribute = new_classification.add_attribute(TextAttribute, "Describe location")
# Create a new ontology with Classifications
ontology = user_client.create_ontology("Text Field Ontology", structure=ontology_structure)
print(f"created ontology {ontology.ontology_hash}")
from encord import EncordUserClient
from encord.objects import Option, OntologyStructure, attributes
from encord.objects.attributes import ChecklistAttribute, RadioAttribute, OntologyNestedElement
requests_settings = RequestsSettings(
max_retries=10,
read_timeout=1800,
write_timeout=1800,
)
user_client = EncordUserClient.create_with_ssh_private_key(
ssh_private_key_path='/Users/encord/.ssh/id_ed25519'
)
# Create a new ontology with Classifications
ontology_structure = OntologyStructure()
new_classification = ontology_structure.add_classification()
new_radio_attribute = new_classification.add_attribute(RadioAttribute, "Green Eggs and Ham?")
yes_option = new_radio_attribute.add_option("Yes")
no_option = new_radio_attribute.add_option("No")
# Provides 1st level nested attribute. RadioAttribute allows further nesting (up to 7 levels deep)
nested_attribute_yes = yes_option.add_nested_attribute(RadioAttribute, "Where?")
# <---- and here
here_yes_option = nested_attribute_yes.add_option("Here")
there_yes_option = nested_attribute_yes.add_option("There")
everywhere_yes_option = nested_attribute_yes.add_option("Everywhere")
nested_attribute_no = no_option.add_nested_attribute(RadioAttribute, "Where?")
# <---- and here
here_no_option = nested_attribute_no.add_option("Here")
there_no_option = nested_attribute_no.add_option("There")
everywhere_no_option = nested_attribute_no.add_option("Everywhere")
# Provides 2nd level nested attribute. ChecklistAttribute and TextAttribute prevent further nesting.
nested_attribute_yes_here = here_yes_option.add_nested_attribute(ChecklistAttribute, "Specific location?")
box_option = nested_attribute_yes_here.add_option("In a box")
house_option = nested_attribute_yes_here.add_option("In a house")
car_option = nested_attribute_yes_here.add_option("In a car")
nested_attribute_yes_there = there_yes_option.add_nested_attribute(ChecklistAttribute, "Specific location?")
box_option = nested_attribute_yes_there.add_option("In a box")
house_option = nested_attribute_yes_there.add_option("In a house")
car_option = nested_attribute_yes_there.add_option("In a car")
nested_attribute_yes_everywhere = everywhere_yes_option.add_nested_attribute(ChecklistAttribute, "Specific location?")
box_option = nested_attribute_yes_everywhere.add_option("In a box")
house_option = nested_attribute_yes_everywhere.add_option("In a house")
car_option = nested_attribute_yes_everywhere.add_option("In a car")
nested_attribute_no_here = here_no_option.add_nested_attribute(ChecklistAttribute, "Specific location?")
box_option = nested_attribute_no_here.add_option("In a box")
house_option = nested_attribute_no_here.add_option("In a house")
car_option = nested_attribute_no_here.add_option("In a car")
nested_attribute_no_there = there_no_option.add_nested_attribute(ChecklistAttribute, "Specific location?")
box_option = nested_attribute_no_there.add_option("In a box")
house_option = nested_attribute_no_there.add_option("In a house")
car_option = nested_attribute_no_there.add_option("In a car")
nested_attribute_no_everywhere = everywhere_no_option.add_nested_attribute(ChecklistAttribute, "Specific location?")
box_option = nested_attribute_no_everywhere.add_option("In a box")
house_option = nested_attribute_no_everywhere.add_option("In a house")
car_option = nested_attribute_no_everywhere.add_option("In a car")
# Create a new Ontology with Classifications
ontology = user_client.create_ontology("Nested Attributes", structure=ontology_structure)
print(f"created ontology {ontology.ontology_hash}")
from encord import EncordUserClient
from encord.objects import OntologyStructure
from encord.objects.attributes import RadioAttribute
from encord.objects.classification import OntologyClassificationLevel
user_client = EncordUserClient.create_with_ssh_private_key(
ssh_private_key_path='/Users/encord/.ssh/id_ed25519'
)
# Create a new ontology with Classifications
ontology_structure = OntologyStructure()
# Adding a global Classification of type radio button
classification = ontology_structure.add_classification(level=OntologyClassificationLevel.GLOBAL)
cat_colour = classification.add_attribute(RadioAttribute, "colour", required=True)
cat_colour.add_option("white")
cat_colour.add_option("black")
# Create a new ontology with Classifications
ontology = user_client.create_ontology("Radio Button Ontology", structure=ontology_structure)
print(f"created ontology {ontology.ontology_hash}")
from encord import EncordUserClient
from encord.objects import OntologyStructure
from encord.objects.attributes import ChecklistAttribute
from encord.objects.classification import OntologyClassificationLevel
user_client = EncordUserClient.create_with_ssh_private_key(
ssh_private_key_path='/Users/encord/.ssh/id_ed25519'
)
# Create a new ontology with Classifications
ontology_structure = OntologyStructure()
# Adding a global checklist classification
new_classification = ontology_structure.add_classification(level=OntologyClassificationLevel.GLOBAL)
new_checklist_attribute = new_classification.add_attribute(ChecklistAttribute, "Location")
# Adding options for the classification
new_checklist_attribute.add_option("Here")
new_checklist_attribute.add_option("There")
new_checklist_attribute.add_option("Everywhere")
# Create a new Ontology with global checklist Classification
ontology = user_client.create_ontology("Checklist Ontology", structure=ontology_structure)
print(f"created ontology {ontology.ontology_hash}")
from encord import EncordUserClient
from encord.objects import OntologyStructure
from encord.objects.attributes import NumericAttribute
from encord.objects.classification import OntologyClassificationLevel
user_client = EncordUserClient.create_with_ssh_private_key(
ssh_private_key_path='/Users/encord/.ssh/id_ed25519'
)
# Create a new Ontology with Classifications
ontology_structure = OntologyStructure()
# Adding a Number Classification
new_classification = ontology_structure.add_classification(level=OntologyClassificationLevel.GLOBAL)
score_attribute = new_classification.add_attribute(NumericAttribute, "Score", required=True)
# Create a new ontology with global number Classification
ontology = user_client.create_ontology(title="Ontology with numeric attributes", structure=ontology_structure)
print(f"created ontology {ontology.ontology_hash}")
from encord import EncordUserClient
from encord.objects import Shape, Object, Option, OntologyStructure
from encord.objects.coordinates import BoundingBoxCoordinates
from encord.objects.attributes import ChecklistAttribute
from encord.objects.classification import OntologyClassificationLevel
user_client = EncordUserClient.create_with_ssh_private_key(
ssh_private_key_path='/Users/encord/.ssh/id_ed25519'
)
# Create a new Ontology with Classifications
ontology_structure = OntologyStructure()
# Adding a Classification of type text field
new_classification = ontology_structure.add_classification(level=OntologyClassificationLevel.GLOBAL)
new_text_attribute = new_classification.add_attribute(TextAttribute, "Describe location")
# Create a new Ontology with global text Classification
ontology = user_client.create_ontology("Text Field Ontology", structure=ontology_structure)
print(f"created ontology {ontology.ontology_hash}")
from encord import EncordUserClient
from encord.objects import Option, OntologyStructure, attributes
from encord.objects.attributes import ChecklistAttribute, RadioAttribute, OntologyNestedElement
requests_settings = RequestsSettings(
max_retries=10,
read_timeout=1800,
write_timeout=1800,
)
user_client = EncordUserClient.create_with_ssh_private_key(
ssh_private_key_path='/Users/encord/.ssh/id_ed25519'
)
# Create a new Ontology with global Classification
ontology_structure = OntologyStructure()
new_classification = ontology_structure.add_classification(level=OntologyClassificationLevel.GLOBAL)
new_radio_attribute = new_classification.add_attribute(RadioAttribute, "Green Eggs and Ham?")
yes_option = new_radio_attribute.add_option("Yes")
no_option = new_radio_attribute.add_option("No")
# Provides 1st level nested attribute. RadioAttribute allows further nesting (up to 7 levels deep)
nested_attribute_yes = yes_option.add_nested_attribute(RadioAttribute, "Where?")
# <---- and here
here_yes_option = nested_attribute_yes.add_option("Here")
there_yes_option = nested_attribute_yes.add_option("There")
everywhere_yes_option = nested_attribute_yes.add_option("Everywhere")
nested_attribute_no = no_option.add_nested_attribute(RadioAttribute, "Where?")
# <---- and here
here_no_option = nested_attribute_no.add_option("Here")
there_no_option = nested_attribute_no.add_option("There")
everywhere_no_option = nested_attribute_no.add_option("Everywhere")
# Provides 2nd level nested attribute. ChecklistAttribute and TextAttribute prevent further nesting.
nested_attribute_yes_here = here_yes_option.add_nested_attribute(ChecklistAttribute, "Specific location?")
box_option = nested_attribute_yes_here.add_option("In a box")
house_option = nested_attribute_yes_here.add_option("In a house")
car_option = nested_attribute_yes_here.add_option("In a car")
nested_attribute_yes_there = there_yes_option.add_nested_attribute(ChecklistAttribute, "Specific location?")
box_option = nested_attribute_yes_there.add_option("In a box")
house_option = nested_attribute_yes_there.add_option("In a house")
car_option = nested_attribute_yes_there.add_option("In a car")
nested_attribute_yes_everywhere = everywhere_yes_option.add_nested_attribute(ChecklistAttribute, "Specific location?")
box_option = nested_attribute_yes_everywhere.add_option("In a box")
house_option = nested_attribute_yes_everywhere.add_option("In a house")
car_option = nested_attribute_yes_everywhere.add_option("In a car")
nested_attribute_no_here = here_no_option.add_nested_attribute(ChecklistAttribute, "Specific location?")
box_option = nested_attribute_no_here.add_option("In a box")
house_option = nested_attribute_no_here.add_option("In a house")
car_option = nested_attribute_no_here.add_option("In a car")
nested_attribute_no_there = there_no_option.add_nested_attribute(ChecklistAttribute, "Specific location?")
box_option = nested_attribute_no_there.add_option("In a box")
house_option = nested_attribute_no_there.add_option("In a house")
car_option = nested_attribute_no_there.add_option("In a car")
nested_attribute_no_everywhere = everywhere_no_option.add_nested_attribute(ChecklistAttribute, "Specific location?")
box_option = nested_attribute_no_everywhere.add_option("In a box")
house_option = nested_attribute_no_everywhere.add_option("In a house")
car_option = nested_attribute_no_everywhere.add_option("In a car")
# Create a new Ontology with Classifications
ontology = user_client.create_ontology("Nested Attributes", structure=ontology_structure)
print(f"created ontology {ontology.ontology_hash}")
Ontologies with Annotations and Classifications
This example explains how to create an Ontology with annotations and classifications. Ensure you replace:<file-path-to-ssh-private-key>with the pull path to your private key.My test Ontologywith the name of your Ontology.Cute Catwith the name of your Ontology class.- As well as any other options relevant to your Ontology.
from encord import EncordUserClient
from encord.objects import Shape, Object, Option, OntologyStructure
from encord.objects.coordinates import BoundingBoxCoordinates
from encord.objects.attributes import RadioAttribute, ChecklistAttribute
user_client = EncordUserClient.create_with_ssh_private_key(
ssh_private_key_path='<file-path-to-ssh-private-key>'
)
ontology_structure = OntologyStructure()
# Adding bounding box annotation
ontology_structure.add_object("Cute Cat", shape=Shape.BOUNDING_BOX)
# Adding a Classification of type radio button
classification = ontology_structure.add_classification()
cat_colour = classification.add_attribute(RadioAttribute, "colour", required=True)
cat_colour.add_option("white")
cat_colour.add_option("black")
# Adding a Classification of type check box
classification = ontology_structure.add_classification()
cat_features = classification.add_attribute(ChecklistAttribute, "features")
cat_features.add_option("soft")
cat_features.add_option("fluffy")
cat_features.add_option("friendly")
cat_ontology = user_client.create_ontology(title="My test Ontology", structure=ontology_structure)

