Three-dimensional transformation mainly includes: translation, rotation, scaling
In open3d, the transformation for three-dimensional objects mainly includes translate, rotate, scale and transform
• Translate translation
• Rotate rotation
• Scale scaling
• Transform transformation matrix (4*4)
mesh_tx = mesh.translate((1.5, 0, 0))
mesh_r = mesh.rotate(R, center=(0, 0, 0))
mesh_s = mesh.scale(0.5, center=(0, 0, 0))
mesh_t = mesh.transform(T)
3D rotation
Open3d's geometry is rotated through rotate.
Its first parameter R is a rotation matrix. Since the rotation of a 3D object can be represented by multiple parameters, Open3d provides a function that can easily change different parameters into a rotation matrix.
- Use get_rotation_matrix_from_xyz to convert from Euler angles (Euler angles) to a matrix (here xyz can also be yzx, zxy, xzy, zyx and yxz);
- Convert from Axis-angle representation using get_rotation_matrix_from_axis_angle;
- Use get_rotation_matrix_from_quaternion to convert from quaternion;
rotation matrix
Rotation matrix: Nine numbers are used to represent three degrees of freedom, and each column in the matrix represents the direction of the unit vector after rotation. The disadvantage is that it is redundant and not compact.
# 旋转,为便于观察,增加了缩放操作
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))
mesh_r.scale(0.5, center=mesh_r.get_center())
o3d.visualization.draw_geometries([mesh])
o3d.visualization.draw_geometries([mesh, mesh_r])
Notice:
- In the three-dimensional coordinate system of open3d, red, green, and blue are used to refer to the three-dimensional coordinate axes, representing the three directions of the X axis (forward), the Y axis (to the right) and the Z axis (upward or outward). ;
- Rotate 90° counterclockwise around the X axis, 0° around the Y axis, and 45° counterclockwise around the Z axis;
rotation vector
Rotation vector: A rotation axis and a rotation angle are used to represent the rotation, but because of periodicity, any 2nπ rotation is equivalent to no rotation, which has singularity.
The rotation matrix R and its corresponding rotation vector r are converted by the following formula:
open3D interface function:
open3d.geometry.get_rotation_matrix_from_axis_angle(rotation: numpy.ndarray[numpy.float64[3, 1]]) →
numpy.ndarray[numpy.float64[3, 3]]
Euler angle
Euler angle: decomposes the rotation into three separate corners, commonly used on aircraft, but also has singularity due to the Gimbal Lock problem.
It is necessary to distinguish whether each rotation rotates around a fixed axis or around the axis after rotation, using ZYX (first around Z, then around Y, and finally around X); the angle of counterclockwise rotation is positive (the same as the right-handed rotation direction
) is the positive direction of rotation), and
the rotation results around different axes:
Note:
- The rotation order of the Euler angle is different, pay attention to the order of multiplication
- Left multiplication in coordinate system rotation - rotation relative to a fixed coordinate system
- Right multiplication in coordinate system rotation - rotation relative to its own coordinate system
open3D interface function:
open3d.geometry.get_rotation_matrix_from_xyz(rotation: numpy.ndarray[numpy.float64[3, 1]]) → numpy.ndarray[numpy.float64[3, 3]]
open3d.geometry.get_rotation_matrix_from_xzy(rotation: numpy.ndarray[numpy.float64[3, 1]]) → numpy.ndarray[numpy.float64[3, 3]]
open3d.geometry.get_rotation_matrix_from_yxz(rotation: numpy.ndarray[numpy.float64[3, 1]]) → numpy.ndarray[numpy.float64[3, 3]]
open3d.geometry.get_rotation_matrix_from_yzx(rotation: numpy.ndarray[numpy.float64[3, 1]]) → numpy.ndarray[numpy.float64[3, 3]]
open3d.geometry.get_rotation_matrix_from_zxy(rotation: numpy.ndarray[numpy.float64[3, 1]]) → numpy.ndarray[numpy.float64[3, 3]]
open3d.geometry.get_rotation_matrix_from_zyx(rotation: numpy.ndarray[numpy.float64[3, 1]]) → numpy.ndarray[numpy.float64[3, 3]]
Quaternion
Quaternion: It is a representation method that is compact, easy to iterate, and does not appear singular values. It is widely used in programs, such as ROS and several famous SLAM public data sets, g2o and other programs all use quaternion to record the pose of the robot.
Quaternions are an extended complex number discovered by Hamilton. A quaternion has one real part and three imaginary parts
Quaternion to rotation matrix:
open3D interface function:
open3d.geometry.get_rotation_matrix_from_quaternion
(rotation: numpy.ndarray[numpy.float64[4, 1]]) → numpy.ndarray[numpy.float64[3, 3]]
3D translation
The translation algorithm is to translate all points/vertices through a single three-dimensional vector t; as follows: translate 2 along the Z axis
# 平移
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:
The get_center algorithm returns the average of the triangle mesh vertices. This results in a coordinate system with the origin at [0, 0, 0], which using get_center returns [0.05167549
0.05167549 0.05167549].
3D zoom
The vertices and points in Open3d can be scaled by applying scale:
# 先沿X轴平移,再缩放
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])
Interchange between Open3D and numpy
Open3D data structures are natively compatible with NumPy buffers;
- Numpy to open3d.pointcloud
mainly uses the Vector3dVector function to directly assign it;
pcd = o3d.geometry.PointCloud()
pcd.points = o3d.utility.Vector3dVector(xyz)
- open3d.PointCloud to NumPy
xyz_load = np.asarray(pcd_load.points)