当前位置: 首页 > news >正文

Python点云显示:open3d快速上手

文章目录

    • 上手
    • 几何变换
    • 曲面重建

上手

open3d主要用于三维对象绘制,为Python提供了非常友好的接口,而且封装了一些基础的点云处理算法,加之Intel维护给力,是Python中处理三维对象的首选模块。

安装很方便

pip install open3d

装完之后还是老规矩,请出斯坦福兔子刷一波成就感

# 此行代码后面不再重复引入
import open3d as o3d
pcd = o3d.io.read_point_cloud("rabbit.pcd")
o3d.visualization.draw_geometries([pcd])

除了import之外,两行代码,第一行是读取本地点云文件rabbit.pcd,第二步绘图,结果如下

在这里插入图片描述

此界面虽然只有点云,但可通过快捷键进行交互,除了点击拖动改变视角之外,还可通过正负号调节点的尺寸;Ctrl和正负号调节网格尺寸;方括号可用于调节视场角。

鼠标控制则很符合直觉,只需Shift、Ctrl然后加上鼠标左键来回拖动,只需试一下就会明白其操作机理,要比文字描述更直观。

对于常用快捷键,由于稍微嫌多,故列在下面

常规指令
H会在命令行中打印英文版的帮助信息,包含快捷键信息
Q/Esc退出窗口
R重置视点
N开关点云法线渲染
S切换平滑着色和网格平面着色
W开关网格线框
B开关背面渲染
I开关插值中的图像放大
T在图像渲染之间切换:无拉伸/保持比例/自由拉伸
P截屏
D进行深度捕捉
O捕获当前渲染设置
L开关照明

数字键用于颜色控制,其中单独点击数设置点云颜色;Ctrl+数字设置网格颜色,Shift用于调用内置的伪彩映射

单独数字/CtrlShift
0默认灰度
1渲染点颜色JET颜色
2颜色对应x坐标Summer颜色
3颜色对应y坐标Winer颜色
4颜色对应z坐标HOT颜色
9正常颜色-

几何变换

鼠标拖动点云的过程,其实对点云进行了空间变换,手段无外乎三种:平移、旋转和缩放。open3d通过translate, rotation, scale来实现这些功能。

下面就演示一下这三个函数

import copy

# 此为原始点云
pcd0 = o3d.io.read_point_cloud("rabbit.pcd")

# 1号点云,沿x轴移动20米
pcd1 = copy.deepcopy(pcd0).translate((20, 0, 0))
pcd1.paint_uniform_color([1, 0, 0])  #设为红色,100 表示rgb

# 2号点云,演示缩放
pcd2 = copy.deepcopy(pcd0).translate((40, 0, 0))
# 前一个参数为缩放比例;后一个参数为缩放后的位置,为必填项
pcd2.scale(0.5, center=pcd2.get_center())
pcd2.paint_uniform_color([0, 1, 1])

# 3号点云,通过欧拉角旋转
pcd3 = copy.deepcopy(pcd0).translate((0, -20, 0))
# 采用Euler角的方法生成旋转角,表示绕y轴旋转90°
thEuler = pcd3.get_rotation_matrix_from_xyz((0,np.pi/2,0))
pcd3.rotate(thEuler)
pcd3.paint_uniform_color([0, 1, 0])

# 4号点云,通过轴角法旋转
pcd4 = copy.deepcopy(pcd0).translate((20, -20, 0))
# 通过轴角表示法生成旋转角,表示绕y轴旋转60°
th = np.array([0, np.pi/3, 0]).T
thAxis = pcd4.get_rotation_matrix_from_axis_angle(th)
pcd4.rotate(thAxis)
pcd4.paint_uniform_color([0, 0, 1])

# 5号点云,通过四元数旋转
pcd5 = copy.deepcopy(pcd0).translate((40, -20, 0))
# 通过四元数法生成转角,表示绕x轴旋转180°
quart = np.array([0,0,0,1]).T
thQuart = pcd5.get_rotation_matrix_from_quaternion(quart)
pcd5.rotate(thQuart)
pcd5.paint_uniform_color([1, 0, 1])

# 5绘图函数可以输入点云列表
pcds = [pcd0, pcd1, pcd2, pcd3, pcd4, pcd5]
o3d.visualization.draw_geometries(pcds)

效果如下

在这里插入图片描述

其中平移和缩放没什么好说的,对于旋转,需要知道欧拉角有三个分量,分别是横滚、俯仰以及航向,代表绕x、y、z轴旋转。

考虑一架正在飞行的飞机,以某一时刻前后为x轴、左右为y轴、上下为z轴。则航向角就是飞机前进方向偏离的角度;俯仰角就是飞机头尾姿态的俯仰;横滚角描述的就是飞机翅膀的摆动。

欧拉角用于描述静态角度是没问题的,但用于表示旋转时会导致万向节死锁,简单来说就是飞机的航向角变化90°之后,其横滚轴变成了俯仰轴,而四元数则没有这个顾虑。

设欧拉角为 ( ψ , θ , ϕ ) (\psi,\theta,\phi) (ψ,θ,ϕ),则四元数可表示为

Q = [ cos ⁡ ( ψ / 2 ) 0 0 sin ⁡ ( ψ / 2 ) ] [ cos ⁡ ( θ / 2 ) 0 sin ⁡ ( θ / 2 ) 0 ] [ cos ⁡ ( ϕ / 2 ) sin ⁡ ( ϕ / 2 ) 0 0 ] \bold{Q}=\begin{bmatrix} \cos(\psi/2)\\0\\0\\\sin(\psi/2) \end{bmatrix}\begin{bmatrix} \cos(\theta/2)&0&\sin(\theta/2)&0 \end{bmatrix}\begin{bmatrix} \cos(\phi/2)\\\sin(\phi/2)\\0\\0 \end{bmatrix} Q= cos(ψ/2)00sin(ψ/2) [cos(θ/2)0sin(θ/2)0] cos(ϕ/2)sin(ϕ/2)00

曲面重建

尽管实现点云绘制已经十分炫酷了,但是毕竟不够真实。斯坦福兔子据说也是用3D扫描仪扫出来的,所以其原型必定不是离散的点,而是连续的面。

作为专业的点云处理模块,open3d提供了多种生成表面的方法。

Alpha Shapes算法

Alpha Shapes算法又叫滚球法,思想很简单,不妨先从二维着手来理解。

假设平面上有一群点,然后我手里有一个球,只要我这个球足够大,那么当这个球滚向这群点之后,就会把最外层的点的轮廓描绘出来,而不至于串入点集的内部。

将这种二维的滚圆法推广到三维,就是滚球法,在open3d中,提供了create_from_point_cloud_alpha_shape函数,用以生成Alpha shapes,其中输入为点云和alpha参数。

将alpha分别设为0.3,0.6,0.9和1.2,得到结果为

在这里插入图片描述

绘图代码如下

tri = o3d.geometry.TriangleMesh
pcd = o3d.io.read_point_cloud("rabbit.pcd")
meshes = []
alpha = 0
for i in range(4):
    alpha += 0.3
    tmpPcd = copy.deepcopy(pcd0).translate((i*20, 0, 0))
    mesh = tri.create_from_point_cloud_alpha_shape(tmpPcd, alpha)
    mesh.compute_vertex_normals()
    meshes.append(mesh)

o3d.visualization.draw_geometries(meshes, mesh_show_back_face=True)

在曲面生成过程中,命令行输出了生成的三角形个数

TriangleMesh with 31267 points and 83772 triangles.
TriangleMesh with 34591 points and 95546 triangles.
TriangleMesh with 32583 points and 82728 triangles.
TriangleMesh with 29041 points and 67944 triangles.

其他重建方法

BPA(Ball pivoting Algorithm)算法从翻译来说,是更加纯正的滚球法,其基本思路也是滚球,但不同于Alpha Shapes,BPA直接将落在滚球上的点连接起来,作为轮廓。

由于在open3d中调用这种方法需要先设置法向量,故而等到讲完法向量再做BPA的代码示例。

此外,open3d还提供了泊松表面重构算法,但理解泊松表面的过程,需要首先理解八叉树,故而讲完八叉树再行讲解。

相关文章:

  • vue转electron项目以及使用fs报错:Module not found: Error: Can‘t resolve ‘fs‘ in解决办法
  • 【MATLAB教程案例14】基于ACO蚁群优化算法的函数极值计算matlab仿真及其他应用
  • 优化算法 - Adam算法
  • Open3D (C++) 点云变换
  • 黑白照片修复彩色软件免费有哪些?分享这三个实用的软件给你
  • CSS基础入门手册
  • python-- for循环的基础语法
  • _Linux进程控制
  • vue3.0--1.vue3.0环境集成、setup、ref函数、reactive函数、计算属性(computed)
  • 基于Opencv5.x(C++)流媒体视频流实现网页浏览器人脸检测
  • 网络安全——XSS跨站脚本攻击
  • AT24C02存储与读取数据
  • Linux高级编程--gdb调试
  • 家校协同小程序实战教程
  • 沉睡者C - 想要通过网上来赚钱,悟性很重要
  • 【391天】每日项目总结系列128(2018.03.03)
  • ES学习笔记(12)--Symbol
  • iOS筛选菜单、分段选择器、导航栏、悬浮窗、转场动画、启动视频等源码
  • JS创建对象模式及其对象原型链探究(一):Object模式
  • linux安装openssl、swoole等扩展的具体步骤
  • Mocha测试初探
  • PV统计优化设计
  • React组件设计模式(一)
  • spring boot 整合mybatis 无法输出sql的问题
  • SQLServer插入数据
  • 阿里云容器服务区块链解决方案全新升级 支持Hyperledger Fabric v1.1
  • 构建工具 - 收藏集 - 掘金
  • 基于HAProxy的高性能缓存服务器nuster
  • 如何使用 JavaScript 解析 URL
  • 深入浏览器事件循环的本质
  • 想晋级高级工程师只知道表面是不够的!Git内部原理介绍
  • 学习Vue.js的五个小例子
  • 用element的upload组件实现多图片上传和压缩
  • 再谈express与koa的对比
  • 在Mac OS X上安装 Ruby运行环境
  • 东超科技获得千万级Pre-A轮融资,投资方为中科创星 ...
  • ​520就是要宠粉,你的心头书我买单
  • ​人工智能书单(数学基础篇)
  • %3cli%3e连接html页面,html+canvas实现屏幕截取
  • (Demo分享)利用原生JavaScript-随机数-实现做一个烟花案例
  • (二)丶RabbitMQ的六大核心
  • (附源码)ssm码农论坛 毕业设计 231126
  • (蓝桥杯每日一题)love
  • (六)库存超卖案例实战——使用mysql分布式锁解决“超卖”问题
  • (每日持续更新)jdk api之FileReader基础、应用、实战
  • (三) prometheus + grafana + alertmanager 配置Redis监控
  • (转载)在C#用WM_COPYDATA消息来实现两个进程之间传递数据
  • *p=a是把a的值赋给p,p=a是把a的地址赋给p。
  • .Net Core webapi RestFul 统一接口数据返回格式
  • .net core控制台应用程序初识
  • .net 设置默认首页
  • .NET/C# 利用 Walterlv.WeakEvents 高性能地中转一个自定义的弱事件(可让任意 CLR 事件成为弱事件)
  • .net中我喜欢的两种验证码
  • /run/containerd/containerd.sock connect: connection refused
  • /var/spool/postfix/maildrop 下有大量文件