| import math |
|
|
| import numpy as np |
| from scipy.spatial.transform import Rotation as R |
|
|
|
|
| def create_perspective_matrix(aspect_ratio): |
| kDegreesToRadians = np.pi / 180. |
| near = 1 |
| far = 10000 |
| perspective_matrix = np.zeros(16, dtype=np.float32) |
|
|
| |
| f = 1.0 / np.tan(kDegreesToRadians * 63 / 2.) |
|
|
| denom = 1.0 / (near - far) |
| perspective_matrix[0] = f / aspect_ratio |
| perspective_matrix[5] = f |
| perspective_matrix[10] = (near + far) * denom |
| perspective_matrix[11] = -1. |
| perspective_matrix[14] = 1. * far * near * denom |
|
|
| |
| |
|
|
| perspective_matrix[5] *= -1. |
| return perspective_matrix |
|
|
|
|
| def project_points(points_3d, transformation_matrix, pose_vectors, image_shape): |
| P = create_perspective_matrix(image_shape[1] / image_shape[0]).reshape(4, 4).T |
| L, N, _ = points_3d.shape |
| projected_points = np.zeros((L, N, 2)) |
| for i in range(L): |
| points_3d_frame = points_3d[i] |
| ones = np.ones((points_3d_frame.shape[0], 1)) |
| points_3d_homogeneous = np.hstack([points_3d_frame, ones]) |
| transformed_points = points_3d_homogeneous @ (transformation_matrix @ euler_and_translation_to_matrix(pose_vectors[i][:3], pose_vectors[i][3:])).T @ P |
| projected_points_frame = transformed_points[:, :2] / transformed_points[:, 3, np.newaxis] |
| projected_points_frame[:, 0] = (projected_points_frame[:, 0] + 1) * 0.5 * image_shape[1] |
| projected_points_frame[:, 1] = (projected_points_frame[:, 1] + 1) * 0.5 * image_shape[0] |
| projected_points[i] = projected_points_frame |
| return projected_points |
|
|
|
|
| def project_points_with_trans(points_3d, transformation_matrix, image_shape): |
| P = create_perspective_matrix(image_shape[1] / image_shape[0]).reshape(4, 4).T |
| L, N, _ = points_3d.shape |
| projected_points = np.zeros((L, N, 2)) |
| for i in range(L): |
| points_3d_frame = points_3d[i] |
| ones = np.ones((points_3d_frame.shape[0], 1)) |
| points_3d_homogeneous = np.hstack([points_3d_frame, ones]) |
| transformed_points = points_3d_homogeneous @ transformation_matrix[i].T @ P |
| projected_points_frame = transformed_points[:, :2] / transformed_points[:, 3, np.newaxis] |
| projected_points_frame[:, 0] = (projected_points_frame[:, 0] + 1) * 0.5 * image_shape[1] |
| projected_points_frame[:, 1] = (projected_points_frame[:, 1] + 1) * 0.5 * image_shape[0] |
| projected_points[i] = projected_points_frame |
| return projected_points |
|
|
|
|
| def euler_and_translation_to_matrix(euler_angles, translation_vector): |
| rotation = R.from_euler('xyz', euler_angles, degrees=True) |
| rotation_matrix = rotation.as_matrix() |
| |
| matrix = np.eye(4) |
| matrix[:3, :3] = rotation_matrix |
| matrix[:3, 3] = translation_vector |
| |
| return matrix |
|
|
|
|
| def matrix_to_euler_and_translation(matrix): |
| rotation_matrix = matrix[:3, :3] |
| translation_vector = matrix[:3, 3] |
| rotation = R.from_matrix(rotation_matrix) |
| euler_angles = rotation.as_euler('xyz', degrees=True) |
| return euler_angles, translation_vector |