RANSAC简介

RANSAC(RAndom SAmple Consensus,随机采样一致)算法是从一组含有“外点”(outliers)的数据中正确估计数学模型参数的迭代算法。“外点”一般指的的数据中的噪声,比如说匹配中的误匹配和估计曲线中的离群点。所以,RANSAC也是一种“外点”检测算法。RANSAC算法是一种不确定算法,它只能在一种概率下产生结果,并且这个概率会随着迭代次数的增加而加大(之后会解释为什么这个算法是这样的)。RANSAC算最早是由Fischler和Bolles在SRI上提出用来解决LDP(Location Determination Proble)问题的。

对于RANSAC算法来说一个基本的假设就是数据是由“内点”和“外点”组成的。“内点”就是组成模型参数的数据,“外点”就是不适合模型的数据。同时RANSAC假设:在给定一组含有少部分“内点”的数据,存在一个程序可以估计出符合“内点”的模型。

算法基本思想和流程

RANSAC是通过反复选择数据集去估计出模型,一直迭代到估计出认为比较好的模型。

具体的实现步骤可以分为以下几步:

1、选择出可以估计出模型的最小数据集;(对于直线拟合来说就是两个点,对于计算Homography矩阵就是4个点);

2、使用这个数据集来计算出数据模型;

3、将所有数据带入这个模型,计算出“内点”的数目;(累加在一定误差范围内的适合当前迭代推出模型的数据);

4、比较当前模型和之前推出的最好的模型的“内点“的数量,记录最大“内点”数的模型参数和“内点”数;

5、重复1-4步,直到迭代结束或者当前模型已经足够好了(“内点数目大于一定数量”)。

迭代次数推导

这里有一点就是迭代的次数我们应该选择多大呢?这个值是否可以事先知道应该设为多少呢?还是只能凭经验决定呢? 这个值其实是可以估算出来的。下面我们就来推算一下。

假设“内点”在数据中的占比为 :

那么我们每次计算模型使用 N 个点的情况下,选取的点至少有一个外点的情况就是:

也就是说,在迭代 k 次的情况下,  (1-tn)k就是 k 次迭代计算模型都至少采样到一个“外点”去计算模型的概率。那么能采样到正确的 N 个点去计算出正确模型的概率就是:

通过上式,可以求得:

“内点”的概率  通常是一个先验值。然后  是我们希望RANSAC得到正确模型的概率。如果事先不知道  的值,可以使用自适应迭代次数的方法。也就是一开始设定一个无穷大的迭代次数,然后每次更新模型参数估计的时候,用当前的“内点”比值当成  来估算出迭代次数。

用Python实现直线拟合:

#!/usr/bin/env python3
# coding: utf-8import math
import random
import numpy as np
import matplotlib.pyplot as plt# 数据量。
SIZE = 50# 产生数据。np.linspace 返回一个一维数组,SIZE指定数组长度。
# 数组最小值是0,最大值是10。所有元素间隔相等。
X = np.linspace(0, 10, SIZE)
Y = 3 * X + 10fig = plt.figure()
# 画图区域分成1行1列。选择第一块区域。
ax1 = fig.add_subplot(1, 1, 1)
# 标题
ax1.set_title("RANSAC")# 让散点图的数据更加随机并且添加一些噪声。
random_x = []
random_y = []
# 添加直线随机噪声
for i in range(SIZE):random_x.append(X[i] + random.uniform(-0.5, 0.5))random_y.append(Y[i] + random.uniform(-0.5, 0.5))
# 添加随机噪声
for i in range(SIZE):random_x.append(random.uniform(0, 10))random_y.append(random.uniform(10, 40))
RANDOM_X = np.array(random_x)  # 散点图的横轴。
RANDOM_Y = np.array(random_y)  # 散点图的纵轴。# 画散点图。
ax1.scatter(RANDOM_X, RANDOM_Y)
# 横轴名称。
ax1.set_xlabel("x")
# 纵轴名称。
ax1.set_ylabel("y")# 使用RANSAC算法估算模型
# 迭代最大次数,每次得到更好的估计会优化iters的数值
iters = 100000
# 数据和模型之间可接受的差值
sigma = 0.25
# 最好模型的参数估计和内点数目
best_a = 0
best_b = 0
pretotal = 0
# 希望的得到正确模型的概率
P = 0.99
for i in range(iters):# 随机在数据中红选出两个点去求解模型sample_index = random.sample(range(SIZE * 2), 2)x_1 = RANDOM_X[sample_index[0]]x_2 = RANDOM_X[sample_index[1]]y_1 = RANDOM_Y[sample_index[0]]y_2 = RANDOM_Y[sample_index[1]]# y = ax + b 求解出a,ba = (y_2 - y_1) / (x_2 - x_1)b = y_1 - a * x_1# 算出内点数目total_inlier = 0for index in range(SIZE * 2):y_estimate = a * RANDOM_X[index] + bif abs(y_estimate - RANDOM_Y[index]) < sigma:total_inlier = total_inlier + 1# 判断当前的模型是否比之前估算的模型好if total_inlier > pretotal:iters = math.log(1 - P) / math.log(1 - pow(total_inlier / (SIZE * 2), 2))pretotal = total_inlierbest_a = abest_b = b# 判断是否当前模型已经符合超过一半的点if total_inlier > SIZE:break# 用我们得到的最佳估计画图
Y = best_a * RANDOM_X + best_b# 直线图
ax1.plot(RANDOM_X, Y)
text = "best_a = " + str(best_a) + "\nbest_b = " + str(best_b)
plt.text(5, 10, text,fontdict={'size': 8, 'color': 'r'})
plt.show()

结果:

原文链接:

1、RANSAC算法详解(附Python拟合直线模型代码)

RANSAC算法详解(附Python拟合直线模型代码) - 知乎

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

RANSAC算法(附RANSAC直线拟合C++与Python版本)_Nick Blog的博客-CSDN博客_ransac拟合直线

ransac直线段拟合相关推荐

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

    文章目录 RANSAC算法简介 RANSAC算法基本思想和流程 迭代次数推导 RANSAC与最小二乘区别 RANSAC直线拟合代码(C++及Python版本) C++版本代码 Python版本代码如下 ...

  2. RANSAC 直线拟合

    result: code: #include "stdafx.h". #include <opencv2\opencv.hpp> #include <iostre ...

  3. RANSAC 直线拟合算法

    1. 参考文献 RANSAC 直线拟合算法 2. 算法实现 #include <iostream> #include <random> #include <vector& ...

  4. RANSAC直线拟合和最小二乘直线拟合的简单介绍

           RANSAC是"RANdom SAmple Consensus(随机抽样一致)"的缩写.它可以从一组包含"局外点"的观测数据集中,通过迭代方式估计 ...

  5. 直线段检测算法---LSD

    直线段检测算法---LSD:a Line Segment Detector LSD的核心是像素合并于误差控制.利用合并像素来检测直线段并不是什么新鲜的方法,但是合并像素的方法通常运算量较大.LSD号称 ...

  6. 计算机图形学直线扫描转论文,计算机图形学实验报告-实验1直线段扫描转换.doc...

    PAGE 32 PAGE 7 计算机图形学 实验报告 班级 计算机工硕班 学号 2011220456 姓名 王泽晶 实验一:直线段扫描转换 实验目的 通过本次试验,学生可以掌握直线段的扫描转换算法及其 ...

  7. 直线段检测算法(LSD:a Line Segment Detector)

    直线段检测算法(LSD:a Line Segment Detector) 1 简介 LSD是一种线段检测算法,该方法能在较短的时间内获得较高精度的直线段检测结果. LSD直线检测算法首先计算图像中所有 ...

  8. 【转】 LSD(Line Segment Detector) 直线段检测算法学习~

    论文回顾之一 一种新的直线段检测算法---LSD:a Line Segment Detector 原文地址:http://blog.csdn.net/polly_yang/article/detail ...

  9. 带你读AI论文:基于Transformer的直线段检测

    摘要:本文提出了一种基于Transformer的端到端的线段检测模型.采用多尺度的Encoder/Decoder算法,可以得到比较准确的线端点坐标.作者直接用预测的线段端点和Ground truth的 ...

最新文章

  1. 53个Python库,你必须要试试
  2. Linux下的USB总线驱动(04)——USB键盘驱动 usbkbd.c
  3. artDiaLog弹出插件
  4. 信息学奥赛一本通 1165:Hermite多项式
  5. 5句话搞定ES5作用域
  6. 事业编,还有前途可谈么?
  7. rman异机恢复数据库
  8. Linux下多线程查看工具(pstree、ps、pstack),linux命令之-pstree使用说明, linux 查看线程状态。 不指定...
  9. 视频教程-MATLAB高等数学计算与可视化-Matlab
  10. 牛客练习赛41:球的体积并【球缺】
  11. 复合梯形公式matlab代码,复合梯形公式
  12. Python 批处理文件(全)
  13. 论如何使用Python进行微信公众号的开发
  14. idea 关于自动导包的设置
  15. 搭建redis的步骤
  16. ENVI计算NDVI
  17. 2021年全球与中国3D和虚拟现实行业市场规模及发展前景分析
  18. 测试人生 | 阿里实习 90 天:从实习生的视角谈谈个人成长
  19. Linux环境下银行家算法,银行家算法
  20. oracle中DDL语句什么意思,执行oracle DDL语句要注意的问题

热门文章

  1. TLE5012B_SPI通讯+零点矫正思路总结
  2. 剩米饭别再炒了,这样做比炒米饭好吃一万倍!
  3. Java:JSON解析工具-json-lib
  4. SAR-Scape处理SBAS-InSAR报错原因之一
  5. 硬件设计—JTAG链
  6. PBOC符号和缩略语记录
  7. python爬取抖音粉丝数据_爬取抖音粉丝数据1(作品、喜欢、ID 、关注) 完整源代码...
  8. 网页用户登录权限校验的两种实现方式
  9. java后台判断请求来自移动端访问还是PC端访问
  10. 2015年上半年系统集成项目管理工程师案例计算题精讲视频(乔俊峰)