You can import all annotation types that are supported in RedBrick AI, including segmentations, classifications, bounding boxes, and more. Imported annotations will appear automatically on your annotator’s interface.

Please note the following critical points about annotation imports:

  • Best practices: It is best practice to import annotations and images together at the start. If you want to add annotations programmatically to images that have already been uploaded, please use the programmatic label & review.
  • API key required: annotation import is only supported through the SDK and CLI. In other words, you cannot use the direct upload UI to import annotations, and you must use the items list with the SDK/CLI to provide the required metadata along with annotations.
  • Consistency in dimensions: the image file and the annotation file must have the same dimensions.
  • Annotation file type: all annotation files must be uint8 or uint16.
  • Valid entries: we do not recommend uploading empty entries (i.e. entries in the segmentMap that do not actually contain a segmentation mask). Using validation parameters such as create_datapoints(label_validate=True) on upload is recommended if you believe there is a chance that your segmentMap contains invalid entries.

To import images along with segmentations, you must provide us with:

  1. Images in any supported format and NIftI segmentation files.

  2. An items list that provides a mapping of:

    • Segmentation files to volumes so that segmentations are applied to correct images.

    • Values within segmentation file to taxonomy categories.

Once you’ve prepared the items list in the format defined below, you can import the images and annotations using the create_datapoints SDK method or CLI upload method.

Items list for importing segmentations

You can find the full format reference here. In this section, we will focus on importing segmentations. In the examples below, pay attention to the following fields:

  1. segmentations: The segmentation files to be applied to the task.

  2. segmentMap: Map the values present in the segmentation files to their corresponding taxonomy categories.

I: One segmentation file per Task

{
  "name": "Task with Annotations",
  "series": [
    {
    "items": ["instance-01.dcm", "instance-02.dcm", ...],

    "segmentations": "segmentation.nii.gz",

    "segmentMap": {
    "1": "category-a", // the value of "category-a" must correspond to the name of an Object Label in your Project's Taxonomy
    "2": "category-b"
      }
    }
  ]
}
The mask in the example above (segmentation.nii.gz) is not necessarily a binary mask, i.e., it might contain multiple mask entries. Therefore, the mask associated with the “1” entry within segmentation.nii.gz will map to “category-a”. The mapping between value and category should be consistent across files.

II: Multiple segmentation files per task

Sometimes, segmentations for a single volume are stored in multiple segmentation files, but these segmentation files are not binary masks. In this case, follow the format below.

{
  "name": "...",
  "series": [
    {
    "items": ["instance-01.dcm", "instance-02.dcm", ...],

    "segmentations": ["segmentation-1.nii.gz", "segmentation-2.nii.gz"],

    "segmentMap": {
    "1": "category-a", // the value of "category-a" must correspond to the name of an Object Label in your Project's Taxonomy
    "2": "category-b"
      }
    }
  ]
}
All “1” within both segmentation files will map to “category-a”.

Common mistakes for I and II.

  • The values 1 and 2 must be present in either segmentation-1.nii.gz or segmentation-2.nii.gz.
  • All values in segmentation.nii.gz that are not in segmentMap will not be mapped to any taxonomy category in the editor.

III: Multiple binary segmentation files per task

A common pattern is to store each segmentation instance in a separate NIfTI file as a binary mask. In the example below, all non-zero values in segmentation-1.nii.gz are meant to correspond to the taxonomy category category-a.

{
  "name": "...",
  "series": [
    {
      "items": [
        "instance-01.dcm", 
        "instance-02.dcm"
      ],
      "segmentations": [
        "path/segmentation-1.nii.gz", 
        "path/segmentation-2.nii.gz"
      ],
      "segmentMap": {
        // when exported, this segmentation mask will be represented by "1" in the resulting NIfTI file.
        "1": {
          "category": "category-a", // this segmentation file supplied in "mask" will be mapped to "category". The "category" must exist in your Project's Taxonomy.
          "mask": "path/segmentation-1.nii.gz" 
        },
        "2": {
          "category": "enhancing-tumor", // this example presumes you have an Object Label Category in your Project Taxonomy with the name "enhancing-tumor"
          "mask": "path/segmentation-2.nii.gz"
        }
      }
    }
  ]
}
For the above example, each segmentation file is a binary mask, i.e., all non-zero values in a file will be mapped to a single category.

Investigating segmentation files

The following code blocks are intended to be copy/paste solutions in Python for users wishing to verify a certain aspect of their segmentation files before upload.

We also recommend using the RedBrick Preview Tool to investigate files that are available on your local machine or in your bucket.

If you are still encountering issues, please reach out to us at support@redbrickai.com.

Verifying the number of entries in a segmentation file


import nibabel as nib
import numpy as np

seg = nib.load('/path/to/seg.nii.gz')
data = seg.get_fdata()
instances = np.unique(data)

print(instances)  # ignore 0

Verifying the file type of a segmentation file

import nibabel as nib
img = nib.load('/path/to/image.nii.gz')
print(img.get_data_dtype())