pythonazuresemantic-segmentationstring-decodingrle

RLE -> Mask for semantic segmentation | Azure Semantic Segmentation (Preview)


I used Azure Data Labelling to prepare my Semantic Segmentation (Preview) Dataset and export it from Azure into my Local System. Now I have images in images folder and Labels in Json file.

I'm trying to decode my RLE string to draw a mask on the image, but it always draws a vertical line at the top right corner. I used the code below, but it seems like it was unable to decode the RLE correctly

RLE String in Json File = '{"rle":[121256,0,3,1,715,0,6,1,712,0,8,1,712,0,8,1,712,0,9,1,711,0,12,1,708,0,19,1,702,0,21,1,699,0,23,1,698,0,22,1,699,0,21,1,700,0,20,1,704,0,15,1,675,0,5,1,714,0,6,1,705,0,4,1,4,0,8,1,703,0,18,1,701,0,20,1,699,0,22,1,697,0,24,1,696,0,25,1,694,0,26,1,693,0,27,1,693,0,28,1,692,0,28,1,692,0,29,1,691,0,29,1,690,0,30,1,691,0,30,1,690,0,30,1,690,0,30,1,690,0,30,1,690,0,30,1,690,0,30,1,690,0,31,1,689,0,31,1,689,0,31,1,689,0,30,1,691,0,29,1,691,0,29,1,691,0,28,1,692,0,28,1,693,0,27,1,693,0,27,1,694,0,26,1,695,0,25,1,696,0,23,1,698,0,22,1,700,0,20,1,701,0,19,1,702,0,18,1,704,0,16,1,705,0,15,1,707,0,13,1,708,0,12,1,710,0,10,1,711,0,9,1,713,0,7,1,714,0,6,1,355398,0]}'

import json
import numpy as np
import cv2

# rle_decode function
def rle_decode(rle_list, shape, fill_value=1, dtype=int, relative=False):
    rle_str = ' '.join(map(str, rle_list))
    s = rle_str.strip().split(" ")
    starts, lengths = np.array([np.asarray(x, dtype=int) for x in (s[0:][::2], s[1:][::2])])
    mask = np.zeros(np.prod(shape), dtype=dtype)
    if relative:
        start = 0
        for index, length in zip(starts, lengths):
            start = start + index
            end = start + length
            mask[start:end] = fill_value
            start = end
        return mask.reshape(shape[::-1]).T
    else:
        starts -= 1
        ends = starts + lengths
        for lo, hi in zip(starts, ends):
            mask[lo:hi] = fill_value
        return mask.reshape(shape[::-1]).T

# Read JSON file
with open('downloads/labels/2D82C4F8-F1F2-4042-AE45-C4988A55048A.json', 'r') as f:
    data = json.load(f)

rle_list = data['rle']
shape = (100, 100)  # Assuming the shape is known or provided

# Decode RLE list
mask = rle_decode(rle_list, shape)

# Create a black image
image = np.zeros(shape, dtype=np.uint8)

# Draw the mask on the black image
image[mask == 1] = 255  # White color for mask

# Display the image
cv2.imshow('Mask', image)
cv2.waitKey(0)
cv2.destroyAllWindows()

This is the Output Image I got from the above code: enter image description here

I'm Expecting to have a Correct Segmented mask on the image so I can use for training Segmentation Model


Solution

  • You can use the python-rle · PyPI python package to decode and same is used when export the labeled data.

    Install using below command.

    pip install python-rle
    

    Tried with my sample json file.

    import rle
    import json
    from PIL import Image
    import numpy as np
    
    image_height=600
    image_width=600
    
    with open("mask.json", "r") as rle_json:
            rle_list = json.load(rle_json)["rle"]
    
    counts = rle_list[::2]
    values = rle_list[1::2]
    decoded = rle.decode(values, counts)[:image_height * image_width]
    combined_mask = np.array(decoded).reshape(image_height,image_width)
    
    binary_mask = combined_mask == 1
    binary_image = Image.fromarray(binary_mask)
    binary_image = binary_image.convert('1')
    binary_image
    

    Output:

    enter image description here

    Also with you rle list got below output.

    enter image description here

    Make sure you are giving the correct height and width for correct results.