zoukankan      html  css  js  c++  java
  • PCL点云分割(2)

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

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

    程序如下

    #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;
      // Optional
      seg.setOptimizeCoefficients (true);
      // Mandatory
      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);
    }

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

                                                                   平面模型的参数

                                                                          此图是采样后的点云图

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

    #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);
    }

    执行结果就如下

    提取了平面,**********************8

    微信公众号号可扫描二维码一起共同学习交流

  • 相关阅读:
    函数指针与函数声明
    long和int的区别
    pthread_create传递参数
    C语言中的static 详细分析
    linux 读写锁应用实例
    linux使用读写锁pthread_rwlock_t
    linux的<pthread.h>
    时间:UTC时间、GMT时间、本地时间、Unix时间戳
    等号赋值与memcpy的效率问题
    单链表带头结点&不带头结点
  • 原文地址:https://www.cnblogs.com/li-yao7758258/p/6595387.html
Copyright © 2011-2022 走看看