sknw icon indicating copy to clipboard operation
sknw copied to clipboard

Empty Graph returned for circular skeletons without branches

Open Quasimondo opened this issue 5 years ago • 8 comments

I am not sure if this is on purpose, but it looks like there is no graph returned for skeletons that result in a single chain that connects back to itself - I tried both multi=False and True but the result is aways an empty graph: image

img = loadImg(path)>127 ske = skeletonize(~img).astype(np.uint16) graph = sknw.build_sknw(ske) print("\n".join(nx.generate_gml(graph)))`

Result: graph [ ]

Quasimondo avatar Oct 16 '20 07:10 Quasimondo

sknw follow these steps:

  1. detect the node end junction (which has 1 neighbour or more than 2neighbours)
  2. trace from one node to another through the path (which has 2 neighbours)

so a pure ring without any branch would not be detected now. If you need detect pure ring or isolate point, we can try to add some features.

yxdragon avatar Oct 16 '20 08:10 yxdragon

Thanks for the quick response! I am looking at the source right now and will see if I can patch it to my needs. I am thinking of adding one random start node if there are 0 nodes, but the skeleton image has non-zero entries.

Quasimondo avatar Oct 16 '20 08:10 Quasimondo

I think this might do for my purposes:

def build_sknw(ske, multi=False):
    buf = buffer(ske)
    nbs = neighbors(buf.shape)
    acc = np.cumprod((1,)+buf.shape[::-1][:-1])[::-1]
    mark(buf, nbs)
    pts = np.array(np.where(buf.ravel()==2))[0]
    
    if len(pts)==0 and np.sum(ske)>0:
        print("ring detected")
        pts = np.where(ske.ravel())[0]
        buf[np.array(np.unravel_index(pts, ske.shape))+1] = 2
    
    nodes, edges = parse_struc(buf, pts, nbs, acc)
    return build_graph(nodes, edges, multi)

Quasimondo avatar Oct 16 '20 08:10 Quasimondo

  1. np.where did not make sure the ring series. (it is in row and columns series)
  2. it did not treat when (both pure ring and branch exist)

I learn np.unravel_index from you, thanks.

yxdragon avatar Oct 16 '20 09:10 yxdragon

i would give a update soon

yxdragon avatar Oct 16 '20 09:10 yxdragon

Oh yes - thanks for checking the code and finding the issues with it - I just needed it for a very simple example so I did miss the other possible cases.

Quasimondo avatar Oct 16 '20 10:10 Quasimondo

add isolate and ring parameter, have a try. ps: if you only need the ring's coordinates, you can try skimage.regionprops

yxdragon avatar Oct 16 '20 10:10 yxdragon

Perfect - looks like it works as intended. Thanks for the quick fix! image

Quasimondo avatar Oct 16 '20 10:10 Quasimondo