获取分割图像的最大连通组件

14
我有一个CT扫描的分割图像(只有1和0值)。我使用skimage.measure中的“label”函数获取连接组件的ndarray。现在我需要从“label”输出(ndarray)中仅获取最大连接组件。你有任何想法如何做到这一点吗?
我的代码如下:
from skimage.measure import label    

def getLargestCC(segmentation):
    labels = label(segmentation)
    // now I need to get only the largest connected component and return it
return largestCC
非常感谢!

你能发布“分割(segmentation)”的内容以供测试吗? - Tiger-222
这是一个问题,因为它是一个图片文件,我不知道如何在这里的帖子中添加此类文件。实际上,这是一个我进行分割的图像文件,因此每个像素值在两个值之间的像素都为1,而其他像素都为0。 - Vipasana
6个回答

24

Gilly的答案很有趣,但如果背景(标签=0)大于所研究的CC,则是错误的。Alaleh Rz的解决方案处理背景,但速度非常慢。通过采用Gilly提出的解决方案并消除背景问题:

吉利的答案虽然有趣,但如果背景(标签=0)比所研究的CC还要大,则是错误的。 Alaleh Rz 的解决方案解决了背景问题,但速度非常慢。通过采用吉利提出的方案并解决背景问题:

import numpy as np
from skimage.measure import label   

def getLargestCC(segmentation):
    labels = label(segmentation)
    assert( labels.max() != 0 ) # assume at least 1 CC
    largestCC = labels == np.argmax(np.bincount(labels.flat)[1:])+1
    return largestCC

6
我不确定你想要什么输出,是一个遮罩吗?
import numpy as np
from skimage.measure import label   

def getLargestCC(segmentation):
    labels = label(segmentation)
    largestCC = labels == np.argmax(np.bincount(labels.flat))
    return largestCC

Numpy的bincount函数将会计算每个标签出现的次数,而argmax函数将会告诉你其中哪一个是最大的。

6

OP的输入分割数据是二进制的,其中背景为0。因此,我们可以使用Vincent Agnus的np.bincount方法,但通过使用np.bincount的weights参数简化背景拒绝逻辑。 将weights = segmentation.flat设置为零以清除背景总和。

import numpy as np
from skimage.measure import label   

def getLargestCC(segmentation):
    labels = label(segmentation)
    largestCC = labels == np.argmax(np.bincount(labels.flat, weights=segmentation.flat))
    return largestCC

有趣的解决方案! - Cris Luengo

4
以下函数提供了最大的连接分割,该分割不是背景。输入和输出的形状相同,可以是2D或3D图像。
import numpy as np
from skimage.measure import label

def getLargestCC(segmentation):
    labels = label(segmentation)
    unique, counts = np.unique(labels, return_counts=True)
    list_seg=list(zip(unique, counts))[1:] # the 0 label is by default background so take the rest
    largest=max(list_seg, key=lambda x:x[1])[0]
    labels_max=(labels == largest).astype(int)
    return labels_max

4

我试图找出如何停止skimage.measure.label将背景视为单独的区域。直到我遇到P Tate优雅的解决方案,我几乎开始查看skimage.measure.regionprops文档。下面是一个快速的图例,展示了如何使用建议的numpy.bincountweights参数可以节省一些代码行。

import skimage
import numpy as np
import matplotlib.pyplot as plt

img_bw = img_as_bool(img)
labels = skimage.measure.label(img_bw, return_num=False)

maxCC_withbcg = labels == np.argmax(np.bincount(labels.flat))
maxCC_nobcg = labels == np.argmax(np.bincount(labels.flat, weights=img_bw.flat))

fig, ax = plt.subplots(1, 2)
ax[0].imshow(maxCC_withbcg), ax[0].set_title('counts bcg')
ax[1].imshow(maxCC_nobcg), ax[1].set_title('not counts bcg')
[axi.set_axis_off() for axi in ax.ravel()]

enter image description here


0

基于P Tate的解决方案,假设二进制分割掩码是bool类型,我们也可以使用该掩码仅将前景像素输入到np.bincount中,通过使用segmentation进行索引/掩蔽:

import numpy as np
from skimage.measure import label   

def largest_connected_component(segmentation):
    labels = label(segmentation)
    largest_cc = labels == np.argmax(np.bincount(labels[segmentation]))
    return largest_cc

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接