点云可视化之旋转GIF动画

点云可视化之旋转GIF动画

在这里插入图片描述

当我们拿到一个点云数据,想看看到底是啥样的东西,或者经过我们一系列操作(如点云重建)得到最后的点云模型,我们要向别人展示点云模型效果,我们可以考虑采用GIF旋转动画的形式。

安装第三方库

open3d numpy imageio

  • Open3D是一个开源的跨平台库,专注于高效的3D数据处理和实时3D可视化。它提供了广泛的功能,包括点云处理、几何体(如网格、体积、线框等)的操作、配准算法、表面重建、基于物理的渲染(PBR)、以及与深度学习框架(如PyTorch和TensorFlow)的集成。Open3D不仅支持CPU运算,还支持GPU加速,特别适合于三维计算机视觉、机器人学、以及三维重建等相关领域的研究和开发。

  • NumPy(Numerical Python)是Python中用于科学计算的核心库之一,它提供了一个强大的N维数组对象ndarray以及一套数学函数库,使得Python能够高效地处理大量的多维数据。NumPy是许多科学计算、数据分析、机器学习等库的基础,例如SciPy、Pandas、Matplotlib以及Open3D等都会依赖NumPy来进行底层的数据操作。

  • imageio是一个Python库,用于读写多种图像文件格式(如JPEG、PNG、TIFF、GIF等)。它允许开发者以统一的接口读取、写入和显示静态图像和动态图像序列。imageio常用于图像处理、计算机视觉、数据预处理和动画制作等方面,因为它提供了一种简洁、直观的方式来操作各种图像数据,并且可以与NumPy无缝集成,方便进行进一步的数据分析和处理。在Open3D中,imageio可用于读取和显示深度图或者其他图像数据,以配合3D数据的可视化和分析。

open3d用来处理点云以及可视化点云数据,imageio用来处理图像,生成GIF动画。

过程分析

关于Open3D库中的点云模型旋转,并没有直接提供具体的GIF动画,需要自行创建一个展示点云旋转的GIF。

在Open3D中,旋转点云可以通过设置旋转矩阵或者欧拉角(轴角式)来实现。

pcd.transform( M)

在 Open3D 库中,transform() 方法应用于点云 (PointCloud) 或三角网格 (TriangleMesh) 对象,参赛M为一个4x4齐次变换矩阵。这个矩阵可以组合了多种基本变换,包括:

  1. 旋转(绕某个轴或任意方向旋转一定角度)
  2. 平移(沿任意方向移动一定距离)
  3. 缩放(沿各个轴按比例放大或缩小)
  4. 镜像(通过反对称矩阵实现)

理想效果:围绕一个固定轴旋转的gif动画,旋转轴可以任意选择

问题拆分:

  • 旋转轴如何确定
  • 求4x4齐次变换矩阵M
  • GIF图像合成

旋转轴如何确定

三维空间的一个旋转轴可以由一个方向向量和一个起点确定

求4x4齐次变换矩阵 M M M

绕任意轴旋转的这个过程可以分解为两步:

  1. 先绕过原点与旋转轴平行的线旋转
  2. 再平移到目标旋转轴

变换矩阵 M 在三维几何变换中可以分为两部分:旋转和平移(Rotation and Translation)

  • 旋转部分通常体现在矩阵的左上角3x3的子矩阵中,这个子矩阵是对称并且行列式为1的正交矩阵,它负责描述点或向量在三维空间中的旋转操作。
  • 平移部分体现在矩阵的第四列(除了最后一行),它们分别对应沿x、y、z轴的平移量

在一个三维空间中,齐次坐标系下的变换矩阵M通常由旋转矩阵R和平移向量T组合而成,其形式如下:

M = [ R T 0 1 ] M = \begin{bmatrix} R & T \\ \mathbf{0} & 1 \end{bmatrix} M=[R0T1]

其中,

  • R R R 是一个3x3的旋转矩阵,表示三维空间中的旋转变换。
  • T T T 是一个长度为3的一维向量,扩展为列向量后构成一个3x1的矩阵,表示三维空间中的平移变换。
  • 0 \mathbf{0} 0 是一个1x3的全零向量。

展开来看,变换矩阵M的具体形式为:

M = [ r 11 r 12 r 13 t x r 21 r 22 r 23 t y r 31 r 32 r 33 t z 0 0 0 1 ] M = \begin{bmatrix} r_{11} & r_{12} & r_{13} & t_x \\ r_{21} & r_{22} & r_{23} & t_y \\ r_{31} & r_{32} & r_{33} & t_z \\ 0 & 0 & 0 & 1 \end{bmatrix} M= r11r21r310r12r22r320r13r23r330txtytz1

其中, r i j r_{ij} rij表示旋转矩阵R中的元素, t x t_x tx, t y t_y ty, t z t_z tz分别表示平移向量T在三维空间中的各个分量。

旋转矩阵 R R R

u ^ \hat{\textbf{u}} u^ 旋转 θ \theta θ 的旋转矩阵R的公式为:
R ( θ , u ^ ) = [ cos ⁡ ( θ ) + u x 2 ( 1 − cos ⁡ ( θ ) ) u x u y ( 1 − cos ⁡ ( θ ) ) − u z sin ⁡ ( θ ) u x u z ( 1 − cos ⁡ ( θ ) ) + u y sin ⁡ ( θ ) u y u x ( 1 − cos ⁡ ( θ ) ) + u z sin ⁡ ( θ ) cos ⁡ ( θ ) + u y 2 ( 1 − cos ⁡ ( θ ) ) u y u z ( 1 − cos ⁡ ( θ ) ) − u x sin ⁡ ( θ ) u z u x ( 1 − cos ⁡ ( θ ) ) − u y sin ⁡ ( θ ) u z u y ( 1 − cos ⁡ ( θ ) ) + u x sin ⁡ ( θ ) cos ⁡ ( θ ) + u z 2 ( 1 − cos ⁡ ( θ ) ) ] R(\theta, \hat{\textbf{u}}) = \begin{bmatrix} \cos(\theta) + u_x^2(1-\cos(\theta)) & u_xu_y(1-\cos(\theta)) - u_z\sin(\theta) & u_xu_z(1-\cos(\theta)) + u_y\sin(\theta) \\ u_yu_x(1-\cos(\theta)) + u_z\sin(\theta) & \cos(\theta) + u_y^2(1-\cos(\theta)) & u_yu_z(1-\cos(\theta)) - u_x\sin(\theta) \\ u_zu_x(1-\cos(\theta)) - u_y\sin(\theta) & u_zu_y(1-\cos(\theta)) + u_x\sin(\theta) & \cos(\theta) + u_z^2(1-\cos(\theta)) \end{bmatrix} R(θ,u^)= cos(θ)+ux2(1cos(θ))uyux(1cos(θ))+uzsin(θ)uzux(1cos(θ))uysin(θ)uxuy(1cos(θ))uzsin(θ)cos(θ)+uy2(1cos(θ))uzuy(1cos(θ))+uxsin(θ)uxuz(1cos(θ))+uysin(θ)uyuz(1cos(θ))uxsin(θ)cos(θ)+uz2(1cos(θ))

其中,

  • θ \theta θ 是围绕轴向量 u ^ \hat{\textbf{u}} u^ 的旋转角度,
  • u x u_x ux, u y u_y uy, u z u_z uz 是轴向量 u ^ \hat{\textbf{u}} u^ x x x y y y z z z轴上的分量,
  • u ^ \hat{\textbf{u}} u^ 是单位向量,满足 ∥ u ^ ∥ = 1 \lVert \hat{\textbf{u}} \rVert = 1 u^=1

平移矩阵 T T T

T T T取旋转轴起点[x,y,z]到原点的平移矩阵

T = [ x y z ] T= \begin{bmatrix} x\\ y\\ z \end{bmatrix} T= xyz

合并得到变换矩阵 M M M

GIF图像合成

使用open3d库渲染旋转的每一贞图像,使用vis.capture_screen_float_buffer保存图像信息列表。

imageio.mimsave()imageio 库中用于将一系列图像帧保存为 GIF 动画文件的一个函数。下面是 imageio.mimsave() 函数的基本用法和参数说明:

imageio.mimsave(gifname, frames, fps=60, duration=None, subrectangles=False, loop=0, metadata=None)
  • gifname (str): 指定要保存的 GIF 动画文件的名称(包括路径和扩展名,例如 "animation.gif")。

  • frames (list or generator): 包含多个图像的数据,可以是 PIL.Image 对象的列表,或者是返回 PIL.Image 对象的生成器。每一幅图像都将作为动画中的一帧。

  • fps (float, 默认为 60): 每秒帧数,即动画播放的速度。例如设置为 60,意味着动画将以每秒 60 帧的速度播放。

  • duration (float, 默认为 None): 如果提供了这个参数,它将覆盖 fps 参数的作用,指定每一帧持续的时间(以秒为单位)。如果不提供,则根据 fps 计算每一帧的持续时间。

  • subrectangles (bool, 默认为 False): 是否启用子矩形优化。如果为 True,imageio 将尝试仅保存每帧发生变化的部分,以减小 GIF 文件大小。但请注意,不是所有格式都支持此特性。

  • loop (int, 默认为 0): 表示动画循环播放的次数。0 或 1 表示循环一次(即播放完后停止),-1 表示无限循环。

  • metadata (dict, 默认为 None): 可选的元数据字典,用于保存附加的信息。

效果展示

在这里插入图片描述

  • 在这里插入图片描述
  • 16
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值