0

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.

Nhyi
  • 373
  • 1
  • 12

1 Answers1

2

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

NONONONONO
  • 612
  • 1
  • 6
  • 10
  • This is exactly what I was looking for. One thing I haven't quite got my head around is how can I use otsu thresholding? What benefit does it have over manual thresholding? – Nhyi Jul 17 '21 at 20:37
  • 1
    yes you can check the opencv website. `Since we are working with bimodal images, Otsu's algorithm tries to find a threshold value (t) which minimizes the weighted within-class variance given by the relation:` So with Otsu you don't have to put in any thresholding value. From the histogram chart of values, in layman terms, it detects value that causes the least variance in image if chosen. It works pretty well for most images depending on your use case of course. – NONONONONO Jul 17 '21 at 20:41
  • This is awesome and I definitely value not needing to put in a threshold value to check and keep on iterating through until I get a "good" picture. – Nhyi Jul 18 '21 at 01:09