I think you can do your thresholding using Otsu method. You can apply it on your whole image or on the blocks of the image. I did the following steps:
- thresholding using
Otsu
method on desired input. Closing
the result.
Python Code
image = cv2.imread('image4.png', cv2.IMREAD_GRAYSCALE) # reading image
if image is None:
print 'Can not find the image!'
exit(-1)
# thresholding image using ostu method
ret, thresh = cv2.threshold(image, 0, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)
# applying closing operation using ellipse kernel
N = 3
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (N, N))
thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)
# showing the result
cv2.imshow('thresh', thresh)
cv2.waitKey(0)
cv2.destroyAllWindows()
Explanation
In the first part I read the input image using imread
and checked that the image opened correctly!.
image = cv2.imread('image4.png', cv2.IMREAD_GRAYSCALE) # reading image
if image is None:
print 'Can not find the image!'
exit(-1)
Now thresholding the image with otsu
method by feeding the thresh
method with THRESH_BINARY_INV | THRESH_OTSU
as its argument. The otsu
method works base on an optimization problem finding the best value for thresholding. So I provided the range of possible value for the threshold value by giving it a lower bound by 0
and an upper bound by 255
.
ret, thresh = cv2.threshold(image, 0, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)
And a closing operation is done for removing black holes in the image using an Ellipse
kernel.
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (N, N))
thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)
Result