RANSAC算法总结
1、什么是RANSAC算法呢?
RANSAC,全称为Random Sample Consensus,即随机抽样一致。 它采用迭代的方式从一组包含离群的被观测数据中估算出数学模型的参数。 RANSAC是一个非确定性算法,在某种意义上说,它会产生一个在一定概率下合理的结果,而更多次的迭代会使这一概率增加。此RANSAC算法在1981年由Fischler和Bolles首次提出。
2、为什么需要这个算法?
从一堆数据找一个合适的模型,再确定合适的模型参数,这是很重要的问题,是人类理性的基础。数据分两种:有效数据(inliers)和无效数据(outliers)。那些偏差不大的数据是有效数据,偏差大的数据是无效数据。如果有效数据占大多数,无效数据只是很少量时,我们可以通过最小二乘法或类似的方法来确定模型的参数和误差。如果无效数据很多(比如,超过了50%的数据是无效数据),最小二乘法就失效了,我们需要新的算法,即RANSAC算法。
3、算法的原理是什么?
RANSAC算法的输入是一组观测数据(往往含有较大的噪声或无效点),一个用于解释观测数据的参数化模型以及一些可信的参数。RANSAC通过反复选择数据中的一组随机子集来达成目标。被选取的子集被假设为局内点,并用下述方法进行验证:
(1)用一个模型适应于假设的局内点,即所有的未知参数都能从假设的局内点计算得出。
(2)用(1)中得到的模型去测试所有的其它数据,如果某个点适用于估计的模型,认为它也是局内点。
(3)如果有足够多的点被归类为假设的局内点,那么估计的模型就足够合理。
(4)然后,用所有假设的局内点去重新估计模型(譬如使用最小二乘法),因为它仅仅被初始的假设局内点估计过。
(5)最后,通过估计局内点与模型的错误率来评估模型。
上述过程被重复执行固定的次数,每次产生的模型要么因为局内点太少而被舍弃,要么因为比现有的模型更好而被选用。
4、算法的步骤是什么?
(1) 在数据中随机选择几个点设定为内群
(2)计算拟合内群的模型
(3)把其它刚才没选到的点带入刚才建立的模型中,计算是否为内群
(4)记下内群数量
(5)重复以上步骤多做几次
The generic RANSAC algorithm works as follows:Given:data – a set of observed data pointsmodel – a model that can be fitted to data pointsn – the minimum number of data values required to fit the modelk – the maximum number of iterations allowed in the algorithmt – a threshold value for determining when a data point fits a modeld – the number of close data values required to assert that a model fits well to dataReturn:bestfit – model parameters which best fit the data (or nul if no good model is found)iterations = 0
bestfit = nul
besterr = something really large
while iterations < k {maybeinliers = n randomly selected values from datamaybemodel = model parameters fitted to maybeinliersalsoinliers = empty setfor every point in data not in maybeinliers {if point fits maybemodel with an error smaller than tadd point to alsoinliers}if the number of elements in alsoinliers is > d {% this implies that we may have found a good model% now test how good it isbettermodel = model parameters fitted to all points in maybeinliers and alsoinliersthiserr = a measure of how well model fits these pointsif thiserr < besterr {bestfit = bettermodelbesterr = thiserr}}increment iterations
}
return bestfit
5、算法的适用场合?
RANSAC常被用在计算机视觉,例如,对应点问题和 估算立体摄影机双眼相对点的基本矩阵。
6、算法如何使用呢?
(1)matlab实现
function [bestParameter1,bestParameter2] = ransac_demo(data,num,iter,threshDist,inlierRatio)% data: a 2xn dataset with #n data points% num: the minimum number of points. For line fitting problem, num=2% iter: the number of iterations% threshDist: the threshold of the distances between points and the fitting line% inlierRatio: the threshold of the number of inliers %% Plot the data pointsfigure;plot(data(1,:),data(2,:),'o');hold on;number = size(data,2); % Total number of pointsbestInNum = 0; % Best fitting line with largest number of inliersbestParameter1=0;bestParameter2=0; % parameters for best fitting linefor i=1:iter%% Randomly select 2 pointsidx = randperm(number,num); sample = data(:,idx); %% Compute the distances between all points with the fitting line kLine = sample(:,2)-sample(:,1);% two points relative distancekLineNorm = kLine/norm(kLine);normVector = [-kLineNorm(2),kLineNorm(1)];%Ax+By+C=0 A=-kLineNorm(2),B=kLineNorm(1)distance = normVector*(data - repmat(sample(:,1),1,number));%% Compute the inliers with distances smaller than the thresholdinlierIdx = find(abs(distance)<=threshDist);inlierNum = length(inlierIdx);%% Update the number of inliers and fitting model if better model is found if inlierNum>=round(inlierRatio*number) && inlierNum>bestInNumbestInNum = inlierNum;parameter1 = (sample(2,2)-sample(2,1))/(sample(1,2)-sample(1,1));parameter2 = sample(2,1)-parameter1*sample(1,1);bestParameter1=parameter1; bestParameter2=parameter2;endend%% Plot the best fitting linexAxis = -number/2:number/2; yAxis = bestParameter1*xAxis + bestParameter2;plot(xAxis,yAxis,'r-','LineWidth',2);
(2)C++实现
#include <math.h>
#include "LineParamEstimator.h" LineParamEstimator::LineParamEstimator(double delta) : m_deltaSquared(delta*delta) {}
/*****************************************************************************/
/* 1. Compute the line parameters [n_x,n_y,a_x,a_y] 2. 通过输入的两点来确定所在直线,采用法线向量的方式来表示,以兼容平行或垂直的情况 3. 其中n_x,n_y为归一化后,与原点构成的法线向量,a_x,a_y为直线上任意一点 */
void LineParamEstimator::estimate(std::vector<Point2D *> &data, std::vector<double> ¶meters)
{ parameters.clear(); if(data.size()<2) return; double nx = data[1]->y - data[0]->y; double ny = data[0]->x - data[1]->x;// 原始直线的斜率为K,则法线的斜率为-1/k double norm = sqrt(nx*nx + ny*ny); parameters.push_back(nx/norm); parameters.push_back(ny/norm); parameters.push_back(data[0]->x); parameters.push_back(data[0]->y);
}
/*****************************************************************************/
/* 4. Compute the line parameters [n_x,n_y,a_x,a_y] 5. 使用最小二乘法,从输入点中拟合出确定直线模型的所需参量 */
void LineParamEstimator::leastSquaresEstimate(std::vector<Point2D *> &data, std::vector<double> ¶meters)
{ double meanX, meanY, nx, ny, norm; double covMat11, covMat12, covMat21, covMat22; // The entries of the symmetric covarinace matrix int i, dataSize = data.size(); parameters.clear(); if(data.size()<2) return; meanX = meanY = 0.0; covMat11 = covMat12 = covMat21 = covMat22 = 0; for(i=0; i<dataSize; i++) { meanX +=data[i]->x; meanY +=data[i]->y; covMat11 +=data[i]->x * data[i]->x; covMat12 +=data[i]->x * data[i]->y; covMat22 +=data[i]->y * data[i]->y; } meanX/=dataSize; meanY/=dataSize; covMat11 -= dataSize*meanX*meanX; covMat12 -= dataSize*meanX*meanY; covMat22 -= dataSize*meanY*meanY; covMat21 = covMat12; if(covMat11<1e-12) { nx = 1.0; ny = 0.0; } else { //lamda1 is the largest eigen-value of the covariance matrix //and is used to compute the eigne-vector corresponding to the smallest //eigenvalue, which isn't computed explicitly. double lamda1 = (covMat11 + covMat22 + sqrt((covMat11-covMat22)*(covMat11-covMat22) + 4*covMat12*covMat12)) / 2.0; nx = -covMat12; ny = lamda1 - covMat22; norm = sqrt(nx*nx + ny*ny); nx/=norm; ny/=norm; } parameters.push_back(nx); parameters.push_back(ny); parameters.push_back(meanX); parameters.push_back(meanY);
}
/*****************************************************************************/
/* 6. Given the line parameters [n_x,n_y,a_x,a_y] check if 7. [n_x, n_y] dot [data.x-a_x, data.y-a_y] < m_delta 8. 通过与已知法线的点乘结果,确定待测点与已知直线的匹配程度;结果越小则越符合,为 9. 零则表明点在直线上 */
bool LineParamEstimator::agree(std::vector<double> ¶meters, Point2D &data)
{ double signedDistance = parameters[0]*(data.x-parameters[2]) + parameters[1]*(data.y-parameters[3]); return ((signedDistance*signedDistance) < m_deltaSquared);
}
7、RANSAC的优点与缺点?
(1)优点:
(i). 它能鲁棒的估计模型参数。例如,它能从包含大量局外点的数据集中估计出高精度的参数。
(2)缺点:
(i). 它计算参数的迭代次数没有上限;如果设置迭代次数的上限,得到的结果可能不是最优的结果,甚至可能得到错误的结果。RANSAC只有一定的概率得到可信的模型,概率与迭代次数成正比。
(ii).它需要的设置问题特定的阈值;
(iii).RANSAC只能估计一个模型,一个特定的数据集。对于任何一个模型方法在两个(或更多)模型实例存在,RANSAC可能无法找到任何一个。
RANSAC算法总结相关推荐
- RANSAC算法(2):(拟合平面)本文以地面为基础以及源码分布解读
本章代码是本人根据一个未曾谋面的好人学习的(要怀抱希望,世界上好人真的是很多的,我要做一个去给别人带去正能量积极态度的人,加油喽),如需转载学习请注明.谢谢 ---------------基于rans ...
- SIFT特征点匹配中KD-tree与Ransac算法的使用
转自:http://blog.csdn.net/ijuliet/article/details/4471311 Step1:BBF算法,在KD-tree上找KNN.第一步做匹配咯~ 1.什么是KD-t ...
- OpenCV 4.5发布!更强的SIFT,OCR,RANSAC算法,新增目标跟踪网络SiamRPN++
点击上方"3D视觉工坊",选择"星标" 干货第一时间送达 OpenCV 4.5版本发布了! 详情:https://github.com/opencv/openc ...
- RANSAC算法原理与实现
参考原文: RANSAC算法学习笔记 重点内容: 算法流程: 1.在可以有(也可以没有,主要看应用场景)条件限制(比如选的子集里的点不能过远等)的情况下,随机选取子集,并假设为局内点.子集的大小,主要 ...
- 机器视觉:ransac算法详解
一.说明: 在线性回归问题中,采样点具备明显的线性相关性:如下图左.然而有些情性中,噪声很大,线性性散布在非线性点的噪声中,将无法用线性回归 的方法进行直线提取. 随机样本一致性 (RANSAC) 是 ...
- openCV中的findHomography函数分析以及RANSAC算法的详解(源代码分析)
本文将openCV中的RANSAC代码全部挑选出来,进行分析和讲解,以便大家更好的理解RANSAC算法.代码我都试过,可以直接运行. 在计算机视觉和图像处理等很多领域,都需要用到RANSAC算法.op ...
- 利用SIFT和RANSAC算法(openCV框架)实现物体的检测与定位,并求出变换矩阵(findFundamentalMat和findHomography的比较)
本文目标是通过使用SIFT和RANSAC算法,完成特征点的正确匹配,并求出变换矩阵,通过变换矩阵计算出要识别物体的边界(文章中有部分源码,整个工程我也上传了,请点击这里). SIFT算法是目前公认的效 ...
- 利用RANSAC算法筛选SIFT特征匹配
关于RANSAC算法的基本思想,可从网上搜索找到,这里只是RANSAC用于SIFT特征匹配筛选时的一些说明. RANSAC算法在SIFT特征筛选中的主要流程是: (1) 从样本集中随机抽选一个RANS ...
- RANSAC算法做直线拟合
RANSAC算法之前了解过相关的原理,这两天利用晚上闲暇的时间,看了一下RANSAC算法的Python代码实现,这方面的资料很多了,这里就不在重复.在分析该RANSAC.py代码之前,想用自己的对RA ...
- RANSAC算法注记
今天学习了一下RANSAC随机样本一致性算法,其在图像融合.特征点匹配方面有很强大的应用.网上已经有很多人写了关于这方面的文档,就不再造轮子了.特此罗列出来,以供后续参考. 我的数学之美(一)--RA ...
最新文章
- c++成员函数的重载、覆盖、隐藏区别
- 二、如何读入图片、显示图像?
- [通用技术]在不同语言中用协程实现全排列算法(C++/Lua/Python/C#)
- 《Tuning I/O Performance》读后笔记
- 成为解决计算机问题的利器,高中数学教学借助计算机的“翅膀”腾飞
- C#的变迁史04 - C# 4.0 之多线程篇
- 小米总参php面试题_php面试题之二——Javascript(基础部分)
- listview选中高亮
- 手机sstv解码软件_关于二维码扫描使用专业扫描设备和手机二维码扫描软件的区别?...
- 高校图书馆管理系统 php 漏洞,江苏汇文Libsys图书馆管理系统几处通用SQL注入漏洞...
- python 把京东订单,推送到测试环境,提供便利
- 尚乘集团联手其蛛网生态圈成员及战略伙伴布局进驻元宇宙
- 2011年中国大陆十佳IC设计公司
- 公司注册不满一年如何名称变更
- How to Install Nvidia Kernel Module Cuda and Pyrit in Kali Linux
- PTA】{10-1 结构拓展实验,函数}6-3 求某学生8门课的平均分 (10 分)
- golang关于panic的解析
- truct in6_addr has no member named in6_u
- 有一个8位机,采用单总线结构......(计算机组成原理课后习题)
- 如何制作电子邮件链接?