3D场景下scipy.spatial.Voronoi返回ridge_vertices格式问题咨询
解答
问题1:为什么3D场景下ridge_vertices的顶点数超过2个
核心原因是你对scipy.spatial.Voronoi的属性定义存在误解:该类中的ridge指代n维Voronoi图中两个Voronoi单元的公共边界,维度永远是输入维度减1:
- 2D输入时,ridge是1维线段,天然只有2个端点,符合你的预期
- 3D输入时,ridge是2维多边形面,自然需要3个及以上顶点来定义面的轮廓,这就是你看到3D场景下每个
ridge_vertices包含3~4个顶点的原因。
问题2:如何得到每条对应2个顶点的1维脊线(满足骨架提取需求)
不需要通过regions反向推导,直接对ridge_vertices做简单后处理即可得到你要的1维边:
3D下每个ridge_vertices存储的是多边形面的有序顶点,你只需要遍历每个面的顶点列表,把相邻顶点(最后一个顶点还要和第一个顶点配对)两两组合,过滤掉包含-1(无穷远点)的无效边,再做一次去重(相邻的面会共享同一条边),就能得到所有仅含2个顶点的Voronoi边,速度远高于你现有的临时方案,稳定性也更好。
后处理示例代码
import numpy as np from scipy.spatial import Voronoi def get_1d_voronoi_edges(vor: Voronoi) -> np.ndarray: edges = set() for ridge in vor.ridge_vertices: # 过滤掉有效顶点不足2的无效脊 valid_verts = [v for v in ridge if v != -1] if len(valid_verts) < 2: continue # 遍历多边形顶点,相邻两两配对 for i in range(len(valid_verts)): v1 = valid_verts[i] v2 = valid_verts[(i+1) % len(valid_verts)] # 统一顺序避免重复存储同一条边 if v1 > v2: v1, v2 = v2, v1 edges.add((v1, v2)) return np.array(list(edges))
3D骨架提取场景补充建议
得到所有1维边后,你可以额外增加一步校验:只保留两个端点都落在原始3D对象内部的边,过滤掉对象外部的Voronoi边,剩下的就是符合要求的骨架结构,可保留更多细节。
内容的提问来源于stack exchange,提问作者Takyon
相关产品推荐
相关产品推荐

