Option 1:
You need to place different threshold values but the same binary operation. Then try subtracting the result:
ret, thresh1 = cv2.threshold(img_grey,20,255,cv2.THRESH_BINARY)
ret, thresh2 = cv2.threshold(img_grey,235,255,cv2.THRESH_BINARY)
result = thresh1 - thresh2
cv2.imshow("Result", result)
cv2.waitKey(0)
See the images of thresh1 and thresh2 to understand what's going on.
And if you are worried about how to subtract use cv2.subtract(), it handles pixel range:
result2 = cv2.subtract(thresh1, thresh2)
cv2.imshow("Result2", result2)
cv2.waitKey(0)
The output does not provide the desired result.
Option 2:
You can also use multi-Otsu threshold module available from skimage. This module provides threshold values based on the number of regions you want to segment the image.
- If you want to segment the image into 3 regions (A, B, C), the function gives you 2 threshold values (t1, t2).
- 0 - t1
--> region A
- t1 - t2
--> region B
- t2 - 255
--> region C
The same can be extended for any number of regions, but the function takes more time to calculate threshold values for regions greater than 5.
Number of Threshold values = Number of regions - 1
Code:
# import the module
from skimage.filters import threshold_multiotsu
im = cv2.imread('cells.png', 0)
# create black screen of same image shape
b = np.zeros(im.shape, np.uint8)
# find threshold values for 3 regions
thresholds = threshold_multiotsu(im,3)
print(thresholds)
>>> [ 65 189] # 2 threshold values
# finding average value
mean = int(np.mean(thresholds))
b[im == mean] = 255

Option 2 would be a more statistical way of determining threshold value for any image