Aligned Image with Page Break

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

Create an Ontology with Annotations


import logging
import time
from tqdm import tqdm
from encord import EncordUserClient
from encord.objects import Shape, Object, Option
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
)

# Creating a new ontology
ontology = user_client.create_ontology("My test ontology", structure=None)

# Adding an object with name "Cute Cat", with type Bounding Box
cat_object = ontology.structure.add_object("Cute Cat", shape=Shape.BOUNDING_BOX)

# And here you are, let's save it
ontology.save()


import logging
import time
from tqdm import tqdm
from encord import EncordUserClient
from encord.objects import Shape, Object, Option
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 = 'f1f1ffd6-e5f8-4180-a852-592832f2f80b'
project_hash = user_client.create_project("Cats annotation project", ontology_hash=ontology.ontology_hash, dataset_hashes=[MY_CAT_DATASET])

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

Create an Ontology with Classifications

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


import logging
import time
from tqdm import tqdm
from encord import EncordUserClient
from encord.objects import Shape, Object, Option
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
)

# Creating a new ontology with Classifications
ontology = user_client.create_ontology("My test ontology", structure=None)

cat_colour = cat_object.add_attribute(RadioAttribute, "colour", required=True)
cat_colour.add_option("white")
cat_colour.add_option("black")

cat_features = cat_object.add_attribute(ChecklistAttribute, "features")
cat_features.add_option("soft")
cat_features.add_option("fluffy")
cat_features.add_option("friendly")

# And here you are, let's save it
ontology.save()

Ontology Classification Types


    # Obtaining the Ontology object, that would allow editing the ontology
    # Ontology hash can be "project.ontology_hash"
    ontology = user_client.get_ontology(ontology_hash=<ontology hash>)

    # Adding a Classification of type radio button
    new_classification = ontology.structure.add_classification()
    new_radio_attribute = new_classification.add_attribute(RadioAttribute, "Green Eggs and Ham?")

    # Adding options for the classification
    new_radio_attribute.add_option("Yes")
    new_radio_attribute.add_option("No")
    
    # Saving the Ontology to apply the changes
    ontology.save()
	

    # Obtaining the Ontology object, that would allow editing the ontology
    # Ontology hash can be "project.ontology_hash"
    ontology = user_client.get_ontology(ontology_hash=<ontology hash>)

    # 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")
    
 # Saving the Ontology to apply the changes

    ontology.save()


    # Obtaining the Ontology object, that would allow editing the Ontology
    # Ontology hash can be "project.ontology_hash"
    ontology = user_client.get_ontology(ontology_hash=<ontology hash>)

    # Adding a Classification of type text field
    new_classification = ontology.structure.add_classification()
    new_text_attribute = new_classification.add_attribute(TextAttribute, "Describe location")
	

    # Saving the Ontology to apply the changes

    ontology.save()


new_classification = ontology.structure.add_classification()
    new_radio_attribute = new_classification.add_attribute(RadioAttribute, "Green Eggs and Ham?")
    new_radio_attribute.add_option("Yes")
    new_radio_attribute.add_option("No")

    # Provides 1st level nested attribute. RadioAttribute allows further nesting (upto 7 levels deep)
    nested_attribute = option.add_nested_attribute(RadioAttribute, "Where?")
    nested_attribute.add_option("Here")
    nested_attribute.add_option("There")
    nested_attribute.add_option("Everywhere")
	
    # Provides 2nd level nested attribute. ChecklistAttribute and TextAttribute prevent further nesting.
    nested_attribute = option.add_nested_attribute(ChecklistAttribute, "Specific location?")
    nested_attribute.add_option("In a box")
    nested_attribute.add_option("In a house")
	nested_attribute.add_option("In a car")

    ontology.save()

Create an Ontology with Annotations and Classifications

This example explains how to create a Project with annotations and classifications.


import logging
import time
from tqdm import tqdm
from encord import EncordUserClient
from encord.objects import Shape, Object, Option
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
)

# Create a new ontology with annotations and classifications
ontology = user_client.create_ontology("My test ontology", structure=None)

# Adding an object with name "Cute Cat", with type Bounding Box
cat_object = ontology.structure.add_object("Cute Cat", shape=Shape.BOUNDING_BOX)

# Now let's add some classifications
cat_colour = cat_object.add_attribute(RadioAttribute, "colour", required=True)
cat_colour.add_option("white")
cat_colour.add_option("black")

cat_features = cat_object.add_attribute(ChecklistAttribute, "features")
cat_features.add_option("soft")
cat_features.add_option("fluffy")
cat_features.add_option("friendly")

# And here you are, let's save it
ontology.save()

# Now let's create a project for a cat dataset and provide annotations
MY_CAT_DATASET = 'f1f1ffd6-e5f8-4180-a852-592832f2f80b'
project_hash = user_client.create_project("Cats annotation project", ontology_hash=ontology.ontology_hash, dataset_hashes=[MY_CAT_DATASET])

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 above, 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()

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

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


# Also lets mark colour, as it is required:
# First, let's find an option we want to set:
cat_colour = cat_object.get_child_by_title("colour", type_=RadioAttribute)
black = cat_colour.get_child_by_title("black", type_=Option)

# And now set it as the answer
cat_object_instance.set_answer(black)

# Attaching object instance to a particular label row
label_row.add_object_instance(cat_object_instance)

# Uploading created frame
label_row.save()