Identify black dots on lemon

Question:

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

Asked By: Dor

||

Answers:

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

Answered By: joan capell

I was able to detect the dark spots, but the spots that were close to the edges were not detectable. Can anyone help me?enter image description here

Here is the code I use:

def detect_black_spots(img):
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) #Chuyển đổi một hình ảnh từ không gian màu BGR (Blue, Green, Red) sang không gian màu xám (grayscale).
binary_img = cv2.adaptiveThreshold(gray_img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
                                cv2.THRESH_BINARY_INV, 101, 6.5)
_, _, boxes, _ = cv2.connectedComponentsWithStats(binary_img)
#plotImg(binary_img)
# Hộp đầu tiên là nền
boxes = boxes[1:]
filtered_boxes = []
for x,y,w,h,pixels in boxes:
    if pixels < 10000 and h < 200 and w < 200 and h > 2 and w > 2:
        filtered_boxes.append((x,y,w,h))
        #cv2.rectangle(img, (x,y), (x+w,y+h), (0,0,255),2)
        #plotImg(img)
if len(filtered_boxes) > 0:
    return True
return False
Answered By: Thư Trần
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.