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

【Open3D】基础操作之三维变换

【Open3D】基础操作之三维变换

文章目录

  • 【Open3D】基础操作之三维变换
  • 前言
  • 三维旋转
    • o3d.geometry.TriangleMesh.create_coordinate_frame(创建表示坐标系的三角形网格的函数)
    • Rotation Matrix(旋转矩阵)
    • o3d.geometry.rotate(对几何对象进行旋转变换的函数)
    • Rotation Vector(旋转向量)
    • o3d.geometry.get_rotation_matrix_from_axis_angle(从旋转向量生成旋转矩阵的函数)
    • Euler Angles(欧拉角)
    • o3d.geometry.get_rotation_matrix_from_AAA(从欧拉角生成旋转矩阵的函数)
    • Quaternions(四元数)
    • o3d.geometry.get_rotation_matrix_from_quaternion(从四元素生成旋转矩阵的函数)
  • 三维平移和缩放
    • Translation(平移)
    • o3d.geometry.translate(对几何对象进行平移操作的函数)
    • Scale(缩放)
    • o3d.geometry.translate(对几何对象进行缩放操作的函数)
    • o3d.geometry.get_center(计算并返回几何体的中心点的函数)
  • 总结


前言

Open3D 是一个开源库,旨在支持快速开发处理 3D 数据的软件。它提供了精心挑选的 C++ 和 Python 数据结构和算法,并且后端经过高度优化并设置为并行化。
官方文档:http://www.open3d.org/docs/
GitHub仓库:https://github.com/isl-org/Open3D


三维旋转

在三维空间中表示和计算旋转是计算机图形学、机器人学、航空航天等领域中的核心问题。主要有四种常用的方法:旋转矩阵 (Rotation Matrix)、旋转向量 (Rotation Vector)、欧拉角 (Euler Angles) 和 四元数 (Quaternions)。

o3d.geometry.TriangleMesh.create_coordinate_frame(创建表示坐标系的三角形网格的函数)

函数原型

o3d.geometry.TriangleMesh.create_coordinate_frame(size=1.0, origin=[0.0, 0.0, 0.0])

返回一个TriangleMesh对象,表示3D坐标系。

红色箭头表示 X 轴;绿色箭头表示 Y 轴;蓝色箭头表示 Z 轴。

参数参数说明
size (float, 可选,默认值1.0)坐标系的大小(比例因子),控制坐标轴的长度和整体大小。
origin (list[float], 可选,默认值[0.0, 0.0, 0.0])坐标系原点的位置,格式为 [x, y, z]。

示例

import open3d as o3d# 创建默认大小的坐标系(原点在[0,0,0],大小为1.0)
coord_frame = o3d.geometry.TriangleMesh.create_coordinate_frame()
# 创建自定义坐标系(原点在[1,2,3],大小为2.0)
custom_coord_frame = o3d.geometry.TriangleMesh.create_coordinate_frame(size=2.0, origin=[1.0, 2.0, 3.0]
)
# 可视化
o3d.visualization.draw_geometries([coord_frame, custom_coord_frame])

Rotation Matrix(旋转矩阵)

旋转矩阵是一个3x3的矩阵,用来描述一个刚体绕着某个固定点(通常是原点)进行旋转的情况。用3x3 旋转矩阵 R\mathbf{R}R来旋转一个三维空间中的点或向量 v=[x,y,z]T\mathbf{v} = [x, y, z]^Tv=[x,y,z]T
v′=Rv=[r11r12r13r21r22r23r31r32r33]v\mathbf{v'} = \mathbf{R}\mathbf{v} = \begin{bmatrix} r_{11} & r_{12} & r_{13} \\ r_{21} & r_{22} & r_{23} \\ r_{31} & r_{32} & r_{33} \end{bmatrix}\mathbf{v}v=Rv=r11r21r31r12r22r32r13r23r33v

后续的旋转向量、欧拉角和 四元数最终都需要先转化成旋转矩阵,然后再进行旋转变换。

o3d.geometry.rotate(对几何对象进行旋转变换的函数)

适用于 TriangleMesh、PointCloud、LineSet 等几何类型。
函数原型

geometry.rotate(R, center=(0, 0, 0))

没有显式返回值,直接修改调用它的几何对象的顶点坐标。

参数参数说明
R (np.ndarray)3x3 的旋转矩阵。
center (tuple/list, 可选,默认为原点(0, 0, 0))旋转中心的坐标,格式为 (x, y, z)。

Rotation Vector(旋转向量)

旋转向量使用一个三维向量来同时描述旋转轴和旋转角度,旋转向量的方向表示旋转轴的方向,而其长度(或者说模)则代表旋转的角度大小。给定一个旋转向量r=(rx,ry,rz)\mathbf{r} = (r_x, r_y, r_z)r=(rx,ry,rz) ,其对应的旋转轴为单位向量n=(nx,ny,nz)\mathbf{n} = (n_x, n_y, n_z)n=(nx,ny,nz),旋转角度为θ\thetaθ,则有r=θn\mathbf{r} = \theta \mathbf{n}r=θn

公式 r=θnr = θnr=θn 中的乘法把旋转角度 θθθ 这个数值直接乘以表示旋转轴方向的单位向量 nnn,得到的向量 rrr 同时包含了旋转轴的方向(由其方向决定)和旋转角度的大小(由其长度决定)。

要将一个三维点p=(x,y,z)\mathbf{p} = (x, y, z)p=(x,y,z)绕此旋转轴旋转指定角度,可以使用罗德里格斯公式得到旋转后的点p′\mathbf{p}'p
p′=cos⁡θp+(1−cos⁡θ)(p⋅n)n+sin⁡θ(n×p)\mathbf{p}' = \cos \theta \mathbf{p} + (1 - \cos \theta) (\mathbf{p} \cdot \mathbf{n}) \mathbf{n} + \sin \theta (\mathbf{n} \times \mathbf{p})p=cosθp+(1cosθ)(pn)n+sinθ(n×p)
另一种常见的方法是使用旋转矩阵,对于绕任意轴 nnn 旋转角度 θθθ 的情况,旋转矩阵 RRR 可以根据旋转向量计算得到:
R=[cos⁡θ+nx2(1−cos⁡θ)nxny(1−cos⁡θ)−nzsin⁡θnxnz(1−cos⁡θ)+nysin⁡θnynx(1−cos⁡θ)+nzsin⁡θcos⁡θ+ny2(1−cos⁡θ)nynz(1−cos⁡θ)−nxsin⁡θnznx(1−cos⁡θ)−nysin⁡θnzny(1−cos⁡θ)+nxsin⁡θcos⁡θ+nz2(1−cos⁡θ)]R = \begin{bmatrix} \cos \theta + n_x^2 (1 - \cos \theta) & n_x n_y (1 - \cos \theta) - n_z \sin \theta & n_x n_z (1 - \cos \theta) + n_y \sin \theta \\ n_y n_x (1 - \cos \theta) + n_z \sin \theta & \cos \theta + n_y^2 (1 - \cos \theta) & n_y n_z (1 - \cos \theta) - n_x \sin \theta \\ n_z n_x (1 - \cos \theta) - n_y \sin \theta & n_z n_y (1 - \cos \theta) + n_x \sin \theta & \cos \theta + n_z^2 (1 - \cos \theta) \end{bmatrix}R=cosθ+nx2(1cosθ)nynx(1cosθ)+nzsinθnznx(1cosθ)nysinθnxny(1cosθ)nzsinθcosθ+ny2(1cosθ)nzny(1cosθ)+nxsinθnxnz(1cosθ)+nysinθnynz(1cosθ)nxsinθcosθ+nz2(1cosθ)

o3d.geometry.get_rotation_matrix_from_axis_angle(从旋转向量生成旋转矩阵的函数)

o3d.geometry.get_rotation_matrix_from_axis_angle(axis_angle)

返回一个 3x3 的旋转矩阵 。

参数参数说明
axis_angle (np.ndarray)形状为(3,)的数组,旋转轴的方向向量,包含三个欧拉角,顺序为绕X、Y、Z轴的旋转角度。

示例:

import open3d as o3d
import numpy as np
import copy# 创建原始坐标系
mesh = o3d.geometry.TriangleMesh.create_coordinate_frame()  # 深拷贝坐标系用于旋转
mesh_r = copy.deepcopy(mesh)    # 定义旋转向量(注意:这里的向量不是分别绕XYZ轴旋转,而是沿某个轴的旋转)
# np.pi/2 是 90度, np.pi/3 是 60度, np.pi/4 是 45度
rotation_vector = np.array([np.pi / 2, np.pi / 3, np.pi / 4])# 将旋转向量转换为旋转矩阵
# 输入表示的是旋转轴方向和旋转角度的组合,不是欧拉角
R = o3d.geometry.get_rotation_matrix_from_axis_angle(rotation_vector)   print("总的旋转矩阵:")
print(R)# 应用旋转,以原点为中心
mesh_r.rotate(R, center=(0, 0, 0))  # 可视化原始和旋转后的坐标系
o3d.visualization.draw_geometries([mesh, mesh_r])

Euler Angles(欧拉角)

欧拉角通过三个角度来表示一个刚体在三维空间中的旋转状态,这三个角度通常代表了绕着特定坐标轴的三次连续旋转。根据选择的旋转顺序不同,可以有多种不同的欧拉角定义方式。

常见的旋转顺序包括XYZ、XZY、YXZ、YZX、ZXY和ZYX等,这些旋转顺序分别代表了按照选定的顺序依次绕着坐标系的X轴、Y轴和Z轴进行旋转。

以下是绕三个基本坐标轴旋转的旋转矩阵。

  • XXX轴旋转α\alphaα角的旋转矩阵:
    Rx(α)=[1000cos⁡α−sin⁡α0sin⁡αcos⁡α]R_x(\alpha) = \begin{bmatrix} 1 & 0 & 0 \\ 0 & \cos\alpha & -\sin\alpha \\ 0 & \sin\alpha & \cos\alpha \end{bmatrix}Rx(α)=1000cosαsinα0sinαcosα
  • YYY轴旋转β\betaβ角的旋转矩阵:
    Ry(β)=[cos⁡β0sin⁡β010−sin⁡β0cos⁡β]R_y(\beta) = \begin{bmatrix} \cos\beta & 0 & \sin\beta \\ 0 & 1 & 0 \\ -\sin\beta & 0 & \cos\beta \end{bmatrix}Ry(β)=cosβ0sinβ010sinβ0cosβ
  • ZZZ轴旋转γ\gammaγ角的旋转矩阵:
    Rz(γ)=[cos⁡γ−sin⁡γ0sin⁡γcos⁡γ0001]R_z(\gamma) = \begin{bmatrix} \cos\gamma & -\sin\gamma & 0 \\ \sin\gamma & \cos\gamma & 0 \\ 0 & 0 & 1 \end{bmatrix}Rz(γ)=cosγsinγ0sinγcosγ0001

总的旋转矩阵可以通过将这三个单独的旋转矩阵相乘得到,对于ZYX顺序的欧拉角变换,其对应的旋转矩阵为:
R=Rz(γ)⋅Ry(β)⋅Rx(α)=[cos⁡γcos⁡βcos⁡γsin⁡βsin⁡α−sin⁡γcos⁡αcos⁡γsin⁡βcos⁡α+sin⁡γsin⁡αsin⁡γcos⁡βsin⁡γsin⁡βsin⁡α+cos⁡γcos⁡αsin⁡γsin⁡βcos⁡α−cos⁡γsin⁡α−sin⁡βcos⁡βsin⁡αcos⁡βcos⁡α]R =R_z(\gamma) \cdot R_y(\beta) \cdot R_x(\alpha)= \begin{bmatrix} \cos\gamma\cos\beta & \cos\gamma\sin\beta\sin\alpha - \sin\gamma\cos\alpha & \cos\gamma\sin\beta\cos\alpha + \sin\gamma\sin\alpha \\ \sin\gamma\cos\beta & \sin\gamma\sin\beta\sin\alpha + \cos\gamma\cos\alpha & \sin\gamma\sin\beta\cos\alpha - \cos\gamma\sin\alpha \\ -\sin\beta & \cos\beta\sin\alpha & \cos\beta\cos\alpha \end{bmatrix}R=Rz(γ)Ry(β)Rx(α)=cosγcosβsinγcosβsinβcosγsinβsinαsinγcosαsinγsinβsinα+cosγcosαcosβsinαcosγsinβcosα+sinγsinαsinγsinβcosαcosγsinαcosβcosα

o3d.geometry.get_rotation_matrix_from_AAA(从欧拉角生成旋转矩阵的函数)

函数原型

o3d.geometry.get_rotation_matrix_from_AAA(rotation)
AAA具体表示的函数旋转顺序说明
get_rotation_matrix_from_xyzX→Y→Z先绕X轴,再绕Y轴,最后绕Z轴
get_rotation_matrix_from_xzyX→Z→Y先绕X轴,再绕Z轴,最后绕Y轴
get_rotation_matrix_from_yxzY→X→Z先绕Y轴,再绕X轴,最后绕Z轴
get_rotation_matrix_from_yzxY→Z→X先绕Y轴,再绕Z轴,最后绕X轴
get_rotation_matrix_from_zxyZ→X→Y先绕Z轴,再绕X轴,最后绕Y轴
get_rotation_matrix_from_zyxZ→Y→X先绕Z轴,再绕Y轴,最后绕X轴
get_rotation_matrix_from_xyxX→Y→X两次绕X轴(经典欧拉角
get_rotation_matrix_from_xzxX→Z→X两次绕X轴(经典欧拉角
get_rotation_matrix_from_yxyY→X→Y两次绕Y轴(经典欧拉角
get_rotation_matrix_from_yzyY→Z→Y两次绕Y轴(经典欧拉角
get_rotation_matrix_from_zxzZ→X→Z两次绕Z轴(经典欧拉角
get_rotation_matrix_from_zyzZ→Y→Z两次绕Z轴(经典欧拉角

返回一个 3x3 的旋转矩阵 。

参数参数说明
rotation (np.ndarray)显式格式:形状为(4,)的数组,前三个元素是旋转轴向量(x, y, z),第四个元素是旋转角度(弧度); 紧凑格式:形状为(3,)的数组,旋转向量的方向表示旋转轴,旋转向量的模长表示旋转角度(弧度)。

示例:

import open3d as o3d
import numpy as np
import copy# 创建原始坐标系
mesh = o3d.geometry.TriangleMesh.create_coordinate_frame()# 深拷贝坐标系用于旋转
mesh_r = copy.deepcopy(mesh)# 定义欧拉角(绕X轴旋转90度,绕Y轴旋转60度,绕Z轴旋转45度)
# 弧度
euler_angles = np.array([np.pi / 2,  # X轴: 90度 (π/2)np.pi / 3,  # Y轴: 60度 (π/3)np.pi / 4])  # Z轴: 45度 (π/4)# 将欧拉角转换为旋转矩阵 (使用 ZYX 旋转顺序)
R = o3d.geometry.get_rotation_matrix_from_zyx(euler_angles)   print("总的旋转矩阵 (XYZ顺序):")
print(R)# 应用旋转,以原点为中心
mesh_r.rotate(R, center=(0, 0, 0))# 可视化原始和旋转后的坐标系
o3d.visualization.draw_geometries([mesh, mesh_r])

Quaternions(四元数)

四元数是一个扩展了复数概念的数学实体,由一个实部和三个虚部组成,可以用来表示三维空间中的旋转。
四元数 q=[w,x,y,z]q = [w, x, y, z]q=[w,x,y,z]形式上可以写作:
q=w+xi+yj+zkq = w + xi + yj + zkq=w+xi+yj+zk
对应的旋转矩阵 RRR 表示为:
R=[1−2(y2+z2)2(xy−wz)2(xz+wy)2(xy+wz)1−2(x2+z2)2(yz−wx)2(xz−wy)2(yz+wx)1−2(x2+y2)]R = \begin{bmatrix} 1 - 2(y^2 + z^2) & 2(xy - wz) & 2(xz + wy) \\ 2(xy + wz) & 1 - 2(x^2 + z^2) & 2(yz - wx) \\ 2(xz - wy) & 2(yz + wx) & 1 - 2(x^2 + y^2) \end{bmatrix}R=12(y2+z2)2(xy+wz)2(xzwy)2(xywz)12(x2+z2)2(yz+wx)2(xz+wy)2(yzwx)12(x2+y2)

这里需要注意的是,四元数 qqq 应该是单位四元数(即满足 w2+x2+y2+z2=1w^2 + x^2 + y^2 + z^2 = 1w2+x2+y2+z2=1),这样才能正确表示一个旋转。如果不是单位四元数,则需要先将其归一化

o3d.geometry.get_rotation_matrix_from_quaternion(从四元素生成旋转矩阵的函数)

函数原型

o3d.geometry.get_rotation_matrix_from_quaternion(quaternion)

返回一个 3x3 的旋转矩阵 。

参数参数说明
quaternion (np.ndarray)旋转的四元数,顺序为 (w, x, y, z)。

示例:

import open3d as o3d
import numpy as np
import copy# 创建原始坐标系
mesh = o3d.geometry.TriangleMesh.create_coordinate_frame()# 深拷贝坐标系用于旋转
mesh_r = copy.deepcopy(mesh)# 定义一个四元数[w,x,y,z]
quat = np.array([0.7330127, 0.30940108, 0.58508386, 0.15891862])
# 从四元数获取旋转矩阵
R = o3d.geometry.get_rotation_matrix_from_quaternion(quat)print("旋转矩阵:")
print(R)# 应用旋转,以原点为中心
mesh_r.rotate(R, center=(0, 0, 0))# 可视化原始和旋转后的坐标系
o3d.visualization.draw_geometries([mesh, mesh_r])


三维平移和缩放

Translation(平移)

在三维空间中,平移变换是最基本的几何变换之一,用于将点或物体沿指定方向移动固定距离,只是它在空间中的位置发生了变化。
原始点坐标: P=(x,y,z)P = (x, y, z)P=(x,y,z),平移T=(tx,ty,tz)T = (t_x, t_y, t_z)T=(tx,ty,tz)后的新坐标:
P′=P+T=(x+txy+tyz+tz)P' = P + T = \begin{pmatrix} x + t_x \\ y + t_y \\ z + t_z \end{pmatrix} P=P+T=x+txy+tyz+tz
其中,txt_xtx, tyt_yty, 和 tzt_ztz 分别表示在 xxx 轴、yyy 轴和 zzz 轴方向上的平移距离。

o3d.geometry.translate(对几何对象进行平移操作的函数)

适用于 TriangleMesh、PointCloud、LineSet 等几何类型。
函数原型

geometry.translate(T, relative=True)

没有显式返回值,直接修改调用它的几何对象的顶点坐标。

参数参数说明
T (np.ndarray,list)形状需为[3,],平移向量的三维数组 [tx, ty, tz]。
relative (bool, 可选,默认为True)True相对平移,在当前基础上增加平移量;False绝对平移,将物体中心移动到指定位置。

示例:

import open3d as o3d
import copy# 创建原始坐标系
mesh = o3d.geometry.TriangleMesh.create_coordinate_frame()# 深拷贝坐标系用于旋转
mesh_t = copy.deepcopy(mesh)# 设置平移向量 (X, Y, Z 三个方向的平移距离)
T = (2, 2, 2)# 平移操作(绝对平移)
mesh_t.translate(T, relative=False)# 可视化原始和旋转后的坐标系
o3d.visualization.draw_geometries([mesh, mesh_t])

Scale(缩放)

在三维空间中,缩放变换是另一种基本的几何变换,用于改变点或物体的大小。通过缩放变换,我们可以使物体变大或变小,而其形状保持不变。
原始点坐标: P=(x,y,z)P = (x, y, z)P=(x,y,z),缩放因子 S=(sx,sy,sz)S = (s_x, s_y, s_z)S=(sx,sy,sz) 后的新坐标:
P′=P⋅S=(x⋅sxy⋅syz⋅sz)P' = P \cdot S = \begin{pmatrix} x \cdot s_x \\ y \cdot s_y \\ z \cdot s_z \end{pmatrix}P=PS=xsxysyzsz
其中,sxs_xsx, sys_ysy, 和 szs_zsz 分别表示在 xxx 轴、yyy 轴和 zzz 轴方向上的缩放比例。如果 sx=sy=szs_x = s_y = s_zsx=sy=sz,则物体将均匀缩放;否则,物体将进行非均匀缩放,导致物体在不同轴方向上的尺寸变化不一致。

o3d.geometry.translate(对几何对象进行缩放操作的函数)

适用于 TriangleMesh、PointCloud、LineSet 等几何类型。
函数原型

geometry.scale(S, center=None)

没有显式返回值,直接修改调用它的几何对象的顶点坐标。

参数参数说明
S (float)所有轴按相同比例缩放。
center (np.ndarray或list)缩放中心点坐标。

示例:

import open3d as o3d
import copy# 创建原始坐标系
mesh = o3d.geometry.TriangleMesh.create_coordinate_frame(size=1.0)  # 设置初始大小# 深拷贝坐标系用于缩放
mesh_s = copy.deepcopy(mesh)# 设置缩放因子 (X, Y, Z 三个方向的缩放比例)
scale_factor = 2.0  # 均匀放大2倍# 执行缩放操作(相对于物体自身坐标系原点)
mesh_s.scale(scale_factor, center=mesh_s.get_center())# 可视化原始和缩放后的坐标系
o3d.visualization.draw_geometries([mesh, mesh_s])

o3d.geometry.get_center(计算并返回几何体的中心点的函数)

适用于 TriangleMesh、PointCloud、LineSet 等几何类型。
函数原型

geometry.get_center()

返回一个中心点坐标的 np.ndarray数组 [cx, cy, cz]。


总结

Open3D的三维变换基本操作。

http://www.lryc.cn/news/607621.html

相关文章:

  • 【数据分享】南海综合波浪数据(1945-2018 年)(获取方式看文末)
  • Servlet作用域,监听器,JSP九大内置对象
  • python基础语法4,函数(简单易上手的python语法教学)课后习题
  • WooCommerce 与 ERP 系统集成解决方案
  • ai项目多智能体
  • 告别软件残留!IObit Uninstaller Pro 让电脑彻底干净!
  • sqli-labs:Less-17关卡详细解析
  • 12.代理模式:Java世界的“中间商“智慧
  • VSCode Python 与 C++ 联合调试配置指南
  • Ⅹ—6.计算机二级综合题23---26套
  • 从内部保护你的网络
  • AIGC(生成式AI)试用 35 -- 用AI解析句子结构
  • 8.1IO进程线程——文件IO函数
  • 60 GHz DreamHAT+ 雷达已被正式批准为“Powered by Raspberry Pi”产品
  • Ubuntu 24.04.2 LTS 安装mysql8.0.36保姆级教程(从安装到远程连接)
  • Elixir 协议与行为
  • 深度揭秘端口映射:原理、场景、路由映射故障,与内网IP端口映射外网工具的选择
  • LOVON——面向足式Open-Vocabulary的物体导航:LLM做任务分解、YOLO11做目标检测,最后L2MM将指令和视觉映射为动作(且解决动态模糊)
  • Go语言的gRPC教程-拦截器
  • IO流File类的基本使用
  • 【2】专业自定义图表创建及应用方法
  • JS核心语法与实战技巧
  • 力扣:2477. 到达首都的最少油耗
  • OCR、文档解析工具合集
  • EasyExcel 格式设置大全
  • LangChain详解
  • OpenShift AI - 用 Hardware profiles 为运行环境分配可用的硬件规格
  • Windows和Linux的tree工具
  • 移动端 WebView 内存泄漏与性能退化问题如何排查 实战调试方法汇总
  • 【数据结构与算法】21.合并两个有序链表(LeetCode)