一种平面提取的点云简化算法

1.本算法使用了PCL点云库,因此运行此代码需要安装PCL (http://pointclouds.org/)

其中平面区域的简化效率时70%,其它区域的简化效率时30%.

//downSample
#include <pcl/ModelCoefficients.h>
#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/filters/extract_indices.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/segmentation/extract_clusters.h>


int 
main (int argc, char** argv)
{
  srand(time(0));
  // Read in the cloud data
  pcl::PCDReader reader;
  pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered (new pcl::PointCloud<pcl::PointXYZ>), cloud_f (new pcl::PointCloud<pcl::PointXYZ>);
  reader.read ("table_scene_lms400.pcd", *cloud_filtered);
  std::cout << "PointCloud has: " << cloud_filtered->points.size () << " data points." << std::endl; //*

  //输出
  ofstream fout("plane.txt");

  // Create the segmentation object for the planar model and set all the parameters
  pcl::SACSegmentation<pcl::PointXYZ> seg;
  pcl::PointIndices::Ptr inliers (new pcl::PointIndices);
  pcl::ModelCoefficients::Ptr coefficients (new pcl::ModelCoefficients);
  pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_plane (new pcl::PointCloud<pcl::PointXYZ> ());
  pcl::PCDWriter writer;
  seg.setOptimizeCoefficients (true);
  seg.setModelType (pcl::SACMODEL_PLANE);
  seg.setMethodType (pcl::SAC_RANSAC);
  seg.setMaxIterations (100);
  seg.setDistanceThreshold (0.02);    //此处可以自己修改,一般保持默认即可

  int i=0, nr_points = (int) cloud_filtered->points.size ();
  while (cloud_filtered->points.size () > 0.3 * nr_points)    //此处的0.3可以修改,一般保持默认即可
  {
    // Segment the largest planar component from the remaining cloud
    seg.setInputCloud (cloud_filtered);
    seg.segment (*inliers, *coefficients);
    if (inliers->indices.size () == 0)
    {
      std::cout << "Could not estimate a planar model for the given dataset." << std::endl;
      break;
    }

    // Extract the planar inliers from the input cloud
    pcl::ExtractIndices<pcl::PointXYZ> extract;
    extract.setInputCloud (cloud_filtered);
    extract.setIndices (inliers);
    extract.setNegative (false);

    // Get the points associated with the planar surface
    extract.filter (*cloud_plane);
    std::cout << "PointCloud representing the planar component: " << cloud_plane->points.size () << " data points." << std::endl;
    for (int i = 0; i <cloud_plane->points.size (); i++)
    {
        if (rand() %100 < 30)            //平面简化率为70%
        {
            fout<<cloud_plane->points[i].x<<" "<<cloud_plane->points[i].y<<" "<<cloud_plane->points[i].z<<endl;
        }
    }
    
    // Remove the planar inliers, extract the rest
    extract.setNegative (true);
    extract.filter (*cloud_f);
    *cloud_filtered = *cloud_f;
  }
  for (int i = 0; i <cloud_filtered->points.size (); i++)
  {
      if (rand() %100 < 70)            //简化率为30%
      {
      fout<<cloud_filtered->points[i].x<<" "<<cloud_filtered->points[i].y<<" "<<cloud_filtered->points[i].z<<endl;
       }
  }
  
  return (0);
}
View Code

2.简化前后对比

3.总结说明

分别对比三组实验数据:

第一组:桌面和地面简化率较高,其他的对象简化率地

第二组:人简化率地而平面板和地面简化率较高

第三组:墙面上的镶嵌物体得到了很好保留的同时,墙面和地面得到了和好的简化

4.实验第一组数据(其它两组数据为实验室数据不能提供)

http://pan.baidu.com/s/1i3kVW37 或

https://raw.github.com/PointCloudLibrary/data/master/tutorials/table_scene_mug_stereo_textured.pcd

原文地址:https://www.cnblogs.com/lwngreat/p/4312749.html