open3d 旋转、平移、位姿变换详解
最近使用 Open3D 进行位姿处理时,遇到让我百思不得其解的情况…… 后来发现用它进行旋转和平移时,默认情况下的表现和我们一般理解的有所不同。(好坑
一言以蔽之:transform(T) 进行位姿变换,或者 .rotate(R, center=(0, 0, 0)).translate(t)
参考:Transformation - Open3D 0.18.0 documentation
首先进行不同形式的变换,对比得到的结果:
import numpy as np
f0 = o3d.geometry.TriangleMesh.create_coordinate_frame(size=1)
f1 = o3d.geometry.TriangleMesh.create_coordinate_frame(size=1).translate((1, 1, 1))
R = o3d.geometry.TriangleMesh.get_rotation_matrix_from_xyz((np.pi / 2, 0, 0))
f2 = o3d.geometry.TriangleMesh.create_coordinate_frame(size=0.5).translate((1, 1, 1)).rotate(R)
f3 = o3d.geometry.TriangleMesh.create_coordinate_frame(size=0.5).translate((1, 1, 1)).rotate(R, center=(0, 0, 0))
o3d.visualization.draw_geometries([bbox, f0, f1, f2, f3])

梳理一下模型位姿变换的方法:
-
get_center获得顶点的均值( the mean of the vertices ) (center 是模型的中心点而非坐标原点) -
translate(self, translation, relative=True)- 默认直接把
translation加到坐标点上。 relative=False时,把模型的中心置于translation位置。
- 默认直接把
-
rotate(self, R),rotate(self, R, center)-
默认情况下(不指定
center时),绕模型本身的 center 为原点的坐标轴进行旋转。f.rotate(R)等同于f.rotate(R, center=f.get_center())按照文档的说法,该方法模型的中心不会改变(我测试了下实际还是会改变,可能改变的比较微小),直观上是接近于期望物体自旋。
-
指定
center时,例如指定(0, 0, 0),就是绕原本坐标系的轴进行旋转。
-
-
transform(self, arg0)一般的位姿变换arg0 (numpy.ndarray[numpy.float64[4, 4]])变换矩阵是 4x4 的 T,其中也包含了旋转矩阵 R 和平移向量 t。我们一般理解的旋转和平移都是两个坐标系之间的相对关系,不涉及模型中心点。以相机位姿 T 为例,R 是相机坐标轴在世界坐标系下的坐标,t 是相机坐标原点在世界坐标系下的坐标。
所以
f.transform(T)等价于f.rotate(R, center=(0, 0, 0)).translate(t).import numpy as np f0 = o3d.geometry.TriangleMesh.create_coordinate_frame(size=1) t = (1, 1, 1) R = f0.get_rotation_matrix_from_xyz((np.pi / 2, 0, 0)) T = np.eye(4) T[:3,:3] = R T[:3,3] = t f1 = o3d.geometry.TriangleMesh.create_coordinate_frame(size=0.5).rotate(R, center=(0, 0, 0)).translate(t) f2 = o3d.geometry.TriangleMesh.create_coordinate_frame(size=0.5).transform(T) o3d.visualization.draw_geometries([bbox, f0, f1, f2])
总结,处理位姿问题还是直接使用 transform 方法吧~~🫡

浙公网安备 33010602011771号