Contents
- Installation
- Config file
- Initialization and authorization
- Creating a project
- Creating a folder in a project
- Uploading images to project
- Working with annotation classes
- Working with annotations
- Exporting projects
- Converting annotation format
- Working with images
- Working with team contributors
- pandas DataFrame out of project annotations and annotation instance filtering
- Aggregating class distribution across multiple projects
- Working with DICOM files
- Computing consensus scores for instances between several projects
- Computing benchmark scores for instances between ground truth project and given project list
SDK is available on PyPI:
pip install superannotateThe package officially supports Python 3.6+ and was tested under Linux and Windows (Anaconda) platforms.
For certain video related functions to work, ffmpeg package needs to be installed. It can be installed on Ubuntu with:
sudo apt-get install ffmpegFor Windows and Mac OS based installations to use :py:obj:`benchmark` and :py:obj:`consensus` functions you might also need to install beforehand :py:obj:`shapely` package, which we found to work properly only under Anaconda distribution, with:
conda install shapelyTo use the SDK, a config file with team specific authentication token needs to be created. The token is available to team admins on team setting page at https://app.superannotate.com/team.
To generate a default location (:file:`~/.superannotate/config.json`) config file, :ref:`CLI init <ref_cli_init>` can be used:
superannotatecli initTo create a custom config file a new JSON file with key "token" can be created:
{
"token" : "<team token>"
}Include the package in your Python code:
import superannotate as saSDK is ready to be used if default location config file was created using the :ref:`CLI init <ref_cli_init>`. Otherwise to authenticate SDK with the :ref:`custom config file <ref_custom_config_file>`:
sa.init("<path_to_config_json>")To create a new "Vector" project with name "Example Project 1" and description "test":
project = "Example Project 1"
sa.create_project(project, "test", "Vector")Warning
In general, SDK functions are not thread-safe.
To create a new folder "folder1" in the project "Example Project 1":
sa.create_folder(project, "folder1")After that point almost all SDK functions that use project name as argument can point to that folder with slash after the project name, e.g., "Example Project 1/folder1", in this case.
To upload all images with extensions "jpg" or "png" from the :file:`"<local_folder_path>"` to the project "Example Project 1":
sa.upload_images_from_folder_to_project(project, "<local_folder_path>")See the full argument options for :py:func:`upload_images_from_folder_to_project` :ref:`here <ref_upload_images_from_folder_to_project>`.
For full list of available functions on projects, see :ref:`ref_projects`.
Note
Python SDK functions that accept project argument will accept both project name or :ref:`project metadata <ref_metadata>` (returned either by :ref:`get_project_metadata <ref_get_project_metadata>` or :ref:`search_projects <ref_search_projects>` with argument :py:obj:`return_metadata=True`). If project name is used it should be unique in team's project list. Using project metadata will give performance improvement.
Note
CLI command :ref:`upload-images <ref_upload_images>` can also be used for image upload.
Note
To upload images to the "folder1" instead of the root of the project:
sa.upload_images_from_folder_to_project(project + "/folder1", "<local_folder_path>")
An annotation class for a project can be created with SDK's:
sa.create_annotation_class(project, "Large car", color="#FFFFAA")To create annotation classes in bulk with SuperAnnotate export format :file:`classes.json` (documentation at: https://app.superannotate.com/documentation Management Tools -> Project Workflow part):
sa.create_annotation_classes_from_classes_json(project, "<path_to_classes_json>")All of the annotation classes of a project are downloaded (as :file:`classes/classes.json`) with :ref:`download_export <ref_download_export>` along with annotations, but they can also be downloaded separately with:
sa.download_annotation_classes_json(project, "<path_to_local_folder>")The :file:`classes.json` file will be downloaded to :file:`"<path_to_local_folder>"` folder.
The SuperAnnotate format annotation JSONs have the general form:
[
{
"className": "Human",
"points" : "...",
"..." : "..."
},
{
"className": "Cat",
"points" : "...",
"..." : "..."
},
{
"..." : "..."
}
]the "className" fields here will identify the annotation class of an annotation object (polygon, points, etc.). The project you are uploading to should contain annotation class with that name.
To upload annotations to platform:
sa.upload_annotations_from_folder_to_project(project, "<path_to_local_dir>")This will try uploading to the project all the JSON files in the folder that have specific file naming convention. For vector projects JSONs should be named :file:`"<image_name>___objects.json"`. For pixel projects JSON files should be named :file:`"<image_name>___pixel.json"` and also for each JSON a mask image file should be present with the name :file:`"<image_name>___save.png"`. Image with :file:`<image_name>` should already be present in the project for the upload to work.
You can add an annotation to local annotations JSON with:
sa.add_annotation_bbox_to_json("<path_to_json>", [10, 10, 100, 100],
"Human")To export the project annotations we need to prepare the export first:
export = sa.prepare_export(project, include_fuse=True)We can download the prepared export with:
sa.download_export(project, export, "<local_folder_path>", extract_zip_contents=True):ref:`download_export <ref_download_export>` will wait until the export is finished preparing and download it to the specified folder.
Warning
Starting from version 1.9.0 :ref:`download_export <ref_download_export>` additionally requires :py:obj:`project` as first argument.
After exporting project annotations (in SuperAnnotate format), it is possible to convert them to other annotation formats:
sa.export_annotation("<input_folder>", "<output_folder>", "<dataset_format>", "<dataset_name>",
"<project_type>", "<task>")Note
Right now we support only SuperAnnotate annotation format to COCO annotation format conversion, but you can convert from "COCO", "Pascal VOC", "DataLoop", "LabelBox", "SageMaker", "Supervisely", "VGG", "VoTT" or "YOLO" annotation formats to SuperAnnotate annotation format.
You can find more information annotation format conversion :ref:`here <ref_converter>`. We provide some examples in our GitHub repository. In the root folder of our github repository, you can run following commands to do conversions.
import superannotate as sa
# From SA format to COCO panoptic format
sa.export_annotation(
"tests/converter_test/COCO/input/fromSuperAnnotate/cats_dogs_panoptic_segm",
"tests/converter_test/COCO/output/panoptic",
"COCO", "panoptic_test", "Pixel","panoptic_segmentation"
)
# From COCO keypoints detection format to SA annotation format
sa.import_annotation(
"tests/converter_test/COCO/input/toSuperAnnotate/keypoint_detection",
"tests/converter_test/COCO/output/keypoints",
"COCO", "person_keypoints_test", "Vector", "keypoint_detection"
)
# Pascal VOC annotation format to SA annotation format
sa.import_annotation(
"tests/converter_test/VOC/input/fromPascalVOCToSuperAnnotate/VOC2012",
"tests/converter_test/VOC/output/instances",
"VOC", "instances_test", "Pixel", "instance_segmentation"
)
# YOLO annotation format to SA annotation format
sa.import_annotation(
'tests/converter_test/YOLO/input/toSuperAnnotate',
'tests/converter_test/YOLO/output',
'YOLO', '', 'Vector', 'object_detection'
)
# LabelBox annotation format to SA annotation format
sa.import_annotation(
"tests/converter_test/LabelBox/input/toSuperAnnotate/",
"tests/converter_test/LabelBox/output/objects/",
"LabelBox", "labelbox_example", "Vector", "object_detection"
)
# Supervisely annotation format to SA annotation format
sa.import_annotation(
"tests/converter_test/Supervisely/input/toSuperAnnotate",
"tests/converter_test/Supervisely/output",
"Supervisely", "", "Vector", "vector_annotation"
)
# DataLoop annotation format to SA annotation format
sa.import_annotation(
"tests/converter_test/DataLoop/input/toSuperAnnotate",
"tests/converter_test/DataLoop/output",
"DataLoop", "", "Vector", "vector_annotation"
)
# VGG annotation format to SA annotation format
sa.import_annotation(
"tests/converter_test/VGG/input/toSuperAnnotate",
"tests/converter_test/VGG/output",
"VGG", "vgg_test", "Vector", "instance_segmentation"
)
# VoTT annotation format to SA annotation format
sa.import_annotation(
"tests/converter_test/VoTT/input/toSuperAnnotate",
"tests/converter_test/VoTT/output",
"VoTT", "", "Vector", "vector_annotation"
)
# GoogleCloud annotation format to SA annotation format
sa.import_annotation(
"tests/converter_test/GoogleCloud/input/toSuperAnnotate",
"tests/converter_test/GoogleCloud/output",
"GoogleCloud", "image_object_detection", "Vector", "object_detection"
)
# GoogleCloud annotation format to SA annotation format
sa.import_annotation(
"tests/converter_test/SageMaker/input/toSuperAnnotate",
"tests/converter_test/SageMaker/output",
"SageMaker", "test-obj-detect", "Vector", "object_detection"
)To download the image one can use:
image = "example_image1.jpg"
sa.download_image(project, image, "<path_to_local_dir>")To download image annotations:
sa.download_image_annotations(project, image, "<path_to_local_dir>")After the image annotations are downloaded, you can add annotations to it:
sa.add_annotation_bbox_to_json("<path_to_json>", [10, 10, 100, 100],
"Human")and upload back to the platform with:
sa.upload_image_annotations(project, image, "<path_to_json>")Last two steps can be combined into one:
sa.add_annotation_bbox_to_image(project, image, [10, 10, 100, 100], "Human")but if bulk changes are made to many images it is much faster to add all required annotations using :ref:`add_annotation_bbox_to_json <ref_add_annotation_bbox_to_json>` then upload them using :ref:`upload_annotations_from_folder_to_project <ref_upload_images_from_folder_to_project>`.
A team contributor can be invited to the team with:
sa.invite_contributor_to_team(email="[email protected]", admin=False)This invitation should be accepted by the contributor. After which, to share the project with the found contributor as an QA:
sa.share_project(project, "[email protected]", user_role="QA")To create a pandas DataFrame from project SuperAnnotate format annotations:
df = sa.aggregate_annotations_as_df("<path_to_project_folder>")The created DataFrame will have columns specified at :ref:`aggregate_annotations_as_df <ref_aggregate_annotations_as_df>`.
Example of created DataFrame:
Each row represents annotation information. One full annotation with multiple
attribute groups can be grouped under instanceId field.
A helper function :ref:`filter_annotation_instances <ref_filter_annotation_instances>` is available to filter annotation instances by their class, attribute, type or error fields from the DataFrame. E.g., to get annotations that have annotation class Human and attribute "height" : "tall" that are not of type polygon:
filtered_df = sa.filter_annotation_instances(df, include=[{"className" : "Human",
"attributes" : [{"groupName" : "height",
"name" : "tall"}]
}],
exclude=[{"type" : "polygon"}])To transform back pandas DataFrame annotations to SuperAnnotate format annotation:
sa.df_to_annotations(filtered_df, "<path_to_output_folder>")After exporting annotations from multiple projects, it is possible to aggregate class distribution of annotated instances as follows
df = sa.class_distribution("<path_to_export_folder>", [project_names])Aggregated distribution is returned as pandas dataframe with columns className and count. Enabling visualize flag plots histogram of obtained distribution.
df = sa.class_distribution("<path_to_export_folder>", [project_names], visualize = True)Similarly aggregation of class attributes across multiple projects can be obtained with
df = sa.attribute_distribution("<path_to_export_folder>", [project_names], visualize = True)Here pandas DataFrame with columns identifying attribute and corresponding instance count is returned. Within visualized histogram attributes of the same class are grouped by color and sorted accordingly.
To convert DICOM file images to JPEG images:
df = sa.dicom_to_rgb_sequence("<path_to_dicom_file>", "<path_to_output_dir>")JPEG images with names :file:`<dicom_file_name>_<frame_num>.jpg` will be created in :file:`<path_to_output_dir>`. Those JPEG images can be uploaded to SuperAnnotate platform using the regular:
sa.upload_images_from_folder_to_project(project, "<path_to_output_dir>")Some DICOM files can have image frames that are compressed. To load them, GDCM : Grassroots DICOM library needs to be installed:
# using conda
conda install -c conda-forge gdcm
# or on Ubuntu with versions above 19.04
sudo apt install python3-gdcmConsensus is a tool to compare the quallity of the annotations of the same image that is present in several projects. To compute the consensus scores:
res_df = sa.consensus([project_names], "<path_to_export_folder>", [image_list], "<annotation_type>")Here pandas DataFrame with following columns is returned: creatorEmail, imageName, instanceId, className, area, attribute, projectName, score
Besides the pandas DataFrame there is an option to get the following plots by setting the show_plots flag to True:
- Box plot of consensus scores for each annotators
- Box plot of consensus scores for each project
- Scatter plots of consensus score vs instance area for each project
sa.consensus([project_names], "<path_to_export_folder>", [image_list], "<annotation_type>", show_plots=True)To the left of each box plot the original score points of that annotator is depicted, the box plots are colored by annotator.
Analogically the box plots of consensus scores for each project are colored according to project name.
Scatter plot of consensus score vs instance area is separated by projects. Hovering on a point reveals its annotator and image name. The points are colored according to class name. Each annotator is represented with separate symbol.
Benchmark is a tool to compare the quallity of the annotations of the same image that is present in several projects with the ground truth annotation of the same image that is in a separate project.
To compute the benchmark scores:
res_df = sa.benchmark("<ground_truth_project_name>",[project_names], "<path_to_export_folder>", [image_list], "<annotation_type>")Here pandas DataFrame with exactly same structure as in case of consensus computation is returned.
Besides the pandas DataFrame there is an option to get the following plots by setting the show_plots flag to True:
- Box plot of benchmark scores for each annotators
- Box plot of benchmark scores for each project
- Scatter plots of benchmark score vs instance area for each project
sa.benchmark("<ground_truth_project_name>", [project_names], "<path_to_export_folder>", [image_list], "<annotation_type>", show_plots=True)To the left of each box plot the original score points of that annotator is depicted, the box plots are colored by annotator.
Analogically the box plots of benchmark scores for each project are colored according to project name.
Scatter plot of benchmark score vs instance area is separated by projects. Hovering on a point reveals its annotator and image name. The points are colored according to class name. Each annotator is represented with separate symbol.









