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:
These are the stains I want to detect - There are 12 stains I detected:
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)