Beispiel #1
0
def downsample(cloud: o3d.geometry.PointCloud,
               v_size: float,
               with_trace=False):
    """
    Downsample the point cloud with a voxel grid with the defined voxel size

    Parameters
    ----------
    cloud: o3d.geometry.PointCloud
        Cloud to be downsampled.
    v_size: float
        Voxel size to downsample into.
    with_trace: bool
        Select recording of point cloud index before downsampling.

    Returns
    ----------
    cloud: o3d.geometry.PointCloud
        Downsampled point cloud
    """
    if with_trace is True:
        [cloud, indices
         ] = cloud.voxel_down_sample_and_trace(v_size,
                                               min_bound=[0, 0, 0],
                                               max_bound=[1000, 1000, 1000])
        return [cloud, indices]
    else:
        cloud = cloud.voxel_down_sample(v_size)
        return cloud
Beispiel #2
0
def preprocess_point_cloud(
    pcd: o3d.geometry.PointCloud, voxel_size: np.float64
) -> {o3d.geometry.PointCloud, o3d.pipelines.registration.Feature}:
    print(":: Downsample with a voxel size %.3f." % voxel_size)
    pcd_down = pcd.voxel_down_sample(voxel_size)

    radius_normal = voxel_size * 2
    print(":: Estimate normal with search radius %.3f." % radius_normal)
    pcd_down.estimate_normals(
        o3d.geometry.KDTreeSearchParamHybrid(radius=radius_normal, max_nn=30))

    # KDTreeSearchParamHybrid: radius - search radius, max_nn - at maximum,
    # max_nn neighbours will be searched
    radius_feature = voxel_size * 5
    print(":: Compute FPFH feature with search radius %.3f.\n" %
          radius_feature)
    pcd_fpfh = o3d.pipelines.registration.compute_fpfh_feature(
        pcd_down,
        o3d.geometry.KDTreeSearchParamHybrid(radius=radius_feature,
                                             max_nn=100))
    # print(pcd_fpfh, '\n')
    return pcd_down, pcd_fpfh
    def filter_ground(self, pcd: o3d.geometry.PointCloud, max_dist: float = -1, height_threshold=0.1,
                      ransac_dist_threshold=0.01, ransac_n=3, ransac_itr=100) -> o3d.geometry.PointCloud:
        """
        Find ground from point cloud by first selecting points that are below the (car's position + a certain threshold)
        Then it will take only the points that are less than `max_dist` distance away
        Then do RANSAC on the resulting point cloud.

        Note that this function assumes that the ground will be the largest plane seen after filtering out everything
        above the vehicle

        Args:
            pcd: point cloud to be parsed
            max_dist: maximum distance
            height_threshold: additional height padding
            ransac_dist_threshold: RANSAC distance threshold
            ransac_n: RANSAC starting number of points
            ransac_itr: RANSAC number of iterations

        Returns:
            point cloud that only has the ground.

        """

        points = np.asarray(pcd.points)
        colors = np.asarray(pcd.colors)
        # height and distance filter
        # 0 -> left and right | 1 -> up and down | 2 = close and far
        points_of_interest = np.where((points[:, 1] < 0.3))
        points = points[points_of_interest]
        colors = colors[points_of_interest]
        pcd.points = o3d.utility.Vector3dVector(points)
        pcd.colors = o3d.utility.Vector3dVector(colors)
        plane_model, inliers = pcd.segment_plane(distance_threshold=ransac_dist_threshold,
                                                 ransac_n=ransac_n,
                                                 num_iterations=ransac_itr)

        pcd: o3d.geometry.PointCloud = pcd.select_by_index(inliers)
        pcd = pcd.voxel_down_sample(0.01)
        return pcd
 def downsample(
         self, point_cloud: open3d.geometry.PointCloud
 ) -> open3d.geometry.PointCloud:
     voxel_down_pcd = point_cloud.voxel_down_sample(voxel_size=1.7)
     return voxel_down_pcd.uniform_down_sample(every_k_points=2)