def filter_and_color_pointcloud(add_noise=False): kitti_loader = KittiLoader(test_date, test_drive) points_3d, rgb_image, calibration, projection_matrix = kitti_loader.get_all_data( test_frame_index) # remove intensity points_3d = points_3d[:, :3] pcd = o3d.geometry.PointCloud() pcd.points = o3d.utility.Vector3dVector( np.append(points_3d, [[0, 0, 0], [-0.27, 0, 0]], axis=0)) pcd.paint_uniform_color([0, 1, 0]) o3d.io.write_point_cloud( os.path.join(pointcloud_save_path, "original.pcd"), pcd) if add_noise: noise = np.random.normal(0., .01, points_3d.shape) points_3d += noise points_2d = project_points_3d_to_points_2d(points_3d.T, projection_matrix) image_height, image_width, _ = rgb_image.shape # Filter out points based on both projection ordered_indexes = create_filter(points_2d, points_3d, image_width=image_width, image_height=image_height) points_2d = points_2d[ordered_indexes] points_2d[:, 0] = np.round(points_2d[:, 0]) points_2d[:, 1] = np.round(points_2d[:, 1]) points_3d = points_3d[ordered_indexes] pcd.points = o3d.utility.Vector3dVector(points_3d) pcd.paint_uniform_color([0, 1, 0]) o3d.io.write_point_cloud( os.path.join(pointcloud_save_path, "filtered.pcd"), pcd) pcd = o3d.geometry.PointCloud() pcd.points = o3d.utility.Vector3dVector(points_3d) colors = [] for point_2d in points_2d: colors.append(rgb_image[int(point_2d[1]), int(point_2d[0])] / 255.) colors = np.asarray(colors) colors = colors[:, ::-1] pcd.colors = o3d.utility.Vector3dVector(colors) o3d.io.write_point_cloud( os.path.join(pointcloud_save_path, "rgb_colored.pcd"), pcd)
def compare_noisy_pointcloud_to_pointcloud(add_noise=True): kitti_loader = KittiLoader(date=test_date, drive=test_drive) source = kitti_loader.load_velodyne_pointcloud_array( test_frame_index)[:, :3] source_pcd = o3d.geometry.PointCloud(o3d.utility.Vector3dVector(source)) o3d.io.write_point_cloud(os.path.join(pointcloud_save_path, "source.pcd"), source_pcd) init_transformation = kitti_loader.calib.T_velo_imu # init_transformation = np.eye(4) target = init_transformation @ np.hstack( (source, np.ones((np.asarray(source).shape[0], 1)))).T target = target.T target = target[:, :3] if add_noise: noise = np.random.normal(0., .01, target.shape) target += noise target_pcd = o3d.geometry.PointCloud(o3d.utility.Vector3dVector(target)) o3d.io.write_point_cloud( os.path.join(pointcloud_save_path, "noisy_target.pcd"), target_pcd) print("init_transformation = ") print(init_transformation) result = o3d.registration.registration_icp( source=source_pcd, target=target_pcd, max_correspondence_distance=10, # todo check: meters? init=init_transformation, estimation_method=o3d.registration. TransformationEstimationPointToPoint()) print("icp translation = ") print(result.transformation) # threshold: 1 meter evaluation_results = o3d.registration.evaluate_registration( source_pcd, target_pcd, 1, result.transformation) print(evaluation_results) print()
def compare_own_noisy_depth_to_own_depth(add_noise=True): kitti_loader = KittiLoader(test_date, test_drive) source_points_3d, rgb_image, calibration, projection_matrix = kitti_loader.get_all_data( test_frame_index) target_points_3d = source_points_3d.copy() # remove intensity source_points_3d = source_points_3d[:, :3] target_points_3d = target_points_3d[:, :3] if add_noise: noise = np.random.normal(0., 0.1, source_points_3d.shape) source_points_3d += noise source_points_2d = project_points_3d_to_points_2d(source_points_3d.T, projection_matrix) target_points_2d = project_points_3d_to_points_2d(target_points_3d.T, projection_matrix) image_height, image_width, _ = rgb_image.shape # Filter out 2d points ordered_indexes = create_filter(source_points_2d, source_points_3d, image_width=image_width, image_height=image_height) source_points_2d = source_points_2d[ordered_indexes] source_points_2d[:, 0] = np.round(source_points_2d[:, 0]) source_points_2d[:, 1] = np.round(source_points_2d[:, 1]) source_points_2d[:, 2] = 0 # Filter out 2d points ordered_indexes = create_filter(target_points_2d, target_points_3d, image_width=image_width, image_height=image_height) target_points_2d = target_points_2d[ordered_indexes] target_points_2d[:, 0] = np.round(target_points_2d[:, 0]) target_points_2d[:, 1] = np.round(target_points_2d[:, 1]) target_points_2d[:, 2] = 0 target_points_3d = target_points_3d[ordered_indexes] target_pcd = o3d.geometry.PointCloud() target_pcd.points = o3d.utility.Vector3dVector(target_points_3d) colors = np.empty(shape=target_points_3d.shape) colors[:, 0] = 0.0 colors[:, 1] = 0.0 colors[:, 2] = 0.99 target_pcd.colors = o3d.utility.Vector3dVector(colors) o3d.io.write_point_cloud( os.path.join(pointcloud_save_path, "filtered.pcd"), target_pcd) # icp source_points_2d_pcd = o3d.geometry.PointCloud() source_points_2d_pcd.points = o3d.utility.Vector3dVector(source_points_2d) target_points_2d_pcd = o3d.geometry.PointCloud() target_points_2d_pcd.points = o3d.utility.Vector3dVector(target_points_2d) result = o3d.registration.registration_icp( source=source_points_2d_pcd, target=target_points_2d_pcd, max_correspondence_distance=2, # init = init_translation, estimation_method=o3d.registration. TransformationEstimationPointToPoint()) print("icp result:") print(result.transformation) print(len(target_points_2d), len(source_points_2d)) # threshold: 1 meter evaluation_results = o3d.registration.evaluate_registration( source_points_2d_pcd, target_points_2d_pcd, 10, result.transformation) print(evaluation_results) print()
def accumulate(): kitti_loader = KittiLoader(date=test_date, drive=test_drive) size = len(kitti_loader.dataset.velo_files) print(size) T_w_imu = kitti_loader.dataset.oxts[0].T_w_imu points = kitti_loader.load_velodyne_pointcloud_array(0)[:, :3] points = T_w_imu @ np.hstack( (points, np.ones((np.asarray(points).shape[0], 1)))).T points = points.T points = points[:, :3] # todo np array bug!!! accumulated_points = points accumulated_pointcloud = o3d.geometry.PointCloud() accumulated_pointcloud.points = o3d.utility.Vector3dVector( accumulated_points) tmp_pointcloud = o3d.geometry.PointCloud() transform = np.eye(4) for index in range(1, size, 1): if index == size: break print(index) T_w_imu = kitti_loader.dataset.oxts[index].T_w_imu points = kitti_loader.load_velodyne_pointcloud_array(index)[:, :3] points = T_w_imu @ np.hstack( (points, np.ones((np.asarray(points).shape[0], 1)))).T points = points.T points = points[:, :3] tmp_pointcloud.points = o3d.utility.Vector3dVector(points) result = o3d.registration.registration_icp( source=tmp_pointcloud, target=accumulated_pointcloud, max_correspondence_distance=1, init=transform, estimation_method=o3d.registration. TransformationEstimationPointToPoint()) transform = result.transformation points = transform @ np.hstack( (points, np.ones((np.asarray(points).shape[0], 1)))).T points = points.T points = points[:, :3] accumulated_points = np.concatenate((accumulated_points, points)) accumulated_pointcloud.points = o3d.utility.Vector3dVector( accumulated_points) print("Number of accumulated points:", accumulated_points.shape) colors = np.empty(shape=(len(accumulated_points), 3)) colors[:, 0] = 0.99 colors[:, 1] = 0.0 colors[:, 2] = 0.0 accumulated_pointcloud.colors = o3d.utility.Vector3dVector(colors) o3d.io.write_point_cloud( os.path.join(pointcloud_save_path, "accumulated.pcd"), accumulated_pointcloud) print()
def imu_validation(): kitti_loader = KittiLoader(date=test_date, drive=test_drive) frame_offset = 70 T_w_imu_0 = kitti_loader.dataset.oxts[test_frame_index].T_w_imu T_w_imu_1 = kitti_loader.dataset.oxts[test_frame_index + frame_offset].T_w_imu target = kitti_loader.load_velodyne_pointcloud_array( test_frame_index)[:, :3] source = kitti_loader.load_velodyne_pointcloud_array(test_frame_index + frame_offset)[:, :3] # source[:, 2] += 1.0 target_pcd = o3d.geometry.PointCloud() colors = np.empty(shape=target.shape) colors[:, 0] = 0.99 colors[:, 1] = 0.0 colors[:, 2] = 0.0 target_pcd.colors = o3d.utility.Vector3dVector(colors) source_pcd = o3d.geometry.PointCloud() colors = np.empty(shape=source.shape) colors[:, 0] = 0.0 colors[:, 1] = 0.99 colors[:, 2] = 0.0 source_pcd.colors = o3d.utility.Vector3dVector(colors) target = T_w_imu_0 @ np.hstack( (target, np.ones((np.asarray(target).shape[0], 1)))).T target = target.T target = target[:, :3] source = T_w_imu_0 @ np.hstack( (source, np.ones((np.asarray(source).shape[0], 1)))).T source = source.T source = source[:, :3] target_pcd.points = o3d.utility.Vector3dVector(target) source_pcd.points = o3d.utility.Vector3dVector(source) o3d.io.write_point_cloud( os.path.join(pointcloud_save_path, "frame_target_initial.pcd"), target_pcd) o3d.io.write_point_cloud( os.path.join(pointcloud_save_path, "frame_source_initial.pcd"), source_pcd) evaluation_results = o3d.registration.evaluate_registration( source_pcd, target_pcd, 5, np.eye(4)) print("initial error without IMU nor ICP:", evaluation_results.inlier_rmse) print() target = kitti_loader.load_velodyne_pointcloud_array( test_frame_index)[:, :3] source = kitti_loader.load_velodyne_pointcloud_array(test_frame_index + frame_offset)[:, :3] target = T_w_imu_0 @ np.hstack( (target, np.ones((np.asarray(target).shape[0], 1)))).T target = target.T target = target[:, :3] source = T_w_imu_1 @ np.hstack( (source, np.ones((np.asarray(source).shape[0], 1)))).T source = source.T source = source[:, :3] target_pcd.points = o3d.utility.Vector3dVector(target) source_pcd.points = o3d.utility.Vector3dVector(source) evaluation_results = o3d.registration.evaluate_registration( source_pcd, target_pcd, 1, np.eye(4)) print("error after IMU correction:", evaluation_results.inlier_rmse) print() o3d.io.write_point_cloud( os.path.join(pointcloud_save_path, "frame_target_imu.pcd"), target_pcd) o3d.io.write_point_cloud( os.path.join(pointcloud_save_path, "frame_source_imu.pcd"), source_pcd) # point-to-point ICP result = o3d.registration.registration_icp( source=source_pcd, target=target_pcd, max_correspondence_distance=1, init=np.eye(4), estimation_method=o3d.registration. TransformationEstimationPointToPoint()) source = result.transformation @ np.hstack( (source, np.ones((np.asarray(source).shape[0], 1)))).T source = source.T source = source[:, :3] source_pcd.points = o3d.utility.Vector3dVector(source) evaluation_results = o3d.registration.evaluate_registration( source_pcd, target_pcd, 1, np.eye(4)) print("error after point-to-point ICP:", evaluation_results.inlier_rmse) print() o3d.io.write_point_cloud( os.path.join(pointcloud_save_path, "frame_target_point.pcd"), target_pcd) o3d.io.write_point_cloud( os.path.join(pointcloud_save_path, "frame_source_point.pcd"), source_pcd) # point-to-plane ICP source_pcd.estimate_normals( search_param=o3d.geometry.KDTreeSearchParamHybrid(radius=0.15, max_nn=50)) target_pcd.estimate_normals( search_param=o3d.geometry.KDTreeSearchParamHybrid(radius=0.15, max_nn=50)) result = o3d.registration.registration_icp( source=source_pcd, target=target_pcd, max_correspondence_distance=1, init=np.eye(4), estimation_method=o3d.registration. TransformationEstimationPointToPlane()) source = result.transformation @ np.hstack( (source, np.ones((np.asarray(source).shape[0], 1)))).T source = source.T source = source[:, :3] source_pcd.points = o3d.utility.Vector3dVector(source) evaluation_results = o3d.registration.evaluate_registration( source_pcd, target_pcd, 1, np.eye(4)) print("error after point-to-plane ICP:", evaluation_results.inlier_rmse) print() source_pcd.normals = o3d.utility.Vector3dVector([]) o3d.io.write_point_cloud( os.path.join(pointcloud_save_path, "frame_target_plane.pcd"), target_pcd) target_pcd.normals = o3d.utility.Vector3dVector([]) o3d.io.write_point_cloud( os.path.join(pointcloud_save_path, "frame_source_plane.pcd"), source_pcd) print()
def synthesize_next_rgb_image(dilation=1): kitti_loader = KittiLoader(test_date, test_drive) source_points_3d, source_rgb_image, _, projection_matrix = kitti_loader.get_all_data( test_frame_index) source_points_3d = np.append(source_points_3d, [[1, 0, 0, 0]], axis=0) _, next_rgb_image, _, _ = kitti_loader.get_all_data(test_frame_index + dilation) source_T_w_imu = kitti_loader.dataset.oxts[test_frame_index].T_w_imu next_T_w_imu = kitti_loader.dataset.oxts[test_frame_index + dilation].T_w_imu # remove intensity source_points_3d = source_points_3d[:, :3] next_pcd = o3d.geometry.PointCloud( o3d.utility.Vector3dVector(source_points_3d)) o3d.io.write_point_cloud( os.path.join(pointcloud_save_path, "source_points_3d.pcd"), next_pcd) source_points_3d_homogeneous = np.hstack( (source_points_3d, np.ones( (np.asarray(source_points_3d).shape[0], 1)))) next_points_3d = source_points_3d_homogeneous @ np.linalg.inv( source_T_w_imu) @ next_T_w_imu # remove homogeneous coordinate 1 next_points_3d = next_points_3d[:, :3] next_pcd = o3d.geometry.PointCloud( o3d.utility.Vector3dVector(next_points_3d)) o3d.io.write_point_cloud( os.path.join(pointcloud_save_path, "next_points_3d.pcd"), next_pcd) source_points_2d = project_points_3d_to_points_2d(source_points_3d.T, projection_matrix) next_points_2d = project_points_3d_to_points_2d(next_points_3d.T, projection_matrix) image_height, image_width, _ = source_rgb_image.shape source_ordered_indexes = create_filter(source_points_2d, source_points_3d, image_width=image_width, image_height=image_height) next_ordered_indexes = create_filter(next_points_2d, next_points_3d, image_width=image_width, image_height=image_height) ordered_indexes = list( set(source_ordered_indexes) & set(next_ordered_indexes)) source_points_2d = source_points_2d[ordered_indexes] source_points_2d[:, 0] = np.round(source_points_2d[:, 0]) source_points_2d[:, 1] = np.round(source_points_2d[:, 1]) next_points_2d = next_points_2d[ordered_indexes] next_points_2d[:, 0] = np.round(next_points_2d[:, 0]) next_points_2d[:, 1] = np.round(next_points_2d[:, 1]) next_points_3d = next_points_3d[ordered_indexes] next_pcd.points = o3d.utility.Vector3dVector(next_points_3d) o3d.io.write_point_cloud( os.path.join(pointcloud_save_path, "next_points_3d_filtered.pcd"), next_pcd) next_pcd = o3d.geometry.PointCloud( o3d.utility.Vector3dVector(next_points_3d)) colors = [] for point_2d in source_points_2d: colors.append(source_rgb_image[int(point_2d[1]), int(point_2d[0])]) synthesized_image = np.zeros((image_height, image_width, 3), dtype=np.float32) for i in range(len(next_points_2d)): point = next_points_2d[i] synthesized_image[int(point[1]), int(point[0])] = colors[i] cv2.imwrite( os.path.join(synthesized_image_save_path, "synthesized_image_" + str(dilation) + ".png"), synthesized_image) colors = np.asarray(colors) colors = colors[:, ::-1] # bgr to rgb next_pcd.colors = o3d.utility.Vector3dVector(colors) o3d.io.write_point_cloud( os.path.join(pointcloud_save_path, "next_points_3d_rgb_colored.pcd"), next_pcd)
def compare_own_depth_to_kitti_depth(add_noise=False): kitti_depth = load_kitti_depth( "/root/ffabi_shared_folder/datasets/_original_datasets/kitti_all/kitti_depth/val/2011_09_26_drive_0005_sync/proj_depth/velodyne_raw/image_02/" + test_image_name + ".png") kitti_points_2d = convert_2d_image_to_2d_points(kitti_depth) # set Z value to zero for this experiment kitti_points_2d[:, 2] = 0 kitti_loader = KittiLoader(test_date, test_drive) points_3d, rgb_image, calibration, projection_matrix = kitti_loader.get_all_data( test_frame_index) # remove intensity points_3d = points_3d[:, :3] if add_noise: noise = np.random.normal(0., .01, points_3d.shape) points_3d += noise points_2d = project_points_3d_to_points_2d(points_3d.T, projection_matrix) image_height, image_width = kitti_depth.shape ordered_indexes = create_filter(points_2d, points_3d, image_width=image_width, image_height=image_height) # Filter out 2d points points_2d = points_2d[ordered_indexes] points_2d[:, 0] = np.round(points_2d[:, 0]) points_2d[:, 1] = np.round(points_2d[:, 1]) # set Z value to zero for this experiment points_2d[:, 2] = 0 # icp points_2d_pcd = o3d.geometry.PointCloud( o3d.utility.Vector3dVector(points_2d)) kitti_points_2d_pcd = o3d.geometry.PointCloud( o3d.utility.Vector3dVector(kitti_points_2d)) result = o3d.registration.registration_icp( source=points_2d_pcd, target=kitti_points_2d_pcd, max_correspondence_distance=2, # init = init_translation, estimation_method=o3d.registration. TransformationEstimationPointToPoint()) print("icp result:") print(result.transformation) print(len(kitti_points_2d), len(points_2d)) # threshold: 1 meter evaluation_results = o3d.registration.evaluate_registration( points_2d_pcd, kitti_points_2d_pcd, 10, result.transformation) print(evaluation_results) print()