I am new to image processing. I am doing image processing of fiber image to generate skeleton using morphology function from skimage. The generated skeleton shows lots of small unnecessary loops/circles around it. I need a single medial axis line (skeleton) for each fiber in image. I have used following code to generate skeleton. Also, attached original and skeleton image for reference. Can someone help in to improve the skeleton generation step?
[import cv2
import numpy as np
from skimage import morphology
img = cv2.imread('img.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# dilate and threshold
kernel = np.ones((2, 2), np.uint8)
dilated = cv2.dilate(gray, kernel, iterations=1)
ret, thresh = cv2.threshold(dilated, 215, 255, cv2.THRESH_BINARY_INV)
cv2.imwrite('Binary.jpg',thresh)
# skeletonize
skeleton = morphology.skeletonize(thresh, method='lee')
skeleton = morphology.remove_small_objects(skeleton.astype(bool), 100, connectivity=2)
cv2.imwrite('Skeleton.jpg',skeleton*255)]
I'm not seeing the skeleton. Here's what I was able to come up with binary thresholding + morphological operations + small object clean up:
from skimage.morphology import binary_opening, binary_closing, thin, disk, remove_small_objects, remove_small_holes
from skimage.filters import threshold_otsu
from skimage.color import rgb2gray
import numpy as np
img_gray = rgb2gray(img) # image was rgb for me
mask = img_gray < threshold_otsu(img_gray) + 15/255
mask = binary_opening(binary_closing(mask, disk(2)), disk(2))
mask = remove_small_objects(mask, 300)
mask = remove_small_holes(mask, 300)
skeleton = thin(mask)
plot(skeleton)
You can probably play around with the kernel shape for the opening/closing, as well as use individual erosion/dilation operations, to get a stronger output. You may also try different skeletonizing techniques, as I know different ones produce varying results.