了解 3D 中“scipy.spatial.Voronoi”返回的山脊顶点

Understanding ridge vertices returned by `scipy.spatial.Voronoi` in 3D

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

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

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

例子

(vor.ridge_vertices中的int指的是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 对象。为此,我将我的对象网格化到表面的 select 点,将它们赋予函数 scipy.spatial.Voronoi 并使用对象内部的脊顶点作为我的骨架.

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

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

在 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。

我仍然不确定我是否答对了问题,如果我没答对请告诉我