1. 程式人生 > >(二)ORB描述子提取原始碼思路與實現

(二)ORB描述子提取原始碼思路與實現

ORBSLAM2中ORB特徵提取的特點


 

  ORBSLAM2中通過對OpenCV中的ORB特徵點提取類進行修改,對影象進行分塊提取,而後劃分節點,使得每個節點中儲存的特徵點效能是該節點所有特徵點中最好的。

  可能按照上面說的方式,大家不太能理解。

  這麼說吧。將鋪滿蘋果的桌子進行畫格子,然後每個格子中就會有不同數量的蘋果,在每個格子中選出最好吃的蘋果,格子中其他的蘋果全部扔掉。(雖然有點可惜,但是大局為重嘛),那麼原先擺滿蘋果的桌子(如圖1所示),現在就剩下每個格子一個蘋果的桌子,儘管蘋果少了很多,但是剩下的都是精英,極品(如圖2所示)。

  

       

  根據上面的類比,還有我那抽象派的蘋果,應該可以對ORBSLAM2中的ORB特徵提取做的事情有個大概的瞭解。

  這裡需要提一下的是原生態的ORB特徵提取的方法,他主要是通過閾值條件選出所有滿足條件的ORB描述子,然後計算所有描述子的響應強度並排序M,根據輸入要求的特徵點數量N,取M中前N個描述子,即響應值最大的前N個描述子。顯然,這種提取的方法會導致特徵點的分佈非常不均勻。而這也會影響到SLAM系統中定位的精度。文末在實現原始碼的時候會給大家看看兩種方法提取特徵的結果。


 

ORB特徵提取的原始碼流程

  ORB描述子的提取流程:

  1. 輸入影象,並對輸入影象進行預處理,將其轉換成灰度影象;

  2. 初始化引數,包括特徵點數量nfeatures,尺度scaleFactor,金字塔層數nlevel,初始閾值iniThFAST,最小閾值minThFAST等引數;

  3. 計算金字塔影象,原始碼中使用8層金字塔,尺度因子為1.2,則通過對原影象進行不同層次的resize,可以獲得8層金字塔的影象;

  4. 計算特徵點:

    1)將影象分割成網格,每個網格大小為W*W=30*30畫素;

    2)遍歷每個網格;

    3)對每個網格提取FAST關鍵點,先用初始閾值iniThFAST提取,若提取不到關鍵點,則改用最小閾值minThFAST提取。(注意,初始閾值一般比最小閾值大)

  5. 對所有提取到的關鍵點利用八叉樹的形式進行劃分:

    1)按照畫素寬和畫素高的比值作為初始的節點數量,並將關鍵點座標落在對應節點內的關鍵點分配入節點中;

    2)根據每個節點中存在的特徵點數量作為判斷依據,如果當前節點只有1個關鍵點,則停止分割。否則繼續等分成4份;

    3)按照上述方法不斷劃分下去,如圖3所示,可見出現一個八叉樹的結構,終止條件是節點的數目Lnode大於等於要求的特徵點數量nfeatures;

    4)對滿足條件的節點進行遍歷,在每個節點中儲存響應值最大的關鍵點,保證特徵點的高效能;

  6. 對上述所儲存的所有節點中的特徵點計算主方向,利用灰度質心的方法計算主方向,上一講中我們已經講解過方法,這講就不再贅述了;

  7. 對影象中每個關鍵點計算其描述子,值得注意的是,為了將主方向融入BRIEF中,在計算描述子時,ORB將pattern進行旋轉,使得其具備旋轉不變性;

    

  綜上,ORB描述子提取的方法已經講解完畢了。現在就是上原始碼了。由於許多人都對原始碼進行過註釋,本文就直接上github:https://github.com/yepeichu123/orbslam2_learn的連結給大家,筆者是在ubuntu14.04 + opencv3.2的環境下執行的,已經實測可以執行。另外,本文還對比了ORB分網格提取和原始方法提取的異同,具體如圖4所示。可以看見,分網格提取,特徵點質量更好,分佈也更均勻,對於SLAM問題的跟蹤和三角化等能實現更魯邦的效果。

 


 

總結

  這一講我們講解了ORBSLAM2中,ORB的分塊提取原始碼是如何實現的,並且分析了分塊提取和原生態的ORB之間的對比;

  另外,本文還將原始碼進行單獨實現,提供了一個github的原始碼,給大家練手。

 

PS:

  如果您覺得我的部落格對您有所幫助,歡迎關注我的部落格。此外,歡迎轉載我的文章,但請註明出處連結。

  對本文有任何問題可以在留言區進行評論,也可以在泡泡機器人論壇:http://paopaorobot.org/bbs/index.php?c=cate&fid=1中的SLAM技術交流模組發帖提問。