# Importing Brush Traces

You may import PNG masks as pre-labels for the [Brush labeling tool](https://docs.imerit.net/labeling/labeling-tools/tools/brush-bucket) in Ango Hub.

## How to Import Masks as Brush Annotations

#### 1. Verify Brush Tool Classes

Navigate to **Settings > Category Schema** in your project to ensure that the necessary Brush tool classes are available in the project.

#### 2. Assign Colors

* For **instance segmentation** tasks, randomly assign a unique RGB color value to each instance in your mask.
* For **semantic segmentation** tasks, randomly assign a unique RGB color value to each class in your mask.

#### 3. Prepare Masks

Prepare the masks you intend to import. Ensure the masks meet the following criteria:

* The imported mask must be a 4-channel RGBA image
* The width and height of the mask image must match the image asset's dimensions
* The **background** value of the mask must be solid white and transparent
  * **Example:** `(RGBA: 255, 255, 255, 0)`
* Use randomly assigned unique colors in the previous step, with fully opaque (255) alpha channel. Make sure that the mask’s **foreground** brush content must match the exact color values of the "brush" field in the JSON file.
  * **Example:**&#x20;
    * Mask Image: `(RGBA: 244, 67, 54, 255)`,&#x20;
    * JSON File: `"brush": [244, 67, 54]`

The following would be a valid PNG mask:

{% file src="<https://3895963154-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FTcOUG6rfWxqGM0N4db2P%2Fuploads%2FcEP3lhSRZhA0rloOJoCX%2Fbrush-import-docs.png?alt=media&token=4d2a5abf-e940-4c97-9c0f-f885f55ffa2a>" %}

You can use the following Python script to convert an RGB mask with a solid black background into the required RGBA format:

```python
import numpy as np
from skimage import io

def rgb_mask_to_rgba_mask(input_mask_path, output_mask_path):
    input_mask = io.imread(input_mask_path)
    output_mask = np.zeros((input_mask.shape[0], input_mask.shape[1], 4), dtype=np.uint8)

    mask_flat = input_mask.reshape(-1, 3)
    unique_colors = np.unique(mask_flat, axis=0)

    for color in unique_colors:
        if np.array_equal(color, [0, 0, 0]):
            indices = np.where(np.all(input_mask == color, axis=-1))
            output_mask[indices] = np.array([255, 255, 255, 0], dtype=np.uint8)
        else:
            indices = np.where(np.all(input_mask == color, axis=-1))
            output_mask[indices] = np.array(list(color) + [255], dtype=np.uint8)

    io.imsave(output_mask_path, output_mask)
```

#### 4. Prepare JSON File

Prepare the JSON to import to Hub, in the following format:

Where `externalId` is the external ID of the asset to pre-annotate, `brushDataUrl` is a link to your publicly accessible PNG mask, and `tools` is the list of instances available in the mask with randomly assigned unique RGB color information (`"brush"`) and the `"schemaId"` of each class.

#### For Brush Traces with Publicly Accessible URLs

```json
[
  {
    "externalId": "0a6e52c9-1eda-426f-8bcb-e6b1cd45668c.png",
    "brushDataUrl": "https://domain.s3.eu-central-1.amazonaws.com/brush-import-samples/0a6e52c9-1eda-426f-8bcb-e6b1cd45668c.png",
    "tools": [{"brush": [244, 67, 54], "schemaId": "29fde0dbe3eca1115f18368"}]
  },
  {
    "externalId": "0e9ee946-ebaa-4847-99ee-ce7386795333.png",
    "brushDataUrl": "https://domain.s3.eu-central-1.amazonaws.com/brush-import-samples/0e9ee946-ebaa-4847-99ee-ce7386795333.png",
    "tools": [{"brush": [244, 67, 54], "schemaId": "29fde0dbe3eca1115f18368"}]
  },
  {
    "externalId": "0eaf2333-5533-4353-ac3d-55774b6adb47.png",
    "brushDataUrl": "https://domain.s3.eu-central-1.amazonaws.com/brush-import-samples/0eaf2333-5533-4353-ac3d-55774b6adb47.png",
    "tools": [{"brush": [244, 67, 54], "schemaId": "29fde0dbe3eca1115f18368"}]
  },
  {
    "externalId": "0ebf0551-6c2d-4b6e-9a46-d5e1a5f22e72.png",
    "brushDataUrl": "https://domain.s3.eu-central-1.amazonaws.com/brush-import-samples/0ebf0551-6c2d-4b6e-9a46-d5e1a5f22e72.png",
    "tools": [{"brush": [244, 67, 54], "schemaId": "29fde0dbe3eca1115f18368"}]
  }
]
```

{% hint style="warning" %}
If your masks are stored in a cloud storage service, ensure the bucket's CORS settings are set properly, or your masks will not be visible on Hub.

[Here is a guide](https://docs.imerit.net/data/storages/set-up-cors) on how to set up CORS in such a way that your masks will be visible.
{% endhint %}

#### For Brush Traces in Private Buckets

* Integrate your private bucket with Ango Hub by following the instructions on the [Storages](https://docs.imerit.net/data/storages) docs page.
* Navigate to your organization's *Organization* page, then navigate to the *Storages* tab.
* Copy the ID of the storage where your brush traces are stored.
* Prepare a JSON with the following format:

```json
[
  {
    "externalId": "0a6e52c9-1eda-426f-8bcb-e6b1cd45668c.png",
    "brushDataUrl": "https://url.com/e6b1cd45668c.png?storageId=<YOUR_STORAGE_ID>",
    "tools": [{"brush": [244, 67, 54], "schemaId": "29fde0dbe3eca1115f18368"}]
  },
  {
    "externalId": "0e9ee946-ebaa-4847-99ee-ce7386795333.png",
    "brushDataUrl": "https://url.com/ce7386795333.png?storageId=<YOUR_STORAGE_ID>",
    "tools": [{"brush": [244, 67, 54], "schemaId": "29fde0dbe3eca1115f18368"}]
  }
]
```

#### 5. Import Annotations

In your project, navigate to the *Assets* tab and ensure that the assets you wish to prelabel are in the *Start* stage, then click on *Import*. Drag and drop the JSON file you have just prepared. Your assets will be pre-labeled.

To programmatically import brush traces, you can use the [import\_labels](https://docs.imerit.net/sdk/sdk-documentation/project-level-sdk-functions/import_labels) function available in our SDK.
