PCL循环分割并提取平面点云——小于阈值数量时停止

PCL循环分割平面点云

PCL提供了 分割点云的算法,分割的点云为平面最大的点云。下面是实现循环分割的代码

#define _USE_MATH_DEFINES
#include <math.h>//pi为M_PI
#include <iostream>
#include <string>
#include <pcl/point_types.h>
#include <pcl/io/ply_io.h>
#include <pcl/io/pcd_io.h>
#include <pcl/PCLPointCloud2.h>
#include <pcl/visualization/cloud_viewer.h>//可视化
#include <pcl/filters/voxel_grid.h>  //体素滤波相关 下采样
#include <pcl/console/time.h>//计时器
//pcl segmentation
#include <pcl/sample_consensus/method_types.h>
#include <pcl/sample_consensus/model_types.h>
#include <pcl/segmentation/sac_segmentation.h>
#include <pcl/ModelCoefficients.h>
#include <pcl/segmentation/extract_clusters.h>
//按照索引提取点云
#include <pcl/filters/extract_indices.h>
//点云移动
#include <pcl/common/transforms.h>
//点云配准
#define BOOST_TYPEOF_EMULATION
#include <pcl/registration/icp.h>

这部分头文件还包含了点云与处理 和点云移动 还有点云配准

using namespace pcl;
using namespace pcl::io;
using namespace std;

int main() {
	pcl::console::TicToc timer;
	//读取保存的点云
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_voxel_filter(new pcl::PointCloud<pcl::PointXYZ>);
	if (pcl::io::loadPCDFile<pcl::PointXYZ>("iphonetest7_sample_filter.pcd", *cloud_voxel_filter) == -1) //* load the file
	{
		PCL_ERROR("Couldn't read file test_pcd.pcd \n");
		return (-1);
	}
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_plane(new pcl::PointCloud<pcl::PointXYZ>);
//循环用到的
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_p(new pcl::PointCloud<pcl::PointXYZ>);
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_f(new pcl::PointCloud<pcl::PointXYZ>);
	pcl::SACSegmentation<pcl::PointXYZ> seg;//  采样一致性分割对象
	pcl::PointIndices::Ptr inliers(new pcl::PointIndices);//存储内点的点索引集合对象inliers
	pcl::ModelCoefficients::Ptr coefficients(new pcl::ModelCoefficients);//创建分割时所需要的模型系数对象coefficients
	seg.setOptimizeCoefficients(true);可选择配置,设置模型系数需要优化
	//必须配置,设置分割的模型类型、所用的随机参数估计方法、距离阈值、输入点云
	seg.setModelType(pcl::SACMODEL_PLANE);//所提取目标模型的属性 分割平面
	seg.setMethodType(pcl::SAC_RANSAC);//ransac法
	seg.setMaxIterations(100);// 最大迭代次数
	seg.setDistanceThreshold(0.5);//查询点到目标模型的距离阈值
	//*******提取表面
	pcl::ExtractIndices<pcl::PointXYZ> extract;
	int i = 0, nr_points = (int)cloud_voxel_filter->points.size();

	
	//为了处理点云中包含多个模型,在一个循环中执行该过程,
	//并在每次模型被提取后,我们保存剩余的点,进行迭代;
	//模型内点通过分割过程获取;
	//当还有30%原始点云数据时退出循环

	while (cloud_voxel_filter->points.size() > 0.2 * nr_points)

	{
		cout << "model points before segt" << i << "is" << cloud_voxel_filter->points.size() << endl;
		// Segment the largest planar component from the remaining cloud
		seg.setInputCloud(cloud_voxel_filter);

		//引发分割实现,并存储分割结果到点集合inliers及存储平面模型的系数coefficients
		seg.segment(*inliers, *coefficients);
		if (inliers->indices.size() == 0)
		{
			std::cout << "Could not estimate a planar model for the given dataset." << std::endl;
			break;
		}
		// 分离内层
		extract.setInputCloud(cloud_voxel_filter);
		extract.setIndices(inliers);
		extract.setNegative(false);
		extract.filter(*cloud_p);
		std::cerr << "PointCloud representing the planar component: " << cloud_p->width * cloud_p->height << " data points." << std::endl;
		std::stringstream ss;
		ss << "cloud_plane" << i << ".pcd";
		pcl::io::savePCDFile<pcl::PointXYZ>(ss.str(), *cloud_p);
		// 创建滤波器对象
		extract.setNegative(true);
		extract.filter(*cloud_f);
		cloud_voxel_filter.swap(cloud_f);
		i++;
	}
return 0;
}

猜你喜欢

转载自blog.csdn.net/m0_37668446/article/details/106989396