RANSAC初识

article/2025/9/7 18:06:33

RANSAC算法:随机抽样一致算法(random sample consensus,RANSAC)

一个简单的例子是从一组观测数据中找出合适的二维直线。假设观测数据中包含局内点和局外点,其中局内点近似的被直线所通过,而局外点远离于直线。简单的最小二乘法不能找到适应于局内点的直线,原因是最小二乘法尽量去适应包括局外点在内的所有点。相反,RANSAC能得出一个仅仅用局内点计算出模型,并且概率还足够高。但是,RANSAC并不能保证结果一定正确,为了保证算法有足够高的合理概率,我们必须小心的选择算法的参数。

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

下面用一张图来模拟一下数据拟合的过程。

与最小二乘法的区别:

RANSA通过多次迭代,计算一个模型包含的局内点,模型好坏的判别依据是:模型包含越多的局内点,则这个模型越好。

而最小二乘法则是计算出一条直线,让所有的样本距离这条直线的距离最短。所以判别模型的标准就是样本距离直线的距离和。

优缺点:

RANSAC 算法的优点是能鲁棒的估计模型参数。例如,他能从包含大量局外点的数据集中估计出高精度的参数。

缺点是它计算参数的迭代次数没有上限,如果设置迭代次数的上限,得到的结果可能不是最优的结果,甚至可能得到错误的结果。

RANSAC只有一定的概率得到的可信的模型,概率与迭代次数成正比。另一个缺点是它要求设置跟问题相关的阈值,

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

输入: 
data —— 一组观测数据 
model —— 适应于数据的模型 
n —— 适用于模型的最少数据个数 
k —— 算法的迭代次数 
t —— 用于决定数据是否适应于模型的阀值 
d —— 判定模型是否适用于数据集的数据数目 
输出: 
best_model —— 跟数据最匹配的模型参数(如果没有找到好的模型,返回null) 
best_consensus_set —— 估计出模型的数据点 
best_error —— 跟数据相关的估计出的模型错误

附上一个可以实现的代码:

# -*- coding: utf-8 -*-
import numpy
import scipy  # use numpy if scipy unavailable
import scipy.linalg  # use numpy if scipy unavailable
import pylab
def ransac(data, model, n, k, t, d, debug=False, return_all=False):'''fit model parameters to data using the RANSAC algorithm
This implementation written from pseudocode found at
Given:data - a set of observed data points # 可观测数据点集model - a model that can be fitted to data points #n - the minimum number of data values required to fit the model # 拟合模型所需的最小数据点数目k - the maximum number of iterations allowed in the algorithm # 最大允许迭代次数t - a threshold value for determining when a data point fits a model #确认某一数据点是否符合模型的阈值d - the number of close data values required to assert that a model fits well to data
Return:bestfit - model parameters which best fit the data (or nil if no good model is found)'''iterations = 0bestfit = Nonebesterr = numpy.infbest_inlier_idxs = Nonewhile iterations < k:maybe_idxs, test_idxs = random_partition(n, data.shape[0])maybeinliers = data[maybe_idxs, :]test_points = data[test_idxs]maybemodel = model.fit(maybeinliers)test_err = model.get_error(test_points, maybemodel)also_idxs = test_idxs[test_err < t]  # select indices of rows with accepted pointsalsoinliers = data[also_idxs, :]if debug:print'test_err.min()', test_err.min()print'test_err.max()', test_err.max()print'numpy.mean(test_err)', numpy.mean(test_err)print'iteration %d:len(alsoinliers) = %d' % (iterations, len(alsoinliers))if len(alsoinliers) > d:betterdata = numpy.concatenate((maybeinliers, alsoinliers))bettermodel = model.fit(betterdata)better_errs = model.get_error(betterdata, bettermodel)thiserr = numpy.mean(better_errs)if thiserr < besterr:bestfit = bettermodelbesterr = thiserrbest_inlier_idxs = numpy.concatenate((maybe_idxs, also_idxs))iterations += 1if bestfit is None:raise ValueError("did not meet fit acceptance criteria")if return_all:return bestfit, {'inliers': best_inlier_idxs}else:return bestfitdef random_partition(n, n_data):#返回n行数据all_idxs = numpy.arange(n_data)numpy.random.shuffle(all_idxs)idxs1 = all_idxs[:n]idxs2 = all_idxs[n:]return idxs1, idxs2#线性系统可以使用最小二乘法求解,这个类是定义最小二乘法求解的一个示例
class LinearLeastSquaresModel:def __init__(self, input_columns, output_columns, debug=False):self.input_columns = input_columnsself.output_columns = output_columnsself.debug = debugdef fit(self, data):A = numpy.vstack([data[:, i] for i in self.input_columns]).TB = numpy.vstack([data[:, i] for i in self.output_columns]).Tx, resids, rank, s = scipy.linalg.lstsq(A, B)return xdef get_error(self, data, model):A = numpy.vstack([data[:, i] for i in self.input_columns]).TB = numpy.vstack([data[:, i] for i in self.output_columns]).TB_fit = scipy.dot(A, model)err_per_point = numpy.sum((B - B_fit) ** 2, axis=1)  # sum squared error per rowreturn err_per_pointdef test():#创建一些数据(局内点)使其在一条直线附近n_samples = 500n_inputs = 1n_outputs = 1A_exact = 20 * numpy.random.random((n_samples, n_inputs))  # x坐标perfect_fit = 60 * numpy.random.normal(size=(n_inputs, n_outputs))  # the model(斜率)B_exact = scipy.dot(A_exact, perfect_fit)  # y坐标#验证y坐标数组的大小,在数组计算中尺寸大小很重要,如果尺寸大小不匹配,则导致计算错误,或者无法计算assert B_exact.shape == (n_samples, n_outputs)#pylab.plot( A_exact, B_exact, 'b.', label='data' ) #这两行是图片显示创建出来的数据,不含噪声的数据#pylab.show()#添加一点点高斯噪声(仅用最小二乘的方法即可很好的去解决小噪声的线性回归问题)A_noisy = A_exact + numpy.random.normal(size=A_exact.shape)  # x坐标添加高斯噪声B_noisy = B_exact + numpy.random.normal(size=B_exact.shape)  # y坐标....#pylab.plot( A_noisy, B_noisy, 'b.', label='data')  #这两句是图片显示带有噪声的数据。#pylab.show()#添加局外点,对模型进行干扰n_outliers = 100  # 500个数据点有100个是putliersall_idxs = numpy.arange(A_noisy.shape[0])numpy.random.shuffle(all_idxs)  # 索引随机排列outlier_idxs = all_idxs[:n_outliers]  # 选取all_idxs前100个做outlier_idxsnon_outlier_idxs = all_idxs[n_outliers:]  # 后面的不是outlier_idxsA_noisy[outlier_idxs] = 20 * numpy.random.random((n_outliers, n_inputs))  # 外点的横坐标B_noisy[outlier_idxs] = 50 * numpy.random.normal(size=(n_outliers, n_outputs))  # 外点的纵坐标pylab.plot( A_noisy, B_noisy, 'b.', label='data' )pylab.show()#建立模型all_data = numpy.hstack((A_noisy, B_noisy))  # 组成坐标对input_columns = range(n_inputs)  # the first columns of the arrayoutput_columns = [n_inputs + i for i in range(n_outputs)]  # the last columns of the arraydebug = Falsemodel = LinearLeastSquaresModel(input_columns, output_columns, debug=debug)linear_fit, resids, rank, s = scipy.linalg.lstsq(all_data[:, input_columns],all_data[:, output_columns])#使用RANSAC算法ransac_fit, ransac_data = ransac(all_data, model,50, 1000, 7000, 300,  # misc. parametersdebug=debug, return_all=True)sort_idxs = numpy.argsort(A_exact[:, 0])  # 对A_exact排序, sort_idxs为排序索引A_col0_sorted = A_exact[sort_idxs]  # maintain as rank-2 arraypylab.plot(A_noisy[:, 0], B_noisy[:, 0], 'k.', label='data')pylab.plot(A_noisy[ransac_data['inliers'], 0], B_noisy[ransac_data['inliers'], 0], 'bx',label='RANSAC data')pylab.plot(A_col0_sorted[:, 0],numpy.dot(A_col0_sorted, ransac_fit)[:, 0] ,label='RANSAC fit')pylab.plot(A_col0_sorted[:, 0],numpy.dot(A_col0_sorted, perfect_fit)[:, 0],label='exact system')pylab.plot(A_col0_sorted[:, 0],numpy.dot(A_col0_sorted, linear_fit)[:, 0] ,label='linear fit')pylab.legend()pylab.show()
#运行主函数
if __name__ == '__main__':test()

这是我自己创建的数据,数据点多的那一大块是我创建的局内点,下面那一小排是我创建的局外点。

实验结果如下图所示:

应用:

RANSAC可以实现特征点检测,通过特征点匹配去辨识人脸。达到一个人脸识别的效果。

同样,通过特征点匹配也可以对多张图进行一个图像融合,比如全景照片的拍摄,用的就是图像融合技术。

 

参考博客:https://blog.csdn.net/laobai1015/article/details/51682596

https://blog.csdn.net/robinhjwy/article/details/79174914

https://blog.csdn.net/fandq1223/article/details/53175964

 


http://chatgpt.dhexx.cn/article/7LrgXAvw.shtml

相关文章

RANSAC算法详解

RANSAC算法详解 给定两个点p1与p2的坐标&#xff0c;确定这两点所构成的直线&#xff0c;要求对于输入的任意点p3&#xff0c;都可以判断它是否在该直线上。初中解析几何知识告诉我们&#xff0c;判断一个点在直线上&#xff0c;只需其与直线上任意两点点斜率都相同即可。实际…

Ransac拟合椭圆

一、Ransac算法介绍 RANSAC(RAndom SAmple Consensus,随机采样一致)最早是由Fischler和Bolles在SRI上提出用来解决LDP(Location Determination Proble)问题的&#xff0c;该算法是从一组含有“外点”(outliers)的数据中正确估计数学模型参数的迭代算法。“外点”一般指的的数据…

RANSAC算法

算法基本思想和流程 RANSAC是通过反复选择数据集去估计出模型&#xff0c;一直迭代到估计出认为比较好的模型。 具体的实现步骤可以分为以下几步&#xff1a; 选择出可以估计出模型的最小数据集&#xff1b;(对于直线拟合来说就是两个点&#xff0c;对于计算Homography矩阵就…

RANSAC迭代估计

RANSAC迭代估计 1. 定义2. 功能3. 流程4. 迭代次数推导5. 实现直线拟合 1. 定义 根据一组包含异常数据的样本数据集&#xff0c;计算出数据的数学模型参数&#xff0c;得到有效样本数据的算法 从一组含有“外点”(outliers)的数据中正确估计数学模型参数的迭代算法 “外点”一…

RANSAC

转自&#xff1a;http://www.cnblogs.com/xrwang/archive/2011/03/09/ransac-1.html 作者&#xff1a;王先荣 本文翻译自维基百科&#xff0c;英文原文地址是&#xff1a;http://en.wikipedia.org/wiki/ransac&#xff0c;如果您英语不错&#xff0c;建议您直接查看原文。 …

机器视觉:ransac算法详解

目录 一、说明&#xff1a; 二、算法步骤 三、算法代码 四、其它补充 一、说明&#xff1a; RANSAC是一种常用的参数估计方法&#xff0c;全称为Random Sample Consensus&#xff08;随机抽样一致性&#xff09;。它通过随机选择数据中的一部分&#xff0c;然后根据这些数据…

RANSAC算法介绍与总结

RANSAC算法 简介RANSAC地面分割 简介 粒子分割主要使用RANSAC算法. RANSAC全称Random Sample Consensus, 即随机样本一致性, 是一种检测数据中异常值的方法. RANSAC通过多次迭代, 返回最佳的模型. 每次迭代随机选取数据的一个子集, 并生成一个模型拟合这个子样本, 例如一条直线…

RANSAC算法原理

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

RANSAC算法理解

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

RANSAC算法(附RANSAC直线拟合C++与Python版本)

文章目录 RANSAC算法简介RANSAC算法基本思想和流程迭代次数推导RANSAC与最小二乘区别RANSAC直线拟合代码&#xff08;C及Python版本&#xff09;C版本代码Python版本代码如下&#xff1a; RANSAC优缺点参考 RANSAC算法简介 RANSAC(RANdom SAmple Consensus,随机采样一致)算法是…

php 枚举类代替hard code代码

新建OrderEnum枚举类 在控制器调用

ERP text object hard code

Created by Wang, Jerry, last modified on Sep 28, 2016 要获取更多Jerry的原创文章&#xff0c;请关注公众号"汪子熙":

Do not hardcode /data/; use Context.getFilesDir().getPath() instead 解决方法

在Android项目中如果使用字符串路径会提示 Do not hardcode "/data/"; use Context.getFilesDir().getPath() instead&#xff0c;如图所示 原因是因为硬编码不是对任何设备都适合&#xff0c;在一些设备上可能会给出错误消息或无法正常工作。可以做如下替换。 Stri…

Drool7s 什么叫KIE和生命周期-系列03课

KIE是缩写&#xff0c;knowledge is everything。可以理解成一个上层接口&#xff0c;本质是由很多个实现类去实现功能的。 另外关于drool7s的生命周期&#xff0c;请看下图 本文只是让你了解drools7的一些概念&#xff0c;也是开始实践的基础。如果不了解这些知识的话&#xf…

drool 7.x 属性 : agenda-group

Agenda Group 是用来在Agenda 的基础之上,对现在的规则进行再次分组,具体的分组方法可以采用为规则添加agenda-group 属性来实现。 agenda-group 属性的值也是一个字符串,通过这个字符串,可以将规则分为若干个Agenda Group,默认情况下,引擎在调用这些设置了agenda-group …

drools视频教程(drool实战实例+数据库+视频讲解)

特别说明&#xff1a;此教程适用任何版本的drools&#xff0c;因为编程思想是不变的 drools的资料网上也有不少&#xff0c;但是大都是讲基础的&#xff0c;几乎没有讲在项目中到底怎么用的&#xff0c;小哥当时学的时候也是&#xff0c;网上看了很多文档&#xff0c;但是还是不…

Drool实战系列(二)之eclipse安装drools插件

这里演示是drools7.5.0&#xff0c;大家可以根据自己需要安装不同的drools版本 drools安装地址: http://download.jboss.org/drools/release/ 一、 二、点击进入7.6.0.Final,并选择droolsjbpm-tools-distribution-XXX.zip(XXX为版本号)进行下载 三、将下载完的插件解压到本地 启…

drool 7.x 属性 : lock-on-active

lock-on-active true&#xff1a;通过这个标签&#xff0c;可以控制当前的规则只会被执行一次&#xff0c;因为一个规则的重复执行不一定是本身触发的&#xff0c;也可能是其他规则触发的&#xff0c;所以这个是no-loop的加强版。当然该标签正规的用法会有其他的标签的配合&…

Drool7s kmodule的作用--系列02课

本文是介绍drool7s kmodule。 一、为什么komdule.xml文件一定要放在resources下的META-INF文件夹中 ---》直接看源码吧&#xff0c;请看下图&#xff0c;应该都知道为什么要放在固定文件夹下。 二、下面是一些知识点&#xff0c;需要大家记住的 kmodule中可以包含一个或多个…