How To : Uniform Color for All Mask Instances of a Label in Composite Mask URLs

Hi Labelbox Community,

I hope you’re all doing well! We have noticed that some users are encountering an issue where multiple annotations under the same label have different colors in the exported masks. Although this is to show uniqueness among instances, this can cause problems when importing these masks into other systems that expect a single color per label.

To help resolve this issue, we’ve created a script that ensures all annotations under the same label have the same color in the generated masks. This script leverages the Labelbox API and processes the mask images to unify the colors.

Solution

We can solve this issue by processing the exported masks and recoloring all annotations of the same label to a consistent color. Below is a simple script to achieve this focusing Image type.

Step-by-Step Guide

Step 1: Set Up the Environment

First, install Labelbox and import the necessary libraries:

import labelbox as lb
import urllib.request
from PIL import Image
import json
import numpy as np

Step 2: Authenticate with Labelbox

API_KEY = "" #Insert your API Key

client = lb.Client(api_key=API_KEY)

Step 3: Define Export Parameters and Fetch Mask URLs

PROJECT_ID = "" #Insert Project ID

project_image = client.get_project(PROJECT_ID)

export_params= {
  "attachments": True,
  "metadata_fields": True,
  "data_row_details": True,
  "project_details": True,
  "label_details": True,
  "performance_details": True,
  "interpolated_frames": True
}

filters= {}

export_task = project_image.export_v2(params=export_params, filters=filters)
export_task.wait_till_done()
result = export_task.result

composite_mask_data = []
for data in result:
    for label in data['projects'][PROJECT_ID]['labels']:
        label_id = label['id']
        for obj in label['annotations']['objects']:
            mask_url = obj['composite_mask']['url']
            composite_mask_data.append((mask_url, label_id))

# Print composite mask data for verification
print(composite_mask_data)

Step 4: Fetch, Modify, and Save the Composite Mask

def fetch_and_recolor_mask(mask_url, target_color=[200, 162, 200, 255]):
    # Fetch the mask image
    req = urllib.request.Request(mask_url, headers=client.headers)
    image = Image.open(urllib.request.urlopen(req))

    # Convert the image to a numpy array
    mask_array = np.array(image)

    # Define the background color (assuming white)
    background_color = [0, 0, 0, 0]

    # Create a boolean mask where the background is True
    background_mask = np.all(mask_array == background_color, axis=-1)

    # Recolor the mask by setting all non-background pixels to the target color
    mask_array[~background_mask] = target_color

    # Convert the modified array back to an image
    modified_image = Image.fromarray(mask_array)

    return modified_image

# Process each composite mask URL and save the modified image
for mask_url, label_id in composite_mask_data:
    modified_image = fetch_and_recolor_mask(mask_url)

    # Save the modified mask
    modified_image.save(f'modified_{label_id}.png')```


Conclusion
This script ensures all annotations under the same label have the same color, making it easier to integrate with external systems requiring uniform colors for each label.

Feel free to reach out if you have any questions or run into any issues!

Reference :green_book: Export image annotations

Best Regards,
Sravani

1 Like

Nice solution, but the problem I am facing is that my cp mask has multiple objects, and all masks have unique mask color for the same object, so I want a way to have consistent color for an object in all of the mask images rather than having same color for all masks in an image.