前言

pcl拟合各种形状,得到相关参数并对参数进行后续处理,是点云处理中的基本操作,这里总结一下平面与直线操作。

一、平面拟合

两种方法都可以用,但是相对来说,方法二可能更稳定。拟合之前最好做一下体素滤波,不然会很慢

1.方式一

#include <pcl/segmentation/sac_segmentation.h>
#include <pcl/segmentation/extract_clusters.h>

	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.1);
	seg.setInputCloud(cloud);
	seg.segment(*inliers, *coefficients);

2.方式二

#include <pcl/sample_consensus/ransac.h>
#include <pcl/sample_consensus/sac_model_plane.h>

	pcl::SampleConsensusModelPlane<pcl::PointXYZ>::Ptr model_plane(new pcl::SampleConsensusModelPlane<pcl::PointXYZ>(cloud));	//选择拟合点云与几何模型
	pcl::RandomSampleConsensus<pcl::PointXYZ> ransac(model_plane);	//创建随机采样一致性对象
	ransac.setDistanceThreshold(0.01);	//设置距离阈值,与平面距离小于0.01的点作为内点
	ransac.computeModel();				//执行模型估计

	//输出模型参数Ax+By+Cz+D=0
	Eigen::VectorXf coefficient;
	ransac.getModelCoefficients(coefficient);

二、直线拟合


#include <pcl/sample_consensus/ransac.h>
#include <pcl/sample_consensus/sac_model_line.h>
	
	std::vector<int> inliers;
	inliers.clear();
	Eigen::VectorXf params;
	Eigen::VectorXf coes;
	pcl::SampleConsensusModelLine<pcl::PointXYZ>::Ptr model(new pcl::SampleConsensusModelLine<pcl::PointXYZ>(cloud));
	pcl::RandomSampleConsensus<pcl::PointXYZ> ransac(model);
	ransac.setDistanceThreshold(threshold);    // 设置距离阈值,即点到直线的距离超过该阈值时,被认为是外点
	ransac.setMaxIterations(iterations);
	//ransac.setNumberOfThreads(10);
	ransac.computeModel();
	ransac.getInliers(inliers);
	ransac.getModelCoefficients(params);   // 获取拟合结果,即直线方程
	model->optimizeModelCoefficients(inliers, params, coes);
	model->selectWithinDistance(coes, threshold, inliers);//优化后的直线方程

总结

总结了一下pcl拟合平面和直线的方法,后续遇到其他情况再补充。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐