I have a binary skeleton image and I'm trying to work out how to detect the terminals of each chain in the skeleton, with a view to eventually detecting the longest continuous chain in the image.
I stumbled on this answer to a similar problem from a few years ago that suggested using OpenCV's Hit-or-Miss morphological transformation to pick up the pixels that terminate each chain, and that seems to have worked in detecting most of the terminals. However, there are a couple that it seems have missed. Both of the pixels have the following environments:
[[0 ,0, 255],[0, 255, 0],[0, 0, 0]]
so I assumed that a kernel of:
[[-1, -1, 0],[-1, 1, 0],[-1, -1, 0]]
would pick this up (k8 in the code below). Can anybody spot where I've went wrong, please?
Here's what I've tried so far:
# make all the kernels
# n.b 1 for foreground pixel, 0 for "don't care", -1 for the background
#staircase
k1 = np.array([[-1,-1,-1],
[-1,1,0],
[-1,0,-1]], dtype="int")
k2 = np.rot90(k1)
k3 = np.rot90(k2)
k4 = np.rot90(k3)
# t, straight or diagonal
k5 = np.array([[0,0,0],
[-1,1,-1],
[-1,-1,-1]], dtype="int")
k6 = np.rot90(k5)
k7 = np.rot90(k6)
k8 = np.rot90(k7)
# hit-and-miss with everything
o1 = cv2.morphologyEx(padded, cv2.MORPH_HITMISS, k1)
o2 = cv2.morphologyEx(padded, cv2.MORPH_HITMISS, k2)
o3 = cv2.morphologyEx(padded, cv2.MORPH_HITMISS, k3)
o4 = cv2.morphologyEx(padded, cv2.MORPH_HITMISS, k4)
out1 = o1 + o2 + o3 + o4
o5 = cv2.morphologyEx(padded, cv2.MORPH_HITMISS, k5)
o6 = cv2.morphologyEx(padded, cv2.MORPH_HITMISS, k6)
o7 = cv2.morphologyEx(padded, cv2.MORPH_HITMISS, k7)
o8 = cv2.morphologyEx(padded, cv2.MORPH_HITMISS, k8)
out2 = o5 + o6 + o7 + o8
# this should contain all terminals
out = cv2.add(out1, out2)
# store the terminal coordinates and draw them
fig, ax = plt.subplots(1)
plt.imshow(padded)
pts = np.argwhere(out == 255)
for pt in pts:
circ = patches.Circle((pt[1], pt[0]), radius=3, facecolor='r')
ax.add_patch(circ)
plt.show()
Here is the original image and here is the output of the code snippet above.
The points at the bottom-left terminals of the longer chains seem to have flown under the radar. Any suggestions to keep me from scratching my head further will be gratefully received, thanks!