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);
}
上一篇: 计算机视觉OpenCV 4
下一篇: pytorch 卷积网络入门实例