pythonopencvthreshold

Identify black dots on lemon


I'm trying to identify black dots on a lemon I've had several attempts. I have problem of differentiating black shadows with the actual black stains on the lemon.

I've tried to use InRange and converting the image to HSV with no success and honestly I'm quite lost and would appreciate some new ideas to identify the black stains.

Here's my code:

import cv2
import matplotlib.pyplot as plt
import numpy as np

img = cv2.imread("./data/lemon1big.jpg")
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray,150,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)

plt.imshow(thresh)

Result:

Original Image

Grayscale

Threshold

These are the stains I want to detect - There are 12 stains I detected:

Result


Solution

  • I reccommend to use adaptative threshold instead of otsu because the black background messes up the threshold calculation that otsu does, then you can obtain the black dots using connected components analysis and filtering by size, here the code:

    import cv2
    import matplotlib.pyplot as plt
    
    def plotImg(img):
        if len(img.shape) == 2:
            plt.imshow(img, cmap='gray')
            plt.show()
        else:
            plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
            plt.show()
    
    img = cv2.imread('lemon.png')
    gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    binary_img = cv2.adaptiveThreshold(gray_img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
                                       cv2.THRESH_BINARY_INV, 131, 15)
    plotImg(binary_img)
    _, _, boxes, _ = cv2.connectedComponentsWithStats(binary_img)
    # first box is the background
    boxes = boxes[1:]
    filtered_boxes = []
    for x,y,w,h,pixels in boxes:
        if pixels < 10000 and h < 200 and w < 200 and h > 10 and w > 10:
            filtered_boxes.append((x,y,w,h))
    
    for x,y,w,h in filtered_boxes:
        cv2.rectangle(img, (x,y), (x+w,y+h), (0,0,255),2)
    
    plotImg(img)
    

    binary image

    image recognized