pythonopencvimage-processingimage-thresholding

How Can I A Threshold Image of a Salience Map?


I currently have the salience map of an image below, the spectral saliency and fine grained saliency images are below obtained by the following code:

import cv2

imgpath = r'Content Image.jpg'
image = cv2.imread(imgpath)

width = 350
height = 450
dim = (width, height)
 
# resize image
resized = cv2.resize(image, dim, interpolation = cv2.INTER_AREA)

saliency = cv2.saliency.StaticSaliencySpectralResidual_create()
(success, saliencyMap) = saliency.computeSaliency(resized)
saliencyMap = (saliencyMap * 255).astype("uint8")
cv2.imshow("Image", resized)
cv2.imshow("Output", saliencyMap)
cv2.waitKey(0)
cv2.destroyAllWindows()

saliency = cv2.saliency.StaticSaliencyFineGrained_create()
(success, saliencyMap) = saliency.computeSaliency(resized)

enter image description here

enter image description here

enter image description here

All of these make sense and I understand why they were obtained.

However, when I try to get the threshold map using the code below:

ret, threshMap = cv2.threshold(saliencyMap.astype("uint8"), 120, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
cv2.imshow("Image", resized)
cv2.imshow("Output", saliencyMap)
cv2.imshow("Thresh", threshMap)
cv2.waitKey(0)

I obtain the following image:

enter image description here

Not quite sure why this is the case since I'm pretty sure I've following everything that I have found online, any help is greatly appreciated.


Solution

  • saliencyMap has values between 0 and 1. You need to rescale the values to 0-255 range. Then, decide if you want otsu threshold or manual threshold. The given value 120 has no effect on Otsu binarization method as itself automatically determines the threshold value.

    ret, threshMap = cv2.threshold((saliencyMap * 255).astype('uint8'), 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
    cv2.imshow("Image", resized)
    cv2.imshow("Output", saliencyMap)
    cv2.imshow("Thresh", threshMap)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    output Otsu binarization:

    otsu thresholded

    Or manual value 120 input for threshold

    ret, threshMap = cv2.threshold((saliencyMap * 255).astype('uint8'), 120, 255, cv2.THRESH_BINARY)
    

    Manual 120 value threshold