Opencv – How to get threshold value from histogram

computer visionimage processingopencv

I'm writing an Android app in OpenCV to detect blobs. One task is to threshold the image to differentiate the foreground objects from the background (see image).

It works fine as long as the image is known and I can manually pass a threshold value to threshold()–in this particular image say, 200. But assuming that the image is not known with the only knowledge that there would be a dark solid background and lighter foreground objects how can I dynamically figure out the threshold value?

I've come across the histogram where I can compute the intensity distribution of the grayscale image. But I couldn't find a method to analyze the histogram and choose the value where the objects of interest (lighter) lies. That is; I want to differ the obviously dark background spikes from the lighter foreground spikes–in this case above 200, but in another case could be say, 100 if the objects are grayish.

enter image description here

Best Answer

If all your images are like this, or can be brought to this style, i think cv2.THRESHOLD_OTSU, ie otsu's tresholding algorithm is a good shot.

Below is a sample using Python in command terminal :

>>> import cv2
>>> import numpy as np
>>> img2 = cv2.imread('D:\Abid_Rahman_K\work_space\sofeggs.jpg',0)

>>> ret,thresh = cv2.threshold(img2,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)

>>> ret
122.0

ret is the threshold value which is automatically calculated. We just pass '0' as threshold value for this.

I got 124 in GIMP ( which is comparable to result we got). And it also removes the noise. See result below:

enter image description here