I have written the following code in order to detect the blobs based on their HSV values, everything works fine, except that when the two blobs intersect(touch) the are detected as one instead of two. I have read here that this can be solved, by using 4-neighborhood and morphological filtering operations, while I have not succeeded in implementing that in my code, I have tried erode operation, but that did not help because I had to combine it with dilate, and they are opposite operations no result was achieved, If I keep only erode all the blobs will be removed and the result will be a black image
The ones on the left are combined as one blob, and I want to separate them, so that I have 7 blobs instead of 6.
import cv2
import numpy as np
img = cv2.imread('./lemon.png')
hsv_img = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
fruit_mask = cv2.inRange(hsv_img, *hsv_bounds[plant_name])
fruit_mask = cv2.cvtColor(fruit_mask, cv2.COLOR_GRAY2BGR)
result = cv2.bitwise_and(img, fruit_mask)
counter = {}
counter['lemon'] = 0
image_gray = cv2.cvtColor(result, cv2.COLOR_BGR2GRAY)
image_gray = cv2.GaussianBlur(image_gray, (5, 5), 0)
image_edged = cv2.Canny(image_gray, 50, 100)
# kernel = np.ones((4, 4), np.uint8)
image_edged = cv2.dilate(image_edged, None, iterations=1)
# kernel = np.ones((4, 4), np.uint8)
image_edged = cv2.erode(image_edged, None, iterations=1)
cnts = cv2.findContours(
image_edged.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0]
for c in cnts:
if cv2.contourArea(c) < 200:
continue
hull = cv2.convexHull(c)
img_mask = cv2.drawContours(result, [hull], 0, (0, 0, 255), 1)
counter['lemon'] += 1
print(counter)
cv2.imwrite('./blob_testing/detected_55.png', img_mask)
Update:
Thanks to the comments, I understood my mistake, and I have added the erode to the drawn contours (not the canny edges), and that fixed the problem, and the result look like that:
I still need to draw the red contours around the blobs so that I can count them


Why don't do your process on binary mask image?
Perhaps
fruit_mask = cv2.inRange(hsv_img, *hsv_bounds[plant_name])is the mask. If so, apply morophology(dilate, erode) to this mask to remove noise and separate blobs. Then,findContourson the moropholygy result.If the result is good(of course you can filter them further (e.g. based on area, shape, etc).), you can count contours, or draw contours on your input image if needed.