PCL 点云平面分割总结

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


 

 

 

 

 

 

  • 4
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是一个基于PCL库的平面分割示例代码: ```c++ #include <iostream> #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> int main(int argc, char** argv) { // 加载点云数据 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>); pcl::io::loadPCDFile<pcl::PointXYZ>("plane.pcd", *cloud); // 创建分割器 pcl::ModelCoefficients::Ptr coefficients(new pcl::ModelCoefficients); 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); // 执行分割 seg.setInputCloud(cloud); seg.segment(*inliers, *coefficients); // 输出分割结果 std::cerr << "Model coefficients: " << coefficients->values[0] << " " << coefficients->values[1] << " " << coefficients->values[2] << " " << coefficients->values[3] << std::endl; std::cerr << "Inliers: " << inliers->indices.size() << std::endl; for (std::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; } ``` 这个示例代码首先加载了一个点云文件,并创建了一个`SACSegmentation`对象作为分割器。然后通过设置模型类型以及分割方法类型等参数,最后执行了分割操作。最终输出了分割得到的平面模型系数以及属于该平面的点云索引。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值