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,
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.
Answers:
add more optional in EuclideanSkeleton with endPixelCondition = "three neighbors could solved.
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,
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.
add more optional in EuclideanSkeleton with endPixelCondition = "three neighbors could solved.