PCL Tutorial
This tutorial will demonstrate the use of PCL for the problem of downsampling a PointCloud2 dataset to a sparser representation.
In addition, in step 2, we will attempt to segment the largest planar component present in the downsampled point cloud.
Step 1 : run the following
Please create a package in your ROS_PACKAGE_PATH using:
$ roscreate-pkg pcl_tutorial pcl
Edit CMakeLists.txt and add
rosbuild_add_executable (pcl_tutorial pcl_tutorial.cpp)
Add pcl_tutorial.cpp to your newly created package:
#include <pcl/filters/voxel_grid.h>
#include <pcl/point_types.h>
int
main (int argc, char **argv)
{
// init ROS
ros::init (argc, argv, "pcl_demo");
ros::NodeHandle nh;
// Publishers
point_cloud::Publisher<pcl::PointXYZ> pub_downsampled;
pub_downsampled.advertise (nh, "downsampled", 1);
// PCL objects
pcl::PointCloud<pcl::PointXYZ> cloud, cloud_downsampled;
pcl::VoxelGrid<pcl::PointXYZ> grid;
grid.setFilterFieldName ("z");
grid.setLeafSize (0.01, 0.01, 0.01);
grid.setFilterLimits (0.4, 1.6);
while (nh.ok ())
{
// Spin until we get a PointCloud2 message
sensor_msgs::PointCloud2ConstPtr cloud2_blob_ptr = ros::topic::waitForMessage<sensor_msgs::PointCloud2>("/narrow_stereo_textured/points2");
// Convert to PCL
point_cloud::fromMsg (*cloud2_blob_ptr, cloud);
// Downsample the data
grid.setInputCloud (boost::make_shared<pcl::PointCloud<pcl::PointXYZ> >(cloud));
grid.filter (cloud_downsampled);
// Publish the data
pub_downsampled.publish (cloud_downsampled);
}
}
Step 2 : edit the above source file
Please edit the above source file and include the following code in the right places:
#include <pcl/filters/project_inliers.h> #include <pcl/segmentation/sac_segmentation.h> #include <pcl/PointIndices.h> #include <pcl/ModelCoefficients.h> // ... point_cloud::Publisher<pcl::PointXYZ> pub_plane; pub_plane.advertise (nh, "plane", 1); // ... pcl::PointIndices plane_inliers; pcl::ModelCoefficients plane_coefficients; pcl::PointCloud<pcl::PointXYZ> cloud_plane; // ... pcl::SACSegmentation<pcl::PointXYZ> seg; seg.setDistanceThreshold (0.05); seg.setMaxIterations (1000); seg.setModelType (pcl::SACMODEL_PLANE); seg.setMethodType (pcl::SAC_RANSAC); // ... pcl::ProjectInliers<pcl::PointXYZ> proj; proj.setModelType (pcl::SACMODEL_PLANE); // ... // Find the largest plane seg.setInputCloud (boost::make_shared<pcl::PointCloud<pcl::PointXYZ> > (cloud_downsampled)); seg.segment (plane_inliers, plane_coefficients); // ... // Extract the inliers indices as a separate point cloud proj.setInputCloud (boost::make_shared<pcl::PointCloud<pcl::PointXYZ> > (cloud_downsampled)); proj.setIndices (boost::make_shared<pcl::PointIndices> (plane_inliers)); proj.setModelCoefficients (boost::make_shared<pcl::ModelCoefficients> (plane_coefficients)); proj.filter (cloud_plane); // ... pub_plane.publish (cloud_plane);