PCL:平面模型分割

Posted 没事就要敲代码

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PCL:平面模型分割相关的知识,希望对你有一定的参考价值。

1 原理描述

RANSAC 平面拟合原理一致,只是实现代码有些差异。

2 代码实现

#include <pcl/io/pcd_io.h>
#include <pcl/ModelCoefficients.h>
#include <pcl/sample_consensus/method_types.h>
#include <pcl/sample_consensus/model_types.h>
#include <pcl/segmentation/sac_segmentation.h>
#include <pcl/filters/extract_indices.h>

using namespace std;

typedef pcl::PointXYZ PointT;
typedef pcl::PointCloud<PointT> PointCloudT;

int main()

	//-------------------------- 加载点云 --------------------------
	cout << "->正在加载点云..." << endl;
	PointCloudT::Ptr cloud(new PointCloudT);
	if (pcl::io::loadPCDFile("desk.pcd", *cloud) < 0)
	
		PCL_ERROR("\\a点云文件不存在!\\n");
		system("pause");
		return -1;
	
	cout << "->加载点数:" << cloud->points.size() << endl;
	//========================== 加载点云 ==========================

	//-------------------------- 平面分割 --------------------------
	pcl::ModelCoefficients::Ptr coefficients(new pcl::ModelCoefficients);	//模型系数
	pcl::PointIndices::Ptr inliers(new pcl::PointIndices);					//模型内点
	pcl::SACSegmentation<PointT> seg;										//创建分割对象
	seg.setOptimizeCoefficients(true);		//优化模型系数(可选设置)
	seg.setModelType(pcl::SACMODEL_PLANE);	//设置模型类型
	seg.setMethodType(pcl::SAC_RANSAC);		//设置方法类型
	seg.setDistanceThreshold(0.01);			//设置点到拟合平面的距离阈值
	seg.setInputCloud(cloud->makeShared());	//设置输入点云,深拷贝,返回指向cloud的智能指针,等价于seg.setInputCloud(cloud);
	seg.segment(*inliers, *coefficients);	//执行分割。将内点和模型系数分别保存至inliers、coefficients

	if (inliers->indices.size() == 0)
	
		PCL_ERROR("\\a->无法从给定的数据集估计出一个平面!\\n");
		system("pause");
		return (-1);
	
	cout << "->平面模型系数: " 
		<< coefficients->values[0] << " "
		<< coefficients->values[1] << " "
		<< coefficients->values[2] << " "
		<< coefficients->values[3] << endl;
	cout << "->平面模型内点个数: " << inliers->indices.size() << endl;
	//========================== 平面分割 ==========================

	//-------------------------- 平面提取 --------------------------
	PointCloudT::Ptr cloud_indice(new PointCloudT);
	/// 方法1,较为简单,一行代码即可实现
	//pcl::copyPointCloud(*cloud, inliers->indices, *cloud_indice);

	/// 方法2,较为繁琐
	pcl::IndicesPtr index_ptr(new vector<int>(inliers->indices));//智能指针转换
	pcl::ExtractIndices<PointT> extract;//创建提取对象
	extract.setInputCloud(cloud);		//设置输入点云
	extract.setIndices(index_ptr);		//设置内点索引
	extract.setNegative(false);			//默认false,提取索引内的点;true,提取索引外的点
	extract.filter(*cloud_indice);		//执行提取,将结果保存至cloud_indice
	//========================== 平面提取 ==========================

	//-------------------------- 保存平面 --------------------------
	pcl::io::savePCDFileBinary("plane.pcd", *cloud_indice);
	cout << "->保存点云点数:" << cloud_indice->points.size() << endl;
	//========================== 保存平面 ==========================

	return 0;

输出结果:

->正在加载点云...
->加载点数:41049
->平面模型系数: -0.00660275 -0.87506 -0.483969 -1.17755
->平面模型内点个数: 20161
->保存点云点数:20161

3 结果展示

红色为分割出的平面点云,白色为原始点云。

4 相关链接

以上是关于PCL:平面模型分割的主要内容,如果未能解决你的问题,请参考以下文章

PCL:多平面分割

PCL 平面拟合——RANSAC

PCL基于法线的差异来分割点云

PCL异常处理:pcl 1.8.13rdpartyoostincludeoost-1_64oost ypeofmsvc ypeof_impl.hpp(125): error(代码片段

PCL中Sample_consensus分割支持的几何模型

PCL—点云分割(最小割算法)