自适应采样次数的Ransac算法
对数据进行拟合操作的同学肯定对Ransac算法不陌生,之前接触过一段时间,最近有空才把这么经典的一个算法分享给大家。RANSAC(RAndom SAmple Consensus,随机采样一致)算法是从一组含有“外点”(outliers)的数据中正确估计数学模型参数的迭代算法。“外点”一般指的的数据中的噪声,比如说匹配中的误匹配和估计曲线中的离群点。所以,RANSAC也是一种“外点”检测算法。RANSAC算法是一种不确定算法,与通常的光滑技术相反:不是用尽可能多的点去获得一个初始解,并在以后消除无效点,而是使用满足可行条件的尽量少的初始数据集,并在可能时用一致性数据集扩大它。
Ransac基本思想
RANSAC是通过反复选择数据集去估计出模型,一直迭代到估计出认为比较好的模型。 具体的实现步骤可以分为以下几步:
1.选择出可以估计出模型的最小数据集;(对于直线拟合来说就是两个点,对于计算Homography矩阵就是4个点)
2.使用这个数据集来计算出数据模型;
3.将所有数据带入这个模型,计算出“内点”的数目;(累加在一定误差范围T内的适合当前迭代推出模型的数据)
4.比较当前模型和之前推出的最好的模型的“内点“的数量,记录最大“内点”数的模型参数和“内点”数;
5.重复1-4步,直到迭代结束或者当前模型已经足够好了(“内点数目大于一定数量”)。
以上的算法是最简单的版本,该算法有缺陷。因为迭代结束的条件没法很好的确定,准确来说,就是无法确定最大迭代次数,以及内点比阈值。那么有没有一种改进的方法可以不用这么麻烦的人为设定这些经验值呢?答案是有的,这个就是下面讲的自适应迭代次数的方法。
自适应采样次数的Ransac算法原理
设 ω = 内 点 个 数 所 有 点 个 数 \omega=\frac{内点个数}{所有点个数} ω=所有点个数内点个数, ω \omega ω为任意选择的数据点为内点的概率,
那么
p
0
=
ω
n
p_0=\omega ^n
p0=ωn表示采样的n个点全为内点的概率(可重复)。
注意:有些算法为了计算更严谨,将
p
0
=
ω
n
=
C
内
点
总
数
n
C
点
总
数
n
p_0=\omega ^n=\frac{C^{n}_{内点总数}}{C^{n}_{点总数}}
p0=ωn=C点总数nC内点总数n
则采样点中至少有一个为外点的概率
p
1
=
1
−
p
0
=
1
−
ω
n
p_1=1-p_0=1-\omega ^n
p1=1−p0=1−ωn
则重复K次实验,每次都至少有一个外点的概率
p
2
=
p
1
k
=
(
1
−
ω
n
)
k
p_2=p_1^k=(1-\omega ^n)^k
p2=p1k=(1−ωn)k
则K次采样中至少一次采样是全为内点的概率为:
p
=
1
−
p
2
=
1
−
(
1
−
ω
n
)
k
p=1-p_2=1-(1-\omega ^n)^k
p=1−p2=1−(1−ωn)k
即:
1
−
p
=
(
1
−
ω
n
)
k
1-p=(1-\omega ^n)^k
1−p=(1−ωn)k
则
k
=
l
o
g
(
1
−
p
)
l
o
g
(
1
−
ω
n
)
k=\frac{log(1-p)}{log(1-\omega ^n)}
k=log(1−ωn)log(1−p)(1)
这个k即采样次数。
有的版本算法喜欢将里面的
ω
\omega
ω替换成
ε
=
1
−
ω
\varepsilon=1-\omega
ε=1−ω,即外点概率。
那么自适应算法伪代码如下:
1、
k
=
∞
k=\infty
k=∞,sample_count=0
2、while(
k
k
k>sample_count)
\space\space\space\space\space
选取一个样本并计算内点数
\space\space\space\space\space
令
ω
=
内
点
数
总
点
数
\omega=\frac{内点数}{总点数}
ω=总点数内点数
\space\space\space\space\space
取
p
=
0.99
p=0.99
p=0.99并由
ω
\omega
ω及式(1)求k
\space\space\space\space\space
sample_count=sample_count+1
3、结束
以上便是确定Ransac样本次数的自适应算法。
注意:由于内点占比
ω
\omega
ω的初始值未知,我们可以从最坏的估计开始,即设
ω
\omega
ω为0,此时k的初始值无穷大。当发现有更大的一致集就把原估计更新。至于p的值取0.99,则是为了保守起见。实际意义可以理解为进行k次采样,至少一次采样是全为内点的概率为0.99,这个就是我们对需要拟合的数据的期望。
如有错误的地方,望各位指正。