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