Create Ontologies

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.

👍

Tip

Before you can apply Classifications to a Collection in Encord Active, the Classifications have to exist in an Ontology in Encord.

Encord supports Classifications with nested attributes up to 7 levels deep using Radio buttons (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 ("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

from encord.http.constants import RequestsSettings

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',
    requests_settings=requests_settings
)


ontology_structure = OntologyStructure()
ontology_structure.add_object("Cute Cat", shape=Shape.BOUNDING_BOX)

cat_ontology = user_client.create_ontology("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

from encord.http.constants import RequestsSettings

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',
    requests_settings=requests_settings
)

# 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()

Classification Ontologies

Use the following example as a guide to creating your Ontology with Classifications using the SDK.

Radio button: Creates an ontology with 2 radio button lists.

Checklist: Creates an ontology with 3 options in a checklist.

Text field: Creates an ontology with a single text field.

Nested attributes: Creates an ontology with 2 levels of nesting.


from encord import EncordUserClient
from encord.objects import Shape, Object, Option, OntologyStructure
from encord.objects.attributes import RadioAttribute, ChecklistAttribute

from encord.http.constants import RequestsSettings

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',
    requests_settings=requests_settings
)

# 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")

# 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")

# Create a new ontology with Classifications
ontology = user_client.create_ontology("Radio Button Ontology", structure=ontology_structure)


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.http.constants import RequestsSettings

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',
    requests_settings=requests_settings
)

# 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)


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.http.constants import RequestsSettings

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',
    requests_settings=requests_settings
)

# 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)


from encord import EncordUserClient
from encord.objects import Shape, Object, Option, OntologyStructure, attributes
from encord.objects.coordinates import BoundingBoxCoordinates
from encord.objects.attributes import ChecklistAttribute, RadioAttribute, OntologyNestedElement

from encord.http.constants import RequestsSettings

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',
    requests_settings=requests_settings
)

# 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 (upto 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)

Ontologies with Annotations and Classifications

This example explains how to create an ontology with annotations and classifications.


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

from encord.http.constants import RequestsSettings

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',
    requests_settings=requests_settings
)


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("My test ontology", structure=ontology_structure)