Open3d学习计划(3)变换
Open3D是一个开源库,支持快速开发和处理3D数据。Open3D在c++和Python中公开了一组精心选择的数据结构和算法。后端是高度优化的,并且是为并行化而设置的。
本系列学习计划有Blue同学作为发起人,主要以Open3D官方网站的教程为主进行翻译与实践的学习计划。点云PCL公众号作为免费的3D视觉,点云交流社区,期待有使用Open3D或者感兴趣的小伙伴能够加入我们的翻译计划,贡献免费交流社区,为使用Open3D提供中文的使用教程。
变换(transform)
Open3d的几何类型有许多变化方法。在本节教程中我们将会展示如何使用旋转(rotate),平移(translate),缩放(scale)和变换(transform)。
平移(translate)
这里我们展示的第一个算法是平移。平移算法就是通过单个三维向量 ttt 来平移所有点/顶点,vt=v+tv_{t} = v + tvt=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])
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来实现旋转。
它的第一个参数RR是一个旋转矩阵。由于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进行缩放,v_s=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算法默认第二个参数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还支持通过通用的4×44×4的矩阵进行变换。接口为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]]
本周线上分享预告:线上分享会预告之传统算法的点云配准与激光SLAM
如果你对Open3D感兴趣,或者正在使用该开源方案,就请加入我们,一起翻译,一起学习,贡献自己的力量,目前阶段主要以微信群为主,有意者发送“Open3D学习计划”到公众号后台,和更多热爱分享的小伙伴一起交流吧!如果翻译的有什么问题或者您有更好的意见,请评论交流!!!!
以上内容如有错误请留言评论,欢迎指正交流。如有侵权,请联系删除
扫描二维码
关注我们
让我们一起分享一起学习吧!期待有想法,乐于分享的小伙伴加入免费星球注入爱分享的新鲜活力。分享的主题包含但不限于三维视觉,点云,高精地图,自动驾驶,以及机器人等相关的领域。