Home > Mobile >  Trouble getting accurate binary image OpenCV
Trouble getting accurate binary image OpenCV

Time:06-28

Using the threshold functions in open CV on an image to get a binary image, with Otsu's thresholding I get a image that has white spots due to different lighting conditions in parts of the imageenter image description here

or with adaptive threshold to fix the lighting conditions, it fails to accurately represent the pencil-filled bubbles that Otsu actually can represent.

enter image description here

How can I get both the filled bubbles represented and a fixed lighting conditions without patches? Here's the original image enter image description here

Here is my code

    #binary image conversion
    thresh2 = cv2.adaptiveThreshold(papergray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY_INV, 21, 13)
    thresh = cv2.threshold(papergray, 0, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1]

    cv2.imshow("Binary", thresh) #Otsu's
    cv2.imshow("Adpative",thresh2)

CodePudding user response:

Problems with your approach:

The methods you have tried out:

  1. Otsu threshold is decided based on all the pixel values in the entire image (global technique). If you look at the bottom-left of your image, there is a gray shade which can have an adverse effect in deciding the threshold value.
  2. Adaptive threshold: enter image description here

    Links:

    1. To know more about enter image description here

      CodePudding user response:

      An alternative approach would be to apply a morphological closing, which would remove all the drawing, yielding an estimate of the illumination level. Dividing the image by the illumination level gives you an image of the sheet corrected for illumination:

      corrected for illumination

      In this image we can easily apply a global threshold:

      thresholded

      I used the following code:

      import diplib as dip
      
      img = dip.ImageRead('tlCw6.jpg')(1)
      corrected = img / dip.Closing(img, dip.SE(40, 'rectangular'))
      out = dip.Threshold(corrected, method='triangle')[0]
      
  • Related