Calculate True Positive, False Positive, True Negative and False negative and colourize output Objective : Calculate True Positive, False Positive, True Negative and False negative and colourize the image accordignly, based on ground-truth and prediction from my classifier model.

Problem : Very Slow 

Description: 

The prediction is a gray-level image that comes from my classifier. 

The truth_image is also a gray-level image, but its the correct image that prediction should try to approximate.

The mask_image segmentates the ROI ( region of interest), when its pixel value is 1, means its inside the region of interest, if its 0, then we should ignore and move on to the next pixel.

The output is the array where I want to keep the colourized image.

def coloured_prediction_truth(prediction, truth_image, mask_image,output_image):
    prediction = prediction.astype(np.uint8)
    truth_image = truth_image.astype(np.uint8)
    #output_image = np.empty(shape=(submission_image.shape[0], submission_image.shape[1], 4), dtype=np.uint8)

    #binarize values , values &gt; 127 becomes 1. Else -&gt; 0
    for i in xrange(0, prediction.shape[0]):
        for j in xrange(0, prediction.shape[1]):
            if prediction[i, j] &gt; 127:
                prediction[i, j] = 1
            else:
                prediction[i, j] = 0

    for i in xrange(0, truth_image.shape[0]):
        for j in xrange(0, truth_image.shape[1]):
            if truth_image[i, j] &gt; 127:
                truth_image[i, j] = 1
            else:
                truth_image[i, j] = 0

    for i in xrange(0, mask_image.shape[0]):
        for j in xrange(0, mask_image.shape[1]):
            if mask_image[i, j] &gt; 127:
                mask_image[i, j] = 1
            else:
                mask_image[i, j] = 0



    # B-G-R-A
    blue = [255, 0, 0, 255]
    green = [0, 255, 0, 255]
    red = [0, 0, 255, 255]
    orange = [0, 128, 255, 255]
    black = [0, 0, 0, 255]

    TruePositive = 0.00
    TrueNegative = 0.00
    FalsePositive = 0.00
    FalseNegative = 0.00

    #Count pixel by pixel
    for i in xrange(0, output_image.shape[0]):
        for j in xrange(0, output_image.shape[1]):

            pred = prediction[i, j]
            truth = truth_image[i, j]
            mask = mask_image[i, j]

            if mask == 1:

                if pred == 1 and truth == 1:
                    output_image[i, j] = blue
                    TruePositive = TruePositive + 1
                else:
                    if pred == 0 and truth == 0:
                        output_image[i, j] = green
                        TrueNegative = TrueNegative + 1
                    else:
                        if pred == 0 and truth == 1:
                            output_image[i, j] = red
                            FalseNegative = FalseNegative + 1
                        else:
                            if pred == 1 and truth == 0:
                                output_image[i, j] = orange
                                FalsePositive = FalsePositive + 1
                            else:
                                output_image[i, j] = black
            else:
                output_image[i, j] = black

    accuracy = float((TruePositive + TrueNegative)) / float((TruePositive + FalsePositive + FalseNegative + TrueNegative))
    sensitivity = float((TruePositive)) / float((TruePositive + FalseNegative))
    specificity = float((TrueNegative)) / float((TrueNegative + FalsePositive))
    try:
        positivePredictiveValue = float((TruePositive)) / float((TruePositive + FalsePositive))
    except Exception:
        positivePredictiveValue = 0

    return output_image, TruePositive, TrueNegative, FalsePositive, FalseNegative, accuracy, sensitivity, specificity, positivePredictiveValue


Example :



From these 3 images, the coloured image, would be:
Don't use manual iteration. It's slow and tedious. Use broadcasting instead. 

For instance, you can create a true positives mask like this:

true_positive_mask = np.logical_and(prediction &gt; 127, truth_image &gt; 127)

After that, you can use this mask to index the output image:

output_image[true_positive_mask] = green # or whatever color you want

and to compute the total number of true positives:

true_positives = np.sum(true_positive_mask)

You can use the same idea to compute other values or for input binarization.