Prof. Christopher Rasmussen
February 15, 2018
Sample "Grand" Challenges: Total ARGOS challenge (2017)
Point Cloud Library (PCL) (>= 1.6)
PCL for point clouds
PCL Basics
PCL Basics
Point cloud storage/display
PCL Basics
pcl::PointCloud<pcl::PointXYZ> cloud;�std::vector<pcl::PointXYZ> data = cloud.points;
PCL Basics
pcl::PointCloud<pcl::PointXYZ> cloud;�std::vector<pcl::PointXYZ> data = cloud.points;
PCL Basics
pcl::PointCloud<pcl::PointXYZ> cloud;�std::vector<pcl::PointXYZ> data = cloud.points;
Point cloud storage: Read, write
#include <iostream>�#include <pcl/io/pcd_io.h>�#include <pcl/point_types.h>�#include <pcl/filters/voxel_grid.h>��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!�� // Do filtering... �
// Save result � pcl::PCDWriter writer;� writer.write ("table_scene_lms400_downsampled.pcd", *cloud_filtered);�� return (0);�}
PCL filtering: Range selection on axis
Original scene
After applying Z ∈ [0, 2] range selection
courtesy of http://robotica.unileon.es/mediawiki/index.php/PCL/OpenNI_tutorial_2:_Cloud_processing_(basic)
PCL filtering:
Range selection with PassThrough
#include <iostream>�#include <pcl/point_types.h>�#include <pcl/filters/passthrough.h>��int� main (int argc, char** argv)�{� pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);� pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered (new pcl::PointCloud<pcl::PointXYZ>);�� // Fill in the cloud data
// Example creates random points, but could also load from .pcd
� std::cerr << "Cloud before filtering: " << std::endl;� for (size_t i = 0; i < cloud->points.size (); ++i)� std::cerr << " " << cloud->points[i].x << " " � << cloud->points[i].y << " " � << cloud->points[i].z << std::endl;�� // Create the filtering object� pcl::PassThrough<pcl::PointXYZ> pass;� pass.setInputCloud (cloud);� pass.setFilterFieldName ("z");� pass.setFilterLimits (0.0, 2.0);� //pass.setFilterLimitsNegative (true); // take points *outside* range instead of inside� pass.filter (*cloud_filtered); // cloud_filtered now contains only points that passed filter�� return (0);�}
PCL filtering: Downsampling
Original
courtesy of http://robotica.unileon.es/mediawiki/index.php/PCL/OpenNI_tutorial_2:_Cloud_processing_(basic)
PCL filtering: Downsampling
1 cm voxel size
courtesy of http://robotica.unileon.es/mediawiki/index.php/PCL/OpenNI_tutorial_2:_Cloud_processing_(basic)
PCL filtering:
Downsampling with VoxelGrid
#include <iostream>�#include <pcl/io/pcd_io.h>�#include <pcl/point_types.h>�#include <pcl/filters/voxel_grid.h>��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!�� // Create the filtering object� pcl::VoxelGrid<pcl::PCLPointCloud2> sor;� sor.setInputCloud (cloud);� sor.setLeafSize (0.01f, 0.01f, 0.01f); // sidelengths of each voxel "box"� sor.filter (*cloud_filtered);��� pcl::PCDWriter writer;� writer.write ("table_scene_lms400_downsampled.pcd", *cloud_filtered);�� return (0);�}
Ground Segmentation
Ground Segmentation
Ground Segmentation
Ground Segmentation
One dominant plane
Important planes
Multiple large planes
Ground Segmentation
Robust Plane Fitting
Robust Plane Fitting
RANSAC plane fitting
RANSAC plane fitting
RANSAC plane fitting
RANSAC in PCL
RANSAC in PCL
#include <iostream>�#include <pcl/ModelCoefficients.h>�#include <pcl/io/pcd_io.h>�#include <pcl/point_types.h>�#include <pcl/sample_consensus/method_types.h>�#include <pcl/sample_consensus/model_types.h>�#include <pcl/segmentation/sac_segmentation.h>��int main (int argc, char** argv)�{� pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);�� // Fill in the cloud data…
// ???�� // Try to do robust plane fit� pcl::ModelCoefficients::Ptr coefficients (new pcl::ModelCoefficients);� pcl::PointIndices::Ptr inliers (new pcl::PointIndices);� pcl::SACSegmentation<pcl::PointXYZ> seg; // Create segmentation object�� seg.setOptimizeCoefficients (true); // optional
seg.setModelType (pcl::SACMODEL_PLANE); // mandatory� seg.setMethodType (pcl::SAC_RANSAC);� seg.setDistanceThreshold (0.01);�� seg.setInputCloud (cloud);� seg.segment (*inliers, *coefficients);�
� // did it work?
� if (inliers->indices.size () == 0) {� PCL_ERROR ("Could not estimate a planar model for the given dataset.");� return (-1);� }�
// report results
std::cerr << "Model coefficients: "
<< coefficients->values[0] << " " � << coefficients->values[1] << " "� << coefficients->values[2] << " " � << coefficients->values[3] << std::endl;�� std::cerr << "Model inliers: " << inliers->indices.size () << std::endl;� for (size_t i = 0; i < inliers->indices.size (); ++i)� std::cerr << inliers->indices[i] << " "
<< cloud->points[inliers->indices[i]].x << " "� << cloud->points[inliers->indices[i]].y << " "� << cloud->points[inliers->indices[i]].z <<
std::endl;
return (0);�}