Search code examples
deep-learningcomputer-visionimage-segmentationscikit-imageimage-morphology

How to check if the labelled regions are the same in two images?


So the idea is to write a precision and recall metric for segmentation task. The usual metrics for segmentation tasks calculate this metric by comparing the ground truth and prediction masks pixelwise. The way I want to calculate is that even if some part of the object in ground truth is predicted, then the whole object os considered as true positive.

The way I am currently approaching the problem is I am calculating logical and of the ground truth and predicted masks. Then using skimage.measure.label to assign a unique id to each blob. Then I calculate True Positives, False Negatives etc. by using the number of blobs in both

and_mask = np.logical_and(gt, pred)
labels1 = measure.label(gt, neighbors=8, background=0)
labels2 = measure.label(and_mask, neighbors=8, background=0)

This works for most cases but in the case where my predicted mask for a blob is predicted in two parts, then performing logical_and on it gives me an extra object. This screws up my calculation of metrics.

Is there a way to prevent this and also, is there a simpler way of doing this?


Solution

  • I managed to solve it. I used measure.label to get the individual masks and then computed the iou with the gt masks. That's what I wanted to

        labels1 = measure.label(gt, neighbors=8, background=0)
            # loop over the unique components
            for label in np.unique(labels1):
                # if this is the background label, ignore it
                if label == 0:
                    continue
                # otherwise, construct the label mask 
                labelMask1 = np.zeros(pred.shape, dtype="uint8")
                labelMask1[labels1 == label] = 255
                c, counts1 = np.unique(np.logical_and(labelMask1, pred, 
                 where=255), return_counts=True)
                inter = np.sum(np.logical_and(labelMask1, pred, where=255)) / 
                np.sum(np.logical_or(labelMask1, pred, where=255))
    

    Here's the rough algorithm if anyone's interested.