前言
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拟合平面和直线的方法,后续遇到其他情况再补充。