Label Nesting and Options

There are often annotation tasks that have too many label choices for a tasker to efficiently sort through them all at once, or times when you want to show one version of a label name to a tasker, but would like another version in the response.

In those cases, you can utilize

LabelDescription
objects to support nested labels, where labels may have subcategories within them, as well as setting
display
values for the label.

When declaring

objects_to_annotate
in your task parameters, we accept a mixed array of strings and the more complex
LabelDescription
objects.

Definition:
LabelDescription

The

LabelDescription
object has the following structure:

Parameters

choicestringrequired

The name of the label. This should be singular and descriptive (ex: car, background, pole).

When both a choice and subchoices are defined, the choice will not be selectable, it will only be used for UX navigation. Only the "leaf" nodes will be returned in Scale's response.


subchoicesarray of objects

Optional: Descriptions of the sub-labels to be shown under this parent label. Array can be a mix of LabelDescription objects or strings.


instance_labelboolean

Optional: For Segmentation-based Tasks - Whether this label should be segmented on a per-instance basis. For example, if you set instance_label to true, each individual car would get a separate mask in the image, allowing you to distinguish between them.


displaystring

Optional: The value to be shown to a Tasker for a given label. Visually overrides the choice field in the user experience, but does not affect the task response or conditionality.


A simple example is illustrated in the example JSON below, where

objects_to_annotate
can simply be a string, a nested label with choices and subchoices, or a nested label where the subchoices themselves are
LabelDescription
objects with a display value.

While there may be a large number of total labels, using subchoices a tasker can first categorize an object as a road, pedestrian, or vehicle, and based on that choice, further select the specific type of pedestrian or vehicle.

Nested labels may be specified both for the object labels (the

objects_to_annotate
array parameter), as well as in the
choices
array of a categorical annotation attribute. In both cases, you would specify a nested label by using a
LabelDescription
object instead of a string.

For example, for an

objects_to_annotate
array of
["Vehicle", "Pedestrian"]
, you could instead add a nested label by passing an array, like
["Vehicle", {"choice": "Pedestrian", "subchoices": ["Animal", "Adult", "Child"]}]
. Then, if a tasker selected "Pedestrian" for an annotation, they would be further prompted to choose one of the corresponding subchoices for that annotation.

📘 See the Conditional attributes section for more details about conditional attributes.

LabelDescription Example

objects_to_annotate = [
  "Road",
  {
    "choice": "Vehicle",
    "subchoices": ["Car", "Truck", "Train", "Motorcycle"]
  },
  {
    "choice": "Pedestrian",
    "subchoices": [
      "Animal", 
      {"choice": "Ped_HeightOverMeter", "display": "Adult" }, 
      {"choice": "Ped_HeightUnderMeter", "display": "Child" }, 
    ]
  }
]

Response Format

Nested labels are only intended for grouping a large set of labels together. Thus, the response will be the same as with unnested labels, where only the final "leaf" label that the worker selected is reported. In the example above, if a worker selected "Pedestrian" and then "Animal" for an annotation, that annotation's label would be "Animal".

The above command returns as object structured like this:

{
  "task_id": "5774cc78b01249ab09f089dd",
  "created_at": "2016-9-03T07:38:32.368Z",
  "callback_url": "http://www.example.com/callback",
  "type": "annotation",
  "status": "pending",
  "instruction": "Annotate the cars and pedestrians",
  "params": {
    "attachment": "https://i.imgur.com/VDPoOZE.jpg",
    "attachment_type": "image",
    "objects_to_annotate": [
      {
        "choice": "Vehicle",
        "subchoices": ["Car", "Truck", "Train", "Motorcycle"]
      },
      {
        "choice": "Pedestrian",
        "subchoices": ["Animal", "Adult", "Child"]
      }
    ],
    "with_labels": false,
    "min_width": 30,
    "min_height": 30,
    "examples": [],
    "annotation_attributes": {
      "occlusion": {
        "description": "What percent of the object is occluded?",
        "choices": ["0%", "25%", "50%", "75%"],
        "conditions": {
          "label_condition": {
            "label": ["Car", "Truck", "Motorcycle"]
          }
        }
      }
    }
  },
  "metadata": {}
}

An example response with nested labels is below:

{
  "response": {
    "annotations": [
      {
        "left": 123,
        "top": 10,
        "width": 121,
        "height": 39,
        "label": "Motorcycle",
        "attributes": {
          "occlusion": "0%"
        }
      },
      {
        "left": 82,
        "top": 56,
        "width": 64,
        "height": 30,
        "label": "Animal"
      },
      { ... },
      { ... }
    ]
  },
  "task_id": "5774cc78b01249ab09f089dd",
  "task": {
    // populated task for convenience
    ...
  }
}
Updated 4 months ago