前言
RANSAC(Random sample consensus,随机采样一致)是3D点云拟合的一种重要的手段,可以对直线、圆、平面,圆球、圆柱等形状的点云进行拟合,其优点在于可以最大程度上减少噪声点对拟合效果的影响。
一、RANSAC
RANSAC各种类型拟合的计算原理基本类似。
1,进行随机抽样,如直线,就随机找到两个点;如平面,就随机找到三个点来创建一个平面。
2,计算除去采样点的其余点与采样点组成的模型之间的距离,设定阈值,将符合阈值标准的点标记为内点,记录内点个数。
3,重复前面的步骤进行迭代计算,直到达到迭代终止条件,选择内点个数最多的模型计算最佳拟合参数。
其去除噪声影响效果好坏的关键在于内点阈值的选择和迭代次数。
PCL中有专门的一个类RandomSampleConsensus来实现其算法。
简单分析下其计算部分。
const double log_probability = std::log (1.0 - probability_);
源码中probability_表示从数据集中选取采样点N均为局内点的概率。
// Better match ?if (n_inliers_count > n_best_inliers_count){n_best_inliers_count = n_inliers_count; // This write and the previous read of n_best_inliers_count must be consecutive and must not be interrupted!n_best_inliers_count_tmp = n_best_inliers_count;// Save the current model/inlier/coefficients selection as being the best so farmodel_ = selection;model_coefficients_ = model_coefficients;// Compute the k parameter (k=std::log(z)/std::log(1-w^n))const double w = static_cast<double> (n_best_inliers_count) * one_over_indices;double p_no_outliers = 1.0 - std::pow (w, static_cast<double> (selection.size ()));p_no_outliers = (std::max) (std::numeric_limits<double>::epsilon (), p_no_outliers); // Avoid division by -Infp_no_outliers = (std::min) (1.0 - std::numeric_limits<double>::epsilon (), p_no_outliers); // Avoid division by 0.k = log_probability / std::log (p_no_outliers);}
以上为寻找最佳模型的代码。
w的值为从数据集中选取一个采样点为局内点的概率。
p_no_outliers:顾名思义,意思为非局外点的概率。
k表示估计的迭代采样次数。
二、应用示例
1.拟合直线
PCL中采样一致直线模型的类为SampleConsensusModelLine
通过这个类将输入的点云转化为采样一致模型。
pcl::SampleConsensusModelLine<pcl::PointXYZ>::Ptr line(new pcl::SampleConsensusModelLine<pcl::PointXYZ>(cloud));
pcl::RandomSampleConsensus<pcl::PointXYZ> ransac(line);
ransac.setDistanceThreshold(0.01);
ransac.setMaxIterations(1000);
ransac.computeModel();vector<int> inliers;
ransac.getInliers(inliers);pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_line(new pcl::PointCloud<pcl::PointXYZ>);
pcl::copyPointCloud<pcl::PointXYZ>(*cloud, inliers, *cloud_line);Eigen::VectorXf coefficient;
ransac.getModelCoefficients(coefficient);
2.拟合平面
同样,SampleConsensusModelPlane表示采样一致平面的模型。
pcl::SampleConsensusModelPlane<pcl::PointXYZ>::Ptr plane(new pcl::SampleConsensusModelPlane<pcl::PointXYZ>(cloud));pcl::RandomSampleConsensus<pcl::PointXYZ> ransac(plane);
ransac.setDistanceThreshold(0.1);
ransac.setMaxIterations(500);
ransac.setProbability(0.99);
ransac.computeModel();
vector<int> inliers;
ransac.getInliers(inliers); Eigen::VectorXf coefficient;
ransac.getModelCoefficients(coefficient);
3.拟合球
SampleConsensusModelSphere表示采样一致平面的模型。
pcl::SampleConsensusModelSphere<pcl::PointXYZ>::Ptr sphere(new pcl::SampleConsensusModelSphere<pcl::PointXYZ>(cloud));pcl::RandomSampleConsensus<pcl::PointXYZ> ransac(sphere);
ransac.setDistanceThreshold(0.1);
ransac.setMaxIterations(1000);
ransac.setProbability(0.99);
ransac.computeModel();Eigen::VectorXf coeff;
ransac.getModelCoefficients(coeff);pcl::IndicesPtr inliers(new vector <int>());
ransac.getInliers(*inliers);
总结
优点:避免噪声点对拟合结果的干扰。
缺点:由于计算结果的不确定性,迭代次数可能过高,对于密集点云来讲,计算时间过长,需要进行预处理后再进行拟合过程,但同样会损失时间。
原理部分参考:
随机抽样一致算法(Random sample consensus,RANSAC)详解,保姆级教程
PCL函数库摘要——采样一致性