深度解析RANSAC算法(精华修正版)

article/2025/9/12 18:04:47

RANSAC算法看似简单,实际上还是有很多坑的,网上有一些关于RANSAC算法的介绍不准确,或者说不全面。

之前我写过一个rnsac算法简介的博客,那么这篇博客将带你再次填这个大坑! 

目录

1.  RANSAC算法论述

2. RANSAC算法示例(线性回归)

3. 反思与总结



算法流程如下:

 


1.  RANSAC算法论述

首先让我们看一份高质量RANSAC算法论述@_@

RANSAC是“RANdom SAmple Consensus(随机抽样一致)”的缩写。它可以从一组包含“局外点”的观测数据集中,通过迭代方式估计数学模型的参数。它是一种不确定的算法——它有一定的概率得出一个合理的结果;为了提高概率必须提高迭代次数。该算法最早由Fischler和Bolles于1981年提出。核心思想就是随机性和假设性,随机性用于减少计算,循环次数是利用正确数据出现的概率。所谓的假设性,就是说随机抽出来的数据都认为是正确的,并以此去计算其他点,获得其他满足变换关系的点,然后利用投票机制,选出获票最多的那一个变换。

RANSAC的基本假设是:
(1)数据由“局内点”组成,例如:数据的分布可以用一些模型参数来解释;
(2)“局外点”是不能适应该模型的数据;
(3)除此之外的数据属于噪声。
局外点产生的原因有:噪声的极值;错误的测量方法;对数据的错误假设。


RANSAC与最小二乘区别最小二乘法尽量去适应包括局外点在内的所有点。相反,RANSAC能得出一个仅仅用局内点计算出模型,并且概率还足够高。但是,RANSAC并不能保证结果一定正确,为了保证算法有足够高的合理概率,必须小心的选择算法的参数(参数配置)。经实验验证,对于包含80%误差的数据集,RANSAC的效果远优于直接的最小二乘法。

验证思路RANSAC算法的输入是一组观测数据,一个可以解释或者适应于观测数据的参数化模型,一些可信的参数。
RANSAC通过反复选择数据中的一组随机子集来达成目标。被选取的子集被假设为局内点,并用下述方法进行验证:
1.有一个模型适应于假设的局内点,即所有的未知参数都能从假设的局内点计算得出。
2.用1中得到的模型去测试所有的其它数据,如果某个点适用于估计的模型,认为它也是局内点。
3.如果有足够多的点被归类为假设的局内点,那么估计的模型就足够合理。
4.然后,用所有假设的局内点去重新估计模型,因为它仅仅被初始的假设局内点估计过。
5.最后,通过估计局内点与模型的错误率来评估模型。

这个过程被重复执行固定的次数,每次产生的模型要么因为局内点太少而被舍弃,要么因为比现有的模型更好而被选用。

参数选择:
根据特定的问题和数据集通过实验来确定参数 t 和 d。然而参数 k(迭代次数)可以从理论结果推断。当估计模型参数时,用 p表示一些迭代过程中从数据集内随机选取出的点均为局内点的概率;此时,结果模型很可能有用,因此 p也表征了算法产生有用结果的概率。用 w表示每次从数据集中选取一个局内点的概率,如下式所示:
    w = 局内点的数目 / 数据集的数目
通常情况下,我们事先并不知道w的值,但是可以给出一些鲁棒的值。假设估计模型需要选定n个点,w^n是所有n个点均为局内点的概率;1 − w^n是n个点中至少有一个点为局外点的概率,此时表明我们从数据集中估计出了一个不好的模型。 (1 − wn)k表示算法永远都不会选择到n个点均为局内点的概率,它和1-p相同。因此,
   1 − p = (1 − w^n)^k
我们对上式的两边取对数,得出
   
值得注意的是,这个结果假设n个点都是独立选择的;也就是说,某个点被选定之后,它可能会被后续的迭代过程重复选定到。这种方法通常都不合理,由此推导出的k值被看作是选取不重复点的上限。例如,要从数据集寻找适合的直线,RANSAC算法通常在每次迭代时选取2个点,计算通过这两点的直线maybe_model,要求这两点必须唯一。
为了得到更可信的参数,标准偏差或它的乘积可以被加到k上。k的标准偏差定义为:
  

注:请注意上面紫色字体的内容!

 

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


2. RANSAC算法示例(线性回归)

下面结合一份线性回归的代码来看:

拟合二维平面中的带噪音直线,其中有不超过10%的样本点远离了直线,另外90%的样本点可能有高斯噪声的偏移

要求输出为

ax+by+c=0的形式
其中a > 0 且 a^2 + b^2 = 1
输入描述:

第一个数n表示有多少个样本点  之后n*2个数 每次是每个点的x 和y

输出描述:

输出a,b,c三个数,至多可以到6位有效数字

示例1

输入

    5
    3 4
    6 8
    9 12
    15 20
    10 -10

输出

-0.800000 0.600000 0.000000

说明

    本题共有10个测试点,每个点会根据选手输出的参数计算非噪音数据点的拟合误差E,并根据E来对每个数据点进行评分0-10分
    输入数据的范围在-10000

#include <cmath>
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <limits>
#include <tuple>
#include <vector>using real = float;
using namespace std;class Point2D {
public:real x, y;public:Point2D(real x_ = 0, real y_ = 0) :x(x_), y(y_) {}bool operator == (const Point2D& p) {return fabs(x - p.x) < 1e-3 && fabs(y - p.y) < 1e-3;}
};class Solution {
public:vector<real> ransaclr(vector<Point2D>& pts, real outlier_prob = 0.1, real accept_prob = 1e-3, real threshold = 10.0) {int n = pts.size();real sample_fail_prob = 1 - (1 - outlier_prob) * (1 - outlier_prob);int K = log(accept_prob) / log(sample_fail_prob);real a_res, b_res, c_res;real min_error = numeric_limits<real>::max();//cout << "K = " << K << endl;for (int k = 0; k < K; ++k) {Point2D p1, p2;while (p1 == p2) {p1 = pts[rand() % n];    // n maybe greater than 65535p2 = pts[rand() % n];}//cout << "p1 = " << p1.x << " " << p1.y << endl;//cout << "p2 = " << p2.x << " " << p2.y << endl;real a, b, c;a = p1.y - p2.y;b = p2.x - p1.x;c = p1.x * p2.y - p1.y * p2.x;real t = sqrt(a * a + b * b);a /= t;b /= t;c /= t;//cout << a << " " << b << " " << c << endl;real error = 0.0;int inliers = 0;for (int i = 0; i < n; ++i) {real dis = fabs(a * pts[i].x + b * pts[i].y + c);if (dis < threshold) {++inliers;error += dis;}}//cout << "inliers = " << inliers << endl;//cout << "error = " << error << endl;if (static_cast<real>(inliers) / static_cast<real>(n) > 0.7) {if (error < min_error) {min_error = error;a_res = a;b_res = b;c_res = c;}}}return vector<real>{ a_res, b_res, c_res };}
};int main() {int n;cin >> n;vector<Point2D> pts(n);for (int i = 0; i < n; ++i)cin >> pts[i].x >> pts[i].y;srand((unsigned)time(nullptr));auto params = Solution().ransaclr(pts, 0.1, 1e-4, 10.0);cout << params[0] << " " << params[1] << " " << params[2] << endl;return 0;
}

 

 

 

3. 反思与总结

上述代码是商汤科技2018年的笔试题,答案来自牛客网上的标准答案,但是!!!

1------------------

 用 w表示每次从数据集中选取一个局内点的概率,如下式所示:w = 局内点的数目 / 数据集的数目
通常情况下,我们事先并不知道w的值,但是可以给出一些鲁棒的值。假设估计模型需要选定n个点,w^n是所有n个点均为局内点的概率;1 − wn是n个点中至少有一个点为局外点的概率,此时表明我们从数据集中估计出了一个不好的模型。 (1 − wn)k表示算法永远都不会选择到n个点均为局内点的概率,它和1-p相同。    1 − p = (1 − w^n)^k

            

这道题中,用来计算参数模型的点为两个,n = 2,点是内点的概率为0.9,两个点都为内点的概率为0.9*0.9, 两个点中至少有一个为外点的概率为 1 - w^n = 1 - 0.9*0.9 ,这是k的计算表达中的分母。p为算法K次迭代后接受的概率,1 - p就是不接受的概率(k次迭代中每次随机选择都有外点),这是分子,此处可以看出代码中的函数名有误。

或一种说法: 其中,p为置信度,一般取0.995;w为"内点"的比例 ; n为计算模型所需要的最少样本数。

 

2---------------------

如果你真的结合RANSAC思想和代码来比对,会发现有BUG。 请注意第一部分中的那两句紫色的话

RANSAC通过反复选择数据中的一组随机子集来达成目标。被选取的子集被假设为局内点,并用下述方法进行验证:
1.有一个模型适应于假设的局内点,即所有的未知参数都能从假设的局内点计算得出。
2.用1中得到的模型去测试所有的其它数据,如果某个点适用于估计的模型,认为它也是局内点。
3.如果有足够多的点被归类为假设的局内点,那么估计的模型就足够合理。
4.然后,用所有假设的局内点去重新估计模型,因为它仅仅被初始的假设局内点估计过。
5.最后,通过估计局内点与模型的错误率来评估模型。

代码中首先判断

static_cast<real>(inliers) / static_cast<real>(n) > 0.7

也就是说内点足够多,比例大于0.7,说明模型合理。

然后我们需要用所有的内点重新估计模型,比如说我们可以用最小二乘法,根据这些内点线性拟合更新abc参数的值。 接下来评估模型好坏。

然而,我们在衡量模型的好坏(评估模型)的时候,不是用内点数量(有时候情况会用内点数量来衡量)来看,也不是用所有点来评估模型,而是用此时所有的内点来评估。也就是说,这道题中min_error应该使用所有的内点来计算,而不是代码中所有的点。


http://chatgpt.dhexx.cn/article/0nxmmVyv.shtml

相关文章

利用RANSAC算法筛选SIFT特征匹配

关于RANSAC算法的基本思想&#xff0c;可从网上搜索找到&#xff0c;这里只是RANSAC用于SIFT特征匹配筛选时的一些说明。 RANSAC算法在SIFT特征筛选中的主要流程是&#xff1a; (1) 从样本集中随机抽选一个RANSAC样本&#xff0c;即4个匹配点对 (2) 根据这4个匹配点对计算变…

Ransac算法学习python版

初学小白,注释的代码比较详细 import numpy as np import scipy as sp import scipy.linalg as sldef ransac(data, model, n, k, t, d, debug False, return_all False):"""参考:http://scipy.github.io/old-wiki/pages/Cookbook/RANSAC伪代码:http://en.wi…

RANSAC算法实现 + 直线拟合

一、RANSAC算法 1.参考资料 [1]题目来源与解析&#xff1a;商汤科技SLAM算法岗的RANSAC编程题 [2]牛客网题目&#xff1a;[编程题]线性回归 [3]牛客网解答参考&#xff1a;商汤科技某算法岗的编程题有点过分了啊 [4]RANSAC算法原理&#xff1a;RANSAC翻译、经典RANSAC以及…

精匹配——Opencv实现RANSAC算法进行误匹配对剔除,并和最小二乘法对比

精匹配——RANSAC算法思想及优缺点 目录 精匹配——RANSAC算法思想及优缺点前言一、RANSAC简介二、RANSAC基本思想1.步骤2.迭代次数的公式3.举例&#xff08;拟合直线&#xff0c;拟合最佳单应性矩阵&#xff09; 三、最小二乘法1、最小二乘法的主要思想2、最小二乘解3、仿射变…

ransca算法详细介绍

1、算法概述&#xff1a; RANSAC算法的基本假设是样本中包含正确数据(inliers&#xff0c;可以被模型描述的数据)&#xff0c;也包含异常数据(outliers&#xff0c;偏离正常范围很远、无法适应数学模型的数据)&#xff0c;即数据集中含有噪声。这些异常数据可能是由于错误的测…

RANSAC 特征匹配算法解析

一、RANSAC特征匹配算法简介   RANSAC算法是RANdom SAmple Consensus的缩写&#xff0c;意为随机抽样一致。表面上的意思就是从匹配样本中随机取样&#xff0c;寻找一致的样本点。RANSAC算法是根据一组包含异常数据的样本数据集&#xff0c;计算出数据的数学模型参数&#x…

RANSAC算法(原理及代码实现+迭代次数参数自适应)

RANSAC算法 前言算法流程Python代码RANSAC算法迭代参数的自适应 前言 随机样本一致性 (RANSAC) 是一种迭代方法&#xff0c;用于从一组包含异常值的观察数据中估计数学模型的参数&#xff0c;此时异常值不会对估计值产生影响。简言之&#xff0c;RANSAC是一种滤除异常值的常用算…

RANSAC算法简介

文章目录 1 算法简介2 基本思想3 参数4 应用案例&#xff08;直线拟合&#xff09; 1 算法简介 RANSAC算法的基本假设是样本中包含正确数据(inliers&#xff0c;可以被模型描述的数据)&#xff0c;也包含异常数据(outlies&#xff0c;偏离正常范围很远、无法适应数学模型的数据…

关于RANSAC的理解

先说最小二乘。 ok&#xff0c;你手头有一堆数据&#xff0c;比如这些蓝点&#xff1a; 那么我们假设它符合一个直线模型&#xff1a;yaxb&#xff0c;用最小二乘就可以很容易求解出未知参数a和b。最小二乘大法确实好哇&#xff0c;毕竟高斯用它来估计谷神星的轨道&#xff08…

RANSAC基本原理

计算机视觉基本原理——RANSAC 1. RANSAC简介2. 基本思想3. 范例4. 迭代次数推导 Reference&#xff1a; 1.计算机视觉基本原理——RANSAC 1. RANSAC简介 RANSAC(RAndom SAmple Consensus,随机采样一致)算法是从一组含有“外点”(outliers)的数据中正确估计数学模型参数的迭代…

RANSAC算法的理解与使用

随机抽样一致算法(random sample consensus, RANSAC)&#xff0c;其实就是采用迭代的方法从一组包含离群的被观测数据中估算出数学模型的参数。(比如通过一群点拟合一条直线等) 基本假设 模型假设&#xff1a;事先知道真实数据满足的数学模型&#xff0c;不知道的只是模型的具…

【特征匹配】RANSAC算法原理与源码解析

转载请注明出处&#xff1a;http://blog.csdn.net/luoshixian099/article/details/50217655 勿在浮沙筑高台 随机抽样一致性&#xff08;RANSAC&#xff09;算法&#xff0c;可以在一组包含“外点”的数据集中&#xff0c;采用不断迭代的方法&#xff0c;寻找最优参数模型&…

RANSAC算法详解+Python实现

1.算法描述 RANSAC的基本假设是&#xff1a; &#xff08;1&#xff09;数据由“局内点”组成&#xff0c;例如&#xff1a;数据的分布可以用一些模型参数来解释&#xff1b; &#xff08;2&#xff09;“局外点”是不能适应该模型的数据&#xff1b; &#xff08;3&#xff0…

RANSAC算法与原理(一)

目录 算法介绍举例 算法的基本思想和流程算法的实现流程&#xff1a;迭代次数的推导算法的实现 python代码实现References 算法介绍 首先我们从Random sample consensus - Wikipedia上找到RANSAC原理的介绍。 RANSAC算法的中文名称是随机抽样一致算法(Random Sample Consenus…

RANSAC算法——看完保证你理解

目录 1 最小二乘算法的缺陷2 RANSAC算法2.1 原理2.2 实例2.3 参数 参考感谢阅读 RANSAC全程Random sample consensus&#xff0c;中文即“随机抽样一致算法”&#xff0c;该方法采用迭代的方式从一组包含离群&#xff08;outlier或者错误数据&#xff09;的被观测数据中估算出数…

RANSAC算法介绍

一、RANSAC介绍 随机抽样一致算法&#xff08;RANdom SAmple Consensus,RANSAC&#xff09;,采用迭代的方式从一组包含离群的被观测数据中估算出数学模型的参数。RANSAC算法假设数据中包含正确数据和异常数据&#xff08;或称为噪声&#xff09;。正确数据记为内点&#xff08;…

RANSAC算法讲解

RANSAC是“RANdom SAmple Consensus&#xff08;随机抽样一致&#xff09;”的缩写。它可以从一组包含“局外点”的观测数据集中&#xff0c;通过迭代方式估计数学模型的参数。它是一种不确定的算法——它有一定的概率得出一个合理的结果&#xff1b;为了提高概率必须提高迭代次…

RANSAC介绍(Matlab版直线拟合+平面拟合)

RANSAC介绍&#xff08;Matlab版直线拟合平面拟合&#xff09; 本人邮箱&#xff1a;sylvester0510163.com&#xff0c;欢迎交流讨论&#xff0c; 欢迎转载&#xff0c;转载请注明网址http://blog.csdn.net/u010128736/ 一、RANSAC介绍 随机抽样一致算法&#xff08;RANdom SA…

RANSAC算法(仅供学习使用)

1.定义 RANSAC&#xff08;Random Sample Consensus&#xff09;算法是一种基于随机采样的迭代算法&#xff0c;用于估计一个数学模型参数。它最初由Fischler和Bolles于1981年提出&#xff0c;主要用于计算机视觉和计算机图形学中的模型拟合和参数估计问题。 RANSAC算法的基本…

前端调试手机app

有时候应用在电脑网页端显示是正常的&#xff0c;但是一安装到手机上或者在手机浏览器上打开&#xff0c;就会显示各种问题问题。 在网上找了很长时间&#xff0c;最方便的就是利用在电脑上利用谷歌浏览器进行调试&#xff0c;输入网址chrome://inspect/#devices&#xff0c;进…