inner holes in segmentation polygons -coco dataset

985 views Asked by At

So to explain the problem I have a dataset with the coco format I want to reconstruct the binary mask from the segmentation information stored in the annotation json file

here is the target mask

in here it is the reconstructed mask

As you can see the inside hole is messing in the reconstructed mask

the mask was reconstructed using the following code

from pycocotools import mask as maskUtils
def annToRLE( ann, height, width):
        """
        Convert annotation which can be polygons, uncompressed RLE to RLE.
        :return: binary mask (numpy 2D array)
        """
        segm = ann['segmentation']
        if isinstance(segm, list):
            # polygon -- a single object might consist of multiple parts
            # we merge all parts into one mask rle code
            rles = maskUtils.frPyObjects(segm, height, width)
            rle = maskUtils.merge(rles)
        elif isinstance(segm['counts'], list):
            # uncompressed RLE
            rle = maskUtils.frPyObjects(segm, height, width)
        else:
            # rle
            rle = ann['segmentation']
        return rle

def annToMask( ann, height, width):
    """
    Convert annotation which can be polygons, uncompressed RLE, or RLE to binary mask.
    :return: binary mask (numpy 2D array)
    """
    rle = annToRLE(ann, height, width)
    m = maskUtils.decode(rle)
    return m

is there a way to keep the inside hole?

1

There are 1 answers

0
hakim47 On

Well the solution I found is to delete the line

rle = maskUtils.merge(rles)

change variable name

rles = maskUtils.frPyObjects(segm, height, width)

to

rle = maskUtils.frPyObjects(segm, height, width)

this is inside the function annToRLE

and after you call annToMask

m = annToMask(sets,width,hight)

we check if there is multiple masks, add the masks into one mask, overlays between masks will be expressed as value greater than 2, so we set these values to zero

if m.ndim >= 2:
                  reduced=np.add.reduce(m,axis=2)
                  m = np.where(reduced>=2,0,reduced)