Open3d 一 点云mesh的入门级操作

本博文主要介绍了3d点云的入门级知识已经入门级操作,最终实现了将点云与mesh的相关转换。

1. 什么是点云数据

点云数据是指在一个三维坐标系中的一组向量的集合。这些向量通常以X,Y,Z三维坐标的形式表示,一般主要代表一个物体的外表面几何形状,除此之外点云数据还可以附带RGB信息,即每个坐标点的颜色信息,或者是其他的信息(强度信息)。

2.点云数据格式

点云数据通常以文本的形式进行存储,常见格式有以下6种,其中ply与pcd格式比较特殊。
在这里插入图片描述

2.1 ply文件格式

PLy多边形文件格式,又被称作斯坦福三角形格式,它是一种为了储存计算机多边形图形集对象的格式。它既可以存储点云数据,也可以存储mesh数据。其格式组成:

头:声明数据格式,规定和点和面片的数据内容
点:点的数据内容(坐标x,y,z 颜色r,g,b等)
线:线的数据内容(组成线的点序号索引,颜色等)
面片:面片的数据内容(组成面的点序号索引,颜色等)
以上内容参考自:[3D基本知识]PLY格式-CSDN博客

2.2 pcd文件

是PCL库中使用的一种标准化的点云数据存储格式,由文件头(Header)和数据表(Data Table)组成。具体数据实例如下所示:

# .PCD v.7 - Point Cloud Data file format
VERSION 0.7
FIELDS x y z rgb
SIZE 4 4 4 4
TYPE F F F F
COUNT 1 1 1 1
WIDTH 213
HEIGHT 1
VIEWPOINT 0 0 0 1 0 0 0
POINTS 213
DATA ascii
0.93773 0.33763 0 4.2108e+06
0.90805 0.35641 0 4.2108e+06
0.81915 0.32 0 4.2108e+06
0.97192 0.278 0 4.2108e+06
0.944 0.29474 0 4.2108e+06

以上内容参考自:PCD点云文件格式解读及在线渲染工具 - 知乎 (zhihu.com)

3、哪些工具可以处理3d点云数据?

常见用于处理3d点云数据的开源库有Open3d与pcl

3.1 Open3d

Open3d是一个开源库,支持快速开发处理3D数据的软件。Open3D后端是用C++实现的,经过高度优化并通过Python的前端接口公开。Open3D提供了三种数据结构: 点云 (point cloud)、网格(mesh)和RGB-D图像。对于每个表示,open3D都实现了一整套基本处理算法,如I/O、采样、可视化和数据转换。此外,还包括一些常用的算法,如法线估计、ICP 配准等。
Open3D的核心功能包括:
三维数据结构
三维数据处理算法
场景重建
曲面对齐
三维可视化
基于物理的渲染(PBR)
基于PyTorch和TensorFlow的三维机器学习支持
对三维数据操作用GPU加速
支持C++和Python

通过pip install open3d 即可在python环境中按照open3d 软件包,本博文后续的操作均使用open3d实现。

3.2 pcl

PCL(Point Cloud Library)是在吸收了前人点云相关研究基础上建立起来的大型跨平台开源C++编程库,它实现了大量点云相关的通用算法和高效数据结构,涉及到点云获取、滤波、分割、配准、检索、特征提取、识别、追踪、曲面重建、可视化等。支持多种操作系统平台,可在Windows、Linux、Android、Mac OS X、部分嵌入式实时系统上运行。

4、点云、体素、mesh之间的关系?

点云是不规则的数据结构,就是用一堆点来表示物体,这种方法的限制是点与点之间没有联系,缺乏物体的表面信息。点云一般采用NxNxN的三维矩阵,或编码xyz三个通道的栅格数据,或以深度图的方式进行表示。

体素就相当于图像中的像素,可以理解为三维物体中的像素。将点云转换为体素,就可以将2d图像领域的处理规则挪用到三维领域,如使用3D卷积等方式直接对体素进行处理,但会消耗大量的计算资源。通常,点云转体素会将多个点合并为一个体素格,该操作会降低数据的分辨率。

Mesh也就是三角网格,其通过多个三角网格来表示3维物体的形态。三角网格存储着顶点、边和面的信息。顶点:每个三角形都有三个顶点,各顶点都有可能和其他三角形共享。边:连接两个顶点的边,每个三角形有三条边。面:每个三角形对应一个面,我们可以用顶点或边列表表示面。

模型是真实物体的数字映射,包含了形态(可用mesh表示)、材质(柔性可变形的,钢性不可变形的)、纹理|texture(表面图案)。通常以mesh+texture的方式形成3d模型,这种模型可用于3d打印;但在3d游戏中的模型通常还包含材质。

4.1 点云转体素

将点云只进行体素划分,计算非空体素的质心代替该体素内的所有点,即可实现点云的下采样。 以下代码可以实现将点云转换为体素,其中关键参数voxel_size决定了体素网格的大小,越大则转换后的体素越失真。点云转体素的操作是不可逆的。

import open3d as o3d
import numpy as np
import copy
#点云读写
print("->正在加载点云... ")
pcd = o3d.io.read_point_cloud("2023_09_27_14_10_50/PointCloudxyzrgb/00000003.txt", format='xyzrgb')
voxel_grid = o3d.geometry.VoxelGrid.create_from_point_cloud(pcd ,voxel_size=30)
o3d.visualization.draw_geometries([voxel_grid])

原始点云图如下所示:
在这里插入图片描述

体素图如下所示:
在这里插入图片描述

4.2 点云转mesh

点云转mesh首先要进行一个法线估计,然后要设置滚球半径。

import open3d as o3d

pcd = o3d.io.read_point_cloud("points cloud document/cat.pcd")
# 法线估计
radius1 = 0.1   # 搜索半径
max_nn = 100     # 邻域内用于估算法线的最大点数
pcd.estimate_normals(search_param=o3d.geometry.KDTreeSearchParamHybrid(radius1, max_nn))     # 执行法线估计
#估计滚球半径
distances = pcd.compute_nearest_neighbor_distance()
avg_dist = np.mean(distances)
radius = 1.5 * avg_dist   
#将点云转换为mesh
mesh = o3d.geometry.TriangleMesh.create_from_point_cloud_ball_pivoting(
           pcd,
           o3d.utility.DoubleVector([radius, radius * 2]))
#进行mesh的可视化
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的保存mesh
o3d.io.write_triangle_mesh("cat_hole2.ply", mesh)
#使用trimesh保存mesh
import trimesh
import numpy as np
tri_mesh = trimesh.Trimesh(np.asarray(mesh.vertices), np.asarray(mesh.triangles),
                          vertex_normals=np.asarray(mesh.vertex_normals))
trimesh.convex.is_convex(tri_mesh)
tri_mesh.export("cat_hole.ply")

代码运行生成的mesh图如下所示:
在这里插入图片描述

4.3 mesh转点云

import open3d as o3d
mesh = o3d.io.read_triangle_mesh("cat_hole2.ply")
#有多种转换方法,https://blog.csdn.net/weixin_53610475/article/details/128188372
#均匀采样5000个点
pcd = mesh.sample_points_uniformly(number_of_points=5000)
#泊松采样5000个点,边缘点分布更加均匀,但是耗时更长
pcd = mesh.sample_points_poisson_disk(number_of_points=5000, init_factor=10)
o3d.visualization.draw_geometries([pcd],  mesh_show_wireframe=True, mesh_show_back_face=True,)

原始mesh图如下所示:
在这里插入图片描述
代码运行后生成的点云如下图所示:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/m0_74259636/article/details/134408710
今日推荐