【问题标题】:How to extract the largest connected component using OpenCV and Python?如何使用 OpenCV 和 Python 提取最大的连通分量?
【发布时间】:2018-04-13 19:47:20
【问题描述】:

我在 Python 中使用 OpenCV,以便能够仅识别图像上显示的叶子。我已经可以分割我的图像了,现在我陷入了“如何在检测到所有图像后裁剪最大的组件。下面是代码,请看一下。

  1. 使用scipy.ndimage,找到组件后无法前进:

    def undesired_objects ( image ):
        components, n = ndimage.label( image )
        components = skimage.morphology.remove_small_objects( components, min_size = 50 )
        components, n = ndimage.label( components )
        plot.imshow( components )
        plot.show()
    
  2. 使用 OpenCV connectedComponentsWithStats:

    def undesired_objects ( image ):
        image = image.astype( 'uint8' )
        nb_components, output, stats, centroids = cv2.connectedComponentsWithStats(image, connectivity=4)
        sizes = stats[1:, -1]; nb_components = nb_components - 1
        min_size = 150
        img2 = np.zeros(( output.shape ))
        for i in range(0, nb_components):
            if sizes[i] >= min_size:
                img2[output == i + 1] = 255
                plot.imshow( img2 )
                plot.show()
    

但是,在这两种方法中,我仍然得到不止一个组件。下面,您将找到二进制图像:

【问题讨论】:

  • 你能上传你试图找到最大连通分量的二进制图像吗?
  • @ZdaR 已更新二进制图像!
  • 你的结果有什么问题?您的代码不能保证只输出一个组件。它将选择所有大于您的 min_size 参数的组件。而且由于您没有清除不同组件之间的img2,因此它们最终都会被绘制在同一个图像上。
  • 是的,@Sunreef。我想删除 min_size 参数以仅选择较大的参数;但是,我坚持下去了

标签: python opencv image-segmentation


【解决方案1】:

使用cv2.CC_STAT_AREA 提高可读性:

# Connected components with stats.
nb_components, output, stats, centroids = cv2.connectedComponentsWithStats(image, connectivity=4)

# Find the largest non background component.
# Note: range() starts from 1 since 0 is the background label.
max_label, max_size = max([(i, stats[i, cv2.CC_STAT_AREA]) for i in range(1, nb_components)], key=lambda x: x[1])

更多:https://stackoverflow.com/a/35854198/650885

【讨论】:

    【解决方案2】:

    我会用这样的代码替换你的代码:

    def undesired_objects (image):
        image = image.astype('uint8')
        nb_components, output, stats, centroids = cv2.connectedComponentsWithStats(image, connectivity=4)
        sizes = stats[:, -1]
    
        max_label = 1
        max_size = sizes[1]
        for i in range(2, nb_components):
            if sizes[i] > max_size:
                max_label = i
                max_size = sizes[i]
    
        img2 = np.zeros(output.shape)
        img2[output == max_label] = 255
        cv2.imshow("Biggest component", img2)
        cv2.waitKey()
    

    组件上的循环现在找到面积最大的组件并将其显示在循环的末尾。

    告诉我这是否适合你,因为我自己没有测试过。

    【讨论】:

    • 谢谢你,@Sunreef。它运作良好;但是,我的结果仍然很差,我需要找到另一种方法来解决我的问题
    猜你喜欢
    • 2020-12-19
    • 2018-05-11
    • 1970-01-01
    • 2014-07-10
    • 1970-01-01
    • 2018-08-01
    • 2021-08-24
    • 2018-03-01
    • 2019-05-05
    相关资源
    最近更新 更多