点云(Point Cloud)

这篇文章将会介绍点云数据的一些基本用法。(本教程可视化的点云数据为官方图片,自己可以根据手头数据进行测试,或者去官方github主页下载对应测试数据)

可视化点云

本教程的第一部分是读取点云数据并将其可视化。

print("Load a ply point cloud, print it, and render it")
pcd = o3d.io.read_point_cloud("../../TestData/fragment.ply")
print(pcd)
print(np.asarray(pcd.points))
o3d.visualization.draw_geometries([pcd])>>>>Load a ply point cloud, print it, and render it
>>>>geometry::PointCloud with 196133 points.[[0.65234375 0.84686458 2.37890625][0.65234375 0.83984375 2.38430572][0.66737998 0.83984375 2.37890625]...[2.00839925 2.39453125 1.88671875][2.00390625 2.39488506 1.88671875][2.00390625 2.39453125 1.88793314]]


read_point_cloud 用来读取点云数据。他尝试通过文件扩展名来解码文件。支持的文件格式在上一节有介绍。
draw_geometries 可视化点云数据。使用鼠标可以查看不同视角的数据。
这个图看着像一个密集表面,实际上还是由无数个点组成。可视化的GUI支持多个快捷键。比如可以通过 - 键来缩小点云中点的尺寸。

Note:

在GUI窗口按 h 键可以输出所有快捷键的列表,关于可视化更多的信息,后面会在介绍。

Note:

在OS X,GUI的快捷键可能不会生效,请使用pythonw替代python来启动Python

体素降采样

体素降采样通过使用规则体素网格从输入点云创造一致化降采样点云。这通常在点云处理任务的预处理步骤,这个算法分为两步:

  1. 把点云装进体素网格
  2. 把每个被占据的体素中的点做平均,取一个精确的点。
print("Downsample the point cloud with a voxel of 0.05")
downpcd = pcd.voxel_down_sample(voxel_size=0.05)
o3d.visualization.draw_geometries([downpcd])>>>>Downsample the point cloud with a voxel of 0.05

顶点法线估计

点云的基本操作还包括定点法线估计。按 n 查看点云法线。使用 - 和 + 可以缩放法线长度。

print("Recompute the normal of the downsampled point cloud")
downpcd.estimate_normals(search_param=o3d.geometry.KDTreeSearchParamHybrid(radius=0.1, max_nn=30))
o3d.visualization.draw_geometries([downpcd], point_show_normal=True)>>>>Recompute the normal of the downsampled point cloud


estimate_normals 计算每个点的法线。这个函数通过对邻点采用协方差分析(covariance analysis)来计算主轴。
这个函数使用KDTreeSearchParamHybrid类的一个实例作为参数。这里有两个关键参数是radius = 0.1 & max_nn = =30 ,用来设置搜索半径和邻域最大点数。这里设置搜索半径为10cm,并且只考虑邻域内的30个点,以此来节约计算时间。

Note:

协方差分析会产生两个方向相反的法线候选,如果不考虑全局结构的话,二者都是正确的。这就是所谓的法向问题。如果法线存在open3d会尝试将法线定位与原始法线对齐。否则open3d将会随机选择。如果需要考虑朝向的话,可以使用函数:orient_normals_to_align_with_direction和orient_normals_towards_camera_location。

检索估计的顶点法线

通过downpcd的normals参数可以检索估计的点的法线。

print("Print a normal vector of the 0th point")
print(downpcd.normals[0])>>>>Print a normal vector of the 0th point
>>>>[-0.21838377 -0.94240442 -0.25334252]

请使用help(downpcd)来查看其他变量。法线向量可以通过np.asarry来转化成numpy数组。

print("Print the normal vectors of the first 10 points")
print(np.asarray(downpcd.normals)[:10, :])>>>>Print the normal vectors of the first 10 points
>>>>[[-0.21838377 -0.94240442 -0.25334252][-0.39147152 -0.43746664 -0.8095511 ][-0.00694405 -0.99478075 -0.10179902][-0.00399871 -0.99965423 -0.02598917][-0.93768261 -0.07378998  0.3395679 ][-0.43476205 -0.62438493 -0.64894177][-0.09739809 -0.9928602  -0.06886388][-0.11728718 -0.95516445 -0.27185399][-0.01038945 -0.99968858 -0.02268921][-0.00816546 -0.99965616 -0.02491762]]

更多和numpy有关的信息后续会讲解,也可以直接查看有关的官方文档。

裁剪点云

print("Load a polygon volume and use it to crop the original point cloud")
vol = o3d.visualization.read_selection_polygon_volume("../../TestData/Crop/cropped.json")
chair = vol.crop_point_cloud(pcd)
o3d.visualization.draw_geometries([chair])>>>>加载一个多边形卷并使它裁剪点云


read_selection_polygon_volume函数是读取一个指定多边形区域得json文件。
vol.crop_point_cloud(pcd)过滤掉点,只保留椅子部分。

点云上色

print("Paint chair")
chair.paint_uniform_color([1, 0.706, 0])
o3d.visualization.draw_geometries([chair])

椅子上色

paint_uniform_color给所有的点上一个统一的颜色,颜色是在RGB空间得[0,1]范围内得值。

包围框

点云几何类型和其他类型一样,也有包围框。当前,open3d实现了两个包围框接口,同时他们也可以用来裁剪几何图形。

aabb = chair.get_axis_aligned_bounding_box()
aabb.color = (1,0,0)
obb = chair.get_oriented_bounding_box()
obb.color = (0,1,0)
o3d.visualization.draw_geometries([chair, aabb, obb])

凸包

点云得凸包是包含所有点的最小凸集。open3d实现了计算凸包的方法:compute_convex_hull.这个接口的实现基于Qhull。关于凸包的中文解释我这里给出百度百科链接。
下面的代码中首先从三角网格中采样一个点云,之后计算凸包并且返回,返回类型为三角网格。最后将会用红色的线可视化凸包。

pcl = o3dtut.get_bunny_mesh().sample_points_poisson_disk(number_of_points=2000)
hull, _ = pcl.compute_convex_hull()
hull_ls = o3d.geometry.LineSet.create_from_triangle_mesh(hull)
hull_ls.paint_uniform_color((1, 0, 0))
o3d.visualization.draw_geometries([pcl, hull_ls])

downloading bunny mesh
extract bunny mesh

DBSCAN 聚类

给定一个点云,比如深度传感器,我们想将局部的点分组/聚合在一起,这时我们就需要聚类算法。open3d实现了DBSCAN[Ester1996] 算法,这是一种基于密度的聚类算法。(这里上面的链接里包含原论文名称,需要可自行查找,这里我也给出百度百科链接****建议大家看原论文)。该算法接口为cluster_dbscan,有两个必须的参数:eps表示聚类的领域距离,min_points表示聚类的最小点数。该函数返回一个label,其中label为-1表示为噪声。

pcd = o3d.io.read_point_cloud("../../TestData/fragment.ply")with o3d.utility.VerbosityContextManager(o3d.utility.VerbosityLevel.Debug) as cm:labels = np.array(pcd.cluster_dbscan(eps=0.02, min_points=10, print_progress=True))max_label = labels.max()
print(f"point cloud has {max_label + 1} clusters")
colors = plt.get_cmap("tab20")(labels / (max_label if max_label > 0 else 1))
colors[labels < 0] = 0
pcd.colors = o3d.utility.Vector3dVector(colors[:, :3])
o3d.visualization.draw_geometries([pcd])>>>>point cloud has 10 clusters

Note:

该算法会对所有在半径内得所有点的邻域进行预计算,如果半径选的过大会占用大量的内存。

平面分割

open3d还支持使用RANSAC从点云中分割几何基元。要查找点云中最有可能存在的平面,我们使用segement_plane函数。这个函数需要三个参数,destance_threshold定义了一个点到一个估计平面的最大距离,这些距离内的点被认为是内点(inlier),ransac_n定义了使用随机抽样估计一个平面的点的个数,num_iterations定义了随机平面采样和验证的频率(迭代次数)。这个函数返回(a,b,c,d)作为一个平面,对于平面上每个点(x,y,z)我们有ax+by+cz+d=0。这个函数还会返回内点索引的列表。

pcd = o3d.io.read_point_cloud("../../TestData/fragment.pcd")
plane_model, inliers = pcd.segment_plane(distance_threshold=0.01,ransac_n=3,num_iterations=1000)
[a, b, c, d] = plane_model
print(f"Plane equation: {a:.2f}x + {b:.2f}y + {c:.2f}z + {d:.2f} = 0")inlier_cloud = pcd.select_by_index(inliers)
inlier_cloud.paint_uniform_color([1.0, 0, 0])
outlier_cloud = pcd.select_by_index(inliers, invert=True)
o3d.visualization.draw_geometries([inlier_cloud, outlier_cloud])>>>>Plane equation: -0.06x + -0.10y + 0.99z + -1.06 = 0

隐点移除

假如你想从一个给定视角去渲染一个点云,但是背景的点在前景也会被看到,这是因为并没有其他点把它遮挡住。为此看可以使用一种隐点去除算法。open3d实现了[Katz2007] 文章中的算法,该算法从没有重建和法线估计的给定视角去近似可视化点云。

print("Convert mesh to a point cloud and estimate dimensions")
pcd = o3dtut.get_armadillo_mesh().sample_points_poisson_disk(5000)
diameter = np.linalg.norm(np.asarray(pcd.get_max_bound()) - np.asarray(pcd.get_min_bound()))
o3d.visualization.draw_geometries([pcd])

print("Define parameters used for hidden_point_removal")
camera = [0, 0, diameter]
radius = diameter * 100print("Get all points that are visible from given view point")
_, pt_map = pcd.hidden_point_removal(camera, radius)print("Visualize result")
pcd = pcd.select_by_index(pt_map)
o3d.visualization.draw_geometries([pcd])

如果翻译的有什么问题或者您有更好的意见,请评论交流!!!!

欢迎大家加入知识星球一起学习。

Open3d学习计划——3(点云)相关推荐

  1. Open3d学习计划—高级篇 4(多视角点云配准)

    本文为转载文章,原创作者为blue同学,可关注他的博客:https://blog.csdn.net/io569417668 Open3D是一个开源库,支持快速开发和处理3D数据.Open3D在c++和 ...

  2. Open3d学习计划—高级篇 3(点云全局配准)

    Open3D是一个开源库,支持快速开发和处理3D数据.Open3D在c++和Python中公开了一组精心选择的数据结构和算法.后端是高度优化的,并且是为并行化而设置的. 本系列学习计划有Blue同学作 ...

  3. Open3d学习计划—高级篇 2(彩色点云配准)

    Open3D是一个开源库,支持快速开发和处理3D数据.Open3D在c++和Python中公开了一组精心选择的数据结构和算法.后端是高度优化的,并且是为并行化而设置的. 本系列学习计划有Blue同学作 ...

  4. Open3d学习计划—高级篇 8(网格变形)

    Open3D是一个开源库,支持快速开发和处理3D数据.Open3D在c++和Python中公开了一组精心选择的数据结构和算法.后端是高度优化的,并且是为并行化而设置的. 本系列学习计划有Blue同学作 ...

  5. Open3d学习计划—高级篇 7(颜色映射)

    Open3D是一个开源库,支持快速开发和处理3D数据.Open3D在c++和Python中公开了一组精心选择的数据结构和算法.后端是高度优化的,并且是为并行化而设置的. 本系列学习计划有Blue同学作 ...

  6. Open3d学习计划—高级篇 6(体素化)

    Open3D是一个开源库,支持快速开发和处理3D数据.Open3D在c++和Python中公开了一组精心选择的数据结构和算法.后端是高度优化的,并且是为并行化而设置的. 本系列学习计划有Blue同学作 ...

  7. Open3d学习计划—高级篇 5(RGBD融合)

    Open3D是一个开源库,支持快速开发和处理3D数据.Open3D在c++和Python中公开了一组精心选择的数据结构和算法.后端是高度优化的,并且是为并行化而设置的. 本系列学习计划有Blue同学作 ...

  8. Open3d 学习计划—12(Jupyter 可视化)

    Open3D是一个开源库,支持快速开发和处理3D数据.Open3D在c++和Python中公开了一组精心选择的数据结构和算法.后端是高度优化的,并且是为并行化而设置的. 本系列学习计划有Blue同学作 ...

  9. Open3d学习计划——2(使用帮助与IO)

    Open3d学习计划--2 在上篇文章,我们介绍了Open3D是什么,和Python版本的如何安装.本篇文章将介绍原文档中Open3D得基础用法,本文翻译文档为0.10.0版本open3d文档,更多之 ...

  10. Open3d学习计划——6(RGBD图像)

    Open3d学习计划--6(RGBD图像) 欢迎大家关注"点云PCL"公众号,进入群聊一起学习. Open3d提供图像(images)数据结构.支持多种函数read_image,w ...

最新文章

  1. PAT (Basic Level) Practise:1012. 数字分类
  2. 10月第3周网络安全报告:新增信息安全漏洞308个
  3. 【Pytorch神经网络实战案例】22 基于Cora数据集实现图注意力神经网络GAT的论文分类
  4. ubuntu复制文件到另一个文件夹_简单介绍一下电脑中的文件或文件夹的复制、移动及删除的操作方式...
  5. 硬解析和软解析 mysql_Oracle学习之shared pool--硬解析和软解析
  6. 邀请和建议的回答_46
  7. 用 PHPRPC 实现 Ajax 安全登录
  8. MyCat分布式数据库集群架构工作笔记0003---Mycat的作用
  9. 菜鸟学习linux笔记(二)
  10. 东芝2000ac废粉盒怎么二次利用_嘉兴秀洲区工业垃圾怎么处理
  11. 基于WEB的达内学子书城/商城源代码
  12. DOS命令与批处理学习历程
  13. Oracle数据库下载安装教程
  14. C#获取电脑硬件信息(CPU ID、主板ID、硬盘ID、BIOS编号)
  15. snort实验(一)
  16. 软件工程改错题例题:请将下面的非结构化程序改成结构化程序
  17. catkin_make 编译包无效(没反应)
  18. 转:Emacs生存指南 (Emacs入门必读)
  19. Python使用Turtle画帕劳共和国国旗
  20. 前端、后端、客户端、数据库、服务器的简单总结

热门文章

  1. 喵哈哈村的魔法源泉(3)-(树的直径)
  2. 提高说话能力的实际操作方法
  3. Python实例之CIFAR-10数据集分类
  4. taichi常见简单报错BUG和应对之策总结
  5. 21. CF-Narrow Components
  6. vue占位控件solt
  7. SpringBoot 零基础教学
  8. d 服务器运行失败,【求助】服务器启动失败,服务器启动时遇到了一些麻烦,请重试...
  9. Scala语法从入门到高级运用
  10. 微盟数据被删后的七天七夜