点云到体素

6
我有一个笛卡尔坐标系下的点云。我想使用Python将这些点包裹在网格中,然后计算出点云的体积。这些点分布在整个点云中,而不仅仅是代表最外层表面的点。我想要包裹最外层表面。请问有哪个库可以帮助我完成这个任务?您推荐我使用哪些函数来包裹和计算体积呢?
谢谢您提前的帮助!

你有查看过 BallPivoting 算法吗? - abenci
1个回答

13

你需要做的是计算您点云的凸包

您可以使用https://github.com/daavoo/pyntcloud来完成此操作(欢迎贡献)。

以下是步骤:

从文件加载点云:

from pyntcloud import PyntCloud
diamond = PyntCloud.from_file("test/data/diamond.ply")

以下是示例点云的外观: point cloud

计算凸包

这里使用了scipy对Qhull库的封装:

convex_hull_id = diamond.add_structure("convex_hull")

您可以通过以下方式访问凸包:

convex_hull = diamond.structures[convex_hull_id]

可视化凸包

您可以按照以下步骤从凸包中生成网格:

diamond.mesh = convex_hull.get_mesh()

将点云和网格保存到文件中(例如ply格式),并在任何3D网格软件(例如Meshlab)中进行可视化:

diamond.to_file("diamond_hull.ply", also_save=["mesh"])

以下是在meshlab中可视化输出的结果:

mesh

从凸包中获取体积

最后,你可以像这样轻松地访问凸包的体积:

volume = convex_hull.volume

使用球进行测试

为了测试此方法的精度,您可以运行以下代码。

这将生成一个半径为25的球体点云,并使用凸包计算该球的体积:

from pyntcloud import PyntCloud
from pyntcloud.geometry.models.sphere import create_sphere
cloud = PyntCloud(create_sphere(center=[0, 0, 0], radius=25, n_points=100000))
convex_hull_id = cloud.add_structure("convex_hull")
convex_hull = cloud.structures[convex_hull_id]
print(convex_hull.volume)

输出:

65439.21101051165

由于它是一个球体,我们实际上可以计算出真实的体积:

import numpy as np
# google: volume of sphere
print((4/3) * np.pi * (25 ** 3))

输出:

65449.84694978735

考虑到我们使用米作为单位,并且只用十万个点来近似表示球体,Whit的回答已经相当接近了。


1
在最新版本的 pyntcloud 中,应该将 volume = convex_hull.volume 替换为 volume = convex_hull.get_feature_vector() - Haozhe Xie

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接