skan icon indicating copy to clipboard operation
skan copied to clipboard

how to remove branch according to the length?

Open qiang-zhang-neu opened this issue 5 years ago • 1 comments

After extract the center line by skan, I find there are some wrong branches. I wanto to remove the short branch (for example. the branch whose length is shorter than 5 should be removed). Dose skan provide this method?

In addition, do you know how to obtain the volume for each center line? Those, we can calculate the area of volume for each branch.

Any suggestion is appreciated.

qiang-zhang-neu avatar Dec 31 '19 06:12 qiang-zhang-neu

You can remove branches below a specific length with the following approach: Let's consider the following image to be our starting point and we want to remove the small branch in the middle right side pointing downwards.

pic

import numpy as np
from skan import csr
from skimage import io, morphology

# loading image
image = io.imread('https://user-images.githubusercontent.com/60721219/90825184-d76add00-e338-11ea-80c6-394e0bbe612f.jpg')

# make image binary
image_binary = image >= 200

# skeletonize; the skeleton is marked as True the other areas as False
sk = morphology.skeletonize(image_binary).astype(bool)

# object for all properties of the graph
graph_class = csr.Skeleton(sk)

# get statistics for each branch, especially relevant the length and type of branch here
stats = csr.branch_statistics(graph_class.graph)

# remove all branches which are shorter than the threshold value and a tip-junction (endpoint to junction) branch
thres_min_size = 5
for ii in range(np.size(stats, axis=0)):
    if stats[ii,2] < thres_min_size and stats[ii,3] == 1:
        # remove the branch
        for jj in range(np.size(graph_class.path_coordinates(ii), axis=0)):
            sk[int(graph_class.path_coordinates(ii)[jj,0]), int(graph_class.path_coordinates(ii)[jj,1])] = False

# during the short branch removing process it can happen that some branches are not longer connected as the complete three branches intersection is removed
# therefor the remaining skeleton is dilatated and then skeletonized again
sk_dilation = morphology.binary_dilation(sk)
sk_final = morphology.skeletonize(sk_dilation)


# optional checks if everything worked like expected
graph_class2 = csr.Skeleton(sk_final)
stats2 = csr.branch_statistics(graph_class2.graph)

It might not be the computationally most efficient way but worked for me.

theo258 avatar Aug 20 '20 21:08 theo258