Ask Your Question

Revision history [back]

click to hide/show revision 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()