【Open3D】入门处理与实战之可视化及相关基本操作
【Open3D】入门处理与实战之可视化及相关基本操作
文章目录
- 【Open3D】入门处理与实战之可视化及相关基本操作
- 前言
- 常见的三维数据格式
- 三维数据类型
- 点云数据
- PCL的格式
- Open3D的格式
- 网格数据
- STL格式
- PLY格式
- OBJ格式
- Open3d 点云读取写入可视化
- 简单示例代码
- o3d.io.read_point_cloud(读取点云数据)
- o3d.visualization.draw(可视化点云数据)
- o3d.io.write_point_cloud(写入点云数据)
- Open3d 网格读取写入可视化
- 简单示例代码
- o3d.io.read_triangle_mesh(读取网格数据)
- o3d.io.write_triangle_mesh(写入网格数据)
- Open3d RGB-D读取写入可视化
- 简单示例代码
- o3d.io.read_image(读取图像文件)
- o3d.geometry.RGBDImage.create_from_color_and_depth(创建 RGB-D 图像)
- o3d.camera.PinholeCameraIntrinsicParameters.PrimeSenseDefault(预定义的针孔相机内参集合)
- o3d.camera.PinholeCameraIntrinsic(针孔相机内参的类)
- o3d.geometry.PointCloud.create_from_rgbd_image(将 RGB-D 图像转换为点云)
- 三维数据基本操作
- geometry.paint_uniform_color (设置点云和网格颜色)
- geometry.estimate_normals(估计点云或网格法线向量)
- Open3D 法线估计邻域搜索策略
- geometry.select_by_index (选择点云或网格子集)
- o3d.utility.Vector3dVector(类型转换器)
- o3d.geometry.PointCloud.hidden_point_removal(去除点云中不可见点)
- 总结
前言
Open3D 是一个开源库,旨在支持快速开发处理 3D 数据的软件。它提供了精心挑选的 C++ 和 Python 数据结构和算法,并且后端经过高度优化并设置为并行化。
官方文档:http://www.open3d.org/docs/
GitHub仓库:https://github.com/isl-org/Open3D
常见的三维数据格式
三维数据类型
数据类型 | 描述 | 存储格式 | 特点 | 应用场景 |
---|---|---|---|---|
点云(Point Cloud) | 某个坐标系下的点数据集,每个点包括三维坐标X、Y、Z、颜色、分类值、强度值、时间等信息。 | pts、LAS、PCD、xyz、asc、ply等 | 数据密集,能直接反映物体表面形状,但文件较大且处理复杂。 | 激光雷达扫描、地形测绘、自动驾驶、三维重建等 |
三角网格(Mesh) | 多边形网格,常见的是三角网格,由点、法向、面组成。 | obj、stl、ply等 | 结构清晰,适合可视化和渲染,但可能丢失部分几何精度。 | 游戏建模、动画制作、3D打印、虚拟现实等 |
数模 | 三维数字模型是通过三维制作软件通过虚拟三维空间构建出具有三维数据的模型,由几何基元构成。 | IGS、part、model、IGES等 | 高精度,适合工程设计和制造,支持参数化建模。 | 工程设计、机械制造、建筑建模、产品设计等 |
点云数据
PCL的格式
PCD格式是用于存储点云数据的一种常见文件格式,通常与PCL(Point Cloud Library)库一起使用。它是一种灵活且高效的格式,可以存储三维坐标以及其他属性信息。
# .PCD v.5 - Point Cloud Data file format
VERSION .5 # 指定PCD文件的版本号 0.5
FIELDS x y z # 定义了每个点包含的字段及其名称xyz,表示三维空间坐标
SIZE 4 4 4 # 每个字段占用的字节数 4字节
TYPE F F F # 每个字段的数据类型 F浮点型float
COUNT 1 1 1 # 每个字段包含的元素数量 默认为1
WIDTH 397 # 点云数据集的宽度:对于有序点云表示每行的点数,对于无序点云表示总的点数
HEIGHT 1 # 点云数据集的高度:对于有序点云表示行数,对于无序点云通常是1
VIEWPOINT 0 0 0 1 0 0 0 # 视点信息:平移向量(前三个值)和四元数(后四个值),用于描述数据集中点云的获取视点
POINTS 397 # 点云中点的总数:WIDTH * HEIGHT
DATA ascii # 数据的存储类型 ascii
# 每一行代表一个点,包含三个浮点数分别对应x、y、z坐标
0.0054216 0.11349 0.040749
-0.0017447 0.11425 0.041273
-0.010661 0.11338 0.040916
0.026422 0.11499 0.032623
0.024545 0.12284 0.024255
0.034137 0.11316 0.02507
........
有序点云可以更高效地处理目标点与邻域之间的关系
有序点云:
WIDTH 640
HEIGHT 480
无序点云:
WIDTH 307200
HEIGHT 1
Open3D的格式
PLY(Polygon File Format)是一种用于存储三维模型数据的文件格式,支持ASCII和二进制两种编码方式,是 Open3D 中非常常见且推荐使用的格式之一。
ply # 表示这是一个PLY文件
format ascii 1.0 # 文件的格式是ASCII编码,版本为1.0
comment Created by CloudCompare v2.10.2 (Zephyrus) # 以comment开头,后面跟着注释内容,用于添加额外的信息或说明
comment Created 2020/3/31/星期二 15:51
obj_info Generated by CloudCompare! # 对象信息,说明文件由CloudCompare生成
element vertex 30000 # 表示顶点数,共有30000个顶点
property float x # 表示每个顶点浮点数三维坐标X、Y、Z
property float y
property float z
property uchar red # 表示每个顶点无符号字符红、绿、蓝颜色信息,范围是0-255;
property uchar green
property uchar blue
property float nx # 表示每个顶点浮点数法向量,用于描述顶点的朝向
property float ny
property float nz
property float scalar_Scalar_field # 表示一个标量场属性,可能用于存储额外的物理量温度、密度等
end_header # 表示头部信息结束,接下来是数据内容
# 每行对应一个顶点,属性(列)之间通常用空格或逗号分隔
# 坐标x/y/z + 颜色r/g/b + 法向量nx/ny/nz + 标量字段
-0.264363 -11.2626 1.13522 228 228 228 0.166045 0.00564778 0.986102 1601
0.818902 -10.047 1.86783 249 249 249 0.986742 0.160845 0.0216741 1937
0.705028 -9.49167 2.56208 250 250 250 0.981685 0.190339 -0.00807497 1953
0.43532 -6.25783 2.03446 231 231 231 0.991076 0.10705 -0.0794242 1649
0.767625 -9.79194 2.75606 251 251 251 0.96945 0.245052 0.0107584 1969
-0.635709 -6.73124 0.0234911 251 251 251 0.916862 0.30177 0.261342 1969
0.940078 -10.5603 3.10365 255 255 255 0.964818 0.262692 0.0108951 2033
0.945945 -10.5881 3.89729 240 240 240 0.982547 0.186011 0.00114117 1793
0.639458 -11.2239 0.980479 225 225 225 0.160573 0.00336866 0.987018 1553
-10.6315 -0.113972 2.27507 208 208 208 0.0457569 -0.170122 -0.98436 1281
........
网格数据
STL格式
STL(Standard Triangle Language)文件是一种用于表示三维物体表面几何形状的文件格式,主要用于快速原型系统和3D打印。它由3D Systems公司在1987年提出,最初用于立体光刻技术。
仅描述表面几何形状:STL文件只包含三维物体的表面信息,不包括颜色、材质贴图等其他属性。
STL文件有两种格式:ASCII明码格式和二进制格式。
- ASCII明码格式:以文本形式存储数据,便于阅读和编辑,但文件体积较大。
//字符段意义 solid filenametstl //文件路径及文件名 facet normal xyz //三角面片法向量的3个分量值outer loopvertex xyz //三角面片第一个顶点坐标vertex xyz //三角面片第二个顶点坐标vertex xyz //三角面片第三个顶点坐标endloop endfacet //完成一个三角面片定义 ...... //其他facet endsolid filenametstl //整个STL文件定义结束
- Binary二进制格式:以二进制形式存储数据,文件体积较小,读写速度更快,但不便于直接阅读。
UINT8[80]//Header//文件头 UINT32//Numberoftriangles//三角面片数量 foreachtriangle(每个三角面片中)REAL32[3]//Normalvector//法线矢量REAL32[3]//Vertex1//顶点1坐标REAL32[3]//Vertex2//顶点2坐标REAL32[3]//Vertex3//顶点3坐标 UINT16//Attributebytecountend//文件属性统计
局限性: 缺乏参数化信息,无法描述曲线和曲面,只能通过大量三角面片逼近复杂形状;无颜色和材质信息,不包含颜色、贴图等视觉属性,需要额外的处理才能实现彩色或纹理效果;精度问题,由于使用三角面片逼近曲面,可能会出现精度损失,特别是在处理高精度要求的模型时。
PLY格式
主要用于保存立体扫描结果的三维数值数据,并通过多边形片面对三维物体进行描述。每个顶点都有其三维坐标,这些顶点之间通过定义的连接关系形成多边形面片,相邻顶点组成的面的信息被用来描述物体的表面。
主要特点:三维数值存储可以存储从立体扫描得到的三维坐标数据;多边形描述通过集合多个多边形面片来描述三维物体的形状;丰富的属性支持,除了基本的顶点坐标外,还可以存储颜色、透明度、表面法向量、材质坐标和数据可信度等信息;双面属性设定,能够对多边形的正反两面设定不同的属性,增加了模型的表现力和灵活性。
PLY文件的两种版本:ASCII版本和Binary版本。
局限性:与STL格式类似,无法表示曲线和曲面,只能通过离散的顶点和由这些顶点组成的多边形面片来近似表示物体的形状,这意味着它不能直接表示连续的曲线或曲面,而是通过足够多的顶点和面片来逼近这些形状;离散顶点为基础:每个顶点都有其三维坐标,这些顶点之间通过定义的连接关系形成多边形面片。
ply # 文件开始标志,表示这是一个PLY文件
format ascii 1.0 # 指定文件格式为ASCII格式,版本号为1.0
comment made by anonymous # 以comment开头,后面跟着注释内容,用于添加额外的信息或说明
comment this file is a cube
element vertex 8 # 定义顶点元素,共有8个顶点
property float32 x # 定义每个顶点的属性,每个顶点有三个浮点数属性,分别表示X、Y、Z坐标
property float32 y
property float32 z
element face 12 # 定义面片元素,共有12个面片
property list uint8 int32 vertex_index # 定义面片的属性,每个面片由一个uint8类型的列表长度和一系列int32类型的顶点索引组成
end_header # 表示头部信息结束,接下来是数据部分
0 0 0 # 接下来8行定义了8个顶点的坐标
0 25.8 0
18.9 0 0
.....
3 5 1 0 # 接下来12行定义了12个面片,包含的顶点数量以及三个顶点索引
3 5 4 0
3 4 0 2
....
OBJ格式
OBJ(Object File Format) 是由Wavefront公司开发的一种标准3D模型文件格式,广泛应用于3D软件模型之间的导入导出。由于其开放性和灵活性,大部分知名的3D软件都支持OBJ文件的读写操作。
OBJ文件有两种格式:OBJ文件通常是一种纯文本文件,可以直接用文本编辑器打开进行查看和编辑,这使得它非常易于理解和修改;虽然OBJ文件也有二进制格式存在,但这种格式是非公开的,不被广泛使用。
# 任何以#开头的行都是注释行,用于提供额外的信息或说明,不会被解析器处理
# v开头的顶点数据段,定义模型的顶点列表,每一行描述一个顶点,行数等于顶点数
v 1.00 -1.00 -1.00 # 每个顶点由三维坐标(x,y,z)表示
v 1.00 1.00 1.00
......
# vt开头的纹理坐标数据段,定义模型顶点的纹理坐标列表,行数可能大于等于顶点数,因为一个模型顶点在贴图的UV坐标系中很可能对应多个顶点/纹理坐标
vt 0.74 0.75 # 每个纹理坐标由二维坐标(u,v)表示,坐标值范围在0-1之间
vt 0.29 0.55
......
# vn开头的法线数据段,定义顶点法线列表,行数大于等于顶点数,因为一个顶点可能参与构成多个面从而对应多个法线向量
vn -1.00 0.00 0.00 # 每个法线向量由三维坐标(x,y,z)表示
vn 1.00 0.00 0.00
......
# f开头的面数据段,定义模型的三角形面列表,每一行定义一个面
f 1/1/2 2/1/3 3/1/1 # 每个面由三个顶点索引组成,每个顶点索引可以包含顶点/纹理坐标/法线的索引值
f 2/2/1 3/3/4 4/1/1
f 1/1/5 10/1/8 14/6
......
f 1/1/2 2/1/3 3/1/1 具体解释
1/1/2从左到右分别表示顶点三维空间坐标索引1,对应顶点的纹理坐标索引,以及对应顶点的法线索引。
1/1/2 2/1/3 3/1/1 三组数据则表明每个面由三个顶点组成。
Open3d 点云读取写入可视化
简单示例代码
import open3d as o3d # 导入Open3D库
pcd = o3d.io.read_point_cloud("bunny.pcd") # 读取点云数据
o3d.visualization.draw(pcd) # 可视化点云数据
o3d.io.write_point_cloud("copy_bunny.pcd", pcd) # 保存点云数据
可视化点云:
o3d.io.read_point_cloud(读取点云数据)
函数原型
open3d.io.read_point_cloud(filename, format='auto', remove_nan_points=True, remove_infinite_points=True, print_progress=False)
返回一个 open3d.geometry.PointCloud 对象,如果读取失败,返回空的点云对象。
参数 | 参数说明 |
---|---|
filename (str) | 要读取的点云文件路径,支持的文件格式包括:.ply, .xyz, .xyzn, .xyzrgb, .pts, .pcd, .las, .laz 等。 |
format (str, 可选, 默认为 ‘auto’) | 指定文件格式,可手动指定格式如 ‘ply’, ‘xyz’, ‘pcd’ 等,如果设为 ‘auto’,函数会根据文件扩展名自动判断格式。 |
remove_nan_points (bool, 可选, 默认为 True) | 是否移除包含 NaN (非数字) 值的点,设置为 True 会自动过滤掉无效点。 |
remove_infinite_points (bool, 可选, 默认为 True) | 是否移除包含无限大值的点,设置为 True 会自动过滤掉无限值点。 |
print_progress (bool, 可选, 默认为 False) | 是否显示读取进度条,对于大文件,可以设置为 True 查看读取进度。 |
不同文件格式的支持的数据属性
o3d.visualization.draw(可视化点云数据)
旧版:draw_geometries
o3d.visualization.draw_geometries(geometry_list,window_name='Open3D',width=1920,height=1080,left=50,top=50,point_show_normal=False,mesh_show_wireframe=False,mesh_show_back_face=False,lookat=None,up=None,front=None,zoom=None)
参数 | 参数说明 |
---|---|
geometry_list (list) | 要可视化的几何对象列表,可以是 PointCloud, TriangleMesh, LineSet 等。 |
window_name (str, 可选) | 窗口标题,默认为 ‘Open3D’。 |
width/height (int, 可选) | 窗口宽度和高度,默认 1920x1080。 |
left/top (int, 可选) | 窗口在屏幕上的位置坐标 |
point_show_normal (bool, 可选, 默认为 False) | 是否显示点云法线 |
mesh_show_wireframe (bool, 可选, 默认为 False) | 是否显示网格线框 |
mesh_show_back_face (bool, 可选, 默认为 False) | 是否显示网格背面 |
lookat (NumPy数组,可选,元素类型 float) | 相机看向的目标点 [x,y,z] |
up (NumPy数组,可选,元素类型 float) | 定义相机的上方向向量 [x,y,z] |
front (NumPy数组,可选,元素类型 float) | 定义相机的前方向向量 [x,y,z] |
zoom (float,可选, 默认为 1.0) | 缩放系数 |
新版(Open3D 0.13+):draw
o3d.visualization.draw(geometry,title="Open3D",width=1024,height=768,actions=None,lookat=None,up=None,front=None,zoom=None,point_size=None,line_width=None,background_color=None,show_ui=None,raw_mode=False)
参数 | 参数说明 |
---|---|
geometry (list) | 要可视化的几何对象列表,可以是 PointCloud, TriangleMesh, LineSet 等。 |
title (str, 可选) | 窗口标题,默认为 ‘Open3D’。 |
width/height (int, 可选) | 窗口宽度和高度,默认 1920x1080。 |
actions (list, 可选) | 预定义的动作列表,可用于设置初始视图状态。 |
lookat (NumPy数组,可选,元素类型 float) | 相机看向的目标点 [x,y,z] |
up (NumPy数组,可选,元素类型 float) | 定义相机的上方向向量 [x,y,z] |
front (NumPy数组,可选,元素类型 float) | 定义相机的前方向向量 [x,y,z] |
zoom (float,可选, 默认为 1.0) | 缩放系数 |
point_size (float, 可选) | 点云显示的点大小。 |
line_width (float, 可选) | 线集的线宽 |
background_color (list, 可选) | 背景颜色 [R,G,B,A],范围 0-1 |
show_ui (bool, 可选) | 是否显示UI控件 |
raw_mode (bool, 可选) | 是否使用原始模式(禁用所有UI) |
o3d.io.write_point_cloud(写入点云数据)
函数原型
o3d.io.write_point_cloud(filename, pointcloud, write_ascii=False, compressed=False, print_progress=False)
返回一个是否写入成功的bool类型。
参数 | 参数说明 |
---|---|
filename (str) | 要保存的文件路径,扩展名决定文件格式,支持的文件格式包括:.ply, .xyz, .xyzn, .xyzrgb, .pts, .pcd, .las, .laz 等。 |
pointcloud (open3d.geometry.PointCloud对象) | 数据内容可以包含点坐标 (必须),颜色信息 (可选),法线信息 (可选)。 |
write_ascii (bool, 默认为False) | 以ASCII文本格式写入或者以二进制格式写入。 |
compressed (bool, 默认为False) | 是否启用压缩,仅对某些格式有效 (如PLY, LAZ)。 |
print_progress (bool, 默认为False) | 是否显示写入进度条,对于大文件,可以设置为 True 查看读取进度。 |
Open3d 网格读取写入可视化
简单示例代码
import open3d as o3d # 导入Open3D库
plymesh = o3d.io.read_triangle_mesh("bunny10k.ply") # 读取三角网格数据
o3d.visualization.draw(plymesh) # 可视化三角网格数据
o3d.io.write_triangle_mesh("copy_bunny10k.ply", plymesh) # 保存三角网格数据
可视化三角网格:
o3d.io.read_triangle_mesh(读取网格数据)
函数原型
open3d.io.read_triangle_mesh(filename,enable_post_processing=False,print_progress=False,legacy_verbose=False
)
返回一个 open3d.geometry.TriangleMesh 对象,如果读取失败,返回空的网格对象。
参数 | 参数说明 |
---|---|
filename (str) | 要读取的网格文件路径,支持的文件格式包括:.ply, .stl, .obj, .off, .gltf, .glb, .fbx等。 |
enable_post_processing (bool, 默认为False) | 新增于Open3D 0.15版本:是否自动执行顶点法线计算(如果文件未包含),重复顶点合并,退化三角形移除 |
print_progress (bool, 可选, 默认为 False) | 是否显示读取进度条,对于大文件,可以设置为 True 查看读取进度。 |
legacy_verbose (bool, 默认为False) | 旧版本兼容参数,控制旧版日志输出方式。 |
不同文件格式的支持的数据属性
注:✓=完全支持,△=部分支持,✗=不支持
o3d.io.write_triangle_mesh(写入网格数据)
函数原型
o3d.io.write_triangle_mesh(filename, mesh,write_ascii=False,compressed=False,write_vertex_normals=True,write_vertex_colors=True,write_triangle_uvs=True,print_progress=False,write_triangle_material=False
)
返回一个是否写入成功的bool类型。
参数 | 参数说明 |
---|---|
filename (str) | 要保存的文件路径,扩展名决定文件格式,支持的文件格式包括:.ply, .stl, .obj, .off, .gltf, .glb, .fbx等。 |
mesh (open3d.geometry.TriangleMesh对象) | 数据内容可以包含顶点坐标 (必须),三角面片索引 (必须),顶点颜色 (可选),顶点法线 (可选),纹理坐标 (可选),材质/纹理 (可选)。 |
write_ascii (bool, 默认为False) | 以ASCII文本格式写入或者以二进制格式写入。 |
compressed (bool, 默认为False) | 是否启用压缩,仅对某些格式有效 (如PLY, GLB)。 |
write_vertex_normals (bool, 默认为True) | 控制是否写入顶点法线,如果网格无法线数据,此参数无效。 |
write_vertex_colors (bool, 默认为True) | 控制是否写入顶点颜色,如果网格无颜色数据,此参数无效。 |
write_triangle_uvs (bool, 默认为True) | 控制是否写入纹理坐标,如果网格无纹理数据,此参数无效。 |
print_progress (bool, 可选, 默认为 False) | 是否显示读取进度条,对于大文件,可以设置为 True 查看读取进度。 |
Open3d RGB-D读取写入可视化
简单示例代码
import open3d as o3d # 导入open3d库
import matplotlib.pyplot as plt # 导入matplotlib库color_raw = o3d.io.read_image("00000.jpg") # 彩色图像
depth_raw = o3d.io.read_image("00000.png") # 对应的深度图像# 创建RGBD图像:将RGB图像和深度图像组合成一个RGBDImage对象
rgbd_image = o3d.geometry.RGBDImage.create_from_color_and_depth(color_raw, depth_raw, convert_rgb_to_intensity=False) # 创建RGBD图像# 显示两张图像
plt.subplot(1, 2, 1)
plt.title('Redwood grayscale image')
plt.imshow(rgbd_image.color)
plt.subplot(1, 2, 2)
plt.title('Redwood depth image')
plt.imshow(rgbd_image.depth)
plt.show()pcd = o3d.geometry.PointCloud.create_from_rgbd_image(rgbd_image, o3d.camera.PinholeCameraIntrinsic(o3d.camera.PinholeCameraIntrinsicParameters.PrimeSenseDefault)) # 将RGBDImage转换为点云
pcd.transform([[1, 0, 0, 0], [0, -1, 0, 0], [0, 0, -1, 0], [0, 0, 0, 1]]) # 对点云应用一个变换矩阵(yz轴取反)
o3d.visualization.draw_geometries([pcd]) # 点云可视化
matplotlib 显示两张图像:
可视化点云:
o3d.io.read_image(读取图像文件)
函数原型
open3d.io.read_image(filename,format='auto',try_decode_bitmaps=True
)
返回一个 open3d.geometry.Image 对象。
参数 | 参数说明 |
---|---|
filename (str) | 要读取的图像文件路径,支持UTF-8编码的文件路径,支持http://或https://开头的网络路径。支持的文件格式包括:.jpg, .png, .bmp, .tga 等。 |
format (str, 可选, 默认为 ‘auto’) | 指定文件格式,可手动指定格式如’jpg’/‘jpeg’,‘png’,‘bmp’,‘tga’,'hdr’和’exr等,如果设为 ‘auto’,函数会根据文件扩展名自动判断格式。 |
try_decode_bitmaps (bool, 可选, 默认为 True) | True则尝试解码压缩位图(如JPEG);False则直接读取原始数据(更快但可能丢失信息),得到单通道8位数据而非真彩色图像。 |
o3d.geometry.RGBDImage.create_from_color_and_depth(创建 RGB-D 图像)
函数原型
@staticmethod
def create_from_color_and_depth(color,depth,depth_scale=1000.0,depth_trunc=3.0,convert_rgb_to_intensity=True,stride=1
)
返回一个 o3d.geometry.RGBDImage 对象,包含两个图像:color纹理图,根据参数可能是单通道灰度或者三通道RGB;depth单通道深度,有效深度范围[0, depth_trunc]。
参数 | 参数说明 |
---|---|
color (o3d.geometry.Image) | 数据类型为uint8 (8位无符号整数);通道数可以为1(灰度)或3(RGB);宽度/高度必须与深度图匹配。 |
depth (o3d.geometry.Image) | 数据类型:uint16是最常见格式,实际深度 = 原始值 / depth_scale;float32则直接表示真实深度值。0值通常表示无效深度。 |
depth_scale (float) | 将整数深度值转换为实际物理单位。 |
depth_trunc (float) | 过滤过远的深度值(通常噪声较大),大于此值的深度会被设为0(无效值)。 |
convert_rgb_to_intensity (bool, 可选, 默认为 True) | 是否将RGB转换为单通道灰度,即是否将输出RGBD图像的color通道转换为单通道。 |
stride (int) | 新增于Open3D 0.15+版本,对图像进行下采样,加速处理大型RGB-D数据。 |
o3d.camera.PinholeCameraIntrinsicParameters.PrimeSenseDefault(预定义的针孔相机内参集合)
该函数是针对 PrimeSense 系列深度相机(如早期的 Kinect、Asus Xtion 等)的默认相机内存参数配置(PrimeSenseDefault):
相机内参(Intrinsic Parameters)是描述相机内部光学特性的参数,主要包括:焦距,主点坐标,图像分辨率以及畸变系数。
参数 | 参数说明 |
---|---|
width/height (int) | 图像宽度和高度(像素单位),默认 640x480。 |
fx/fy (int) | x轴/y轴焦距(像素单位),默认 (525.0,525.0) |
cx/cy (float) | 主点x坐标/y坐标(图像坐标系原点偏移的像素),默认 (319.5,239.5) |
返回一个预配置的 PinholeCameraIntrinsic 对象,包含 PrimeSense 相机的默认内参。
o3d.camera.PinholeCameraIntrinsic(针孔相机内参的类)
这里只简单介绍类的构造函数,暂时不在介绍其他成员函数。
通过预设参数构造
intrinsic = o3d.camera.PinholeCameraIntrinsic(o3d.camera.PinholeCameraIntrinsicParameters.PrimeSenseDefault)
通过具体参数构造
intrinsic = o3d.camera.PinholeCameraIntrinsic(width=640, height=480,fx=525.0,fy=525.0,cx=319.5,cy=239.5)
参数 | 参数说明 |
---|---|
width/height (int,可选) | 图像宽度和高度(像素单位) |
fx/fy (int,可选) | x轴/y轴焦距(像素单位),默认 (525.0,525.0) |
cx/cy (float,可选) | 主点x坐标/y坐标(图像坐标系原点偏移的像素),默认 (319.5,239.5) |
返回一个 PinholeCameraIntrinsic 对象,包含相机内参(width, height, fx, fy, cx, cy)的实例。
o3d.geometry.PointCloud.create_from_rgbd_image(将 RGB-D 图像转换为点云)
函数原型
@staticmethod
def create_from_rgbd_image(image,intrinsic,extrinsic=np.identity(4),project_valid_depth_only=True,depth_scale=1000.0,depth_trunc=1000.0,stride=1,with_normals=False
)
返回一个 o3d.geometry.PointCloud 对象。
参数 | 参数说明 |
---|---|
image (o3d.geometry.RGBDImage) | RGBDImage对象,包含有效的color和depth图像,两图像尺寸必须一致。 |
intrinsic (o3d.camera.PinholeCameraIntrinsic) | PinholeCameraIntrinsic对象,包含相机内参,与RGBD图像匹配。 |
extrinsic (4x4 np.ndarray,默认值np.identity(4)) | 将点云从相机坐标系变换到世界坐标系的变换矩阵,默认相机坐标系就是世界坐标系,不发生改变 。 |
project_valid_depth_only (bool) | 是否仅处理有效深度像素,使得生成的点云更干净,排除大量无效点。 |
depth_scale (float) | 将整数深度值转换为实际物理单位:实际深度 = 深度图值 / depth_scale |
depth_trunc (float) | 过滤过远的深度值(通常噪声较大),大于此值的深度会被设为0(无效值)。 |
stride (int,默认 1) | 控制点云密度,每隔指定采样点个数采样。 |
with_normals (bool,默认 False) | 新增于Open3D 0.17+版本,是否自动计算点云法线,执行会增加计算时间。 |
三维数据基本操作
geometry.paint_uniform_color (设置点云和网格颜色)
Open3D 中点云(PointCloud)和网格(TriangleMesh)对象的方法,用于为几何体所有元素(点/顶点)设置统一的颜色,会覆盖原有的任何颜色属性:PointCloud对象所有点设置为相同颜色;TriangleMesh对象所有顶点设置为相同颜色,面片颜色由顶点插值决定。
函数原型
geometry.paint_uniform_color(color)
返回修改后的几何体对象(会直接修改原对象),与输入类型相同。
参数 | 参数说明 |
---|---|
color (list 或 np.ndarray) | 3元素序列 [R, G, B],每个通道取值范围 0到1(不同于常规的0-255)。 |
典型示例:
红色:[1, 0, 0]
绿色:[0, 1, 0]
蓝色:[0, 0, 1]
白色:[1, 1, 1]
灰色:[0.5, 0.5, 0.5]
统一设置点云颜色示例:
import open3d as o3d # 导入Open3D库
pcd = o3d.io.read_point_cloud("bunny.pcd") # 读取点云数据
pcd.paint_uniform_color([1, 0, 1]) # 设置点云颜色
o3d.visualization.draw(pcd) # 可视化点云数据
对比此前的点云可视化结果:
统一设置网格颜色示例:
import open3d as o3d # 导入Open3D库
plymesh = o3d.io.read_triangle_mesh("bunny10k.ply") # 读取三角网格数据
plymesh .paint_uniform_color([1, 0, 1]) # 设置网格颜色
o3d.visualization.draw(plymesh) # 可视化三角网格数据
对比此前的网格可视化结果:
geometry.estimate_normals(估计点云或网格法线向量)
Open3D 中点云(PointCloud)和网格(TriangleMesh)对象的方法,用于估计点云或网格法线向量。
函数原型
geometry.estimate_normals(search_param=o3d.geometry.KDTreeSearchParamHybrid(radius=0.1, max_nn=30),fast_normal_computation=True,viewpoint=np.array([0., 0., 0.]),normals=None
)
无显式返回值,直接修改几何体的normals属性。可通过np.asarray(geometry.normals)转为NumPy数组获得。
参数 | 参数说明 |
---|---|
search_param (搜索策略) | 控制法线估计时的邻域搜索方式,支持三种模式: KDTreeSearchParamHybrid;KDTreeSearchParamKNN;KDTreeSearchParamRadius。 |
fast_normal_computation (bool,默认True) | True使用更快的近似算法,或者False使用更耗时但更准确的PCA计算。 |
viewpoint (3元素 np.ndarray) | 统一法线朝向指向该视点,视点为[0,0,0]或相机位置。 |
normals (可选,输出数组) | 新增于Open3D 0.16+版本,允许预分配内存,避免重复内存分配,提升性能。 |
点云法线估计:
import open3d as o3d
pcd = o3d.io.read_point_cloud("bunny.pcd") # 读取点云数据
pcd.paint_uniform_color([0, 0, 1]) # 设置点云颜色-蓝色
pcd.estimate_normals(search_param=o3d.geometry.KDTreeSearchParamHybrid(radius=0.01, max_nn=30)) # 估计点云法线
o3d.visualization.draw_geometries([pcd], point_show_normal=True) # 可视化点云数据
Open3D 法线估计邻域搜索策略
Open3D 提供了三种不同的邻域搜索策略来控制法线估计的行为,分别是 KDTreeSearchParamHybrid、KDTreeSearchParamKNN 和 KDTreeSearchParamRadius。
- KDTreeSearchParamHybrid(混合搜索)
控制条件 同时满足以下两个条件时停止搜索,搜索半径不超过radius;搜索半径不超过radius。
函数原型
参数详解 radius (float):点云局部曲率半径的2-3倍;max_nn (int): π×(预期局部点密度×radius²)。根据经验值设定。o3d.geometry.KDTreeSearchParamHybrid(radius=0.1,max_nn=30)
- KDTreeSearchParamHybrid(混合搜索)
控制条件 固定数量邻域,始终查找最近的k个点,不考虑距离。
函数原型
参数详解 knn:≈ 局部点密度× π r²,r=预期特征尺寸。o3d.geometry.KDTreeSearchParamKNN(knn=20)
- KDTreeSearchParamRadius(半径搜索)
控制条件 固定范围搜索,查找半径内的所有点,不考虑数量。
函数原型
参数详解 radius:≈ 应大于点云平均间距的3倍。o3d.geometry.KDTreeSearchParamRadius(radius=0.1)
核心概念对比
搜索策略 | 核心原理 | 核心原理 | 核心原理 |
---|---|---|---|
KDTreeSearchParamHybrid | 结合半径和最大点数限制 | 变密度点云(推荐默认) | 高 |
KDTreeSearchParamKNN | 固定近邻点数 | 均匀密度点云 | 最高 |
KDTreeSearchParamKNN | 固定搜索半径 | 结构特征提取 | 低(稀疏区域慢) |
geometry.select_by_index (选择点云或网格子集)
Open3D 中点云(PointCloud)和网格(TriangleMesh)对象的方法,用于根据索引选择几何体的子集。
函数原型
geometry.select_by_index(indices,invert=False,clean=False
)
返回一个与输入类型相同的新几何体对象,PointCloud,包含选定点的新点云;TriangleMesh,包含选定顶点及其相关面片的新网格。
参数 | 参数说明 |
---|---|
indices (list,tuple,np.ndarray) | 点云,索引对应点的顺序;网格,索引对应顶点的顺序。 |
invert (bool,默认False ) | False选择指定索引的元素,True选择不包含在索引中的元素。 |
clean (bool,默认False ) | 仅网格有效,False保留所有顶点,即使未被面片引用;True移除未被任何三角形引用的孤立顶点。 |
网格处理流程:选择指定顶点,移除包含未选择顶点的面片,clean=True时移除未被任何面片引用的顶点。
保留前20个点:
import open3d as o3d
pcd = o3d.io.read_point_cloud("bunny.pcd") # 读取点云数据
pcd = pcd.select_by_index(range(20)) # 选择前20个点
o3d.visualization.draw_geometries([pcd], point_show_normal=True) # 可视化点云数据
o3d.utility.Vector3dVector(类型转换器)
它是 Open3D 内部封装的一个数据结构,用于高效地传递和处理 3D 向量数据的核心工具类。将Python的数值数据转换为Open3D内部的高效数据结构,避免Python与C++间的数据拷贝,与源NumPy数组共享内存(当数据类型匹配时),提升性能。
用于任何需要批量处理3D向量的场合,表示三维向量集合的一个类:点云坐标设置;法线向量存储;法线向量存储。共享内存导致修改原始数组会影响已创建的Vector3dVector。
构造函数
o3d.utility.Vector3dVector(data)
返回一个Open3D内部的std::vectorEigen::Vector3d包装对象,支持与NumPy数组的无缝转换。
参数 | 参数说明 |
---|---|
data(list,np.ndarray或其他可迭代对象) | NumPy数组必须为N×3的float64类型;列表则为俩层列表且子列表必须是数值类型的3个元素;生成器表达式必须能转换为Nx3形式。 |
根据索引点设置对应颜色:
import open3d as o3d
import numpy as nppcd = o3d.io.read_point_cloud("bunny.pcd") # 读取点云数据
pcd.paint_uniform_color([0, 0, 1]) # 设置点云颜色-蓝色# 获取颜色数组并修改部分点的颜色-红色
color = np.array(pcd.colors)
inlier = [i for i in range(0, color.shape[0]) if i % 2==0]
color[inlier] = [1, 0, 0]pcd.colors = o3d.utility.Vector3dVector(color[:, :3]) # 重新赋值给点云对象颜色属性
o3d.visualization.draw(pcd) # 可视化点云数据
o3d.geometry.PointCloud.hidden_point_removal(去除点云中不可见点)
常用于点云预处理和表面重建前的数据清理。
函数原型
o3d.geometry.PointCloud.hidden_point_removal(viewpoint,radius,n_points=None,visibility_score=None
)
返回两个对象的元组:visible_cloud (PointCloud)仅包含可见点的新点云对象,保留原始点的所有属性;visible_indices (List[int])visible_indices (List[int])。
参数 | 参数说明 |
---|---|
viewpoint (3元素 np.ndarray) | 相机/观察者位置 |
radius (float) | 控制可见性判断的搜索范围,应大于点云最大尺寸。 |
n_points (int, 可选) | 新增于Open3D 0.16+版本,指定期望输出的可见点数,自动调整阈值保留最可见的点。 |
visibility_score (np.ndarray, 可选) | 新增于Open3D 0.17+版本,预计算的可见性分数。 |
算法原理
基于球形投影和深度测试,将点云投影到以视点viewpoint为中心的球面上,对每个球面像素保留最近的点,移除被其他点遮挡的点。
数学实现
- 对于点 pip_ipi,计算球面坐标(俯仰角θθθ和方位角φφφ):
θ=atan2(py,px),φ=acos(pz/∣∣p∣∣)θ = atan2(p_y, p_x),φ = acos(p_z/||p||)θ=atan2(py,px),φ=acos(pz/∣∣p∣∣) - 多个点云可能在同一球面坐标,计算球面坐标到视点的最小距离,即当前球面坐标中距离视点最近的点云的距离,建立深度缓冲:
dbuf(θ,φ)=min(∣∣pj−viewpoint∣∣)d_{buf}(θ,φ) = min(||p_j - viewpoint||)dbuf(θ,φ)=min(∣∣pj−viewpoint∣∣) - 可见性判断,留下每个球面坐标中距离视点最近的点云pip_ipi ,可见当且仅当:
∣∣pi∣∣==dbuf(θi,φi)||p_i|| == d_{buf}(θ_i,φ_i)∣∣pi∣∣==dbuf(θi,φi)
隐藏点移除:
import open3d as o3d
pcd = o3d.io.read_point_cloud("bunny.pcd") # 读取点云数据
_, pt_map = pcd.hidden_point_removal([0, 0, 0.2], 3) # 移除从给定视角无法看到的点
pcd = pcd.select_by_index(pt_map) # 根据隐藏点移除的结果选择点
o3d.visualization.draw_geometries([pcd], point_show_normal=True) # 可视化点云数据
总结
Open3D的可视化及相关基本操作。