How to change the order and assignment of the mask labels?

I used supervise.ly tool to manually create masks. However, the order and assignment of mask labels are not consistent across images. Is it possible to redefine the order and assignment of them?

Note: If this problem needs mask label annotations you can download them from here.

Input- 1

Order
[0 3 4 5 6 7 8]

Assignment
0 - unlabeled
3 - left_psoas
4 - right_psoas
5 - left_erector
6 - right_erector
7 - left_rectus
8 - right_rectus

Input-2

Order
[0 3 4 5 6 7 8]

Assignment
0 - unlabeled
3 - left_rectus
4 - right_rectus
5 - left_psoas
6 - right_psoas
7 - left_erector
8 - right_erector

I want something like this

output-1

Order
[0 1, 2, 3, 4, 5, 6]

Assignment
0 - unlabeled
1 - left_psoas
2 - right_psoas
3 - left_erector
4 - right_erector
5 - left_rectus
6 - right_rectus

output-2

Order
[0 1, 2, 3, 4, 5, 6]

Assignment
0 - unlabeled
1 - left_psoas
2 - right_psoas
3 - left_erector
4 - right_erector
5 - left_rectus
6 - right_rectus

Reproducible_example

Input-1

numpy.set_printoptions(threshold=sys.maxsize)

#IM-0010-0007 - Rectus, Psoas

mask = Image.open(urlopen('https://user-images.githubusercontent.com/3885659/78283975-27721000-750e-11ea-8c0b-57d682c45f18.png'))
#plt.imshow(mask)
array = np.array(mask)
#print('Array Dimensions', array.shape)
new_array = [tuple(row) for row in array]
uniques = np.unique(new_array)
print(uniques)

#IM-0010-0010 - Rectus, Psoas, Erector

mask = Image.open(urlopen('https://user-images.githubusercontent.com/3885659/78284008-38228600-750e-11ea-95cc-0e71c1c90ade.png'))
array = np.array(mask)
new_array = [tuple(row) for row in array]
uniques = np.unique(new_array)
print(uniques)

#IM-0010-0011 - Rectus, Erector

mask = Image.open(urlopen('https://user-images.githubusercontent.com/3885659/78284035-453f7500-750e-11ea-8439-d26b9168c805.png'))
array = np.array(mask)
new_array = [tuple(row) for row in array]
uniques = np.unique(new_array)
print(uniques)

Input-2


numpy.set_printoptions(threshold=sys.maxsize)

# IM-0010-0005 - Rectus

mask = Image.open(urlopen('https://user-images.githubusercontent.com/3885659/78290155-cef14180-7512-11ea-96f4-c7f0ad9566b4.png'))
array = np.array(mask)
new_array = [tuple(row) for row in array]
uniques = np.unique(new_array)
print(uniques)

# IM-0010-0006 - Rectus, Psoas

mask = Image.open(urlopen('https://user-images.githubusercontent.com/3885659/78290189-dd3f5d80-7512-11ea-9eab-d0f861c5bf16.png'))
array = np.array(mask)
new_array = [tuple(row) for row in array]
uniques = np.unique(new_array)
print(uniques)

# IM-0010-0008 - Rectus, Psoas, Erector

mask = Image.open(urlopen('https://user-images.githubusercontent.com/3885659/78290216-eb8d7980-7512-11ea-9b17-1f1c1c170886.png'))
array = np.array(mask)
new_array = [tuple(row) for row in array]
uniques = np.unique(new_array)
print(uniques)

Unfortunetely, I haven’t used supervisely yet, but this seems to be a common problem so that I would assume you can create “empty” classes when labeling the images.
Do you have the index-to-class mapping for each image?
If so, you could manually postprocess the indices using a fixed order of all class names.

1 Like

Yes I have the index-to-class mappings. I have thousands of images but I would give it a go.

This worked for me. Thank you for the tip. @ptrblck

import sys
import os
from PIL import Image
import numpy as np


mask_dir = "input/"
new_mask_dir = "output/"
if not os.path.exists(new_mask_dir):
    os.mkdir(new_mask_dir)

for filename in os.scandir(mask_dir):
    if filename.path.endswith(".png"):
        image = Image.open(filename.path)
        mask = np.array(image)
        mask[mask==3] = 50, #Right_Rectus
        mask[mask==4] = 51, #Left_Rectus
        mask[mask==5] = 52, #Right_Psoas
        mask[mask==6] = 53, #Left_Psoas
        mask[mask==7] = 54, #Right_Erector
        mask[mask==8] = 55, #Left_Erector
        mask[mask<50] = 0,  #unlabeled
        mask[mask==50] = 1, #Right_Rectus
        mask[mask==51] = 2, #Left_Rectus
        mask[mask==52] = 3, #Right_Psoas
        mask[mask==53] = 4, #Left_Psoas
        mask[mask==54] = 5, #Right_Erector
        mask[mask==55] = 6  #Left_Erector
        
        masked_img = Image.fromarray(mask)
        new_img_path = os.path.join(new_mask_dir, filename.name)
        masked_img.save(new_img_path)