【小白深度教程 1.13】手把手教你使用 Open3D,简明教程(含 Python 代码)

Open3D是一个开源库,支持处理3D数据的软件的 快速开发

它是由英特尔实验室的研究人员周乾一、Jaesik Park和Vladlen Koltun 开发的,这是对应的论文:

http://www.open3d.org/wordpress/wp-content/paper.pdf

1. 创建环境

conda create -n open3denv python=3.6
conda activate open3denv
conda install -c open3d-admin open3d==0.8.0.0
  • 1
  • 2
  • 3

2. 下载数据集

http ://graphics.stanford.edu/data/3Dscanrep/
在这里插入图片描述

3. 加载点云数据

import open3d as o3d
import wget
url = 'https://raw.githubusercontent.com/PointCloudLibrary/pcl/master/test/bunny.pcd'
#filename = wget.download(url)

pcd = o3d.io.read_point_cloud("bunny.pcd")
print(pcd)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

4. Open3D 文件点云文件格式

在这里插入图片描述

#The code below writes a point cloud.
o3d.io.write_point_cloud("copy_of_bunny.pcd", pcd)
  • 1
  • 2
pcd = o3d.io.read_point_cloud("sample.xyz", format='xyz')
print(pcd)
  • 1
  • 2

5. Open3D 文件 Mesh 文件格式

在这里插入图片描述

# The code below reads and writes a mesh.
print("Testing IO for meshes ...")

#Function to read TriangleMesh from file
mesh = o3d.io.read_triangle_mesh("knot.ply")
print(mesh)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

6. 在样例数据使用 Open3D

6.1 Bunny 数据集

import open3d as o3d
import numpy as np
import PIL.Image
import IPython.display
import os
import urllib
import tarfile
import gzip
import zipfile
import shutil

#Download the point cloud using below command
import wget
url = 'http://graphics.stanford.edu/pub/3Dscanrep/bunny.tar.gz'
#filename = wget.download(url)

bunny_path = "bunny"
with tarfile.open(bunny_path + ".tar.gz") as tar:
            tar.extractall(path=os.path.dirname(bunny_path))

bunny_path = "D:/open3D_env/bunny/reconstruction/bun_zipper.ply"
mesh = o3d.io.read_triangle_mesh(bunny_path)
mesh.compute_vertex_normals()

mesh.compute_vertex_normals()
o3d.visualization.draw_geometries([mesh])

pcd = mesh.sample_points_uniformly(number_of_points=500)
o3d.visualization.draw_geometries([pcd])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

6.2 Happy Buddha 数据集

#Download the Happy Buddha dataset
import wget
url = 'http://graphics.stanford.edu/pub/3Dscanrep/happy/happy_recon.tar.gz'
#filename = wget.download(url)

budha_path = "happy_recon"
with tarfile.open(budha_path + ".tar.gz") as tar:
            tar.extractall(path=os.path.dirname(budha_path))
        
budha_path = "D:/open3D_env/happy_recon/happy_vrip.ply"
mesh_budha = o3d.io.read_triangle_mesh(budha_path)
mesh_budha.compute_vertex_normals()

mesh_budha.compute_vertex_normals()
o3d.visualization.draw_geometries([mesh_budha])

pcd_budha = mesh_budha.sample_points_uniformly(number_of_points=500)
o3d.visualization.draw_geometries([pcd_budha])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

6.3 Dragon 数据集

import wget
url = 'http://graphics.stanford.edu/pub/3Dscanrep/dragon/dragon_recon.tar.gz'
#filename = wget.download(url)

dragon_path = "dragon_recon"
with tarfile.open(dragon_path + ".tar.gz") as tar:
            tar.extractall(path=os.path.dirname(dragon_path))
        
dragon_path = "D:/open3D_env/dragon_recon/dragon_vrip.ply"
mesh_dragon = o3d.io.read_triangle_mesh(dragon_path)
mesh_dragon.compute_vertex_normals()

mesh_dragon.compute_vertex_normals()
o3d.visualization.draw_geometries([mesh_dragon])

pcd_dragon = mesh_dragon.sample_points_uniformly(number_of_points=500)
o3d.visualization.draw_geometries([pcd_dragon])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

7. 体素降采样

  1. 这是点云处理任务的预处理步骤。
  2. 它取点云和下采样。
  3. 在1体素中的点被平均,平均后我们得到1点。

为什么要降采样?

  • 它使数据的大小更易于管理

  • 降低数据的维数,从而实现更快的数据处理

  • 减少数据的存储大小

print("Downsample the point cloud with a voxel of 0.05")
downpcd = pcd_dragon.voxel_down_sample(voxel_size=0.05)
o3d.visualization.draw_geometries([downpcd],width=1920, height=1080, left=50, top=50)
  • 1
  • 2
  • 3

另一种实现方式:


import numpy as np
print("Load a ply point cloud, print it, and render it")

#read_point_cloud reads a point cloud from a file. It tries to decode the file based on the extension name.
pcd = o3d.io.read_point_cloud("fragment.ply")
print(pcd)
print(np.asarray(pcd.points))

#draw_geometries visualizes the point cloud. 
o3d.visualization.draw_geometries([pcd],width=1920, height=1080, left=50, top=50)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

在这里插入图片描述

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],width=1920, height=1080, left=50, top=50)
  • 1
  • 2
  • 3

在这里插入图片描述

8. 裁剪点云

print("Load a polygon volume and use it to crop the original point cloud")

#read_selection_polygon_volume reads a json file that specifies polygon selection area. 
vol = o3d.visualization.read_selection_polygon_volume("cropped.json")

#vol.crop_point_cloud(pcd) filters out points. Only the chair remains.
chair = vol.crop_point_cloud(pcd)
o3d.visualization.draw_geometries([chair],width=1920, height=1080, left=50, top=50)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

加载一个模型,并使用它来裁剪原始点云

在这里插入图片描述

9. 点云着色

print("Paint chair")

#paint_uniform_color paints all the points to a uniform color. The color is in RGB space, [0, 1] range.
chair.paint_uniform_color([1, 0.706, 0])
o3d.visualization.draw_geometries([chair], width=1920, height=1080, left=50, top=50)
  • 1
  • 2
  • 3
  • 4
  • 5

在这里插入图片描述

10. 绘制矩形

PointCloud几何类型与Open3D中的所有其他几何类型一样具有边界框。

目前,Open3D实现了一个AxisAlignedBoundingBox和一个orientteddboundingbox,它们也可以用来裁剪几何图形。

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])
  • 1
  • 2
  • 3
  • 4
  • 5

在这里插入图片描述

11. Mesh 处理

Open3D有一个3D三角形网格的数据结构,叫做TriangleMesh。下面的代码展示了如何从ply文件中读取三角形网格并打印其顶点和三角形。

#!pip install pillow

# import functions from open3d_tutorial.py 
import open3d_tutorial as o3dtut


print("Testing mesh in Open3D...")
mesh = o3dtut.get_knot_mesh()
print(mesh)
print('Vertices:')
print(np.asarray(mesh.vertices))
print('Triangles:')
print(np.asarray(mesh.triangles))

#The TriangleMesh class has a few data fields such as vertices and triangles. Open3D provides direct memory access to these fields via numpy.

print("Try to render a mesh with normals (exist: " +str(mesh.has_vertex_normals()) + ") and colors (exist: " +str(mesh.has_vertex_colors()) + ")")
o3d.visualization.draw_geometries([mesh])
print("A mesh with no normals and no colors does not look good.")
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

在这里插入图片描述

print("Computing normal and rendering it.")
mesh.compute_vertex_normals()
print(np.asarray(mesh.triangle_normals))
o3d.visualization.draw_geometries([mesh])
  • 1
  • 2
  • 3
  • 4

在这里插入图片描述

12. 裁剪 Mesh

我们通过直接操作网格的triangle和triangle_normals数据字段来去除一半的表面。这是通过 numpy 完成的。

print("We make a partial mesh of only the first half triangles.")
#mesh1 = copy.deepcopy(mesh)
mesh1=mesh
mesh1.triangles = o3d.utility.Vector3iVector(
    np.asarray(mesh1.triangles)[:len(mesh1.triangles) // 2, :])
mesh1.triangle_normals = o3d.utility.Vector3dVector(
    np.asarray(mesh1.triangle_normals)[:len(mesh1.triangle_normals) // 2, :])
print(mesh1.triangles)
o3d.visualization.draw_geometries([mesh1])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

在这里插入图片描述

13. Mesh 着色

Paint_uniform_color用统一的颜色绘制网格。颜色在RGB空间,[0,1]范围内。

print("Painting the mesh")
mesh1.paint_uniform_color([1, 0.706, 0])
o3d.visualization.draw_geometries([mesh1])
  • 1
  • 2
  • 3

在这里插入图片描述

文章知识点与官方知识档案匹配,可进一步学习相关知识

举报

选择你想要举报的内容(必选)
  • 内容涉黄
  • 政治相关
  • 内容抄袭
  • 涉嫌广告
  • 内容侵权
  • 侮辱谩骂
  • 样式问题
  • 其他