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個匹配點
http://www.imagerabit.com/?p=141