我编写了以下代码,以便根据斑点的
HSV
值检测斑点,一切正常,除了当两个斑点相交(触摸)时,它们被检测为一个而不是两个。我已经读到here,这可以通过使用4-neighborhood
和形态过滤操作来解决,虽然我没有在我的代码中成功实现这一点,但我尝试过erode
操作,但这没有帮助,因为我必须将它与 dilate
结合起来,它们是相反的操作,没有达到任何结果,如果我只保留 erode
,所有斑点都将被删除,结果将是黑色图像
左边的那些组合成一个斑点,我想将它们分开,这样我就有 7 个斑点而不是 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)
更新: 感谢这些评论,我理解了我的错误,并且我已将
erode
添加到绘制的轮廓(而不是精明的边缘),这解决了问题,结果如下所示:
我仍然需要在斑点周围绘制红色轮廓,以便我可以计算它们
为什么不在二值掩模图像上进行处理?
也许
fruit_mask = cv2.inRange(hsv_img, *hsv_bounds[plant_name])
就是面具。
如果是这样,请对此蒙版应用形态学(扩张、侵蚀)以消除噪声并分离斑点。
然后,findContours
关于形态分析结果。
如果结果良好,您可以计算轮廓,或者根据需要在输入图像上绘制轮廓。