Ransac算法--直线拟合

Ransac算法

项目主页https://github.com/libing64/RansacLine

1、算法简介

随机抽样一致算法(RANdom SAmple Consensus,RANSAC)。它是一种迭代的方法,用来在一组包含离群的被观测数据中估算出数学模型的参数。 RANSAC是一个非确定性算法,在某种意义上说,它会产生一个在一定概率下合理的结果,其允许使用更多次的迭代来使其概率增加。此RANSAC算法在1981年由Fischler和Bolles首次提出。

RANSAC的基本假设是 “内群”数据可以通过几组模型参数来叙述其数据分布,而“离群”数据则是不适合模型化的数据。 数据会受噪声影响,噪声指的是离群,例如从极端的噪声或错误解释有关数据的测量或不正确的假设。 RANSAC假定,给定一组(通常很小)的内群,存在一个程序,这个程序可以估算最佳解释或最适用于这一数据模型的参数。

2、范例

这里用一个简单的例子来说明,在一组数据点中找到一条最适合的线。 假设,此有一组集合包含了内群以及离群,其中内群为可以被拟合到线段上的点,而离群则是无法被拟合的点。如果我们用简单的最小平方法来找此线,我们将无法得到一条适合于内群的线,因为最小平方法会受离群影响而影响其结果。而RANSAC,可以只由内群来计算出模型,而且概率还够高。 然而,RANSAC无法保证结果一定最好,所以必须小心选择参数,使其能有足够的概率。

3、概述

  1. 在数据中随机选择几个点设定为内群
  2. 计算适合内群的模型
  3. 把其它刚才没选到的点带入刚才建立的模型中,计算是否为内群
  4. 记下内群数量
  5. 重复以上步骤多做几次
  6. 比较哪次计算中内群数量最多,内群最多的那次所建的模型就是我们所要求的解
  7. 这里有几个问题
  8. 一开始的时候我们要随机选择多少点(n)
  9. 以及要重复做多少次(k)

4、参数确定

假设每个点时真正内群的概率为 w

w = 内群的数目/(内群数目+外群数目)
 

通常我们不知道 w 是多少, w^n是所选择的n个点都是内群的机率, 1-w^n 是所选择的n个点至少有一个不是内群的机率, (1 − w^n)^k 是表示重复 k 次都没有全部的n个点都是内群的机率, 这边定算法跑 k 次以后成功的机率是p,那么,

1 − p = (1 − w^n)^k
p = 1 − (1 − w^n)^k
 

所以如果希望成功机率高,p = 0.99, 当n不变时,k越大,p越大, 当w不变时,n越大,所需的k就越大, 通常w未知,所以n 选小一点比较好。

5、应用

RANSAC常被用在电脑视觉 ,例如,对应点问题 和 估算立体摄影机双眼相对点的基本矩阵。

6、C实现源码

[cpp]  view plain copy
  1. float Ransac  
  2. (  
  3.     Point2D32f* points,   
  4.     size_t Cnt,   
  5.     float *line,  
  6.     int numForEstimate,  
  7.     float successProbability,  
  8.     float maxOutliersPercentage  
  9. ){  
  10.   
  11.     //1 − p = (1 − w^n)^k  
  12.     //p =   
  13.     //float outlierPercentage = maxOutliersPercentage;//估计值  
  14.     float numerator = log(1.0f-successProbability);  
  15.     float denominator = log(1.0f- pow(1.0-maxOutliersPercentage, numForEstimate));  
  16.     //随机抽取一定比例的点  
  17.     int ransac_times = (int)(numerator/denominator + 0.5);  
  18.       
  19.     printf("ransac_times: %d\n", ransac_times);  
  20.     int numDataObjects = Cnt;  
  21.     //int numForEstimate = Cnt*0.1;  
  22.     int maxVoteCnt = 0;  
  23.     float tempLine[4];  
  24.     float inliersPercentage = 0.0;  
  25.       
  26.       
  27.     int *Chosen = new int[numDataObjects];  
  28.   
  29.     Point2D32f *subPoints = new Point2D32f[numForEstimate];  
  30.     int pointCnt = 0;  
  31.     int voteCnt = 0;  
  32.     for(int i = 0; i < ransac_times; i++)  
  33.     {  
  34.         //随机抽取   
  35.         //randomly select data for exact model fit ('numForEstimate' objects).  
  36.         memset(Chosen,0,numDataObjects*sizeof(int));  
  37.         int maxIndex = numDataObjects-1;  
  38.         for(int j = 0; j < numForEstimate; j++)  
  39.         {  
  40.             int selectedIndex = rand() % numDataObjects;  
  41.             Chosen[selectedIndex] = 1;  
  42.         }  
  43.         //拟合  
  44.         pointCnt = 0;  
  45.         for(int k = 0; k < numDataObjects; k++)  
  46.         {  
  47.             if(Chosen[k])  
  48.             {  
  49.                 subPoints[pointCnt].x = points[k].x;  
  50.                 subPoints[pointCnt].y = points[k].y;  
  51.                 pointCnt++;  
  52.             }  
  53.         }  
  54.         FitLine2D(subPoints, pointCnt, tempLine);  
  55.         float a = tempLine[1]/tempLine[0];  
  56.         float b = tempLine[3] - a*tempLine[2];  
  57.           
  58.           
  59.         //拟合完整之后要对拟合的结果进行鉴定,选出最优的结果  
  60.         voteCnt = 0;  
  61.         for(int k = 0; k < Cnt; k++)  
  62.         {  
  63.             //如果在直线上或者附近  
  64.             if(abs(points[k].y - a*points[k].x - b) < 2)  
  65.             {  
  66.                 voteCnt++;  
  67.             }  
  68.         }  
  69.   
  70.         if(voteCnt > maxVoteCnt)  
  71.         {  
  72.             maxVoteCnt = voteCnt;  
  73.             inliersPercentage = (float)maxVoteCnt/Cnt;  
  74. //          printf("a: %f\tb%f\tpercent: %f\n", a, b, inliersPercentage);  
  75.             for(int m = 0; m < 4; m++)  
  76.             {  
  77.                 line[m] = tempLine[m];  
  78.             }  
  79.               
  80.         }     
  81.         //当inliers的比例比较高的时候就可以直接取该值作为最优解  
  82. //      if(inliersPercentage > 0.2)  
  83. //      {  
  84. //          return inliersPercentage;  
  85. //      }  
  86.     }  
  87.     return inliersPercentage;  
  88. }  


7、优缺点

RANSAC的优点是它能鲁棒的估计模型参数。例如,它能从包含大量局外点的数据集中估计出高精度的参数。RANSAC的缺点是它计算参数的迭代次数没有上限;如果设置迭代次数的上限,得到的结果可能不是最优的结果,甚至可能得到错误的结果。RANSAC只有一定的概率得到可信的模型,概率与迭代次数成正比。RANSAC的另一个缺点是它要求设置跟问题相关的阀值。

RANSAC只能从特定的数据集中估计出一个模型,如果存在两个(或多个)模型,RANSAC不能找到别的模型。

转载:http://blog.csdn.net/renshengrumenglibing/article/details/9009959

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值