上一篇我们介绍了标准 RANSAC。而在之后的四十多年里,围绕这一经典算法,又陆续出现了大量改进方法。
不同于 SIFT 在局部特征领域衍生出众多并行发展的分支,RANSAC 的演进路线更加清晰:研究者们针对算法内部的不同环节不断提出改进,最终由 USAC(Universal RANSAC) 将这些成熟的方法整合到同一个统一框架中。
这一过程有些类似于我们之前在 DL 中优化算法部分从 SGD 不断演进到 Adam 的思路:在原有框架上持续优化各个组成部分,最终形成工程实践中的默认选择。
而在误匹配剔除这一环节,USAC 已经成为现代计算机视觉中最主流的通用 RANSAC 框架,被 OpenCV 等主流视觉库默认采用。
这里提前说明一点:USAC 的原论文在 12 年发表,但其中组件也在不断更新,本文介绍的是 OpenCV 的现代 USAC 管道,因此出现年份更新的论文和技术是正常的。
1. RANSAC 的局限
还是老样子,标准 RANSAC 仍然存在一些明显的局限:
| 问题 | 影响 |
|---|---|
| 随机采样完全"盲目",对所有匹配点一视同仁 | 浪费大量迭代在低质量匹配上 |
| 内点判定使用固定硬阈值 | 无法适应不同场景的噪声分布 |
| 只选"最多内点"的模型,不区分模型好坏 | 对低内点率场景不够鲁棒 |
| 没有局部优化步骤 | 最终模型精度有限 |
| 超参数需要人工设定 | 实际使用不够自适应 |
基于这些局限,在 RANSAC 提出后的四十多年里,大量研究工作开始围绕这些问题不断改进。
但就 RANSAC 本身而言,它的使命非常明确:从包含噪声的数据中稳健地估计正确的几何模型。
由此,它的改进也始终围绕一个核心问题展开:
如何更快、更准、更鲁棒地从误匹配中找到正确的单应性矩阵?
由此,我们从 USAC 的各个组件开始介绍,最终组成完整的 USAC 框架。
2. PROSAC:有优先级的采样
基本的退化检测就不再展开了,不同模型的内容并不相同,但思想都是一样的。
首先,标准 RANSAC 的一个突出问题在于采样的盲目性 。在 SIFT 匹配之后,我们已经拿到了描述子距离,靠近的描述子往往更可能是正确的匹配。但标准 RANSAC 在随机采样时完全忽略了这些信息,对每一对匹配点一视同仁。
改进想法由此而生:
能否利用匹配质量信息,优先选择那些"看起来就更可靠"的匹配点来采样?
05 年,论文 Matching with PROSAC -- Progressive Sample Consensus 提出的 PROSAC(Progressive Sample Consensus) 便是针对这一问题的著名改进。
它的核心思路相当直观:
既然我们有 SIFT 匹配时的距离信息(比率测试的结果),为什么不优先从那些距离最近、质量最高的匹配点中采样?
其针对采样环节的具体优化是这样的:
- 排序: 将所有匹配点按照 SIFT 描述子间的欧式距离从小到大排序。
- 渐进采样: 初始时,只从前 \(k\) 个质量最高的匹配点中随机采样;随着迭代次数增加,逐渐扩大 \(k\) 值,将质量稍差的点也纳入采样范围。

这样,初期大部分采样都集中在高质量的匹配点上,早期就能快速找到正确的模型。
实验结果也表明,在相同置信度下,PROSAC 通常只需要标准 RANSAC 1/2 到 1/10 的迭代次数。
3. SPRT:快速模型验证
PROSAC 解决了采样效率低 的问题,下一个环节就是模型验证 。
标准 RANSAC 的验证过程较直接:
依次计算每个匹配点到当前模型的重投影误差,统计最终有多少属于内点。
假设共有 \(N\) 个匹配点,那么每生成一个候选模型,都需要完成 \(N\) 次误差计算,耗时较多。
而改进思路是这样的:
既然很多错误模型在验证初期就会暴露,为什么还要坚持验证所有匹配点?
同样是 05 年发表的论文 Randomized RANSAC with Sequential Probability Ratio Test 将统计学中的 SPRT(Sequential Probability Ratio Test) 引入 RANSAC,对这一阶段进行了优化。
它的核心思想是:边验证,边判断当前模型是否还有继续验证的必要。
具体来说,对于一个候选模型,SPRT 不再一次性验证全部匹配点,而是按照一定顺序逐个检查,其流程如下:
- 随机取一个匹配点,计算重投影误差并判断内外点。
- 根据当前累计得到的内点、外点情况,不断更新模型正确的概率。
- 如果统计结果表明该模型几乎不可能成为正确模型,则立即停止验证,直接进入下一次采样。
显然,算法的关键在于如何评估当前模型的正确率,其内容就是开始提到的 SPRT:
把模型验证看成一个统计假设检验问题,而不是简单地统计最终内点数。
对于每一个候选模型,SPRT 建立两个互斥假设:
- \(H_g\)(Good Model):当前模型是真正的好模型。
- \(H_b\)(Bad Model):当前模型只是随机产生的错误模型。
在此基础上维护一个似然比:
\\\Lambda = \\frac{P(\\text{当前所有观测}\|H_g)} {P(\\text{当前所有观测}\|H_b)} \\
显然,如果公式结果 \(\Lambda \gg 1\) ,那么这些数据更像是好模型产生的。
对于一个真正正确的模型,它产生内点的概率较高,因此定义:
\P(\\text{Inlier}\|H_g)=\\varepsilon \\
其中 \(\varepsilon\) 表示好模型的预期内点率 ,经验上可能取 \(\varepsilon=0.6\sim0.8\),说明一个正确模型大约有 60%~80% 的匹配属于内点。
而对于一个错误模型,大部分匹配都会失败,因此定义:
\P(\\text{Inlier}\|H_b)=\\delta \\
其中 \(\delta\ll\varepsilon\),例如 \(\delta=0.1\),表示随机错误模型只有约 10% 的概率碰巧解释一个匹配点。
现在,设当前验证到第 \(i\) 个匹配,若该匹配属于内点,则累计似然比乘上:
\\\frac{\\varepsilon}{\\delta} \\
这代表好模型解释这个点的概率更多,反之,若属于外点,则乘上:
\\\frac{1-\\varepsilon}{1-\\delta} \\
最终累计似然比不断更新:
\\\Lambda_n = \\prod_{i=1}\^{n} \\frac{P(x_i\|H_g)} {P(x_i\|H_b)} \\
继续,SPRT 设置了一个拒绝阈值 \(A\)(SPRT 本身其实还有一个接受阈值,但在这里不使用),如果:
\\\Lambda_n\>A \\
说明数据越来越支持 \(H_g\) 好模型,继续验证,反之:
则说明模型更符合错误模型 \(H_b\),此时立刻终止当前模型的验证,回到采样阶段进行下一轮。
关于最终的判断不同方法间会有所差异,但其思想都是相同的。

这样,一个错误模型可能只验证二十几个匹配点就被丢弃,而无需继续检查剩余几百个匹配。
4. MAGSAC:更加鲁棒的模型评分
经过 PROSAC 与 SPRT 的优化,USAC 已经能够更好地生成候选模型,并更快地淘汰错误模型。
而下一步改进在模型评分环节,标准 RANSAC 的做法十分直接:
统计内点数量,选择内点最多的模型作为最终结果。
这种方法实现简单,但也存在明显问题:
它把所有内点都视为同样优秀,而所有外点都直接舍弃,没有考虑误差大小带来的差异。
19 年,论文 MAGSAC: Marginalizing Sample Consensus 提出了 MAGSAC(Marginalizing Sample Consensus) ,对模型评分进行了改进。
它不再简单统计有多少内点,而是综合考虑每个匹配点的误差大小,对模型进行更加精细的评分。
首先,传统 RANSAC 的评分可以理解为一个 0/1 损失函数:
\L(e)= \\begin{cases} 1,\&e\<\\tau\\\\ 0,\&e\\ge\\tau \\end{cases} \\
误差只要超过阈值,贡献立即变为 0;只要低于阈值,无论误差大小都贡献 1。
而 MAGSAC 则认为:
匹配误差越小,对模型可信度的贡献应该越大;误差越大,贡献应逐渐降低,而不是突然变成 0。
而从这个思路出发,一个很直接的想法就是用总误差排序 ,但仔细想想,这种方法受离群点影响严重,很容易出现"99 个完美匹配被 1 个极大误差拖后腿"的情况,因此无法真实应用。
为此 MAGSAC 引入了一个概念:噪声标准差 \(\sigma\),这其实是内外点阈值的上层逻辑 ,它是指相机精度本身造成的误差,比如工业相机精度较高,同一个特征点每次检测的结果间可能存在 \(±0.5 \text{px}\) 的误差。其目的是说明当前数据本身允许多大的误差。
现在,假如 \(\sigma=0.5\) ,而重投影误差 \(e=3\),说明正常误差只有半个像素,结果却出现 3 个像素,这个点应该扣很多分。
但如果 \(\sigma=5\),代表正常情况下大家都有5像素误差,那 3 像素反而很好,应该给高分。
而 RANSAC 里面的阈值其实就是依据噪声标准差定下的,通常经验公式是:
\\\tau = k\\sigma (k\\approx2\\sim3 ) \\
因此,标准 RANSAC 其实隐含着一个前提:我认为 \(\sigma\) 就是某一个固定值。 所以直接输入一个阈值作为权威标准指导评分。
但实际上不同设备,不同数据的噪声标准差完全不同。
所以 MAGSAC 说:
既然不知道σ是多少,那就不要猜。
其表现出的最终算法说直白点其实就是遍历阈值后加权求和作为最终评分 :
论文里的公式是这样的:
\Q(M) = \\int P(\\sigma) L(M,\\sigma) ,d\\sigma \\
但这是理想的积分形式,真实实现中都是按不同步长的加权求和:
\Q(M) \\approx \\sum_i P(\\sigma_i) L(M,\\sigma_i) \\

举个例子,噪声标准差可能如下:
| σ | 概率 |
|---|---|
| 1 | 0.2 |
| 2 | 0.3 |
| 3 | 0.3 |
| 4 | 0.2 |
以此,我们对于同一个模型 M,分别计算得分:
| σ | 内点数量 |
|---|---|
| 1 | 50 |
| 2 | 63 |
| 3 | 71 |
| 4 | 75 |
那么最终评分就是:
\Q(M) = 0.2\\times50 + 0.3\\times63 + 0.3\\times71 + 0.2\\times75 = 65.2 \\
这样,我们可以避免不切实际的阈值对结果一刀切,让越可能出现的噪声水平,对最终评分影响越大。
而如果没有先验的话,直接平均也是一个常见选择。
5. LO-RANSAC:在迭代中局部优化
继续下一步优化,03 年,论文 Locally Optimized RANSAC 提出了 LO-RANSAC(Locally Optimized RANSAC),其目标是进一步提高最终模型精度。
我们知道标准 RANSAC 只会对最后迭代完成得到最优模型再使用所有内点进行一次最小二乘优化来提升最终精度。
但问题是:
RANSAC 每次迭代生成模型时,本身只使用了最小采样集,其计算得到的内点只用于评分。
但一个真实场景往往存在几十甚至上百个正确匹配,仅利用其中 4 个点,即使模型正确,也不可避免会受到采样噪声的影响。
于是,一个很自然的优化思路产生了:
既然已经找到了大量内点,为什么不在迭代过程中就利用这些内点重新估计一次模型?
它并没有改变 RANSAC 的整体流程,而是在发现一个比历史最优模型更好的候选模型时,额外插入一次局部优化,整个流程如下:
- 使用当前最优模型找出全部内点。
- 从这些内点中重新随机采样,利用新的采样重新估计模型。
- 再次统计新的内点集合,重复上述过程,直到模型不再继续改善。
- 最后,对当前最优模型进行一次全内点的最小二乘优化,并更新为最优模型,继续外层整体迭代。
这里要说明一点,原始 LO-RANSAC 的采样其实本质只是缩小了搜索范围,其内部仍然是最小采样集,只是在局部优化的最后增加了一次最小二乘优化。
而在现代管道中,非最小估计技术更加成熟,局部优化会使用全部内点直接重新拟合,更高效。

6.自适应终止策略
我们在上一篇就提到了这个问题,标准 RANSAC 的做法十分直接:
提前设定最大迭代次数,达到次数后直接结束。
优化方向自然产生:
既然已经找到了一个非常好的模型,为什么不能提前结束算法?
事实上,标准 RANSAC 本身已经提出了这一思想,就是我们上一篇推导的终止公式:
\N = \\frac{\\ln(1-p)} {\\ln(1-w\^m)} \\
但问题是这个公式只能指导我们选择迭代次数:真正的内点率 \(w\) 是未知的,只有在运行中才能不断估计。
因此,现代 USAC 采用了更加合理的策略:
每当找到新的最佳模型,就重新估计当前内点率,并重新计算还需要多少次迭代。
比如如最开始的模型:
\w=0.4 \\
计算得到需要约1800次迭代,继续迭代发现一个更好的模型:
\w=0.7 \\
再计算只需要约 190 次迭代,如果此时已经完成了更多次迭代,那么已经超过理论所需迭代次数,可以直接结束算法。
而且,这种提前结束是具有概率保证的,设定 \(p=0.99\),意味着算法结束时,已经有至少 99% 的概率采样过一次全部由内点组成的最小采样集。
因此,即使提前停止,也不会明显降低算法成功率。

7. USAC 统一框架
至此,我们已经分别介绍了 USAC 的各个组成模块,12 年,论文 USAC: A Universal Framework for Random Sample Consensus 提出了 USAC(Universal Sample Consensus) ,它并不是一种全新的 RANSAC 算法,而是把上述的多种经典改进方法统一整合到同一个框架中,这正是其名称中 Universal(统一) 的含义。

对比图如下,可以直观感受到精度的提升:
