tfv
tfv

Reputation: 6259

Skeletonize with 4-neighborhood

I am using skeletonize from skimage, which delivers a result connected as a 8-neigborhood:

import numpy as np
from skimage.morphology import skeletonize

image = np.array(
      [[0, 0, 1, 1, 1, 1, 1, 0, 0],
       [0, 0, 1, 1, 1, 1, 1, 0, 0],
       [0, 0, 1, 1, 1, 1, 1, 1, 1],
       [0, 0, 0, 1, 1, 1, 1, 1, 1]])

print image
print
skel = skeletonize(image)
print skel.astype(np.uint8)

# result
#[[0 0 0 0 0 0 0 0 0]
# [0 0 0 1 1 1 0 0 0]
# [0 0 0 0 0 0 1 1 1]
# [0 0 0 0 0 0 0 0 0]]

What I want to get instead is a 4-connected result such as:

#[[0 0 0 0 0 0 0 0 0]
 #[0 0 0 1 1 1 1 0 0]
 #[0 0 0 0 0 0 1 1 1]
 #[0 0 0 0 0 0 0 0 0]]

or

#[[0 0 0 0 0 0 0 0 0]
 #[0 0 0 1 1 1 0 0 0]
 #[0 0 0 0 0 1 1 1 1]
 #[0 0 0 0 0 0 0 0 0]]

but not

#[[0 0 0 0 0 0 0 0 0]
 #[0 0 0 1 1 1 0 0 0]
 #[0 0 0 0 1 1 1 1 1]
 #[0 0 0 0 0 0 0 0 0]]

How would I do this? There is no neigborhood option in skeletonize.

The reason why I am asking is that I want to further process the connected lines with skimage.measure.find_contours, which would break the lines into two if they are not 4-connected.

Upvotes: 1

Views: 241

Answers (1)

Stefan van der Walt
Stefan van der Walt

Reputation: 7263

Neither skeletonize nor medial_axis supports a connectivity argument. But perhaps you can get away with a post-processing pass:

from scipy import ndimage as ndi
diagonals = ndi.correlate(skel.astype(int), [[0, 1, 0], [0, 0, 1], [0, 0, 0]])
skel2 = skel.copy()
skel2[diagonals == 2] = 1

This yields

[[0 0 0 0 0 0 0 0 0]
 [0 0 0 1 1 1 0 0 0]
 [0 0 0 0 0 1 1 1 1]
 [0 0 0 0 0 0 0 0 0]]

By modifying the mask, you can get the other example outputs you describe.

Upvotes: 2

Related Questions