Skip to main content

Create Annotations

Label your data


Annotations (also known as labels) describe your inputs. When you add inputs to your app, we will create an input level annotation for each input. This input level annotation contains any data you provided in POST /inputs call. Models in your default workflow can also write annotations.

Once your input is successfully indexed, you can add additional annotations, such as concepts and bounding boxes.

You can label your inputs by calling the POST /annotations endpoint. For example, you can add concept(s) to an image, draw a bounding box, or label concept(s) in a video frame.

When you add an annotation, the app's default workflow will be run by default. This means that any newly added annotations will be immediately available for AI based search and training.

tip

You can add from 1 up to 128 annotations in a single API call.

Each annotation should contain at most one region. If it is a video, each annotation should contain 1 frame. If there are multiple regions in a frame you want to label, you can add multiple annotations for each region and each annotation will be contained within the same frame but in a different region.

Annotate Images With Concepts

Below is an example of how to annotate a concept present anywhere in an image.

#################################################################################################
# In this section, we set the user authentication, app ID, and how we want to annotate the image.
# Change these strings to run your own example.
#################################################################################################

USER_ID = 'YOUR_USER_ID_HERE'
# Your PAT (Personal Access Token) can be found in the Account's Security section
PAT = 'YOUR_PAT_HERE'
APP_ID = 'YOUR_APP_ID_HERE'
# Change these based on the image you want to annotate
INPUT_ID = "53d0362a9dfa4e03b2293375e2d0db73"
CONCEPT_ID_1 = "tree"
CONCEPT_ID_2 = "water"

##########################################################################
# YOU DO NOT NEED TO CHANGE ANYTHING BELOW THIS LINE TO RUN THIS EXAMPLE
##########################################################################

from clarifai_grpc.channel.clarifai_channel import ClarifaiChannel
from clarifai_grpc.grpc.api import resources_pb2, service_pb2, service_pb2_grpc
from clarifai_grpc.grpc.api.status import status_code_pb2

channel = ClarifaiChannel.get_grpc_channel()
stub = service_pb2_grpc.V2Stub(channel)

metadata = (('authorization', 'Key ' + PAT),)

userDataObject = resources_pb2.UserAppIDSet(user_id=USER_ID, app_id=APP_ID)

post_annotations_response = stub.PostAnnotations(
service_pb2.PostAnnotationsRequest(
user_app_id=userDataObject, # The userDataObject is created in the overview and is required when using a PAT
annotations=[
resources_pb2.Annotation(
input_id=INPUT_ID,
data=resources_pb2.Data(
concepts=[
resources_pb2.Concept(id=CONCEPT_ID_1, value=1.), # 1 means true, this concept is present
resources_pb2.Concept(id=CONCEPT_ID_2, value=0.) # 0 means false, this concept is not present
]
)
)
]
),
metadata=metadata
)

if post_annotations_response.status.code != status_code_pb2.SUCCESS:
print(post_annotations_response.status)
raise Exception("Post annotations failed, status: " + post_annotations_response.status.description)

Annotate Images With Multiple Concepts

Below is an example of how to annotate an image with multiple concepts in a single API call. You can provide the concepts in a list and iterate through it.

#################################################################################################
# In this section, we set the user authentication, app ID, and how we want to annotate the image.
# Change these strings to run your own example.
#################################################################################################

USER_ID = 'YOUR_USER_ID_HERE'
# Your PAT (Personal Access Token) can be found in the Account's Security section
PAT = 'YOUR_PAT_HERE'
APP_ID = 'YOUR_APP_ID_HERE'
# Change these based on the image you want to annotate with multiple concepts
INPUT_ID = "53d0362a9dfa4e03b2293375e2d0db73"
CONCEPT_IDS_LIST = ['one', 'two', 'three', 'four', 'five', 'six']

##########################################################################
# YOU DO NOT NEED TO CHANGE ANYTHING BELOW THIS LINE TO RUN THIS EXAMPLE
##########################################################################

from clarifai_grpc.channel.clarifai_channel import ClarifaiChannel
from clarifai_grpc.grpc.api import resources_pb2, service_pb2, service_pb2_grpc
from clarifai_grpc.grpc.api.status import status_code_pb2

channel = ClarifaiChannel.get_grpc_channel()
stub = service_pb2_grpc.V2Stub(channel)

metadata = (('authorization', 'Key ' + PAT),)

userDataObject = resources_pb2.UserAppIDSet(user_id=USER_ID, app_id=APP_ID)

post_annotations_response = stub.PostAnnotations(
service_pb2.PostAnnotationsRequest(
user_app_id=userDataObject, # The userDataObject is created in the overview and is required when using a PAT
annotations=[
resources_pb2.Annotation(
input_id=INPUT_ID,
data=resources_pb2.Data(
concepts=[
# We use Python list comprehension to iterate through the list of concepts
resources_pb2.Concept(id=str(i), value=1.) for i in CONCEPT_IDS_LIST
]
)
)
]
),
metadata=metadata
)

if post_annotations_response.status.code != status_code_pb2.SUCCESS:
print(post_annotations_response.status)
raise Exception("Post annotations failed, status: " + post_annotations_response.status.description)

Annotate New Bounding Boxes in an Image

Below is an example of how to label a new rectangular bounding box for a region.

These are the bounding box coordinates you need to provide:

  • top_row—The top left of the bounding box normalized to the data dimension to be within [0-1.0];
  • left_col—The left column of the bounding box normalized to the data dimension to be within [0-1.0];
  • bottom_row—The bottom row of the bounding box normalized to the data dimension to be within [0-1.0];
  • right_col—The right col of the bounding box normalized to the data dimension to be within [0-1.0].
########################################################################################
# In this section, we set the user authentication, app ID, and how we want to annotate
# new bounding boxes. Change these strings to run your own example.
#########################################################################################

USER_ID = 'YOUR_USER_ID_HERE'
# Your PAT (Personal Access Token) can be found in the Account's Security section
PAT = 'YOUR_PAT_HERE'
APP_ID = 'YOUR_APP_ID_HERE'
# Change these based on the new bounding boxes you want to annotate
INPUT_ID = "53d0362a9dfa4e03b2293375e2d0db73"
CONCEPT_ID_1 = "tree"
CONCEPT_ID_2 = "water"
CONCEPT_ID_3 = "bike"

##########################################################################
# YOU DO NOT NEED TO CHANGE ANYTHING BELOW THIS LINE TO RUN THIS EXAMPLE
##########################################################################

from clarifai_grpc.channel.clarifai_channel import ClarifaiChannel
from clarifai_grpc.grpc.api import resources_pb2, service_pb2, service_pb2_grpc
from clarifai_grpc.grpc.api.status import status_code_pb2

channel = ClarifaiChannel.get_grpc_channel()
stub = service_pb2_grpc.V2Stub(channel)

metadata = (('authorization', 'Key ' + PAT),)

userDataObject = resources_pb2.UserAppIDSet(user_id=USER_ID, app_id=APP_ID)

post_annotations_response = stub.PostAnnotations(
service_pb2.PostAnnotationsRequest(
user_app_id=userDataObject, # The userDataObject is created in the overview and is required when using a PAT
annotations=[
resources_pb2.Annotation(
input_id=INPUT_ID,
data=resources_pb2.Data(
regions=[
resources_pb2.Region(
region_info=resources_pb2.RegionInfo(
bounding_box=resources_pb2.BoundingBox( # draw a bounding box
top_row=0,
left_col=0,
bottom_row=0.5,
right_col=0.5
)
),
data=resources_pb2.Data(
concepts=[
resources_pb2.Concept(id=CONCEPT_ID_1, value=1.), # 1 means true, this concept is present.
resources_pb2.Concept(id=CONCEPT_ID_2, value=0.) # 0 means false, this concept is not present.
]
)
)
]
)

),
resources_pb2.Annotation(
input_id=INPUT_ID,
data=resources_pb2.Data(
regions=[
resources_pb2.Region(
region_info=resources_pb2.RegionInfo(
bounding_box=resources_pb2.BoundingBox( # draw another bounding box
top_row=0.6,
left_col=0.6,
bottom_row=0.8,
right_col=0.8
)
),
data=resources_pb2.Data(
concepts=[
resources_pb2.Concept(id=CONCEPT_ID_3, value=1.), # 1 means true, this concept is present.
]
)
)
]
)

)
]
),
metadata=metadata
)

if post_annotations_response.status.code != status_code_pb2.SUCCESS:
print(post_annotations_response.status)
raise Exception("Post annotations failed, status: " + post_annotations_response.status.description)


Annotate Polygons in an Image

Below is an example of how to provide annotations within any polygon-shaped region of an image.

These are the list of points that connect together to form a polygon:

  • row—The row location of the point. This has a [0.0-1.0] range with 0.0 being top row and 1.0 being the bottom row;
  • col—The column location of the point. This has a [0.0-1.0] range with 0.0 being left col and 1.0 being the right col;
  • z—Depth, if applicable, of the point.
#########################################################################################
# In this section, we set the user authentication, app ID, and how we want to annotate
# a polygon. Change these strings to run your own example.
#########################################################################################

USER_ID = 'YOUR_USER_ID_HERE'
# Your PAT (Personal Access Token) can be found in the Account's Security section
PAT = 'YOUR_PAT_HERE'
APP_ID = 'YOUR_APP_ID_HERE'
# Change these based on the polygon you want to annotate
INPUT_ID = "ca8666e974ac4c2c8dfbd7df1e7cbc44"
CONCEPT_ID_1 = "tree"
CONCEPT_ID_2 = "water"
CONCEPT_ID_3 = "bike"

##########################################################################
# YOU DO NOT NEED TO CHANGE ANYTHING BELOW THIS LINE TO RUN THIS EXAMPLE
##########################################################################


from clarifai_grpc.grpc.api.status import status_code_pb2
from clarifai_grpc.grpc.api import resources_pb2, service_pb2, service_pb2_grpc
from clarifai_grpc.channel.clarifai_channel import ClarifaiChannel

channel = ClarifaiChannel.get_grpc_channel()
stub = service_pb2_grpc.V2Stub(channel)

metadata = (('authorization', 'Key ' + PAT),)

userDataObject = resources_pb2.UserAppIDSet(user_id=USER_ID, app_id=APP_ID)

post_annotations_response = stub.PostAnnotations(
service_pb2.PostAnnotationsRequest(
# The userDataObject is created in the overview and is required when using a PAT
user_app_id=userDataObject,
annotations=[
resources_pb2.Annotation(
input_id=INPUT_ID,
data=resources_pb2.Data(
regions=[
resources_pb2.Region(
region_info=resources_pb2.RegionInfo(
polygon=resources_pb2.Polygon( # draw a polygon
points=[
resources_pb2.Point(row=0.30), # row location of the point, with a [0.0-1.0] range
resources_pb2.Point(col=0.50), # column location of the point, with a [0.0-1.0] range
resources_pb2.Point(z=0.50) # depth, if applicable, of the point
]
)
),
data=resources_pb2.Data(
concepts=[
resources_pb2.Concept(id=CONCEPT_ID_1, value=1), # 1 means true, this concept is present
resources_pb2.Concept(id=CONCEPT_ID_2, value=0) # 0 means false, this concept is not present
]
)
)
]
)

),
resources_pb2.Annotation(
input_id=INPUT_ID,
data=resources_pb2.Data(
regions=[
resources_pb2.Region(
region_info=resources_pb2.RegionInfo(
polygon=resources_pb2.Polygon( # draw another polygon
points=[
resources_pb2.Point(row=0.60),
resources_pb2.Point(col=0.80),
resources_pb2.Point(z=0.50)
]
)
),
data=resources_pb2.Data(
concepts=[
resources_pb2.Concept(id=CONCEPT_ID_3, value=1), # 1 means true, this concept is present
]
)
)
]
)

)
]
),
metadata=metadata
)

if post_annotations_response.status.code != status_code_pb2.SUCCESS:
print(post_annotations_response.status)
raise Exception("Post annotations failed, status: " + post_annotations_response.status.description)

Annotate Existing Regions in an Image

When you add an input, detection models (such as Face Detection or General Detection) will detect regions in your image where there appear to be relevant objects. You can get the IDs of these detected regions by listing model's annotations.

Your labels should be contained within Region.data. Each annotation can only have 1 region. If you want to label multiple regions, it is possible to label multiple annotations in a single API call.

Below is an example of how to annotate existing regions in an image.

########################################################################################
# In this section, we set the user authentication, app ID, and how we want to annotate
# existing regions in an image. Change these strings to run your own example.
#########################################################################################

USER_ID = 'YOUR_USER_ID_HERE'
# Your PAT (Personal Access Token) can be found in the Account's Security section
PAT = 'YOUR_PAT_HERE'
APP_ID = 'YOUR_APP_ID_HERE'
# Change these based on the existing regions you want to annotate
INPUT_ID = "53d0362a9dfa4e03b2293375e2d0db73"
CONCEPT_ID_1 = "tree"
CONCEPT_ID_2 = "water"
CONCEPT_ID_3 = "bike"
REGION_ID_1 = "361d6a9253be9152968012660258a4bf"
REGION_ID_2 = "dcfa961b753f3b197d0bf7b242718ab1"

##########################################################################
# YOU DO NOT NEED TO CHANGE ANYTHING BELOW THIS LINE TO RUN THIS EXAMPLE
##########################################################################

from clarifai_grpc.channel.clarifai_channel import ClarifaiChannel
from clarifai_grpc.grpc.api import resources_pb2, service_pb2, service_pb2_grpc
from clarifai_grpc.grpc.api.status import status_code_pb2

channel = ClarifaiChannel.get_grpc_channel()
stub = service_pb2_grpc.V2Stub(channel)

metadata = (('authorization', 'Key ' + PAT),)

userDataObject = resources_pb2.UserAppIDSet(user_id=USER_ID, app_id=APP_ID)

post_annotations_response = stub.PostAnnotations(
service_pb2.PostAnnotationsRequest(
user_app_id=userDataObject, # The userDataObject is created in the overview and is required when using a PAT
annotations=[
resources_pb2.Annotation( # label a region in this image
input_id=INPUT_ID,
data=resources_pb2.Data(
regions=[
resources_pb2.Region(
id=REGION_ID_1, # this should be a region id returned from list annotations call
data=resources_pb2.Data(
concepts=[
resources_pb2.Concept(id=CONCEPT_ID_1, value=1.), # 1 means true, this concept is present.
resources_pb2.Concept(id=CONCEPT_ID_2, value=0.) # 0 means false, this concept is not present.
]
)
)
]
)

),
resources_pb2.Annotation( # label another region in this image
input_id=INPUT_ID,
data=resources_pb2.Data(
regions=[
resources_pb2.Region(
id=REGION_ID_2 , # this should be a region id returned from list annotations call
data=resources_pb2.Data(
concepts=[
resources_pb2.Concept(id=CONCEPT_ID_3, value=1.), # 1 means true, this concept is present.
]
)
)
]
)

),
]
),
metadata=metadata
)


if post_annotations_response.status.code != status_code_pb2.SUCCESS:
print(post_annotations_response.status)
raise Exception("Post annotations failed, status: " + post_annotations_response.status.description)

Annotate Images With Mask

Below is an example of how to add a mask to an Image using a single API call. In this example, we provide an image mask as a base64 string.

Click here to learn more about image mask annotations.

#########################################################################################
# In this section, we set the user authentication, app ID, and how we want to create an
# image mask. Change these strings to run your own example.
#########################################################################################

# Your user and app ID
USER_ID = 'YOUR_USER_ID_HERE'
# Your PAT (Personal Access Token) can be found in the Account's Security section
PAT = 'YOUR_PAT_HERE'
APP_ID = 'YOUR_APP_ID_HERE'
# Change these based on the new bounding boxes you want to annotate
INPUT_ID = "INPUT_ID_FROM_UI"

##########################################################################
# YOU DO NOT NEED TO CHANGE ANYTHING BELOW THIS LINE TO RUN THIS EXAMPLE
##########################################################################


from clarifai_grpc.grpc.api.status import status_code_pb2
from clarifai_grpc.grpc.api import resources_pb2, service_pb2, service_pb2_grpc
from clarifai_grpc.channel.clarifai_channel import ClarifaiChannel

channel = ClarifaiChannel.get_grpc_channel()
stub = service_pb2_grpc.V2Stub(channel)

metadata = (('authorization', 'Key ' + PAT),)

userDataObject = resources_pb2.UserAppIDSet(user_id=USER_ID, app_id=APP_ID)

post_annotations_response = stub.PostAnnotations(
service_pb2.PostAnnotationsRequest(
# The userDataObject is created in the overview and is required when using a PAT
user_app_id=userDataObject,
annotations=[
resources_pb2.Annotation(
input_id=INPUT_ID,
data=resources_pb2.Data(
regions=[
resources_pb2.Region(
region_info=resources_pb2.RegionInfo(
mask=resources_pb2.Mask(
image=resources_pb2.Image(
base64=b"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"
),
)
),
data=resources_pb2.Data(
concepts=[
resources_pb2.Concept(id="CONCEPT_ID_FROM_UI", value=1), # 1 means true, this concept is present
]
)
)
]
)

)
]
),
metadata=metadata
)

if post_annotations_response.status.code != status_code_pb2.SUCCESS:
print(post_annotations_response.status)
raise Exception("Post annotations failed, status: " + post_annotations_response.status.description)

Annotate Images With Different user_id and status

Each annotation is tied to a user or a model in your workflow. By default, when a user posts an annotation, this user is the owner of the annotation.

Sometimes, however, you might want to post an annotation as another user; for example, when assigning an image to another user. In such a case, you can create an annotation with another user_id (and status PENDING).

note

Only the app owner can post an annotation with other user's user_id; collaborators cannot.

Below is an example of how to annotate images with different user_id and status.

#########################################################################
# In this section, we set the user authentication, app ID, input ID,
# and another user ID. Change these strings to run your own example.
#########################################################################

USER_ID = 'YOUR_USER_ID_HERE'
# Your PAT (Personal Access Token) can be found in the Account's Security section
PAT = 'YOUR_PAT_HERE'
APP_ID = 'YOUR_APP_ID_HERE'
# Change these to post your own annotations
INPUT_ID = 'e838fac8da9d40c89f2291a6496593da'
ANOTHER_USER_ID = 'ANOTHER_USER_ID_HERE'

##########################################################################
# YOU DO NOT NEED TO CHANGE ANYTHING BELOW THIS LINE TO RUN THIS EXAMPLE
##########################################################################

from clarifai_grpc.channel.clarifai_channel import ClarifaiChannel
from clarifai_grpc.grpc.api import resources_pb2, service_pb2, service_pb2_grpc
from clarifai_grpc.grpc.api.status import status_code_pb2, status_pb2

channel = ClarifaiChannel.get_grpc_channel()
stub = service_pb2_grpc.V2Stub(channel)

metadata = (('authorization', 'Key ' + PAT),)

userDataObject = resources_pb2.UserAppIDSet(user_id=USER_ID, app_id=APP_ID) # The userDataObject is created in the overview and is required when using a PAT

post_annotations_response = stub.PostAnnotations(
service_pb2.PostAnnotationsRequest(
user_app_id=userDataObject,
annotations=[
resources_pb2.Annotation(
input_id=INPUT_ID,
user_id=ANOTHER_USER_ID, # If empty, it is the user who posts this annotation
status=status_pb2.Status(
code=status_code_pb2.ANNOTATION_PENDING # annotation pending status. By default success.
),
)
]
),
metadata=metadata
)

if post_annotations_response.status.code != status_code_pb2.SUCCESS:
print(post_annotations_response.status)
raise Exception("Post annotations failed, status: " + post_annotations_response.status.description)