网格数据
1. 网格
Open3D有一个称为TriangleMesh
的3D三角网格数据结构。下面的代码演示如何从ply文件中读取三角形网格并打印其顶点和三角形。
import open3d as o3d
import numpy as np
import matplotlib.pyplot as plt
import open3d_tutorial as o3dtut
print("Testing mesh in Open3D...")
mesh = o3dtut.get_knot_mesh()
print(mesh)
print('Vertices:')
print(np.asarray(mesh.vertices))
print('Triangles:')
print(np.asarray(mesh.triangles))
print("Try to render a mesh with normals (exist: " +
str(mesh.has_vertex_normals()) + ") and colors (exist: " +
str(mesh.has_vertex_colors()) + ")")
o3d.visualization.draw_geometries([mesh])
print("A mesh with no normals and no colors does not look good.")
TriangleMesh
类有一些数据字段,例如顶点和三角形。Open3D通过numpy提供对这些字段的直接内存访问。
注:open3d_tutorial.py 位于\examples\python文件夹下
2. 显示3D网格
print("Try to render a mesh with normals (exist: " +
str(mesh.has_vertex_normals()) + ") and colors (exist: " +
str(mesh.has_vertex_colors()) + ")")
o3d.visualization.draw_geometries([mesh])
print("A mesh with no normals and no colors does not look good.")
注:A mesh with no normals and no colors does not look good.
您可以旋转和移动网格,但它是用统一的灰色绘制的,看起来不像“3d”。原因是当前网格没有顶点或面的法线。因此,使用统一的颜色着色,而不是更复杂的Phong着色。
3. 曲面法向估计
让我们用曲面法线绘制网格。
print("Computing normal and rendering it.")
mesh.compute_vertex_normals()
print(np.asarray(mesh.triangle_normals))
o3d.visualization.draw_geometries([mesh])
绘制时使用了mesh
类中的compute_vertex_normals
和paint_uniform_color
两个函数。
4. 裁剪网格
我们通过直接操作网格triangle
和triangle_normals
数据场来去除一半的曲面。这是通过numpy完成的。
print("We make a partial mesh of only the first half triangles.")
# mesh = copy.deepcopy(mesh)
mesh.triangles = o3d.utility.Vector3iVector(
np.asarray(mesh.triangles)[:len(mesh.triangles) // 2, :])
mesh.triangle_normals = o3d.utility.Vector3dVector(
np.asarray(mesh.triangle_normals)[:len(mesh.triangle_normals) // 2, :])
print(mesh.triangles)
o3d.visualization.draw_geometries([mesh])
5. 给mesh上色
paint_uniform_color
使用统一的颜色绘制网格。颜色在RGB空间,[0,1]范围内。
print("Painting the mesh")
mesh1 = mesh
mesh1.paint_uniform_color([1, 0.706, 0])
o3d.visualization.draw_geometries([mesh1])
6. 取样
Open3D包含从三角形网格采样点云的函数。最简单的方法是sample_points_uniformly
,即基于三角形区域从三维曲面均匀采样点。参数number_of_points
定义了从三角形曲面中采样的点的数量。
import open3d as o3d
import numpy as np
import matplotlib.pyplot as plt
import open3d_tutorial as o3dtut
mesh = o3d.geometry.TriangleMesh.create_sphere()
mesh.compute_vertex_normals()
o3d.visualization.draw_geometries([mesh])
pcd = mesh.sample_points_uniformly(number_of_points=500)
o3d.visualization.draw_geometries([pcd])