Search code examples
c++point-cloud-librarypoint-clouds

How to downsample a point cloud while maintaining its order? (PCL C++)


I want to downsample incoming pointclouds by using the passthrough filter provided by the pcl library and also maintain the order of the given clouds. My current solution is as follows:

using point_type_colored = pcl::PointXYZRGB;
using point_cloud_colored = pcl::PointCloud<point_type_colored>;

point_cloud_colored::Ptr registration_util::pass_through_filter(
     const point_cloud_colored::Ptr& cloud_in, double p_t_x_min, double p_t_x_max,
     double p_t_y_min, double p_t_y_max, double p_t_z_min, double p_t_z_max)
{
     point_cloud_colored::Ptr filtered_cloud(new point_cloud_colored);
     *filtered_cloud = *cloud_in;
     pcl::PassThrough<point_type_colored> pass_filter;

     //filter x boundaries
     if (p_t_x_min != p_t_x_max)
     {
         pass_filter.setInputCloud(filtered_cloud);
         pass_filter.setFilterFieldName("x");
         pass_filter.setFilterLimits(p_t_x_min, p_t_x_max);
         pass_filter.filter(*filtered_cloud);
     }

     //filter y boundaries
     if (p_t_y_min != p_t_y_max)
     {
         pass_filter.setInputCloud(filtered_cloud);
         pass_filter.setFilterFieldName("y");
         pass_filter.setFilterLimits(p_t_y_min, p_t_y_max);
         pass_filter.filter(*filtered_cloud);
     }

     //filter z boundaries
     if (p_t_z_min != p_t_z_max)
     {
         pass_filter.setInputCloud(filtered_cloud);
         pass_filter.setFilterFieldName("z");
         pass_filter.setFilterLimits(p_t_z_min, p_t_z_max);
         pass_filter.filter(*filtered_cloud);
     }

     return std::move(filtered_cloud);
}

The input cloud has a defined width (= 1280) and height (=720) which means the point cloud is ordered. But the output cloud has only the height of one and a width of 92160 which means the cloud has lost its order due to downsampling.

How do I keep the original order of the input cloud? If it is possible are there similar solutions for other downsampling methods like random filtering?


Solution

  • You are looking for the function setKeepOrganized. Providing true will set each filtered point to NaN instead of removing the point.

    You can also change the value to set it to with setUserFilterValue, but keeping it NaN has the benefit that other PCL algorithms won't consider these points for their algorithm.