Extracting masks generated by freehand pen tool


Ive labelled some images using the pen tool. When exporting the data I only have the option to export a json file which contains URL links to the masks. I couldnt find an exporter within the documentation which extracted these masks and saved them locally so I wrote my own by modifying the available exporters. However when exporting the mask from the link they always appear blank (all white). This simplified gist shows how I extract masks.

I am able to extract the raw images fine and the mask images display fine from the URL link within a webrowser but will not download manually from this (e.g.

Does anyone know what I might be doing wrong or an alternative way to export masks generated by the pen tool?

Thank you

Hi Jeremy, that’s correct- in segmentation, the exported file contains URLs to the mask PNGs. Try this script, which parses your export (there are both JSON and CSV parsing methods) for the masks and downloads them into your machine’s local Downloads folder.

# make sure that the exported JSON file and this script are in the same directory
# replace filename with appropriate
from PIL import Image
import requests, urllib, json, os, csv, sys
from urllib.request import urlopen

# for extracting masks from JSON exports
def parseJSON(filename):
    with open(filename) as file:
        data = file.read()
        # we use json loads to be able to parse data
        decoded_data = json.loads(data)
        # res := list containing all instanceURIs
        res = []
        num_labels = len(decoded_data)
        for i in range(num_labels):
            object_data = decoded_data[i]['Label']['objects']

            for j in range(len(object_data)):

        return res

# for extracting masks from CSV exports
def parseCSV(filename):
    mask_list = []

    with open(filename, 'r') as file:
        readCSV = csv.reader(file, delimiter=',')
        for row in readCSV:
            # mask URLs are stored in column 17
            tokenized = row[17].split(":")
            if len(tokenized) == 3:
                mask_URL = tokenized[1] + ":" + tokenized[2][:-1]
    return mask_list

# opens all exported data images. use with caution
def readAllImageData(image_data):
    for url in image_data:
        response = requests.get(url)
        img = Image.open(urlopen(url))

def downloadData(url_list):
    # creating a LabelboxData folder in user's local machine's download directory
    download_path = os.path.expanduser("~") + "/Downloads/LabelboxData/"
    if not os.path.exists(download_path):

    print("Beginning download for Labelbox exported data...")

    for i in range(len(url_list)):
        # generating unique image names
        # Format: LabelID_Class_mask1.jpg
        file_name = download_path + url_list[i][0] + "_" + url_list[i][1] + "_mask" + str(i) + ".png"
        urllib.request.urlretrieve(url_list[i], file_name)

if __name__ == '__main__':
    # to run: python3 download_masks.py <FILENAME>

    exported_data = parseJSON(sys.argv[1])
    # exported_data = parseCSV(sys.argv[1])

Hi Clarice

Great, thank you very much for the response and the script.