In order to make annotation as efficient as possible, Prodigy’s philosophy is centered around reducing the annotation to a binary decision (accept or reject) and focusing the annotator on one annotation task at a time.
So you can simply create separate questions using the choice
interface, and add them to your stream of annotation examples. choice
tasks can also specify an "image"
, so using your example above, the stream could look like this:
{"image": "image.jpg", "label": "image quality", "options": [{"id": 2, "text": "excellent"}, {"id": 1, "text": "good"}, {"id": 3, "text": "poor"}]}
{"image": "image.jpg", "label": "motion", "options": [{"id": 0, "text": "none"}, {"id": 1, "text": "minimal"}, {"id": 2, "text": "mild"}, {"id": 3, "text": "moderate"}, {"id": 4, "text": "severe"}]}
Since the annotation tasks are simple JSON objects (i.e. dictionaries in Python), you can create them programmatically in your recipe. For example, for each image in the stream, you can duplicate the task and add the respective label and options.
from prodigy.components.loaders import Images
stream = Images('/path/to/images') # this returns a stream of dictionaries
def get_stream(stream):
for eg in stream: # iterate over the stream
# this isn't the most elegant way to do this – but I'm keeping it
# simple to make it easier to follow the example:
image_quality = dict(eg)
image_quality['label'] = 'image_quality'
image_quality['options'] = [{'id': 2, 'text': 'excellent'}] # ... and so on
yield image_quality # yield the task
# and so on
You can find more info on this in the custom recipes workflow or in the PRODIGY_README.html
available for download with Prodigy (which also includes detailed documentation of the dictionary / JSON object format your script needs to create.)