3

我不明白函数scipy.spatial.Voronoi的脊顶点的返回格式。在 2D 中使用此功能时,一个脊的顶点成对出现,这是我期望的格式,但在 3D 中,脊中的顶点数往往超过 2 个点。

为什么一个山脊需要超过 2 个点?

通过一些后处理,我可以将格式简化为每个脊 2 个点吗?

例子

intvor.ridge_vertices指的是 中的点索引vor.vertices

import numpy as np
from scipy.spatial import Voronoi

# for 2D
points = np.array([[0, 0], [0, 1], [0, 2],
                   [1, 0], [1, 1], [1, 2],
                   [2, 0], [2, 1], [2, 2]])

vor = Voronoi(points)

# vor.vertices :
# [[0.5 0.5]
#  [0.5 1.5]
#  [1.5 0.5]
#  [1.5 1.5]]
#
# vor.ridge_vertices : (only pairs of vertices)
# [[-1, 0],
#  [-1, 0],
#  [-1, 1],
#  [-1, 1],
#  [0, 1],
#  [-1, 3],
#  [-1, 2],
#  [2, 3],
#  [-1, 3],
#  [-1, 2],
#  [1, 3],
#  [0, 2]]
import numpy as np
from scipy.spatial import Voronoi

# for 3D
points = np.array([[0, 0, 0], [0, 0, 1], [0, 0, 2],
                   [0, 1, 0], [0, 1, 1], [0, 1, 2],
                   [0, 2, 0], [0, 2, 1], [0, 2, 2],
                   [1, 0, 0], [1, 0, 1], [1, 0, 2],
                   [1, 1, 0], [1, 1, 1], [1, 1, 2],
                   [1, 2, 0], [1, 2, 1], [1, 2, 2]])

vor = Voronoi(points)

# vor.vertices :
# [[0.5 1.5 0.5]
#  [0.5 0.5 0.5]
#  [0.5 0.5 1.5]
#  [0.5 1.5 1.5]]
#
# vor.ridge_vertices : (3-4 vertices per ridge)
# [[3, 0, -1],
#  [0, -1, 1],
#  [1, 0, 3, 2],
#  [2, 1, -1],
#  [2, 3, -1],
#  [3, -1, 0],
#  [-1, 1, 0],
#  [-1, 3, 0],
#  [-1, 1, 0],
#  [-1, 2, 3],
#  [-1, 1, 2],
#  [-1, 1, 2],
#  [-1, 2, 3]]

语境:

我想使用 voronoi 脊顶点来骨架化 3D 对象。为此,我将对象网格化以选择表面的点,将它们提供给函数scipy.spatial.Voronoi并使用对象内部的脊顶点作为我的骨架。

作为一种解决方法,我目前正在使用这些区域来猜测山脊顶点,但它容易出现错误并且速度很慢。学习如何正确使用返回的脊顶点应该可以解决这个问题。

我想使用 voronoi 骨架化的原因是因为它似乎最容易实现。我知道skimage.morphology.skeletonize_3d,但它往往会丢失较小的细节(不够明智)并且没有可使用的参数。

4

1 回答 1

3

在 2D 中,区域由一条线段分隔,因此每个脊总是 2 个点。在 3D 及更高版本中,区域分隔“平面段”通常是三角形的,但它们也可以有 4 个以上的边。

出于立体化目的,一种方法是显示分离区域的轮廓,跳过虚拟 (-1) 点。因此,[3, 0, -1]将转换为点 3 和 0 之间的一条线。[1, 0, 3, 2]将生成线段 1-0、0-3、3-2、2-1。作为一项额外的改进,具有 4 个以上点的山脊可以进一步拆分为三角形,因此在[1, 0, 3, 2]另一个分段的情况下将是 0-2 或 1-3。

我仍然不确定我的问题是否正确,如果没有,请告诉我

于 2021-08-29T20:08:53.633 回答