RANSAC算法

  • 前言
  • 算法流程
  • Python代码
  • RANSAC算法迭代参数的自适应

前言

  随机样本一致性 (RANSAC) 是一种迭代方法,用于从一组包含异常值的观察数据中估计数学模型的参数,此时异常值不会对估计值产生影响。简言之,RANSAC是一种滤除异常值的常用算法。

算法流程

  以直线拟合为例,通用RANSAC算法的流程如下

输入:data – 观测结果.model – 数学模型.n – 估计模型所需的最小样本.k – 最大迭代次数.t – 用于确定模型适合的数据点的阈值.输出:bestFit – 模型iterations = 0
bestFit = null
bestErr = something really largewhile iterations < k domaybeInliers := n randomly selected values from datamaybeModel := model parameters fitted to maybeInliersalsoInliers := empty setfor every point in data not in maybeInliers doif point fits maybeModel with an error smaller than tadd point to alsoInliersend ifend forif the number of elements in alsoInliers is > d thenbetterModel := model parameters fitted to all points in maybeInliers and alsoInliersthisErr := a measure of how well betterModel fits these pointsif thisErr < bestErr thenbestFit := betterModelbestErr := thisErrend ifend ifincrement iterations
end whilereturn bestFit

Python代码

"""_summary_
RANSAC直线拟合
"""
from copy import copy
import numpy as np
from numpy.random import default_rng
rng = default_rng()class RANSAC:def __init__(self, n=10, k=100, t=0.05, d=10, model=None, loss=None, metric=None):self.n = n              self.k = k              self.t = t              self.d = d              self.model = model     self.loss = loss        self.metric = metric  self.best_fit = Noneself.best_error = np.infdef fit(self, X, y):for _ in range(self.k):ids = rng.permutation(X.shape[0])maybe_inliers = ids[: self.n]maybe_model = copy(self.model).fit(X[maybe_inliers], y[maybe_inliers])thresholded = (self.loss(y[ids][self.n :], maybe_model.predict(X[ids][self.n :]))< self.t)inlier_ids = ids[self.n :][np.flatnonzero(thresholded).flatten()]if inlier_ids.size > self.d:inlier_points = np.hstack([maybe_inliers, inlier_ids])better_model = copy(self.model).fit(X[inlier_points], y[inlier_points])this_error = self.metric(y[inlier_points], better_model.predict(X[inlier_points]))if this_error < self.best_error:self.best_error = this_errorself.best_fit = maybe_modelreturn selfdef predict(self, X):return self.best_fit.predict(X)def square_error_loss(y_true, y_pred):return (y_true - y_pred) ** 2def mean_square_error(y_true, y_pred):return np.sum(square_error_loss(y_true, y_pred)) / y_true.shape[0]class LinearRegressor:def __init__(self):self.params = Nonedef fit(self, X: np.ndarray, y: np.ndarray):r, _ = X.shapeX = np.hstack([np.ones((r, 1)), X])self.params = np.linalg.inv(X.T @ X) @ X.T @ yreturn selfdef predict(self, X: np.ndarray):r, _ = X.shapeX = np.hstack([np.ones((r, 1)), X])return X @ self.paramsif __name__ == "__main__":regressor = RANSAC(model=LinearRegressor(), loss=square_error_loss, metric=mean_square_error)X = np.array([-0.848,-0.800,-0.704,-0.632,-0.488,-0.472,-0.368,-0.336,-0.280,-0.200,-0.00800,-0.0840,0.0240,0.100,0.124,0.148,0.232,0.236,0.324,0.356,0.368,0.440,0.512,0.548,0.660,0.640,0.712,0.752,0.776,0.880,0.920,0.944,-0.108,-0.168,-0.720,-0.784,-0.224,-0.604,-0.740,-0.0440,0.388,-0.0200,0.752,0.416,-0.0800,-0.348,0.988,0.776,0.680,0.880,-0.816,-0.424,-0.932,0.272,-0.556,-0.568,-0.600,-0.716,-0.796,-0.880,-0.972,-0.916,0.816,0.892,0.956,0.980,0.988,0.992,0.00400]).reshape(-1,1)y = np.array([-0.917,-0.833,-0.801,-0.665,-0.605,-0.545,-0.509,-0.433,-0.397,-0.281,-0.205,-0.169,-0.0531,-0.0651,0.0349,0.0829,0.0589,0.175,0.179,0.191,0.259,0.287,0.359,0.395,0.483,0.539,0.543,0.603,0.667,0.679,0.751,0.803,-0.265,-0.341,0.111,-0.113,0.547,0.791,0.551,0.347,0.975,0.943,-0.249,-0.769,-0.625,-0.861,-0.749,-0.945,-0.493,0.163,-0.469,0.0669,0.891,0.623,-0.609,-0.677,-0.721,-0.745,-0.885,-0.897,-0.969,-0.949,0.707,0.783,0.859,0.979,0.811,0.891,-0.137]).reshape(-1,1)regressor.fit(X, y)import matplotlib.pyplot as pltplt.style.use("seaborn-darkgrid")fig, ax = plt.subplots(1, 1)# 支持中文plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号plt.scatter(X, y)plt.title("RANSAC拟合直线")line = np.linspace(-1, 1, num=100).reshape(-1, 1)plt.plot(line, regressor.predict(line), c="peru")plt.show()

RANSAC算法迭代参数的自适应

  上面提到的RANSAC算法总要迭代足够的次数才能终止,这就留给设计者一个难题,迭代次数少了,找不到最优解,迭代次数多了,程序耗时增加。接下来给读者介绍一种自适应的迭代次数的方法。
  当错误点所占比例较小时,则应该尽快停止迭代;反之,则需要足够的迭代次数再终止算法以获取更可靠的结果。
  令 p:p:p: :RANSAC 算法在运行后提供至少一个有用结果的期望概率。
  令w:w:w: 满足模型的点 / 检测到的所有点
  令n:n:n:满足当前模型的点的个数
  则1−p=(1−wn)k1-p = (1-{w}^n)^k1−p=(1−wn)k
  即k=log(1−p)log(1−wn)k = \frac{log(1-p)}{log(1-w^{n})}k=log(1−wn)log(1−p)​
  代码实现过程如下

// 以下代码来自OpenCV
/*** @Method:    更新ransac的迭代次数* @Returns:   int 更新后的最大迭代次数* @Qualifier: * @Parameter: double p 信心分数* @Parameter: double ep 错误点所占的比例* @Parameter: int modelPoints 模型中点的数量* @Parameter: int maxIters 当前最大迭代次数*/
int RANSACUpdateNumIters( double p, double ep, int modelPoints, int maxIters )
{if( modelPoints <= 0 )CV_Error( Error::StsOutOfRange, "the number of model points should be positive" );p = MAX(p, 0.);p = MIN(p, 1.);ep = MAX(ep, 0.);ep = MIN(ep, 1.);// avoid inf's & nan'sdouble num = MAX(1. - p, DBL_MIN);double denom = 1. - std::pow(1. - ep, modelPoints);if( denom < DBL_MIN )return 0;num = std::log(num);denom = std::log(denom);return denom >= 0 || -num >= maxIters*(-denom) ? maxIters : cvRound(num/denom);
}

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

  1. 多类线性分类器算法原理及代码实现 MATLAB

    多类线性分类器算法原理及代码实现 MATLAB 一.算法原理 下面举例说明为何蓝圈部分在case2中是确定的而在case1中不确定: 二.代码实现 1.HK函数 function [] = HK(w1 ...

  2. 【MATLAB】混合粒子群算法原理、代码及详解

    目录 1.算法 1.1.原理 1.2.性能比较 1.3.步骤 2.代码 2.1.源码及注释 2.2.执行与效果 1.算法 1.1.原理 \qquad建议没接触过粒子群算法的朋友先看较为基础的全局粒子群 ...

  3. HoughCircle(霍夫圆)算法原理及代码实现

      此算法建立在Canny算法的基础上,对Canny算法检测出的边缘图像进行拟合,因此要用到Canny算法返回的边缘图像及梯度方向矩阵.Canny算法相关内容详见上一篇博客:Canny边缘检测算法原理 ...

  4. 深度强化学习-Double DQN算法原理与代码

    深度强化学习-Double DQN算法原理与代码 引言 1 DDQN算法简介 2 DDQN算法原理 3 DDQN算法伪代码 4 仿真验证 引言 Double Deep Q Network(DDQN)是 ...

  5. 【MATLAB】Parzen窗与K近邻算法原理与代码详解

    文章目录 1.非参数估计原理 2.Parzen窗 2.1.算法原理 2.2.Matlab实现与参数探究 3.K近邻 3.1.算法原理 3.2.Matlab实现与参数探究 1.非参数估计原理 \qqua ...

  6. SSD算法原理与代码(三)

    说明:这几篇文章是讲解SSD,从算法原理.代码到部署到rk3588芯片上的过程.环境均是TF2.2,具体的安装过程请参考网上其他的文章. 一.SSD简介 SSD算法是一个优秀的one-stage目标检 ...

  7. 计算机图形学--中点椭圆算法原理及代码实现

    目录 椭圆的几何特性: 算法原理: 代码实现: 说明,我们这里讨论的椭圆都是对称轴平行于坐标轴的椭圆,对于其他方程较为复杂的椭圆我们不做讨论. 椭圆的几何特性: 首先我们考虑椭圆的几何特性.椭圆是抽对 ...

  8. 论文|Node2vec算法原理、代码实战和在微信朋友圈的应用

    1 概述 Node2vec是2016年斯坦福教授 Jure Leskovec.Aditya Grover提出的论文,论文的下载链接为:https://arxiv.org/pdf/1607.00653. ...

  9. 深度强化学习-D3QN算法原理与代码

    Dueling Double Deep Q Network(D3QN)算法结合了Double DQN和Dueling DQN算法的思想,进一步提升了算法的性能.如果对Doubel DQN和Duelin ...

  10. 萤火虫算法_40多种智能优化算法原理和代码分享

    40多种智能优化算法原理和代码分享 <智能优化算法讲解>PDF下载地址: <智能优化算法原理讲解>PDF​mianbaoduo.com 包括: 1.海鸥算法SOA 智能优化算法 ...

最新文章

  1. java9可执行jar_单个java文件打成可执行jar包
  2. CSS Sprites (CSS精灵)
  3. Linux服务器下运行SpringBoot HelloWorldDemo(Mac篇)
  4. pyqt5讲解12:自定义参数 (给信号传入参数)
  5. java同步通信方式_java多线程同步与通信示例(synchronized方式)
  6. python读取sqlserver数据库方法_SQLServer数据库之Python读取配置文件,并连接数据库SQL Server...
  7. 谈谈分布式事务(Distributed Transaction)[共5篇]
  8. 大学生开题报告php,php毕业设计开题报告
  9. c3p0 0.9.1.2 配套mysql_连接数据库,使用c3p0技术连接MySQL数据库
  10. Git之同一台电脑连接多个远程仓库
  11. iOS 实现长屏截图,scrollview,tableview截图
  12. ami编码设计流程图_AMI码型变换
  13. android 金山电池医生,金山电池医生3.0(android版).PDF
  14. 目标检测中PR曲线和mAP
  15. 免费网站流量统计服务汇总
  16. Mesos | 1.3.2 webui static 界面代码分析 ——app.js/relative-date.js
  17. 面试经历(纯属个人经历,仅供观看参考)
  18. 从其他地方复制过来的文字中间有空格怎么删除?
  19. 为什么我不建议你将python作为入门编程语言
  20. Hadoop三大框架之MapReduce工作流程

热门文章

  1. VS2019下cmake项目:利用ELAS方法计算双目视差
  2. java换行输出的几种方式
  3. Qt绘制中国地图轮廓边界
  4. IDEA中使用Maven命令失败解决办法
  5. 如何书写IT行业的个人简历
  6. 计算机考研408每日一题 day165
  7. AD16创建元器件库步骤
  8. Python爬虫——全网获取音乐
  9. nmap扫描服务器端口不稳定,端口扫描命令nmap
  10. springboot使用Log4j动态改变日志级别