【问题标题】:Opencv - Close a specific contourOpencv - 关闭特定轮廓
【发布时间】:2017-06-05 01:06:52
【问题描述】:

我正在处理一张图片,我需要你的帮助。经过大量图像处理后,我从显微图像中得到了这个。这是我的最终阈值图像:

如您所见,左上角有一个很大的C。这不应该是一个开放的 blob,它必须是一个封闭的。

如何在不修改其余部分的情况下实现这一目标?我正在考虑将 Convex Hull 应用到那个轮廓,但我不知道如何应用到那个轮廓,并且只应用那个轮廓,甚至不接触其他轮廓

我的意思是,也许我可以使用一种“措施”将这个轮廓与其他轮廓隔离开来。也许是一种方法来判断它的凸/凹程度或它所界定的“洞”有多大。

在进一步的工作中,可能会出现一些我需要关闭的未闭合轮廓,所以不要集中在这个特殊情况下,我需要一些我可以使用或适应其他类似情况的东西。

提前致谢!

【问题讨论】:

  • 在所有斑点上绘制轮廓。使用:contour[1] 选择该特定 blob 并屏蔽其余 blob。

标签: opencv image-processing convex-hull opencv-contour


【解决方案1】:

我有办法。

首先,我在你给的阈值图像上找到并绘制了轮廓。

在图像中,我发现第 29 个轮廓是带有 C 的轮廓。因此,除了第 29 个轮廓之外,我用黑色为每个轮廓着色。仅具有 C 的轮廓是白色的。

代码:

#---- finding all contours
contours, iji = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)

#---- Turning all contours black
cv2.drawContours(im1, contours, -1, (0,0,0), -1)

#---- Turning contour of interest alone white
cv2.drawContours(im1, contours, 29, (255, 255, 255), -1)

你只剩下感兴趣的 blob

在隔离了所需的 blob 之后,我使用椭圆内核执行了一定次数的迭代的形态闭合。

#---- k = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(30,30))
#---- closing = cv2.morphologyEx(opening, cv2.MORPH_CLOSE, k)
#---- cv2.imshow("closed_img", closing)

球现在在你的球场上!我也学到了一些东西!玩得开心。

【讨论】:

  • 谢谢 Jeru,但正如 @Soltius 所指出的,我需要一个自动过程
  • 还有一件事,你能发布代码来实现它吗?特别是您应用使用椭圆内核进行一定数量的迭代的形态闭合的部分。如果是 C++ 更好
  • 如果你没问题,我有python的解决方案
  • 谢谢Jeru,我已经按照@Soltius 的建议做到了,我已经使用convexHull 关闭了轮廓
  • connectedComponents 对我来说是新事物。好在他提到了:)
【解决方案2】:

虽然 Jeru 的回答在您确定轮廓后要关闭轮廓的部分是正确的,但我认为 OP 还想知道他如何自动识别“C”斑点,而无需手动找出就是它29 等高线。

因此,我提出了一种识别它的方法:计算每个形状的质心并检查该质心是否在形状内。 blob(圆圈)应该是这种情况,但“C”不是。

img=cv2.imread(your_image,0)
if img is None:
     sys.exit("No input image") #good practice
res=np.copy(img) #just for visualisation purposes    

#finding the connectedComponents (each blob)
output=cv2.connectedComponentsWithStats(img,8)
#centroid is sort of the "center of mass" of the object.
centroids=output[3]
#taking out the background
centroids=centroids[1:]


#for each centroid, check if it is inside the object
for centroid in centroids:
    if(img[int(centroid[1]),int(centroid[0])]==0):
        print(centroid) 
        #save it somewhere, then do what Jeru Luke proposes

    #an image with the centroids to visualize
    res[int(centroid[1]), int(centroid[0])]=100

这适用于您的代码(我试过了),但需要注意的是,可能不适用于每种“C 形式”,尤其是如果它们“更胖”,因为它们的质心很可能在它们内部。正如你所说,我认为可能有更好的凸度衡量标准,至少寻找这样的衡量标准对我来说似乎是正确的方向。

也许您可以尝试在所有对象上计算 ConvexHull(不修改输入图像),而不是测量对象面积与“围绕它的凸包”面积之间的比率,如果该比率低于一定的阈值,然后您将其归类为“C”形并相应地进行修改。

【讨论】:

  • 谢谢!一个非常聪明的解决方案!我会试试的
  • 加上 1 个绝妙的主意。但我认为使用convexHull 的建议最重要!!!
猜你喜欢
  • 2018-10-12
  • 1970-01-01
  • 1970-01-01
  • 2019-01-25
  • 2023-03-18
  • 2015-09-26
  • 2011-10-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多