Downsampling point clouds with PCL

PCL (Point Cloud Library) offers two ways that I know of to downsample a point cloud to a more manageable size.

The first uses pcl::VoxelGrid, and the second uses pcl::octree::OctreePointCloudVoxelCentroid.

They are both simple to use:

pcl::VoxelGrid

using Point = pcl::PointXYZ;
using Cloud = pcl::PointCloud<Point>;

float leaf = 1.f;
pcl::VoxelGrid<Point> vg;
vg.setInputCloud(input);
vg.setLeafSize(leaf, leaf, leaf);
Cloud::Ptr output(new Cloud);
vg.filter(*output);

Here we create the filtering object, give it an input cloud to work on, give it the only parameter it requires, `leaf` being the voxel dimension, and filter it to a new output cloud.

The size of the resultant output cloud is dependent on the leaf size.

pcl::octree::OctreePointCloudVoxelCentroid

float leaf = 1.f;
pcl::octree::OctreePointCloudVoxelCentroid octree(leaf);
octree.setInputCloud(input);
octree.defineBoundingBox();
octree.addPointsFromInputCloud();
pcl::octree::OctreePointCloud::AlignedPointTVector centroids;
octree.getVoxelCentroids(centroids);

Cloud::Ptr output(new Cloud);
output->points.assign(centroids.begin(), centroids.end());
output->width = uint32_t(centroids.size());
output->height = 1;
output->is_dense = true;

Here we create an octree initialised with it’s voxel dimension, give it an input cloud to work with, and get back a vector of the centroids of all possible voxels. This vector can then be used to construct a new cloud.

Convergence

In both cases the size of the output cloud is unknown beforehand. It’s dependent on the choice made for the voxel leaf dimension. Only after downsampling can you query the cloud for it’s size.

An iterative method is needed if you want to end up with a given size: You can perform one of the downsampling methods, and based on the resultant output size, adjust leaf up or down and do it again. Stop iterating when the output cloud size converges to within a tolerance of a required size or percentage of the input.

I do this for both methods in my hobby project of pcl-tools.

 

3 thoughts on “Downsampling point clouds with PCL”

  1. Is the code/syntax for the octree downsampling correct? It won’t even compile on my computer. The line:

    octree.getVoxelCentroids(centroids);

    fails with a “used without template parameters” error message.

  2. Hi, Mr. Craig.

    Thank you very much for this tutorial! It gave some great insight about the implementation of Point Cloud down sampling.

    If you don’t mind, I have a question about the down sampling method with OctreePointCloudVoxelCentroid. It seemed to be working but there are 2 problems that arose when I tried to implement your method:

    1. In the down sampling result, there are points which colors are incorrect (does not exist in the original clouds). Do you have any suggestion why this problem occur?

    For this one I am thinking it might be caused by during the calculation of centroid, maybe the value of RGB is also calculated causing the value to be changed.

    2. I noticed that for the smaller leaf size, in the result of down sampling, a portion of the point cloud area is missing. Do you have any suggestion why this problem occur?

    A couple of points that might be related to my problems:
    – I used the pcl::PointXYZRGB type for the templates
    – I used .las file as the input and output of my point clouds. So I did a bit RGB conversion to store the RGB value from .las to the pcl format (and conversion back before writing to output .las file). When using the VoxelGrid filter, the color conversion seemed to work properly so I think that is not the problem.

    I am still really new to this field and don’t have anyone to ask for advice so I would be really thankful if you could help me in solving this problem.

    Thank you and have a great day

Leave a Reply

Your email address will not be published. Required fields are marked *