欢迎点云相关产学研的学者和团体加入我们。
本小节中我们将学习如何使用一个ExtractIndices滤波器,基于某一分割算法提取点云中的一个子集。
首先,在PCL(Point Cloud Learning)中国协助发行的书[1]提供光盘的第8章例5文件夹中,打开名为extract_indices.cpp的代码文件,同文件夹下可以找到相关的测试点云文件table_scene_lms400.pcd。
下面解析打开源文件的关键语句,从输入的.PCD文件载入数据后,我们创建了一个VoxelGrid滤波器对数据进行下采样,我们在这里进行下采样的原因是来加速处理过程,越少的点意味着分割循环中处理起来越快。
pcl::VoxelGrid<sensor_msgs::PointCloud2> sor;//体素栅格下采样对象
sor.setInputCloud(cloud_blob);//设置下采样原始点云数据
sor.setLeafSize(0.01f,0.01f,0.01f); //设置采样的体素大小
sor.filter(*cloud_filtered_blob); //执行采样保存数据cloud_filtered_blob
下一代码块我们将处理参数化分割,为了保持教程的简单化,我们在这里先跳过解释,更多信息请参阅分割章节。
pcl::ModelCoefficients::Ptrcoefficients(new pcl::ModelCoefficients());
pcl::PointIndices::Ptrinliers(new pcl::PointIndices());
pcl::SACSegmentation<pcl::PointXYZ> seg; //创建分割对象
seg.setOptimizeCoefficients(true); //设置对估计的模型参数进行优化处理
seg.setModelType(pcl::SACMODEL_PLANE); //设置分割模型类别
seg.setMethodType(pcl::SAC_RANSAC); //设置用哪个随机参数估计方法
seg.setMaxIterations(1000); //设置最大迭代次数
seg.setDistanceThreshold(0.01); //设置判断是否为模型内点的距离阈值
设置extraction filter的实际参数。
pcl::ExtractIndices<pcl::PointXYZ> extract; //创建点云提取对象
extract.setInputCloud(cloud_filtered); //设置输入点云
extract.setIndices(inliers); //设置分割后的内点为需要提取的点集
extract.setNegative(false); //设置提取内点而非外点
extract.filter(*cloud_p); //提取输出存储到cloud_p
为了处理点云中包含多个模型,我们在一个循环中执行该过程,并在每次模型被提取后,我们保存剩余的点,进行迭代。模型内点通过分割过程获取,如下
seg.setInputCloud(cloud_filtered);
seg.segment(*inliers,*coefficients);
利用光盘提供的CMakeLists.txt文件,在cmake中建立工程文件,并生成相应的可执行文件,生成执行文件后,就可以运行了,在cmd中键入命令:
...>extract_indices.exe
你会看到类似图2所示的结果,从输出打印结果可以看出从输入点云中分割出两个平面模型的点云数据,运行之后在当前目录下有3个点云文件产生,为table_scene_lms400_downsampled.pcd、table_scene_lms400_plane_0/1.pcd,分别存储了下采样后的点云数据,以及分割得到的两个平面模型对应的点云数据,其可视化结果如图3所示。
图2平面提取运行结果
图3 例5中原始点云与分割后得到两平面的可视化结果
敬请关注PCL(Point Cloud Learning)中国更多的点云库PCL(Point Cloud Library)相关官方教程。
参考文献:
1.朱德海、郭浩、苏伟.点云库PCL学习教程(ISBN 978-7-5124-0954-5)北京航空航天出版社 2012-10