查找多个连接对象的每个质心

我是 python 编码的超级新手,需要一些帮助。我能够分割生物组织内的每个细胞轮廓(超酷!),现在我正尝试使用以下方法找到组织内每个细胞的质心:

http://img3.mukewang.com/641285710001500806480591.jpg

我正在使用这段代码:


img = cv2.imread('/Users/kate/Desktop/SegmenterTest/SegmentedCells/Seg1.png')

image = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

thresh = cv2.threshold(image, 60, 255, cv2.THRESH_BINARY)[1]


cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

cnts = imutils.grab_contours(cnts)


# loop over the contours

for c in cnts:

    # compute the center of the contour

    M = cv2.moments(c)

    cX = int(M["m10"] / M["m00"])

    cY = int(M["m01"] / M["m00"])

    # draw the contour and center of the shape on the image

    cv2.drawContours(image, [c], -1, (0, 255, 0), 2)

    cv2.circle(image, (cX, cY), 7, (255, 255, 255), -1)

    cv2.putText(image, "center", (cX - 20, cY - 20),

        cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 2)

    # show the image

    cv2.imshow("Image", image)

    cv2.waitKey(0)

但是,当我使用这段代码时,它给出了整个对象的质心,而不是每个单独的对象都给出了这个。

http://img4.mukewang.com/6412857f00011b9f06390549.jpg

我不知道从这里去哪里,所以向正确的方向轻推将不胜感激!



MYYA
浏览 118回答 2
2回答

DIEA

您可以在您的案例中使用模块 scikit-image 中的函数regionprops 。这是我得到的。这是我使用的代码。import cv2import matplotlib.pyplot as pltfrom skimage import measureimport numpy as npcells = cv2.imread('cells.png',0)ret,thresh = cv2.threshold(cells,20,255,cv2.THRESH_BINARY_INV)labels= measure.label(thresh, background=0)bg_label = labels[0,0] labels[labels==bg_label] = 0 # Assign background label to 0props = measure.regionprops(labels)fig,ax = plt.subplots(1,1)plt.axis('off')ax.imshow(cells,cmap='gray')centroids = np.zeros(shape=(len(np.unique(labels)),2)) # Access the coordinates of centroidsfor i,prop in enumerate(props):    my_centroid = prop.centroid    centroids[i,:]= my_centroid    ax.plot(my_centroid[1],my_centroid[0],'r.')# print(centroids)# fig.savefig('out.png', bbox_inches='tight', pad_inches=0)plt.show()祝你研究顺利!

POPMUISE

问题cv2.findContours使用具有几种不同“检索模式”的算法。这些会影响返回哪些轮廓以及返回方式。这记录在这里。这些作为 的第二个参数给出findContours。您的代码使用cv2.RETR_EXTERNALwhich 意味着findContours只会返回单独对象的最外层边框。解决方案将此参数更改为cv2.RETR_LIST将为您提供图像中的所有轮廓(包括最外层的边框)。这是最简单的解决方案。例如import cv2import imutilsimg = cv2.imread('/Users/kate/Desktop/SegmenterTest/SegmentedCells/Seg1.png')image = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)thresh = cv2.threshold(image, 60, 255, cv2.THRESH_BINARY)[1]cnts = cv2.findContours(thresh.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)cnts = imutils.grab_contours(cnts)# loop over the contoursfor c in cnts:&nbsp; &nbsp; # compute the center of the contour&nbsp; &nbsp; M = cv2.moments(c)&nbsp; &nbsp; cX = int(M["m10"] / M["m00"])&nbsp; &nbsp; cY = int(M["m01"] / M["m00"])&nbsp; &nbsp; # draw the contour and center of the shape on the image&nbsp; &nbsp; cv2.drawContours(image, [c], -1, (0, 255, 0), 2)&nbsp; &nbsp; cv2.circle(image, (cX, cY), 7, (255, 255, 255), -1)&nbsp; &nbsp; cv2.putText(image, "center", (cX - 20, cY - 20),&nbsp; &nbsp; &nbsp; &nbsp; cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 2)&nbsp; &nbsp; # show the image&nbsp; &nbsp; cv2.imshow("Image", image)&nbsp; &nbsp; cv2.waitKey(0)只选择最里面的对象要可靠地忽略外部轮廓,您可以利用findContours返回它检测到的轮廓的层次结构的能力。为此,您可以再次将检索模式参数更改为RETR_TREE,这将生成完整的层次结构。层次结构是一个数组,其中包含图像中每个轮廓的 4 个值的数组。每个值都是轮廓数组中轮廓的索引。从文档:对于每个第 i 个轮廓contours[i],元素hierarchy[i][0]、&nbsp;hierarchy[i][1]、hierarchy[i][2]和hierarchy[i][3]分别设置为同一层级下一个和上一个轮廓、第一个子轮廓和父轮廓的轮廓中从 0 开始的索引。如果轮廓 i 没有下一个、上一个、父级或嵌套轮廓,则相应的元素&nbsp;hierarchy[i]将为负数。当我们说“最里面”时,我们的意思是没有孩子的轮廓(它们内部的轮廓)。所以我们想要那些在层次结构中的条目具有负的第三值的轮廓。也就是说,&nbsp;contours[i],使得hierarchy[i][2] < 0一个小问题是,虽然findContours返回一个包含层次结构的元组,但imutils.grabContours会丢弃层次结构并仅返回轮廓数组。grabContours所有这一切意味着,如果我们打算使用不同版本的 OpenCV,我们必须自己完成工作。这只是一个简单的if else声明。res = cv2.findContours(thresh.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)# switch for different versions of OpenCVif len(cnts) == 3:&nbsp; &nbsp; _, cnts, hierarchy = reselse:&nbsp; &nbsp; cnts, hierarchy = res一旦你有了hierarchy,检查一个轮廓是否cnts[i]是“最里面的”可以用 完成hierarchy[0][i][2] < 0,这应该是False针对包含其他轮廓的轮廓。基于您问题代码的完整示例:import cv2import imutilsimg = cv2.imread('/Users/kate/Desktop/SegmenterTest/SegmentedCells/Seg1.png')image = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)thresh = cv2.threshold(image, 60, 255, cv2.THRESH_BINARY)[1]cnts = cv2.findContours(thresh.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)# switch for different versions of OpenCVif len(cnts) == 3:&nbsp; &nbsp; _, cnts, hierarchy = cntselse:&nbsp; &nbsp; cnts, hierarchy = cnts# loop over the contoursfor i, c in enumerate(cnts):&nbsp; &nbsp; # check that it is 'innermost'&nbsp; &nbsp; if hierarchy[0][i][2] < 0:&nbsp; &nbsp; &nbsp; &nbsp; # compute the center of the contour&nbsp; &nbsp; &nbsp; &nbsp; M = cv2.moments(c)&nbsp; &nbsp; &nbsp; &nbsp; cX = int(M["m10"] / M["m00"])&nbsp; &nbsp; &nbsp; &nbsp; cY = int(M["m01"] / M["m00"])&nbsp; &nbsp; &nbsp; &nbsp; # draw the contour and center of the shape on the image&nbsp; &nbsp; &nbsp; &nbsp; cv2.drawContours(image, [c], -1, (0, 255, 0), 2)&nbsp; &nbsp; &nbsp; &nbsp; cv2.circle(image, (cX, cY), 7, (255, 255, 255), -1)&nbsp; &nbsp; &nbsp; &nbsp; cv2.putText(image, "center", (cX - 20, cY - 20),&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 2)&nbsp; &nbsp; &nbsp; &nbsp; # show the image&nbsp; &nbsp; &nbsp; &nbsp; cv2.imshow("Image", image)&nbsp; &nbsp; &nbsp; &nbsp; cv2.waitKey(0)
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python