3维图像处理的新星--Open3D(实操过程持续更新ing....

听说Open3D很好用,我先学习学习,后面再转战PCL,毕竟PCL是点云届的经典大佬*.*

本人使用的是python版本噢:)

1.官网功能介绍及例程
http://www.open3d.org/docs/release/tutorial/geometry/index.html
也可以参考这位朋友整理的Open3D算法资料:

https://blog.csdn.net/qq_40985985/article/details/108715871?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.control

2.环境配置
ubuntu18.04下可以使用pip命令:
pip install open3d
安装完毕后,在终端使用python:

yy@yy:~$ python
Python 3.7.6 (default, Jan  8 2020, 19:59:22) 
[GCC 7.3.0] :: Anaconda, Inc. on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import open3d
>>> 

如果没有报错说明安装成功>.<
3.开始使用
官网提供了丰富的python接口教程,动手试一试吧:
http://www.open3d.org/docs/release/tutorial/geometry/python_interface.html
3.1 读取点云数据并可视化
需要使用的函数有:
1)read_point_cloud 文件读取函数
2)draw_geometries 可视化函数

yy@yy:~$ python
Python 3.7.6 (default, Jan  8 2020, 19:59:22) 
[GCC 7.3.0] :: Anaconda, Inc. on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import open3d as o3d
>>> pcd = o3d.io.read_point_cloud("/home/yy/文档/pointcloud/desk_1.pcd")  ###输入被读取文件的路径
>>> print(pcd)
PointCloud with 1595906 points.
>>> import numpy as np
>>> print(np.asarray(pcd.points))
[[-0.7070244  -0.52971417  1.2640001 ]
 [-0.7070244  -0.52084869  1.2640001 ]
 [-0.7070244  -0.51198316  1.2640001 ]
 ...
 [-0.76719701 -0.32806134  1.2508162 ]
 [-0.77002394 -0.32122216  1.2594384 ]
 [-0.76220942 -0.31320193  1.2549695 ]]
>>> o3d.visualization.draw_geometries([pcd],
                                      zoom=0.3412,
                                      front=[0.4257, -0.2125, -0.8795],
                                      lookat=[2.6172, 2.0475, 1.532],
                                      up=[-0.0694, -0.9768, 0.2024])

执行完毕后会显示出我们读取文件的3d图像:
3维图像处理的新星--Open3D(实操过程持续更新ing...._第1张图片
3.2 体素下采样
体素下采样使用常规体素网格从输入点云创建统一下采样的点云,它通常用作许多点云处理任务的预处理步骤。
1) 点被存储到体素中;
2) 每个占用的体素通过平均内部的所有点来精确生成一个点。

>>> downpcd = pcd.voxel_down_sample(voxel_size=0.05)  ###使用0.05的体素对点云下采样,值越大,得到点数越少
>>> o3d.visualization.draw_geometries([downpcd],
                                      zoom=0.3412,
                                      front=[0.4257, -0.2125, -0.8795],
                                      lookat=[2.6172, 2.0475, 1.532],
                                      up=[-0.0694, -0.9768, 0.2024])

结果如下:
PS:可以使用键盘上的-或者+改变点的大小
3维图像处理的新星--Open3D(实操过程持续更新ing...._第2张图片
3.3 顶点法线估计
1) estimate_normals 法线估计(计算法向量)

>>> downpcd.estimate_normals(
        search_param=o3d.geometry.KDTreeSearchParamHybrid(radius=0.1, max_nn=30)) ###设置kd树查找半径为0.1,最大点数为30的领域,拟合平面求出该平面法向量
>>> o3d.visualization.draw_geometries([downpcd],
                                      zoom=0.3412,
                                      front=[0.4257, -0.2125, -0.8795],
                                      lookat=[2.6172, 2.0475, 1.532],
                                      up=[-0.0694, -0.9768, 0.2024],
   .                                  point_show_normal=True)

PPS:键入n可以隐藏或者显示法向量,使用键盘上的-或者+改变点的大小以及法线的长短
3维图像处理的新星--Open3D(实操过程持续更新ing...._第3张图片
3.4 读取法向量

>>> print(downpcd.normals[0])  ###打印第一个点的法向量
[ 0.48468789  0.85733389 -0.17336738]
>>> print(np.asarray(downpcd.normals)[:5, :]) ###打印前5个点的法向量
[[ 0.48468789  0.85733389 -0.17336738]
 [ 0.8085128   0.04854127 -0.58647318]
 [-0.07516671 -0.98791843 -0.13552542]
 [ 0.8371842   0.18250328 -0.51557267]
 [ 0.06751124  0.97692563  0.20262907]]

3.5 点云上色
1)paint_uniform_color 将所有点绘制为统一的颜色,颜色范围在[0,1]的RGB空间中。

>>> downpcd.paint_uniform_color([1, 0.5, 0])
PointCloud with 1595906 points.
>>> o3d.visualization.draw_geometries([downpcd],
                                      zoom=0.7,
                                      front=[0.5439, -0.2333, -0.8060],
                                      lookat=[2.4615, 2.1331, 1.338],
                                      up=[-0.1781, -0.9708, 0.1608])

经过体素下采样后的点云上色效果:
3维图像处理的新星--Open3D(实操过程持续更新ing...._第4张图片
原点云上色效果:
3维图像处理的新星--Open3D(实操过程持续更新ing...._第5张图片
3.6 边界体积
Open3D实现了AxisAlignedBoundingBox和OrientedBoundingBox也可以用于裁剪几何。
1)axis_aligned_bounding_box 轴对齐包围盒AABB
2)oriented_bounding_box 方向包围盒OBB

>>> aabb = downpcd.get_axis_aligned_bounding_box()
>>> aabb.color = (1, 0, 0)
>>> obb = downpcd.get_oriented_bounding_box()
>>> obb.color = (0, 1, 0)
>>> o3d.visualization.draw_geometries([downpcd, aabb, obb],
                                      zoom=0.7,
                                      front=[0.5439, -0.2333, -0.8060],
                                      lookat=[2.4615, 2.1331, 1.338],
                                      up=[-0.1781, -0.9708, 0.1608])

3维图像处理的新星--Open3D(实操过程持续更新ing...._第6张图片
3.7 凸包
点云的凸包是包含所有点的最小凸集。Open3D包含compute_convex_hull计算点云的凸包的方法。该实现基于Qhull。
首先从网格中采样点云,然后计算返回为三角形网格的凸包,最后将凸包可视化为红LineSet。

>>> hull, _ = downpcd.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([downpcd, hull_ls])

3维图像处理的新星--Open3D(实操过程持续更新ing...._第7张图片

ply格式的点云数据呈现的效果:

>>> chair = o3d.io.read_point_cloud("/home/yy/文档/pointcloud/chair1.ply")
>>> hull, _ = chair.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([chair, hull_ls])

3维图像处理的新星--Open3D(实操过程持续更新ing...._第8张图片
3.8 DBSCAN集群
DBSCAN集群是一种基于密度的聚类算法,该算法在中实现,cluster_dbscan并且需要两个参数:eps定义到群集中邻居的距离,并使用min_points定义形成群集所需的最小点数。该函数返回labels,其中标签-1指示噪音。

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()
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],
                                  zoom=0.455,
                                  front=[-0.4999, -0.1659, -0.8499],
                                  lookat=[2.1813, 2.0619, 2.0999],
                                  up=[0.1204, -0.9852, 0.1215])

But,遇到问题了!进程被杀死了!

[Open3D DEBUG] Precompute Neighbours
已杀死pute Neighbours[===================================>    ] 87%

逛了下相关博客,据说可能是点数太多。我的数据有1595906 points
fine,我用下采样后的数据试试:

import open3d as o3d
import numpy as np
import matplotlib.pyplot as plt
pcd = o3d.io.read_point_cloud("/home/yy/文档/pointcloud/desk_1.pcd")
print(pcd)
downpcd = pcd.voxel_down_sample(voxel_size=0.03)
print(downpcd)
with o3d.utility.VerbosityContextManager(o3d.utility.VerbosityLevel.Debug) as cm:
    labels = np.array(downpcd.cluster_dbscan(eps=0.02, min_points=5, print_progress=True))
max_label = labels.max()
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([downpcd],
                                  zoom=0.455,
                                  front=[-0.4999, -0.1659, -0.8499],
                                  lookat=[2.1813, 2.0619, 2.0999],
                                  up=[0.1204, -0.9852, 0.1215])

结果如下:

PointCloud with 1595906 points.
PointCloud with 13460 points.
[Open3D DEBUG] Precompute Neighbours
Precompute Neighbours[========================================] 100%
[Open3D DEBUG] Done Precompute Neighbours
[Open3D DEBUG] Compute Clusters
[Open3D DEBUG] Done Compute Clusters: 0

哎,一个集群都没有吗?我去瞧瞧open3d中聚类函数的参数具体设置…T^T
PPPS:若downpcd = pcd.voxel_down_sample(voxel_size=0.01),点数还是较多,邻近点寻找的过程太漫长,进程会被杀死

PointCloud with 1595906 points.
PointCloud with 122690 points.
[Open3D DEBUG] Precompute Neighbours
已杀死pute Neighbours[====>                                 ] 10%

!!!!!!解决问题啦!将集群半径设置大一点,因为我的原始数据排列紧密,如果半径设置得大,会不容易分开

labels = np.array(downpcd.cluster_dbscan(eps=0.5, min_points=5, print_progress=True))

其中,eps参数:代表epsilon社区的最大半径,如果数据点的相互距离小于或等于指定的epsilon,那么它们将是同一类的。换句话说,它是DBSCAN用来确定两个点是否相似和属于同一类的距离。更大的epsilon将产生更大的簇(包含更多的数据点),更小的epsilon将构建更小的簇。如果取值太小,集群将被分割的越来越小;
min_points:在一个邻域的半径内minPts数的邻域被认为是一个簇。注意!初始点包含在minpoints中。一个较低的minpoints帮助算法建立更多的集群与更多的噪声或离群值,较高的minpoints将确保更健壮的集群,但如果集群太大,较小的集群将被合并到较大的集群中。

[Open3D DEBUG] Precompute Neighbours
Precompute Neighbours[========================================] 100%
[Open3D DEBUG] Done Precompute Neighbours
[Open3D DEBUG] Compute Clusters
[Open3D DEBUG] Done Compute Clusters: 4===========>] 97%

3维图像处理的新星--Open3D(实操过程持续更新ing...._第9张图片
3.9 平面分割
分割函数segment_plane

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],
                                  zoom=0.8,
                                  front=[-0.4999, -0.1659, -0.8499],
                                  lookat=[2.1813, 2.0619, 2.0999],
                                  up=[0.1204, -0.9852, 0.1215])

生成平面方程:
Plane equation: -0.02x + 0.94y + 0.34z + -0.31 = 0
3维图像处理的新星--Open3D(实操过程持续更新ing...._第10张图片
3维图像处理的新星--Open3D(实操过程持续更新ing...._第11张图片

PPPPS:今天才发现原来ubuntu自带有截图快捷键,而且可以根据自己喜好修改!!!啊,我太蠢了
3维图像处理的新星--Open3D(实操过程持续更新ing...._第12张图片

你可能感兴趣的:(笔记,深度学习,python)