0

我想在每个端点的中间,第五个像素处找到中轴距离变换。我的输入图像和所需的点是:

骨架上的输入图像 输入图像 所需点 在此处输入图像描述

我的代码如下:

skeleton, distance = medial_axis(cimg, return_distance=True)
                med_dist = distance * skeleton
                width = med_dist*2
                skeld=width[skeleton]
                dwidth=skeld[skeld.shape[0]//2]

但它没有给出正确的结果

4

1 回答 1

2

编辑0:如果你说,骨架可以是任何方向的,让我们变得复杂:)。让我从我过去的一个类似问题开始。在那里,我需要一种方法来追踪骨架上给定两点之间的像素。请检查问题中接受的答案,并将这种方法牢记在心,因为我也会将它用于您的问题。

这是我针对您的问题所遵循的步骤。

  1. 获取骨架图像
  2. 通过使用tips周围的相邻像素数获取骨架的tips(即起点、终点)
  3. 通过BFS绘制起点和终点之间的路径
  4. 从绘制的路径中获取所需的索引(端点的第五个像素)
import numpy as np
import cv2
import os
import matplotlib.pyplot as plt
import sys
from collections import deque
from skimage.morphology import medial_axis
from itertools import combinations


img = cv2.imread('curvy_1.png',0)/255
skel = medial_axis(img, return_distance=False) # skeleton


img_conv = cv2.filter2D(skel.astype(np.uint8),-1,np.ones((3,3))) #
img_conv = img_conv*skel
img_tips = img_conv == 2
tips = np.array(np.nonzero(img_tips)).T
tip_combs = combinations(tips, 2) # get all the combinations of the tips in case the skeleton are branched

这是找到的提示。 骨骼的提示

# BFS
def findPathBwTwoPoints(img_binary,points):
    '''
    img_binary: skeleton image
    points: (y_start_point,x_start_point),(y_end_point,x_end_point)
    '''
    height, width = img_binary.shape

    # The start and end point you're looking at
    # start, end = (31, 14), (34, 51)

    start,end = points

    # print(start,end)

    # All 8 directions
    delta = [(-1, -1), (-1, 0), (-1, 1), (0, 1), (1, 1), (1, 0), (1, -1), (0, -1)]

    # Store the results of the BFS as the shortest distance to start
    grid = [[sys.maxsize for _ in range(width)] for _ in range(height)]
    grid[start[0]][start[1]] = 0

    # The actual BFS algorithm
    bfs = deque([start])
    found = False
    while len(bfs) > 0:
        y, x = bfs.popleft()
        # print(y,x)
        # We've reached the end!
        if (y, x) == end:
            found = True
            break

        # Look all 8 directions for a good path
        for dy, dx in delta:
            yy, xx = y + dy, x + dx
            # If the next position hasn't already been looked at and it's white
            if 0 <= yy < height and 0 <= xx < width and grid[y][x] + 1 < grid[yy][xx] and img_binary[yy][xx] != 0:
                grid[yy][xx] = grid[y][x] + 1
                bfs.append((yy, xx))

    if found:
        # Now rebuild the path from the end to beginning
        path = []
        y, x = end
        while grid[y][x] != 0:
            for dy, dx in delta:
                yy, xx = y + dy, x + dx
                if 0 <= yy < height and 0 <= xx < width and grid[yy][xx] == grid[y][x] - 1:
                    path.append([yy, xx])
                    y, x = yy, xx

        return np.array(path)
    else:
        # print(f'No path found between {start} and {end}')
        return 0

让我们使用 BFS 获取找到的提示之间的路径。

for tip_comb in list(tip_combs):

    start, end = tuple(tip_comb[0]), tuple(tip_comb[1])

    paths = findPathBwTwoPoints(skel,points=[start,end]) # this will return the path between the start and end points

    # ready to get the indices you are asking for
    first_fifth = paths[4]
    last_fifth = paths[-5]
    middle = paths[int(len(paths)/2)]


    fig,ax = plt.subplots(1)
    ax.imshow(skel,'gray')
    ax.scatter( [first_fifth[1],last_fifth[1],middle[1]],
                [first_fifth[0],last_fifth[0],middle[0]],s=10,c='r')

plt.show()

骨架上的索引

以下是我的方法的更多示例输出。

curvy_2

如果您的骨架是分支的,这种方法将为您提供提示之间所有组合的索引。

curvy_3_0 curvy_3_1 curvy_3_2

于 2021-04-20T07:41:20.613 回答