Python 使用opencv检测和计数水滴/连接对象

Python 使用opencv检测和计数水滴/连接对象,python,opencv,Python,Opencv,我想检测和计算图像中的物体,这些物体相互接触,而忽略可以被视为单个物体的物体。我有一个基本的图像,我尝试在上面应用cv2.houghcirles()方法来尝试识别一些圆。然后我解析返回的数组,并尝试使用cv2.circle()在图像上绘制它们 然而,我似乎总是得到太多由cv2.HoughCircles()返回的圆,并且不知道如何只计算接触的对象 到目前为止,我的代码是: import numpy import matplotlib.pyplot as pyp import cv2 segme

我想检测和计算图像中的物体,这些物体相互接触,而忽略可以被视为单个物体的物体。我有一个基本的图像,我尝试在上面应用
cv2.houghcirles()
方法来尝试识别一些圆。然后我解析返回的数组,并尝试使用
cv2.circle()
在图像上绘制它们

然而,我似乎总是得到太多由
cv2.HoughCircles()
返回的圆,并且不知道如何只计算接触的对象

到目前为止,我的代码是:

import numpy
import matplotlib.pyplot as pyp
import cv2

segmentet = cv2.imread('photo')
houghCircles = cv2.HoughCircles(segmented, cv2.HOUGH_GRADIENT, 1, 80, param1=450, param2=10, minRadius=30, maxRadius=200)
houghArray = numpy.uint16(houghCircles)[0,:]

for circle in houghArray:
    cv2.circle(segmented, (circle[0], circle[1]), circle[2], (0, 250, 0), 3)

如何正确识别和计数所述物体?

逐步接近

为连接的组件添加标签。两个连接的blob具有相同的标签,因为它们是连接的。到目前为止还不错

现在分开你的斑点。使用分水岭(第一个注释)或任何其他方法获得结果。我不能完全预测分水岭方法。它可能处理触摸大小不同的斑点,也可能做一些愚蠢的事情。样本/教程还假设最小尺寸(0.7*最大峰值);插入一些绝对像素的东西

然后,对于每个分离的blob,检查它位于哪个标签上(取质心坐标以确保安全),并记下该标签的a+1(直方图)


任何一个标签上有多个分离的斑点,都是您要寻找的。在Python OpenCV中,有一种方法是获取轮廓区域和轮廓的凸包区域。取比例(面积/凸包面积)。如果足够小,那么它就是一簇水滴。否则它就是一个孤立的斑点

输入:



可能会有帮助。@bicker如果我的理解是正确的,这个例子将找到正在接触的对象,并将它们分成单独的圆圈。我想要的是找到接触的对象并对它们进行标记/计数,同时忽略那些分开的对象。找到所有区域的所有轮廓。然后测试轮廓面积与凸包面积之比。如果比率接近1,则它是单个对象。如果过低,则是多个触摸对象。再见,非常感谢!完美地工作
import cv2
import numpy as np

# read input image
img = cv2.imread('blobs_connected.jpg')

# convert to grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# threshold to binary
thresh = cv2.threshold(gray, 128, 255, cv2.THRESH_BINARY)[1]

# find contours
#label_img = img.copy()
contour_img = img.copy()
contours = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours = contours[0] if len(contours) == 2 else contours[1]
index = 1
isolated_count = 0
cluster_count = 0
for cntr in contours:
    area = cv2.contourArea(cntr)
    convex_hull = cv2.convexHull(cntr)
    convex_hull_area = cv2.contourArea(convex_hull)
    ratio = area / convex_hull_area
    #print(index, area, convex_hull_area, ratio)
    #x,y,w,h = cv2.boundingRect(cntr)
    #cv2.putText(label_img, str(index), (x,y), cv2.FONT_HERSHEY_COMPLEX_SMALL, 1, (0,0,255), 2)
    if ratio < 0.91:
        # cluster contours in red
        cv2.drawContours(contour_img, [cntr], 0, (0,0,255), 2)
        cluster_count = cluster_count + 1
    else:
        # isolated contours in green
        cv2.drawContours(contour_img, [cntr], 0, (0,255,0), 2)
        isolated_count = isolated_count + 1
    index = index + 1
    
print('number_clusters:',cluster_count)
print('number_isolated:',isolated_count)

# save result
cv2.imwrite("blobs_connected_result.jpg", contour_img)

# show images
cv2.imshow("thresh", thresh)
#cv2.imshow("label_img", label_img)
cv2.imshow("contour_img", contour_img)
cv2.waitKey(0)
number_clusters: 4
number_isolated: 81