Import audio annotations

How to import annotations on audio data and sample import formats.

You can use the Python SDK to import annotations on audio data.

This page shows how to declare the annotations and demonstrates the import process.

A Python notebook demonstrates these steps and can be run directly with Google CoLab.

Supported annotations

This section shows how to create the annotation payload. You can declare annotation payloads as Python annotation types (preferred) or a NDJSON objects. Examples are shown for each supported annotation type.

Classification: free-form text

text_annotation = lb_types.ClassificationAnnotation(
    name="text_audio",
    value=lb_types.Text(answer="free text audio annotation"),
)
text_annotation_ndjson = {
    'name': 'text_audio',
    'answer': 'free text audio annotation',
}

Classification: checklist (multi-choice)

checklist_annotation= lb_types.ClassificationAnnotation(
  name="checklist_audio",
  value=lb_types.Checklist(
      answer = [
        lb_types.ClassificationAnswer(
            name = "first_checklist_answer"
        ), 
        lb_types.ClassificationAnswer(
            name = "second_checklist_answer"
        )
      ]
    ),
 )
checklist_annotation_ndjson = {
    'name': 'checklist_audio',
    'answers': [
        {'name': 'first_checklist_answer'},
        {'name': 'second_checklist_answer'}
    ]
}

Classification: radio (single choice)

radio_annotation = lb_types.ClassificationAnnotation(
    name="radio_audio",
    value=lb_types.Radio(answer=lb_types.ClassificationAnswer(
        name="second_radio_answer")))
radio_annotation_ndjson = {
    'name': 'radio_audio',
    'answer': {
        'name': 'first_radio_answer'
    }
}

Example: Import prelabels or ground truth

The process to mport prelabels (model assisted labeling) is similar to the process to import ground truths. They vary slightly in Steps 5 and 6, which detail the differences.

Before you start

These code samples require the following libraries:

import labelbox as lb
import uuid
import labelbox.types as lb_types

Replace API key

API_KEY = ""
client = lb.Client(API_KEY)

Step 1: Import data rows into Catalog

global_key = "sample-audio-1.mp3"

asset = {
    "row_data": "https://storage.googleapis.com/labelbox-datasets/audio-sample-data/sample-audio-1.mp3",
    "global_key": global_key
}

dataset = client.create_dataset(name="audio_annotation_import_demo_dataset")
task = dataset.create_data_rows([asset])
task.wait_till_done()
print("Errors:", task.errors)
print("Failed data rows: ", task.failed_data_rows)

Step 2: Set up ontology

Your project ontology should support all tools and classifications required by your annotations. To ensure correct schema feature matches, tool names and classification names should match the name field in your annotation.

To illustrate, imagine that you used the name text_audio when you created a text classification. When setting up the ontology, you must use text_audio as the value of the name when defining the classifications of your ontology. in addition, you must follow a similar process when defining other tools and classifications in your ontology.

ontology_builder = lb.OntologyBuilder(
  classifications=[ 
    lb.Classification( 
      class_type=lb.Classification.Type.TEXT,
      name="text_audio"), 
    lb.Classification( 
      class_type=lb.Classification.Type.CHECKLIST,                   
      name="checklist_audio", 
      options=[
        lb.Option(value="first_checklist_answer"),
        lb.Option(value="second_checklist_answer")            
      ]
    ), 
    lb.Classification( 
      class_type=lb.Classification.Type.RADIO, 
      name="radio_audio", 
      options=[
        lb.Option(value="first_radio_answer"),
        lb.Option(value="second_radio_answer")
      ]
    )
  ]
)

ontology = client.create_ontology("Ontology Audio Annotations", 
                                  ontology_builder.asdict(), 
                                  media_type=lb.MediaType.Audio)

Step 3: Create labeling project

Connect the ontology to the labeling project.

 #Create Labelbox project
project = client.create_project(name="audio_project", 
                                    media_type=lb.MediaType.Audio)

# Setup your ontology 
project.setup_editor(ontology) 

Step 4: Send data rows to project


# Create a batch to send to your MAL project
batch = project.create_batch(
  "first-batch-audio-demo", # Each batch in a project must have a unique name
  global_keys=[global_key], # Paginated collection of data row objects, list of data row ids or global keys
  priority=5 # priority between 1(Highest) - 5(lowest)
)

print("Batch: ", batch)

Step 5: Create annotation payloads

See Supported annotations for help creating annotation payloads.

You can declare annotation payloads as Python annotation types (preferred) or NDJSON objects.

label = []
label.append(
  lb_types.Label(
    data=lb_types.AudioData(
      global_key=global_key
    ),
    annotations=[
      text_annotation,
      checklist_annotation,
      radio_annotation
    ]
  )
)
label_ndjson = []
for annotations in [text_annotation_ndjson,
                    checklist_annotation_ndjson,
                    radio_annotation_ndjson]:
  annotations.update({
      'dataRow': {
          'globalKey': global_key
      }
  })
  label_ndjson.append(annotations)

Step 6: Upload annotations as prelabels or ground truth

Whichever option you choose, pass your annoation payload (label or label_ndjson) as the value of the predictions or labels parameter.

Option A: Upload as prelabels (model-assisted labeling)

upload_job = lb.MALPredictionImport.create_from_objects(
    client = client, 
    project_id = project.uid, 
    name=f"mal_job-{str(uuid.uuid4())}", 
    predictions=label)

upload_job.wait_until_done();
print("Errors:", upload_job.errors)
print("Status of uploads: ", upload_job.statuses)

Option B: Upload as ground truth

upload_job = lb.LabelImport.create_from_objects(
    client = client, 
    project_id = project.uid, 
    name="label_import_job"+str(uuid.uuid4()),  
    labels=label)

upload_job.wait_until_done();
print("Errors:", upload_job.errors)
print("Status of uploads: ", upload_job.statuses)