欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

PCL 点云平面分割总结

程序员文章站 2024-03-25 10:49:58
...

PCL 点云分割方法总结

一、平面模型分割

1、分割代码

首先要引入关于平面分割的头文件

#include <pcl/ModeCoefficients.h> //模型系数相关头文件
#include<pcl/sample_consensus/method_types.h> //模型定义头文件
#include<pcl/sample_consensus/model_types.h> //随机参数估计方法头文件
#include<pcl/segmentation/sac_segmentation.h>//基于采样一致性分割的头文件

2、创建分割时所需的模型系数对象coefficients以及存储内点的点索引集合对象

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

这种语法的意思就是创建一个××指针对象并且实例化

3、创建分割对象

pcl::SACSegmentation<pcl::PointXYZ> seg;

4、设置模型系数需要优化

seg.setOPtimizeCoefficients(true);

5、上面的模型系数需要优化的设置是可选的,但是下面关于模型分割的参数是必须设置的,需要设置的有分割的模型类型、所用的随机参数估计方法、距离阈值、输入点云

seg.setModelType(pcl::SACMODEL_PAANE);//模型类型
seg.setMerhodType(pcl::SAC_RANSAC);   //所用的随机参数估计方法
seg.setDistanceThreshold(0.01); //距离阈值,包括0.01
seg.setInputCloud(cloud.makeShared()); //设置输入点云
seg.segment(*inliers,*coefficients); 

seg.segment(*inliers,*coefficients);

用于分割,存储分割结果到点集合inliers及存储平面模型的系数coeddicients,这里模型系数的个人理解为就像平面方程Ax+By+Cz+D=0,类似于里面的系数。

完整的测试代码如下:

#include <iostream>
#include <pcl/ModelCoefficients.h>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/sample_consensus/method_types.h>//模型定义头文件
#include <pcl/sample_consensus/model_types.h>//随机参数估计方法头文件
#include <pcl/segmentation/sac_segmentation.h>//基于采样一致性分割的类的头文件
 
#include <pcl/visualization/pcl_visualizer.h>//可视化头文件
int
main (int argc, char** argv)
{
  pcl::PointCloud<pcl::PointXYZ> cloud;
//填充点云数据
cloud.width  = 15;
  cloud.height = 1;
  cloud.points.resize (cloud.width * cloud.height);
//生成数据
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;
  }
//设置几个局外点,使其偏离z=1的平面
cloud.points[0].z = 2.0;
cloud.points[3].z = -2.0;
cloud.points[6].z = 4.0;
cloud.points[7].z = 1.01;
cloud.points[8].z = 1.005;
  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);//创建分割时所需要的模型系数对象coefficients以及存储内点的点索引集合对象
pcl::PointIndices::Ptr inliers (new pcl::PointIndices);
//创建分割对象
  pcl::SACSegmentation<pcl::PointXYZ> seg;
 //可选设置,设置模型系数需要优化
  seg.setOptimizeCoefficients (true);
//必须设置,设置分割的模型类型、所用的随机参数估计方法、距离阈值、输入点云
  seg.setModelType (pcl::SACMODEL_PLANE);
  seg.setMethodType (pcl::SAC_RANSAC);
  seg.setDistanceThreshold (0.01);//距离阈值,包括0.01
  seg.setInputCloud (cloud.makeShared ());
  seg.segment (*inliers, *coefficients);//分割,存储分割结果到点集合inliers及存储平面模型的系数coefficients
if (inliers->indices.size () == 0)
  {
    PCL_ERROR ("Could not estimate a planar model for the given dataset.");
return (-1);
  }
//输出平面模型的系数 a,b,c,d
  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;
 
//可视化
pcl::visualization::PCLVisualizer::Ptr viewer(new pcl::visualization::PCLVisualizer("3d viewer"));
//左边窗口显示输入的点云(待拟合)
int v1(0);
viewer->createViewPort(0,0,0.5,1,v1);
viewer->setBackgroundColor(0,0,0,v1);
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> color_in(cloud.makeShared(),255,0,0);
viewer->addPointCloud<pcl::PointXYZ>(cloud.makeShared(),color_in,"cloud_in",v1);
viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE,9,"cloud_in",v1);
 
//右边的窗口显示拟合之后的点云
int v2(0);
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_out(new pcl::PointCloud<pcl::PointXYZ>);//存放最后拟合好的平面
cloud_out->width = inliers->indices.size();
cloud_out->height = 1;
cloud_out->is_dense = false;
cloud_out->resize(cloud_out->height * cloud_out->width);
for(size_t i=0;i<inliers->indices.size();i++)
{
    cloud_out->points[i].x = cloud.points[inliers->indices[i]].x;
    cloud_out->points[i].y = cloud.points[inliers->indices[i]].y;
    cloud_out->points[i].z = cloud.points[inliers->indices[i]].z;
}
std::cout<<"convert succeed!"<<std::endl;
viewer->createViewPort(0.5,0,1,1,v2);
viewer->setBackgroundColor(255,255,255,v2);
viewer->addPointCloud<pcl::PointXYZ>(cloud_out,"cloud_out",v2);
viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR,0,255,0,"cloud_out",v2);
viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE,9,"cloud_out",v2);
 
while (!viewer->wasStopped())
{
    viewer->spinOnce();
}
return (0);
}


 

 

 

 

 

 

相关标签: 自动驾驶