# Downsampling a PointCloud using a VoxelGrid filter

In this tutorial we will learn how to downsample – that is, reduce the number of points – a point cloud dataset, using a voxelized grid approach.

The VoxelGrid class that we’re about to present creates a 3D voxel grid (think about a voxel grid as a set of tiny 3D boxes in space) over the input point cloud data. Then, in each voxel (i.e., 3D box), all the points present will be approximated (i.e., downsampled) with their centroid. This approach is a bit slower than approximating them with the center of the voxel, but it represents the underlying surface more accurately.

# The code

Then, create a file, let’s say, voxel_grid.cpp in your favorite editor, and place the following inside it:

  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 #include #include #include #include int main (int argc, char** argv) { pcl::PCLPointCloud2::Ptr cloud (new pcl::PCLPointCloud2 ()); pcl::PCLPointCloud2::Ptr cloud_filtered (new pcl::PCLPointCloud2 ()); // Fill in the cloud data pcl::PCDReader reader; // Replace the path below with the path where you saved your file reader.read ("table_scene_lms400.pcd", *cloud); // Remember to download the file first! std::cerr << "PointCloud before filtering: " << cloud->width * cloud->height << " data points (" << pcl::getFieldsList (*cloud) << ")."; // Create the filtering object pcl::VoxelGrid sor; sor.setInputCloud (cloud); sor.setLeafSize (0.01f, 0.01f, 0.01f); sor.filter (*cloud_filtered); std::cerr << "PointCloud after filtering: " << cloud_filtered->width * cloud_filtered->height << " data points (" << pcl::getFieldsList (*cloud_filtered) << ")."; pcl::PCDWriter writer; writer.write ("table_scene_lms400_downsampled.pcd", *cloud_filtered, Eigen::Vector4f::Zero (), Eigen::Quaternionf::Identity (), false); return (0); } 

# The explanation

Now, let’s break down the code piece by piece.

The following lines of code will read the point cloud data from disk.

  // Fill in the cloud data
// Replace the path below with the path where you saved your file


Then, a pcl::VoxelGrid filter is created with a leaf size of 1cm, the input data is passed, and the output is computed and stored in cloud_filtered.

  pcl::VoxelGrid<pcl::PCLPointCloud2> sor;
sor.setInputCloud (cloud);
sor.setLeafSize (0.01f, 0.01f, 0.01f);
sor.filter (*cloud_filtered);


Finally, the data is written to disk for later inspection.

  pcl::PCDWriter writer;
writer.write ("table_scene_lms400_downsampled.pcd", *cloud_filtered,
Eigen::Vector4f::Zero (), Eigen::Quaternionf::Identity (), false);


# Compiling and running the program

  1 2 3 4 5 6 7 8 9 10 11 12 cmake_minimum_required(VERSION 2.8 FATAL_ERROR) project(voxel_grid) find_package(PCL 1.2 REQUIRED) include_directories(${PCL_INCLUDE_DIRS}) link_directories(${PCL_LIBRARY_DIRS}) add_definitions(${PCL_DEFINITIONS}) add_executable (voxel_grid voxel_grid.cpp) target_link_libraries (voxel_grid${PCL_LIBRARIES}) 
\$ ./voxel_grid

PointCloud before filtering: 460400 data points (x y z intensity distance sid).