点云是由大量的点组成的三维数据集,而mesh是由三角形组成的三维模型。点云转换为mesh的过程称为曲面重建。曲面重建的目的是从点云数据中提取出表面的形状信息。曲面重建的方法有很多种,其中一种常用的方法是贪心投影三角化法。该方法的大致流程如下:将点云通过法线投影到某一二维坐标平面内,对投影得到的点云做平面内的三角化,从而得到各点的拓扑连接关系。最后根据平面内投影点的拓扑连接关系确定各原始三维点间的拓扑连接,所得三角网格即为重建得到的曲面模型(mesh)。
1、基本转换(点云直接转mesh)
关键词:点云法线、点的法向量、法线的作用
点云法线计算的原理是通过计算点云中每个点的法向量来得到整个点云的法向量。法向量是垂直于曲面的向量,它可以用于描述曲面的方向和形状(区分凹凸)。在点云中,每个点的法向量可以通过计算其周围的点的几何特征来得到。
计算点的法向量有两种方法:基于协方差矩阵的方法、基于曲率的方法。基于协方差矩阵的方法是通过计算每个点周围的点与该点的协方差矩阵来得到该点的法向量
。基于曲率的方法是通过计算点s附近的多个点拟合出一个平面,然后求拟合平面的法线,该法线即为点s的法线
。
法线可用于点云的渲染、区分正反面、重建、法线贴图。在点云渲染中主要是设置点云或模型的光照效果,用于区分物体正侧面、得到物体的凹凸感(如下图左兔子纯色渲染没有立体感,而下图右兔子则有明暗区别,体现出较强的立体感)。
我们可以基于点云的渲染效果来初步判定法线的正确性,光源在模型的正前方,下图右模型的阴影区域与模型立体结构明显不符,故可得出该点云区域法线方向计算错误。
区分正反面,通过对点s附近的点的法线方向进行统计,使其保持在一个大方向,使相邻点法线方向变化最小,即可矫正方向错误的法线。
以上内容与图片参考自:http://geometryhub.net/notes/pointcloudnormal
https://www.shili8.cn/article/detail_20000668276.html
http://geometryhub.net/notes/pointcloudnormal
1.1 完整代码案例
import open3d as o3d
import numpy as np
import trimesh
import copy
pcd = o3d.io.read_point_cloud("points cloud document/cat.pcd")
#转换的mash存在孔洞
# 法线估计
radius1 = 0.1 # 搜索半径
max_nn = 100 # 邻域内用于估算法线的最大点数
pcd.estimate_normals(search_param=o3d.geometry.KDTreeSearchParamHybrid(radius1, max_nn)) # 执行法线估计
# 可视化
o3d.visualization.draw_geometries([pcd],
window_name = "可视化参数设置",
width = 600,
height = 450,
left = 30,
top = 30,
point_show_normal = True)
# 滚球半径的估计
distances = pcd.compute_nearest_neighbor_distance()
avg_dist = np.mean(distances)
radius = 1.5 * avg_dist
mesh = o3d.geometry.TriangleMesh.create_from_point_cloud_ball_pivoting(
pcd,
o3d.utility.DoubleVector([radius, radius * 2]))
print(mesh.get_surface_area())
o3d.visualization.draw_geometries([mesh], window_name='Open3D downSample', width=800, height=600, left=50,
top=50, point_show_normal=True, mesh_show_wireframe=True, mesh_show_back_face=True,)
# 从open3d创建具有顶点和面的三角形网格
tri_mesh = trimesh.Trimesh(np.asarray(mesh.vertices), np.asarray