Search code examples
pythonopencvimage-processingmathematical-morphologyscikit-image

How can i find cycles in a skeleton image with python libraries?


I have many skeletonized images like this:

enter image description here enter image description here

How can i detect a cycle, a loop in the skeleton? Are there "special" functions that do this or should I implement it as a graph?

In case there is only the graph option, can the python graph library NetworkX can help me?


Solution

  • You can exploit the topology of the skeleton. A cycle will have no holes, so we can use scipy.ndimage to find any holes and compare. This isn't the fastest method, but it's extremely easy to code.

    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()
    

    I've used your "B" picture as an example. The first two images are the original and the filled version which detects a cycle. In the second version, I've broken the cycle and nothing gets filled, thus the two images are the same.

    enter image description here