ransac的原理,有一些不错的资料已经详细的叙述,刚开始学习的时候我看的是Marco Zuliani的<<Ransac for Dummies>>,这份资料讲得不错,想要详细了解其原理的同学不妨看看这份资料。本着实用为主的原则,此处,主要描绘具体怎么实现ransac算法。
ransac算法的输入为:需要处理的点集;以及可能符合的函数模型, 选择的模型决定了需要计算模型参数的点的个数。
ransac算法的输出为:满足某种关系的过滤点集 ;函数模型的参数。
ransac算法的实现步骤:
- 根据你设定的函数模型,选定足够的点
- 使用选定的点,计算得到函数模型参数
- 判定其他点是否符合该函数,并统计满足的点的个数
- 反复1-3步,最后,具有最多点满足的函数为求取的函数,满足该函数的点为inlier,反之,不满足该函数的点为outlier。
以特征点对的几何去噪这一应用为例,具体实现代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
//输入: // 需要去噪的特征点对:vector<pair<CvPoint CvPoint> > matcher_ori // 点对估计应该满足的特征点对几何模型:xform_fn = 投影、仿射、RST或者其他 // 对应的计算模型参数需要特征点对个数:sample_n // 误差求取函数: err_fn // 误差阈值: err_w // 另外还有几个特别重要的参数:infrac, p_badxform, RANSAC_PROB_BAD_SUPP //输出: // 去噪后的特征点对 vector<pair<CvPoint CvPoint> > matcher_dst // 应满足的实际几何模型参数: Ptr<CvMat> H_matrix int
k = 0; double p =
pow (1.0 - pow (in_frac, MSS_n), k); int
mather_n = ( int )mather_ori.size(); int done_n = 0; while (p > p_badxform && (((matcher_n - done_n) - sample_n) >= 0) ) { matcher_sample.clear(); // 随机选择足够的点对 choice_ransac_sample(matcher_ori, matcher_sample, sample_n); done_n += sample_n; // 使用选择的点对计算模型的参数 H_matrix = xform_fn(matcher_sample); if (NULL == H_matrix) { p = pow (1.0 -
pow (in_frac, sample_n, ++k); continue ; } matcher_inliners.clear(); // 检测有哪些点对满足当前的几何模型 find_consensus( matcher_ori, H_matrix, err_fn, err_w, matcher_inliners); // 选择最多点对符合的几何模型 if (matcher_dst.size() < matcher_inliners.size()) { matcher_dst.clear(); matcher_dst = matcher_inliners; in_frac = double (matcher_dst.size())/ double (matcher_ori.size()); } p = pow (1.0 -
pow (in_frac, sample_n), ++k); } |
结果示例图:
ransac之前的匹配点 : 共有20个匹配点
ransac之后的匹配点:共有17个匹配点