PCL中RANSAC模型的使用

RANSAC算法是什么

        RANSAC算法于1981年由Fischler和Bolles提出,全程是RANdom SAmple Consensus,一般中文翻译为“随机抽样一致性算法”,它是一个迭代算法,主要用于从包含外点(outliers,可理解为噪声)的数据集中估计数学模型的参数。RANSAC算法有两个假设,第一个是假定所有的数据都是由内点和外点组成,内点可由特定参数的模型所表示,而外点则在任何情况下都不能满足由内点的模型,另外一个必要的假设是存在程序可以从数据中最优的估计出所选择模型的参数。

RANSAC算法迭代过程

        RANSAC算法的输入需要数据集和可以表示数据集的参数化模型,以及一些置信参数。RANSAC算法通过迭代的从原始数据里选择一个随机性的子集来得到最终结果,假定子数据集为内点,然后通过以下步骤来验证这个假设:

  1. 由假定的内点拟合出一个数据模型,即根据内点重构模型的所有自由参数;
  2. 所有其他的数据在拟合出的模型上进行验证,假如某个点符合所得到的模型,那么这个点就被认为也是内点;
  3. 如果有足够多的点被认为是内点,则估计的模型就相当好;
  4. 然后根据所有的内点重新估计模型,因为之前的模型只是从初始的内点估计出来的;
  5. 最后通过内点和模型的误差来评估整个模型的好坏。

这个过程重复固定次数,每次都会产生一个模型,假如太少的点被归类为内点,则模型被丢弃,反之则得到一个改进的模型以及测量误差,如果测量误差低于上次保存的模型的话,就保留改进的模型。

RANSAC算法优缺点

        RANSAC算法的优点是能够对模型参数进行鲁棒估计,也就是说,即使数据集中存在大量的异常值,它也可以高精度地估计参数。RANSAC的缺点是计算这些参数所需的时间没有上限,当计算的迭代次数有限时,得到的解可能不是最优解,甚至可能不是一个很好地适合数据的解。所以RANSAC提供了一个折衷方案:通过计算更多的迭代次数,可以增加产生合理模型的概率。RANSAC的另一个缺点是它需要设置特定的问题域,即对于某个特定的数据集,RANSAC只能估计出一个模型,如果原始数据里存在两个(或多个)模型,RANSAC可能无法找到其中一个。

RANSAC算法简单示例

        RANSAC算法应用于一个二维的数据集上(来源维基百科),左边图片显示了一个包含内点和外点的数据集,右边图片中所有的外点为红色,内点为蓝色,蓝色的线为应用RANSAC算法生成的模型,这个示例是要在原始数据中拟合出一条直线,从右图中可以看到模型与数据匹配的相当好。

PCL中RANSAC模型的使用_第1张图片PCL中RANSAC模型的使用_第2张图片

 PCL中RANSAC算法使用

        使用PCL中的RANSAC算法,需要包含ransac.h头文件,在此示例中,需要指定平面和球两个模型,因此同时加入了平面和球模型相关的头文件,如下所示:

#include 
#include 
#include 

首先,定义所需要的模型,这里定义了两个,第一个为球模型,第二个为平面模型:

pcl::SampleConsensusModelSphere::Ptr
    model_s(new pcl::SampleConsensusModelSphere (cloud));
pcl::SampleConsensusModelPlane::Ptr
    model_p (new pcl::SampleConsensusModelPlane (cloud));

其次,使用RandomSampleConsensus实例化RANSAC算法,inliers用于存储内点的索引,传入所要拟合的模型(这里为平面或球模型),计算并得到内点

std::vector inliers;
pcl::RandomSampleConsensus ransac (model_p);
ransac.setDistanceThreshold (.01);
ransac.computeModel();
ransac.getInliers(inliers);

在本示例中,程序中的数据集如下所示,两张图为同一个点云的不同角度,其中有1/5的数据为随意放置的,从图中可以看到,点云并不是很规整,并包含一些外点在里面

PCL中RANSAC模型的使用_第3张图片PCL中RANSAC模型的使用_第4张图片

 RandomSampleConsensus输入平面模型可得结果如下,可以看到不符合平面模型的外点被移除,而平面的内点组成了一个平面:

PCL中RANSAC模型的使用_第5张图片PCL中RANSAC模型的使用_第6张图片

未应用RANSAC算法的球状点云包含部分外点如以下左图所示,使用球体模型应用RANSAC算法后官方示例如下右图所示,在此需要注意的是,PCL官方示例中给出的图是正确的,但是在Windows上运行时,原始点云为一个正方体,不是球体,然后应用RANSAC后只能得到少数几个点,原因是官方的示例代码在windows上时,rand()产生的值在[0,32767],并不是官方文档中说的[0,1],所以最后得出的是一个正方体,修改代码生成合适的球体即可应用PCL的RANSAC算法,结果如下:

PCL中RANSAC模型的使用_第7张图片PCL中RANSAC模型的使用_第8张图片

 

开发环境及程序

    开发环境:VS2015 & PCL1.8.1

    PCL 头及库文件配置

Include:
$(PCL_ROOT);
$(PCL_ROOT)\include\pcl-1.8;
$(PCL_ROOT)\3rdParty\Eigen\eigen3;
$(PCL_ROOT)\3rdParty\FLANN\include;
$(PCL_ROOT)\3rdParty\VTK\include\vtk-8.0;
$(PCL_ROOT)\3rdParty\Boost\include\boost-1_64;
 
lib:
$(PCL_ROOT)\lib\*.lib
$(PCL_ROOT)\3rdParty\VTK\lib\*.lib
$(PCL_ROOT)\3rdParty\FLANN\lib\*.lib
$(PCL_ROOT)\3rdParty\Boost\lib\*.lib

工程及源码地址: https://github.com/yazhouzheng/RANSACInPCL.git

参考

    1. http://pointclouds.org/documentation/tutorials/random_sample_consensus.php 

你可能感兴趣的:(PCL)