【问题标题】:How can i find cycles in a skeleton image with python libraries?如何使用 python 库在骨架图像中找到循环?
【发布时间】:2013-04-01 15:14:56
【问题描述】:

我有很多这样的骨架图像:

我怎样才能检测到一个循环,一个骨架中的循环? 是否有执行此操作的“特殊”功能,或者我应该将其实现为图形?

如果只有图形选项,python图形库NetworkX可以帮到我吗?

【问题讨论】:

  • 使用 python 字典很容易实现一个简单的图形。这里是an example from the python docs。 NetworkX 似乎有点矫枉过正,尽管我从未使用过它。关于将图像转换为图形,我不知道一种简单的方法来做到这一点,尽管这似乎是一个有趣的问题。我使用opencv,它提供了很多用于处理图像的功能。您可能会在其中找到一些有用的部分。

标签: python opencv image-processing mathematical-morphology scikit-image


【解决方案1】:

您可以利用骨架的拓扑结构。一个循环不会有漏洞,因此我们可以使用scipy.ndimage 查找任何漏洞并进行比较。这不是最快的方法,但它非常容易编码。

import scipy.misc, scipy.ndimage

# Read the image
img = scipy.misc.imread("Skel.png")

# Retain only the skeleton
img[img!=255] = 0
img = img.astype(bool)

# Fill the holes
img2 = scipy.ndimage.binary_fill_holes(img)

# Compare the two, an image without cycles will have no holes
print "Cycles in image: ", ~(img == img2).all()

# As a test break the cycles
img3 = img.copy()
img3[0:200, 0:200] = 0
img4 = scipy.ndimage.binary_fill_holes(img3)

# Compare the two, an image without cycles will have no holes
print "Cycles in image: ", ~(img3 == img4).all()

我以您的“B”图片为例。前两个图像是原始版本和检测周期的填充版本。在第二个版本中,我打破了循环,没有填充,因此两个图像是相同的。

【讨论】:

    【解决方案2】:

    首先,让我们用 PIL 构建字母 B 的图像:

    import Image, ImageDraw, ImageFont
    image = Image.new("RGBA", (600,150), (255,255,255))
    draw = ImageDraw.Draw(image)
    fontsize = 150
    font = ImageFont.truetype("/usr/share/fonts/truetype/liberation/LiberationMono-Regular.ttf", fontsize)
    txt = 'B'
    draw.text((30, 5), txt, (0,0,0), font=font)
    img = image.resize((188,45), Image.ANTIALIAS)
    print type(img)
    plt.imshow(img)
    

    您可能会找到更好的方法来做到这一点,尤其是使用字体路径。 ii 加载图像而不是生成图像会更好。无论如何,我们现在有一些工作要做:

    现在,真正的部分:

    import mahotas as mh
    img = np.array(img)
    im = img[:,0:50,0]
    im = im < 128
    skel = mh.thin(im)
    noholes = mh.morph.close_holes(skel)
    plt.subplot(311)
    plt.imshow(im)
    plt.subplot(312)
    plt.imshow(skel)
    plt.subplot(313)
    cskel = np.logical_not(skel)
    choles = np.logical_not(noholes)
    holes = np.logical_and(cskel,noholes)
    lab, n = mh.label(holes)
    print 'B has %s holes'% str(n)
    plt.imshow(lab)
    

    我们在控制台(ipython)中有: B 有 2 个洞

    【讨论】:

      【解决方案3】:

      将您的骨架图像转换为图形表示并非易事,而且我不知道有任何工具可以为您做到这一点。

      在位图中执行此操作的一种方法是使用flood fill,就像 Photoshop 中的油漆桶一样。如果您开始对图像进行泛光填充,如果没有循环,整个背景将被填充。如果填充没有得到整个图像,那么您已经找到了一个循环。稳健地找到所有循环可能需要多次填充。

      这可能执行起来很慢,但可能比将骨架追踪到图形数据结构的技术快得多。

      【讨论】:

      • 我认为这是一个很好的解决方案。我计算像素的骨架数和图像的总像素数并计算差异,如果 Floodfill 返回相同数量的像素,则没有循环,如果返回较少则有循环。
      • 是的,基本上你需要标记骨骼的补充。这将返回被骨架循环切割的连接组件。如果组件的数量大于 1 说 N 你有 N-1 循环。这也可以看作是一种瘦骨架的形式。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-04-28
      • 2017-06-02
      • 2014-12-19
      • 1970-01-01
      • 2017-08-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多