前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >PCL点云分割(2)

PCL点云分割(2)

作者头像
点云PCL博主
发布2019-07-31 11:42:58
1K0
发布2019-07-31 11:42:58
举报
文章被收录于专栏:点云PCL点云PCL

关于点云的分割算是我想做的机械臂抓取中十分重要的俄一部分,所以首先学习如果使用点云库处理我用kinect获取的点云的数据,本例程也是我自己慢慢修改程序并结合官方API 的解说实现的,其中有很多细节如果直接更改源程序,可能会因为数据类型,或者头文件等各种原因编译不过,会导致我们比较难得找出其中的错误,首先我们看一下我自己设定的一个场景,然后我用kinect获取数据

观察到kinect获取的原始图像的,然后使用简单的滤波,把在其中的NANS点移除,因为很多的算法要求不能出现NANS点,我们可以看见这里面有充电宝,墨水,乒乓球,一双筷子,下面是两张纸,上面分别贴了两道黑色的胶带,我们首先就可以做一个提取原始点云的平面的实验,那么如果提取点云中平面,之前有一些基本的实例,使用平面分割法

程序如下

代码语言:javascript
复制
#include <iostream>
#include <pcl/ModelCoefficients.h>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/filters/voxel_grid.h>
#include <pcl/features/normal_3d.h>
#include <pcl/kdtree/kdtree.h>
#include <pcl/sample_consensus/method_types.h>
#include <pcl/sample_consensus/model_types.h>
#include <pcl/segmentation/sac_segmentation.h>
#include <pcl/console/parse.h>
#include <pcl/filters/extract_indices.h>
#include <pcl/sample_consensus/ransac.h>
#include <pcl/sample_consensus/sac_model_plane.h>
#include <pcl/sample_consensus/sac_model_sphere.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <boost/thread/thread.hpp>

int
main (int argc, char** argv)
{  
// 读取文件   
  pcl::PCDReader reader;
  pcl::PointCloud<pcl::PointXYZRGBA>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZRGBA>), cloud_f (new pcl::PointCloud<pcl::PointXYZRGBA>);
pcl::PointCloud<pcl::PointXYZRGBA>::Ptr final (new pcl::PointCloud<pcl::PointXYZRGBA>);
reader.read ("out0.pcd", *cloud);
std::cout << "PointCloud before filtering has: " << cloud->points.size () << " data points." << std::endl; //*  

// 下采样,体素叶子大小为0.01
 pcl::VoxelGrid<pcl::PointXYZRGBA> vg;
 pcl::PointCloud<pcl::PointXYZRGBA>::Ptr cloud_filtered (new pcl::PointCloud<pcl::PointXYZRGBA>);  vg.setInputCloud (cloud);
 vg.setLeafSize (0.01f, 0.01f, 0.01f);
 vg.filter (*cloud_filtered);
 std::cout << "PointCloud after filtering has: " << cloud_filtered->points.size ()  << " data points." << std::endl; //*

 pcl::ModelCoefficients::Ptr coefficients (new pcl::ModelCoefficients);
 pcl::PointIndices::Ptr inliers (new pcl::PointIndices);  

// Create the segmentation object
pcl::SACSegmentation<pcl::PointXYZRGBA> seg;  
seg.setOptimizeCoefficients (true);   
seg.setModelType (pcl::SACMODEL_PLANE);  //  seg.setModelType
(pcl::SACMODEL_LINE ); 
  seg.setMethodType (pcl::SAC_RANSAC);
 seg.setDistanceThreshold (0.01); seg.setInputCloud (cloud_filtered);
 seg.segment (*inliers, *coefficients);  if (inliers->indices.size () == 0)
 {
   PCL_ERROR ("Could not estimate a planar model for the given dataset.");      return (-1);
 }
 std::cerr << "Model coefficients: " << coefficients->values[0] << " "
                                     << coefficients->values[1] << " "
                                     << coefficients->values[2] << " "
                                    << coefficients->values[3] <<std::endl;
 return (0);
}

运行生成的可执行文件会输出平面模型的参数

平面模型的参数

此图是采样后的点云图

也可以在这个程序中直接实现平面的提取,但是为了更好的说明,我是将获取平面参数与平面提取给分成两个程序实现,程序如下

代码语言:javascript
复制
#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/ModelCoefficients.h>
#include <pcl/filters/project_inliers.h>
#include <pcl/filters/extract_indices.h>
#include <pcl/filters/voxel_grid.h>
#include <pcl/visualization/pcl_visualizer.h>
#include<boost/thread/thread.hpp>

boost::shared_ptr<pcl::visualization::PCLVisualizer>simpleVis (pcl::PointCloud<pcl::PointXYZ>::ConstPtr cloud)
{
 boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer (new pcl::visualization::PCLVisualizer ("3D Viewer"));
 viewer->setBackgroundColor (0, 0, 0);
 viewer->addPointCloud<pcl::PointXYZ> (cloud, "project_inliners cloud");
 viewer->setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "sample cloud");  
//viewer->addCoordinateSystem (1.0, "global");  viewer->initCameraParameters ();  return (viewer);
}
 
int
main (int argc, char** argv)
{   // 读取文件  
  pcl::PCDReader reader;
 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>), cloud_f (new pcl::PointCloud<pcl::PointXYZ>);
 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_projected (new pcl::PointCloud<pcl::PointXYZ>);pcl::PointCloud<pcl::PointXYZ>::Ptr final (new pcl::PointCloud<pcl::PointXYZ>);
 reader.read ("out0.pcd", *cloud);
 std::cout << "PointCloud before filtering has: " << cloud->points.size () << " data points." << std::endl; //*  

// 下采样,体素叶子大小为0.01
 pcl::VoxelGrid<pcl::PointXYZ> vg;
 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered (new pcl::PointCloud<pcl::PointXYZ>);  vg.setInputCloud (cloud);
 vg.setLeafSize (0.01f, 0.01f, 0.01f);
 vg.filter (*cloud_filtered);
 std::cout << "PointCloud after filtering has: " << cloud_filtered->points.size ()  << " data points." << std::endl; //*  

// Create a set of planar coefficients with X=Y=
 pcl::ModelCoefficients::Ptr coefficients (new pcl::ModelCoefficients ());
 coefficients->values.resize (4);
 coefficients->values[0] = 0.140101;
 coefficients->values[1] = 0.126715;
 coefficients->values[2] = 0.981995;
 coefficients->values[3] = -0.702224;  

// Create the filtering object
 pcl::ProjectInliers<pcl::PointXYZ> proj;
 proj.setModelType (pcl::SACMODEL_PLANE);
 proj.setInputCloud (cloud_filtered);
 proj.setModelCoefficients (coefficients);
 proj.filter (*cloud_projected); boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer;
 viewer = simpleVis(cloud_projected);  while (!viewer->wasStopped ())
 {
   viewer->spinOnce (100);
   boost::this_thread::sleep (boost::posix_time::microseconds (100000));
 }  return (0);
}

执行结果就如下

提取了平面,但是我选择的PCD文件不太好,效果不明显,在这里你可以使用不同的文件,可以看出不同的效果,同时你也可以使用不通的模型来提取参数,再进行提取,同时你也可以把这两个程序合并成一个程序,积极动手吧!

基础的点云知识就已经差不多了,还有就是不端有网友提问的疑问,我会在相应的博客下,把提问比较好的问题再次解答,并写在博客中,公众号的文章就不再更新

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-05-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 点云PCL 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档