【点云处理教程】01如何创建和可视化点云

一、说明

        本文是系列教程,专门介绍点云处理的全流程,是一个入门工具。“点云处理”教程对初学者友好,我们将在其中简单地介绍从数据准备到数据分割和分类的点云处理管道。

【点云处理教程】00计算机视觉的Open3D简介

【点云处理教程】01如何创建和可视化点云 

【点云处理教程】02从 Python 中的深度图像估计点云 

【点云处理教程】03使用 Python 实现地面检测 

 【点云处理教程】04 Python 中的点云过滤

【点云处理教程】05-Python 中的点云分割 

 

 二、 简介

        点云应用无处不在:机器人、自动驾驶汽车、辅助系统、医疗保健等。点云是一种适合处理真实世界数据的 3D 表示,尤其是当需要场景/对象的几何形状时,例如物体的距离、形状和大小。

        点云是一组表示现实世界中的场景或空间中的对象的点。它是几何对象和场景的离散表示。更正式地说,点云PCD是一组n个点,其中每个点Pi由其3D坐标表示:

        请注意,可以添加一些其他功能来描述点云,例如 RGB 颜色、法线等。例如,可以添加 RGB 颜色以提供颜色信息。

三. 点云生成

        点云通常使用3D扫描仪(激光扫描仪,飞行时间扫描仪和结构光扫描仪)或计算机辅助设计(CAD)模型生成。在本教程中,我们将首先创建随机点云并可视化它们。然后,我们将通过使用 Open3D 库从 3D 表面采样点,从 3D 模型生成它。最后,我们将看到如何从 RGB-D 数据创建它们。

让我们从导入库开始:

import numpy as np
import matplotlib.pyplot as plt
import open3d as o3d

3.1 随机点云

        最简单的方法是随机创建点云。请注意,我们通常不会创建要处理的随机点,例如为 GAN(生成对抗网络)创建噪声。

        通常,点云由(n × 3)数组表示,其中n是点数。让我们创建一个包含 5 个随机点的点云:

number_points = 5
pcd = np.random.rand(number_points, 3)  # uniform distribution over [0, 1)
print(pcd)

        我们可以只打印这些点,但它效率不高,特别是如果点的数量像大多数应用程序一样很大。更好的方法是在 3D 空间中显示它们。让我们使用 Matplotlib 库来可视化它:

# Create Figure:
fig, ax = plt.subplots(subplot_kw={"projection": "3d"})
ax.scatter3D(pcd[:, 0], pcd[:, 1], pcd[:, 2])
# label the axes
ax.set_xlabel("X")
ax.set_ylabel("Y")
ax.set_zlabel("Z")
ax.set_title("Random Point Cloud")
# display:
plt.show()

随机点云可视化

3.2 采样点云

有时直接处理 3D 模型需要时间和内存。因此,从其3D表面对点云进行采样是一种潜在的解决方案。让我们从 Open3D 数据集导入兔子模型:

bunny = o3d.data.BunnyMesh()
mesh = o3d.io.read_triangle_mesh(bunny.path)

或者从以下链接下载后导入它:

mesh = o3d.io.read_triangle_mesh("data/bunny.ply")

接下来,显示 3D 模型以查看其外观。您可以移动鼠标从不同的视点进行查看。

# Visualize:
mesh.compute_vertex_normals() # compute normals for vertices or faces
o3d.visualization.draw_geometries([mesh])
兔子3D模型

        要对点云进行采样,有几种方法。在此示例中,我们从导入的网格中均匀采样 1000 个点并将其可视化:

# Sample 1000 points:
pcd = mesh.sample_points_uniformly(number_of_points=1000)

# visualize:
o3d.visualization.draw_geometries([pcd])

         兔子点云

我们可以将创建的点云保存为 .ply 格式,如下所示:

# Save into ply file:
o3d.io.write_point_cloud("output/bunny_pcd.ply", pcd)

3.3 来自RGB-D数据的点云

        RGB-D 数据是使用 RGB-D 传感器(如 Microsoft Kinect)收集的,这些传感器同时提供 RGB 图像和深度图像。RGB-D传感器涉及许多应用,例如室内导航,避障等。由于RGB图像提供像素颜色,因此深度图像的每个像素都指示其与相机的距离。

        Open3D 提供了一组用于 RGB-D 图像处理的功能。要使用Open3D函数从RGB-D数据创建点云,只需导入两个图像,创建一个RGB-D图像对象,最后计算点云,如下所示:

# read the color and the depth image:
color_raw = o3d.io.read_image("../data/rgb.jpg")
depth_raw = o3d.io.read_image("../data/depth.png")

# create an rgbd image object:
rgbd_image = o3d.geometry.RGBDImage.create_from_color_and_depth(
    color_raw, depth_raw, convert_rgb_to_intensity=False)
# use the rgbd image to create point cloud:
pcd = o3d.geometry.PointCloud.create_from_rgbd_image(
    rgbd_image,
    o3d.camera.PinholeCameraIntrinsic(
        o3d.camera.PinholeCameraIntrinsicParameters.PrimeSenseDefault))

# visualize:
o3d.visualization.draw_geometries([pcd])

                                                        从RGB-D图像生成的彩色点云

四. Open3D 和 NumPy

        有时您需要在Open3D和NumPy表示之间切换。例如,假设我们想将 NumPy 点云转换为对象以进行可视化,并使用 Matplotlib 可视化兔子的 3D 模型。Open3D.PointCloud

4.1 从NumPy到Open3D

在此示例中,我们使用函数创建 2000 个随机点,该函数从 上的均匀分布创建随机样本。然后我们创建一个对象,并使用函数将其特征设置为随机点。NumPy.random.rand()[0,1[Open3D.PointCloudOpen3D.PointCloud.pointsOpen3D.utility.Vector3dVector()

# Create numpy pointcloud:
number_points = 2000
pcd_np = np.random.rand(number_points, 3)

# Convert to Open3D.PointCLoud:
pcd_o3d = o3d.geometry.PointCloud()  # create point cloud object
pcd_o3d.points = o3d.utility.Vector3dVector(pcd_np)  # set pcd_np as the point cloud points

# Visualize:
o3d.visualization.draw_geometries([pcd_o3d])

                                                随机点云的 Open3D 可视化

4.2 从Open3D到NumPy。

        在这里,我们首先使用返回对象的函数从 .ply 文件中读取点云。之后,我们只需要使用函数将表示点的特征转换为 NumPy 数组。最后,我们像上面一样显示获得的数组。Open3D.io.read_point_cloud()Open3D.PointCloudOpen3D.PointCloud.pointsNumPy.asarray()

# Read the bunny point cloud file:
pcd_o3d = o3d.io.read_point_cloud("../data/bunny_pcd.ply")

# Convert the open3d object to numpy:
pcd_np = np.asarray(pcd_o3d.points)

# Display using matplotlib:
fig, ax = plt.subplots(subplot_kw={"projection": "3d"})
ax.scatter3D(pcd_np[:, 0], pcd_np[:, 2], pcd_np[:, 1])
# label the axes
ax.set_xlabel("X")
ax.set_ylabel("Y")
ax.set_zlabel("Z")
ax.set_title("Bunny Point Cloud")
# display:
plt.show()

                                                使用 Matplotlib 显示的兔子点云

五. 结论

        在本教程中,我们学习了如何创建和可视化点云。在接下来的教程中,我们将学习如何处理它们。在下一教程中,我们将了解如何在不使用 Open3D 函数的情况下从深度图像和 RGB-D 数据详细计算点云。

参考来源:

Introduction to Point Cloud Processing | by Chayma Zatout | Better Programming

猜你喜欢

转载自blog.csdn.net/gongdiwudu/article/details/132006209
今日推荐