Image-Py / sknw

build net work from skeleton image (2D-3D)
BSD 3-Clause "New" or "Revised" License
222 stars 47 forks source link

Empty Graph returned for circular skeletons without branches #11

Open Quasimondo opened 3 years ago

Quasimondo commented 3 years ago

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 [ ]

yxdragon commented 3 years ago

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.

Quasimondo commented 3 years ago

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 commented 3 years ago

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)
yxdragon commented 3 years ago
  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 commented 3 years ago

i would give a update soon

Quasimondo commented 3 years ago

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.

yxdragon commented 3 years ago

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

Quasimondo commented 3 years ago

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