PCL点云分割---平面模型分割

PCL点云分割---平面模型分割

  • 适用对象
  • 工作原理
  • PCL核心代码实现
  • 参考资料

适用对象

适用于存在大面积平面的点云分割,比如墙和地面等。
该算法能够拟合平面点云,配合点云滤波—提取子集滤波器可以实现去掉或者保留平面点云的功能。

工作原理

该算法基于Ransac做平面拟合,Ransac为了找到点云的平面,不停的改变平面模型(ax+by+cz+d=0)的参数:a, b, c和d。经过多次调参后,在一定程度上找出一组参数使得这个模型拟合最多的点。这个程度由distance threshold来定义。distance threshold实质上指定了在平面拟合中平面可以包罗的点的厚度阈值

PCL核心代码实现

pcl::ModelCoefficients::Ptr coefficients (new pcl::ModelCoefficients);	//定义模型系数
pcl::PointIndices::Ptr inliers (new pcl::PointIndices);					//定义点索引

pcl::SACSegmentation seg;								//创建分割对象
//可选的设置,设置分割是否优化系数
seg.setOptimizeCoefficients (true);
//必须要设置的内容
seg.setModelType (pcl::SACMODEL_PLANE);									//设置分割对象所选用的模型类型
seg.setMethodType (pcl::SAC_RANSAC);									//设置算法类型
seg.setDistanceThreshold (0.01);										//本算法中唯一一个参数,设置距离阈值

seg.setInputCloud (cloud);												//设置输入点云
seg.segment (*inliers, *coefficients);									//开始执行分割算法

完整代码:

#include 
#include 
#include 
#include 
#include 
#include 
#include 

int
 main (int argc, char** argv)
{
  pcl::PointCloud::Ptr cloud(new pcl::PointCloud);

  // Fill in the cloud data
  cloud->width  = 15;
  cloud->height = 1;
  cloud->points.resize (cloud->width * cloud->height);

  // Generate the data
  for (size_t i = 0; i < cloud->points.size (); ++i)
  {
    cloud->points[i].x = 1024 * rand () / (RAND_MAX + 1.0f);
    cloud->points[i].y = 1024 * rand () / (RAND_MAX + 1.0f);
    cloud->points[i].z = 1.0;
  }

  // Set a few outliers
  cloud->points[0].z = 2.0;
  cloud->points[3].z = -2.0;
  cloud->points[6].z = 4.0;

  std::cerr << "Point cloud data: " << cloud->points.size () << " points" << 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;

  pcl::ModelCoefficients::Ptr coefficients (new pcl::ModelCoefficients);
  pcl::PointIndices::Ptr inliers (new pcl::PointIndices);
  // Create the segmentation object
  pcl::SACSegmentation seg;
  // Optional
  seg.setOptimizeCoefficients (true);
  // Mandatory
  seg.setModelType (pcl::SACMODEL_PLANE);
  seg.setMethodType (pcl::SAC_RANSAC);
  seg.setDistanceThreshold (0.01);

  seg.setInputCloud (cloud);
  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;

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

参考资料

Plane model segmentation

你可能感兴趣的:(三维图像处理,PCL,点云分割,平面模型)