曲面
最原始的点云只包含了点的位置信息,这些信息可以呈现出一些散点,但并不能还原出物体的样貌。相比之下,曲面更加完美地表现物体,我们平时看到的三维模型,实际上也是通过曲面来实现的。
open3d对曲面对象也有着非常不错的支持,并提供了示例文件,如下图所示
其中,左图是曲面对应的点云数据;中图是未生成法线的曲面图;右图是生成法线的曲面图,绘图代码如下。
import open3d as o3d
from copy import deepcopy
pcdPath = o3d.data.KnotMesh()
pcd = o3d.io.read_point_cloud(pcdPath.path)
mesh = o3d.io.read_triangle_mesh(pcdPath.path)
meshBare = deepcopy(mesh).translate((200, 0, 0))
mesh.compute_vertex_normals()
meshNormal = deepcopy(mesh).translate((400, 0, 0))
o3d.visualization.draw_geometries([pcd, meshBare, meshNormal])
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
由代码可知,尽管打开的是同一数据,但【read_point_cloud】和【read_triangle_mesh】将得到两种不同的数据类型。
【compute_vertex_normals】用于计算曲面的法向量。
法线
所谓法线,就是平面的垂线,众所周知三点就可以连成一个平面,那么点云中那么多点,每个点周围又有很多点,故而点云也可以生成法线。下面右图便是由knot点云生成的法线图
代码如下
pcdNormal = deepcopy(pcd).translate((200, 0, 0))
pcdNormal.estimate_normals()
o3d.visualization.draw_geometries([pcd, pcdNormal], point_show_normal=True)
- 1
- 2
- 3
【estimate_normals】即为生成法线的方法,有两个输入参数,其中 search_param
为k-d树的索引参数,用以生成法线时索引邻近点;fast_normal_computation
为布尔型的参数,顾名思义,为 True
时将开启加速,但可能会导致数值不稳定。
Alpha Shapes曲面重建
点云和曲面之间,并不仅仅隔着一层法线,通过点云重建曲面需要算法的加持。Alpha Shapes算法又叫滚球法,思想很简单,不妨先从二维着手来理解。
假设平面上有一群点,然后我手里有一个球,只要我这个球足够大,那么当这个球滚向这群点之后,就会把最外层的点的轮廓描绘出来,而不至于串入点集的内部。将这种二维的滚圆法推广到三维,就是滚球法。
对于fragment点云而言,当 α \alpha α取值分别为0.1和0.2时,其生成曲面对比如下,其中左侧是原图。
可见,当滚球的半径太大的时候,会把本来不相连的物体连接在一起。实现代码如下
tri = o3d.geometry.TriangleMesh
pcdDemo = o3d.data.PCDPointCloud()
pcd = o3d.io.read_point_cloud(pcdDemo.path)
meshes = [pcd]
alpha = 0
for i in range(1,3):
alpha += 0.1
tmpPcd = deepcopy(pcd).translate((i*2.5, 0, 0))
tmpMesh = tri.create_from_point_cloud_alpha_shape(tmpPcd, alpha)
tmpMesh.compute_vertex_normals()
meshes.append(tmpMesh)
o3d.visualization.draw_geometries(meshes, mesh_show_back_face=True)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
【create_from_point_cloud_alpha_shape】就是生成Alpha shapes的函数,其中输入为点云和alpha参数。
评论记录:
回复评论: