【问题标题】:How to find the joints and endpoints of medial axis如何找到中轴的关节和端点
【发布时间】:2021-11-10 00:28:13
【问题描述】:

我能够使用

获得中轴
image = Image.open('path/to/img.png')
image = (np.array(image) / 255).astype(np.uint8)
medial = skeletonize(image)
medial_x, medial_y = np.where(medial == 1)

但是如何使用 python 找到中轴的端点和关节,因为我从medial_x, medial_y = np.where(medial == 1) 获得的坐标没有以我可以轻松获得端点或关节的方式排序?

下面附上原始剪影。

【问题讨论】:

  • 你能把你原来的img.png也发上来,这样更容易做实验吗?
  • @AKX 嗨,感谢您的回复。我将原始 img.png 添加到帖子中

标签: python numpy python-imaging-library scikit-image


【解决方案1】:

我将骨架视为一个图,并构造它的邻接矩阵。使用邻接矩阵,您可以很容易地找到端点。图中具有一个邻居的节点是端点,而具有两个以上邻居的节点就是您所说的“关节”。我喜欢称它们为十字路口。 我创建邻接矩阵的方式是,如果从节点 i 到节点 j 的欧几里德距离小于 2,则我用零初始化一个 NxN 数组,并将数组中的 [i, j] 值设置为 1,这意味着它们是相邻像素在图片中。

# create an adjacency matrix 
xx, yy = np.where(skeleton)
n = len(xx)

dist_mat = ((xx[:, None]-xx[None, :])**2 + (yy[:, None]-yy[None, :])**2)
adj_mat  = (dist_mat <= 2).astype(int)
# joints will have more than 2 neighbors and endpoints
# will have only one.
ends = np.where(adj_mat.sum(1)==1)[0]
intersections = np.where(adj_mat.sum(1)>2)[0]

最后,变量“ends”将保存端点的索引,使得图像中端点 k 的[x, y] 位置将为[xx[ends[k]], yy[ends[k]]]。交叉口也是如此。

【讨论】:

  • 你的答案可能很精彩,但除非你解释你在做什么以及结果是什么,否则没人知道或理解......
  • @MarkSetchell,感谢您的评论。我希望我添加的评论能让事情变得更清楚。如果有什么我可以做得更好的,我会很高兴听到并改进它。
【解决方案2】:

我使用wand 完成此操作 - 它源自 ImageMagick。它有一个skeletonise 方法和“Hit and Miss Morphology”,用于查找特定形状,例如线端或连接点。

Anthony Thyssen here 进行了精彩的讨论,但如果我可以总结一下,您在尝试查找行端时正在寻找以下形状:

在寻找路口时:

黑色方块表示图像在该位置必须是黑色的,并且在代码的内核中表示为零。白色方块意味着图像在该位置必须是白色的,并且在代码的内核中表示为那些。空白方块表示我们“不关心”该位置有什么,并在代码中表示为破折号(减号)。

代码如下所示:

#!/usr/bin/env python3

import numpy as np
from wand.image import Image

# Use 'wand' to:
# 1 skeletonize
# 2 find line-ends using Top-Hat Morphology
# 3 find line-junctions using Top-Hat Morphology

with Image(filename='Q4J0l.png') as img:
    # Skeletonize
    img.morphology(method='thinning',
                   kernel='skeleton',
                   iterations=-1)
    img.save(filename='DEBUG-skeleton.png')

    # Find line-ends using Top-Hat Morphology
    # There are two kernels here, separated by a semi-colon
    # Each is rotated through 90 degress to form all 4 orientations
    # The first 3x3 kernel is the one tinted red in the diagram above.
    # The second 3x3 kernel is the one tinted green in the diagram above
    lineEnds = """
    3>:
        0,0,-
        0,1,1
        0,0,-;
    3>:
        0,0,0
        0,1,0
        0,0,1
    """
    # Clone the original image as we are about to destroy it
    with img.clone() as endsImage:
        endsImage.morphology(method='hit_and_miss', kernel=lineEnds)
        endsImage.save(filename='DEBUG-ends.png')

    # Find line-junctions using Top-Hat Morphology
    # There are three kernels here, separated by a semi-colon
    # Each is rotated through 90 degress to form all 4 orientations
    # The first 3x3 kernel is the one tinted yellow in the diagram above
    # The second 3x3 kernel is the one tinted magenta in the diagram above 
    # The third 3x3 kernel is the one tinted cyan in the diagram above
    lineJunctions = """
    3>:
        1,-,1
        -,1,-
        -,1,-;
    3>:
        -,1,-
        -,1,1
        1,-,-;
    3>:
        1,-,-
        -,1,-
        1,-,1
    """
    # Clone the original image as we are about to destroy it
    with img.clone() as junctionsImage:
        junctionsImage.morphology(method='hit_and_miss', kernel=lineJunctions)
        junctionsImage.save(filename='DEBUG-junctions.png')

调试图像如下:

调试骨架

调试行尾

调试连接


使用 ImageMagick 在终端中实际上要简单得多:

magick Q4J0l.png -morphology Thinning:-1 Skeleton skeleton.png
magick skeleton.png -morphology HMT lineends ends.png
magick skeleton.png -morphology HMT linejunctions junctions.png

或者您可以在一个命令中生成所有 3 个图像:

magick Q4J0l.png \
    -morphology Thinning:-1 Skeleton -write S.png              \
    \( +clone -morphology HMT lineends -write E.png +delete \) \
    -morphology HMT linejunctions J.png

【讨论】:

    猜你喜欢
    • 2021-05-09
    • 2018-09-15
    • 2016-06-07
    • 2018-01-03
    • 1970-01-01
    • 1970-01-01
    • 2022-12-14
    • 2016-04-12
    • 2016-09-07
    相关资源
    最近更新 更多