Medial Axis Transform/Skeletonization on morphological for calculating numbers of component

Question:

I’m trying to calculate the number components on opencv library "connectedComponentsWithStats" in python, but my skeletonization result seems not do well, cause the number of component return incorrect result.
Here my original image to convert to skeleton.
input

And here’s my code as below,

Code

import cv2
import os
import sys
import numpy as np
import diplib as dip

def skel_trans(img):
    size = np.size(img)
    skel = np.zeros(img.shape,np.uint8)

    element = cv2.getStructuringElement(cv2.MORPH_CROSS,(3,3))
    done = False

    while( not done):
        eroded = cv2.erode(img,element)
        temp = cv2.dilate(eroded,element)
        temp = cv2.subtract(img,temp)
        skel = cv2.bitwise_or(skel,temp)
        img = eroded.copy()

        zeros = size - cv2.countNonZero(img)
        if zeros==size:
            done = True

    return skel

threshold_value = 128  
max_value = 255  
select_map = cv2.imread('map.bmp', 0)
_, selected_map_binary = cv2.threshold(select_map, threshold_value, max_value, cv2.THRESH_BINARY)

selected_map_binary_temp = selected_map_binary.copy()
I = np.ones((selected_map_binary.shape[0], selected_map_binary.shape[1]), dtype=np.uint8)


for rows in range (selected_map_binary_temp.shape[0]):
    for cols in range (selected_map_binary_temp.shape[1]):
        if(selected_map_binary_temp[rows, cols] > threshold_value):
            selected_map_binary_temp[rows, cols] = 1
        else:
            selected_map_binary_temp[rows, cols] = 0

image = cv2.bitwise_xor(selected_map_binary_temp,I)

for rows in range (image.shape[0]):
    for cols in range (image.shape[1]):
        if(image[rows, cols] == 1):
            image[rows, cols] = 255

#DipLib EuclideanSkeleton
dip_img = dip.Image(image)
bin = image > threshold_value
sk = dip.EuclideanSkeleton(bin)

#skel_trans
test_skel = skel_trans(image)
cv2.imshow('test_skel', test_skel)

dip.Show(sk)
input("Press Enter to continue...")

num_components, labeled_image, stats, centroids = cv2.connectedComponentsWithStats(test_skel, connectivity=8)

print("Return num_components for the image" , num_components)

I tried the "medial_axis" in morphology and "EuclideanSkeleton" in DIPlib , the numbers of component still incorrect, after all I reference the Skeletonization using OpenCV-Python
and try it in same input, the result still have problem on ellipse in the binary image,

result of skeletonizetion

It still effect to the connectedComponentsWithStats of num_components, how can I fix this?

Expected result

I check the matlab using "bwmorph(bw1,’skel’,inf);" the skeleton will do well to the input and the numbers of conponents is 8.

matlab result

Asked By: Dio

||

Answers:

add more optional in EuclideanSkeleton with endPixelCondition = "three neighbors could solved.

Answered By: Dio