1 | initial version |
This is the Python code for @pklab answer, in case someone is in a hurry...
import numpy as np
import cv2
def getJunctions(src):
# the hit-and-miss kernels to locate 3-points junctions to be used in each directions
# NOTE: float type is needed due to limitation/bug in warpAffine with signed char
k1 = np.asarray([
0, 1, 0,
0, 1, 0,
1, 0, 1], dtype=float).reshape((3, 3))
k2 = np.asarray([
1, 0, 0,
0, 1, 0,
1, 0, 1], dtype=float).reshape((3, 3))
k3 = np.asarray([
0, -1, 1,
1, 1, -1,
0, 1, 0], dtype=float).reshape((3, 3))
# Some useful declarations
tmp = np.zeros_like(src)
ksize = k1.shape
center = (ksize[1] / 2, ksize[0] / 2) # INVERTIRE 0 E 1??????
# 90 degrees rotation matrix
rotMat = cv2.getRotationMatrix2D(center, 90, 1)
# dst accumulates all matches
dst = np.zeros(src.shape, dtype=np.uint8)
# Do hit & miss for all possible directions (0,90,180,270)
for i in range(4):
tmp = cv2.morphologyEx(src, cv2.MORPH_HITMISS, k1.astype(np.int8), tmp, (-1, -1), 1, cv2.BORDER_CONSTANT, 0)
dst = cv2.add(dst, tmp)
tmp = cv2.morphologyEx(src, cv2.MORPH_HITMISS, k2.astype(np.int8), tmp, (-1, -1), 1, cv2.BORDER_CONSTANT, 0)
dst = cv2.add(dst, tmp)
tmp = cv2.morphologyEx(src, cv2.MORPH_HITMISS, k3.astype(np.int8), tmp, (-1, -1), 1, cv2.BORDER_CONSTANT, 0)
dst = cv2.add(dst, tmp)
# Rotate the kernels (90deg)
k1 = cv2.warpAffine(k1, rotMat, ksize)
k2 = cv2.warpAffine(k2, rotMat, ksize)
k3 = cv2.warpAffine(k3, rotMat, ksize)
return dst
# This is your sample image (objects are black)
src = np.asarray([0, 1, 1, 1, 1, 1, 0, 0,
1, 0, 1, 1, 1, 0, 1, 1,
1, 1, 0, 0, 0, 1, 1, 1,
1, 1, 1, 0, 0, 0, 1, 1,
1, 0, 0, 1, 1, 1, 0, 1,
0, 1, 1, 1, 1, 1, 0, 0,
0, 1, 1, 1, 1, 1, 1, 1], dtype=np.uint8).reshape((7,8))
src *= 255;
# Morphology logic is: white objects on black foreground
src = 255 - src;
# Get junctions
junctionsScore = getJunctions(src)
# Draw markers where junction score is non zero
dst = cv2.cvtColor(src, cv2.COLOR_GRAY2RGB)
# find the list of location of non-zero pixels
junctionsPoint = cv2.findNonZero(junctionsScore)
for pt in junctionsPoint:
pt = pt[0]
dst[pt[1], pt[0], :] = [0, 0, junctionsScore[pt[1], pt[0]]]
# show the result
winDst = "Dst"
winSrc = "Src"
winJunc = "Junctions"
cv2.namedWindow(winSrc, cv2.WINDOW_NORMAL | cv2.WINDOW_KEEPRATIO);
cv2.namedWindow(winJunc, cv2.WINDOW_NORMAL | cv2.WINDOW_KEEPRATIO);
cv2.namedWindow(winDst, cv2.WINDOW_NORMAL | cv2.WINDOW_KEEPRATIO);
scale = 24
cv2.resizeWindow(winSrc, scale*src.shape[1], scale*src.shape[0])
cv2.resizeWindow(winJunc, scale*src.shape[1], scale*src.shape[0])
cv2.resizeWindow(winDst, scale*src.shape[1], scale*src.shape[0])
cv2.imshow(winSrc, src)
cv2.imshow(winJunc, junctionsScore)
cv2.imshow(winDst, dst)
cv2.waitKey()