如何使用python库在骨架图像中找到循环?

imp*_*roc 7 python opencv image-processing mathematical-morphology scikit-image

我有很多这样的镂空图像:

在此输入图像描述 在此输入图像描述

我如何检测一个循环,一个骨架中的循环?是否有"特殊"功能可以执行此操作,还是应将其实现为图形?

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

Hoo*_*ked 5

您可以利用骨架的拓扑结构。一个循环将没有孔洞,因此我们可以使用它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()
Run Code Online (Sandbox Code Playgroud)

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

在此处输入图片说明


Jea*_*Pat 5

首先,让我们用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)
Run Code Online (Sandbox Code Playgroud)

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

现在,真正的部分是:

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)
Run Code Online (Sandbox Code Playgroud)

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