Open3d之坐标变换

Open3d的几何类型有许多种坐标变换的方法。在本节教程中我们将会展示如何使用旋转(rotate),平移(translate),缩放(scale)和变换(transform)。

平移(translate)

这里我们展示的第一个算法是平移。平移是将单个3D矢量t作为输入,并通过该矢量平移几何图形的所有点/顶点,v_{t} = v + t。下面的代码展示了网格分别在x方向和y方向平移一次的结果。

# -*-coding:utf-8 -*-
import open3d as o3d
import copy

# 在原点创建坐标框架网格
mesh = o3d.geometry.TriangleMesh.create_coordinate_frame()
# 往x方向平移1.3米
mesh_tx = copy.deepcopy(mesh).translate((1.3, 0, 0))
# 往y方向平移1.3米
mesh_ty = copy.deepcopy(mesh).translate((0, 1.3, 0))
# 打印网格中心坐标
print(f'Center of mesh: {mesh.get_center()}')
print(f'Center of mesh tx: {mesh_tx.get_center()}')
print(f'Center of mesh ty: {mesh_ty.get_center()}')
# 可视化
o3d.visualization.draw_geometries([mesh, mesh_tx, mesh_ty])

Center of mesh: [0.05167549 0.05167549 0.05167549]
Center of mesh tx: [1.35167549 0.05167549 0.05167549]
Center of mesh ty: [0.05167549 1.35167549 0.05167549]

Note:
get_center算法返回的是三角网格顶点的平均值。这就会导致原点在[0,0,0]处的坐标系,使用get_center返回的是[0.05167549 0.05167549 0.05167549]。

这个算法有第二个参数relative,默认为true。如果我们将其设为false,中心点就会被转换到第一个参数指定的位置。

# -*-coding:utf-8 -*-
import open3d as o3d
import copy

# 在原点创建坐标框架网格
mesh = o3d.geometry.TriangleMesh.create_coordinate_frame()
# 往xyz方向平移2米
mesh_mv = copy.deepcopy(mesh).translate((2,2,2), relative=False)
# 打印网格中心坐标
print(f'Center of mesh: {mesh.get_center()}')
print(f'Center of translated mesh: {mesh_mv.get_center()}')
# 可视化
o3d.visualization.draw_geometries([mesh, mesh_mv])

Center of mesh: [0.05167549 0.05167549 0.05167549]
Center of translated mesh: [2. 2. 2.]

旋转(Rotation)

Open3d的几何体通过rotate来实现旋转。
它的第一个参数是一个旋转矩阵R。由于3D中的旋转可以用多种方式进行参数化,Open3D提供了不同的参数化方法,从而得到旋转矩阵:

  • 使用get_rotation_matrix_from_xyz从欧拉角(Euler angles)转换为矩阵(这里xyz也可以是yzx,zxy,xzy,zyx和yxz)。
  • 使用get_rotation_matrix_from_axis_angle从轴角(Axis-angle representation)转换
  • 使用get_rotation_matrix_from_quaternion从四元数进行转换
    下面的代码展示了从欧拉角进行转换。
# -*-coding:utf-8 -*-
import numpy as np
import open3d as o3d
import copy

# 在原点创建坐标框架网格
mesh = o3d.geometry.TriangleMesh.create_coordinate_frame()
# 使用欧拉角创建旋转矩阵
mesh_r = copy.deepcopy(mesh)
R = mesh.get_rotation_matrix_from_xyz((np.pi / 2, 0, np.pi / 4))
# 旋转网格
mesh_r.rotate(R, center=(0, 0, 0))
# 可视化
o3d.visualization.draw_geometries([mesh, mesh_r])

函数rotate的第二个参数center默认为True。这表示对象在旋转之前首先居中,然后移动到先前的中心。如果设置为False,则几何图像将直接围绕坐标中心旋转。这意味着网格中心可以在旋转之后改变。

# -*-coding:utf-8 -*-
import numpy as np
import open3d as o3d
import copy

# 在原点创建坐标框架网格
mesh = o3d.geometry.TriangleMesh.create_coordinate_frame()
# 平移网格
mesh_r = copy.deepcopy(mesh).translate((2, 0, 0))
# 使用欧拉角创建旋转矩阵
mesh_r.rotate(mesh.get_rotation_matrix_from_xyz((np.pi / 2, 0, np.pi / 4)), center=(0, 0, 0))
# 可视化
o3d.visualization.draw_geometries([mesh, mesh_r])

缩放(Scale)

Open3d里面的顶点和点可以应用scale进行缩放,v_{s} = s \cdot v

# -*-coding:utf-8 -*-
import numpy as np
import open3d as o3d
import copy

# 在原点创建坐标框架网格
mesh = o3d.geometry.TriangleMesh.create_coordinate_frame()
# 平移网格
mesh_s = copy.deepcopy(mesh).translate((2, 0, 0))
# 使用缩放网格
mesh_s.scale(0.5, center=mesh_s.get_center())
# 可视化
o3d.visualization.draw_geometries([mesh, mesh_s])


scale算法默认第二个参数center也是True。如果设置为False,对象在缩放前没有居中,这样就可以移动对象的中心。

# -*-coding:utf-8 -*-
import numpy as np
import open3d as o3d
import copy

# 在原点创建坐标框架网格
mesh = o3d.geometry.TriangleMesh.create_coordinate_frame()
# 平移网格
mesh_s = copy.deepcopy(mesh).translate((2, 1, 0))
# 使用缩放网格
mesh_s.scale(0.5, center=(0, 0, 0))
# 可视化
o3d.visualization.draw_geometries([mesh, mesh_s])

通用变换(General transformation)

Open3d还支持通过通用的4 × 4的矩阵进行变换。接口为transform

# -*-coding:utf-8 -*-
import numpy as np
import open3d as o3d
import copy

# 在原点创建坐标框架网格
mesh = o3d.geometry.TriangleMesh.create_coordinate_frame()
# 网格坐标变换
T = np.eye(4)
T[:3, :3] = mesh.get_rotation_matrix_from_xyz((0, np.pi / 3, np.pi / 2))
T[0, 3] = 1
T[1, 3] = 1.3
print(T)
mesh_t = copy.deepcopy(mesh).transform(T)
# 可视化
o3d.visualization.draw_geometries([mesh, mesh_t])

[[ 3.06161700e-17 -5.00000000e-01 8.66025404e-01 1.00000000e+00]
[ 1.00000000e+00 6.12323400e-17 0.00000000e+00 1.30000000e+00]
[-5.30287619e-17 8.66025404e-01 5.00000000e-01 0.00000000e+00]
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00]]

  • 2
    点赞
  • 50
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值