Transformation 变形

Open3D 的几何类型具有许多变换方法。在本教程中,我们将展示如何使用translate 、rotate 、scale 和 transform。

Translate

我们要查看的第一个转换方法是translatet 。平移方法采用单个 3D 矢量作为输入,并通过此矢量平移几何的所有点/顶点。vt=v+t。下面的代码显示了网格在 x方向 中转换一次,在 y 方向上转换一次。

mesh = o3d.geometry.TriangleMesh.create_coordinate_frame()
mesh_tx = copy.deepcopy(mesh).translate((1.3, 0, 0))
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])

get_center方法返回TriangleMesh顶点的平均值。这意味着对于在原点创建的坐标系[0,0,0],get_center将返回[0.05167549 0.05167549 0.05167549]
该方法采用缺省设置为True的第二个参数relative。如果设置为False ,几何的中心将直接平移到第一个参数中指定的位置。

Rotation 旋转

Open3D的几何类型也可以使用rotate方法旋转。它采用旋转矩阵R作为第一个参数。由于 3D 中的旋转可以通过多种方式进行参数化,因此 Open3D 提供了从不同的参数化转换为旋转矩阵的便利功能:

从欧拉角转换为 get_rotation_matrix_from_xyz(其中xyz也可以是yzx ,zxy 、xzy ,zyx 和yxz)

从轴角表示转换为get_rotation_matrix_from_axis_angle

从四元数转换为get_rotation_matrix_from_quaternion

在下面的代码中,我们使用欧拉角旋转网格。

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,则将直接应用旋转,使得整个几何围绕坐标中心旋转。这意味着在旋转后可以更改网格中心。

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 , 进行缩放。vs=s⋅v

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方法还具有默认设置为True的第二个参数。center。如果将其设置为False ,则对象在缩放之前不会居中,因此对象的中心可以由于缩放操作而移动.

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 还支持使用transform方法由4×4齐次变换矩阵定义的一般变换。
为什么是4x4的矩阵(而不是3x3)?可以参考https://xiaozhuanlan.com/topic/9285364071,仿射变换等解释。

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])