前言
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函數庫摘要——采樣一致性