Open3d学习计划——5(变换)
Open3d学习计划——5(变换)
欢迎大家关注“点云PCL”公众号,进入群聊一起学习。
Open3d的几何类型有许多变化方法。在本节教程中我们将会展示如何使用旋转(rotate),平移(translate),缩放(scale)和变换(transform)。
平移(translate)
这里我们展示的第一个算法是平移。平移算法就是通过单个三维向量 来平移所有点/顶点,。下面的代码展示了网格分别在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])
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,中心点就会被转换到第一个参数指定的位置。
mesh = o3d.geometry.TriangleMesh.create_coordinate_frame()
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.]
旋转
Open3d的几何体通过rotate来实现旋转。
它的第一个参数是一个旋转矩阵。由于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从四元数进行转换
下面的代码展示了从欧拉角进行转换。
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])
缩放
Open3d里面的顶点和点可以应用scale进行缩放, 。
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,对象在缩放前没有居中,这样就可以移动对象的中心。
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])
通用的变换
Open3d还支持通过通用的的矩阵进行变换。接口为transform。
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]]