【ORB-SLAM2】探索之旅 第 5 天 : ORB SLAM2 中的關鍵點提取技巧

接下來,本文章會以這張當作示範圖,講解ORB SLAM2中的關鍵點提取技巧

對於「關鍵點提取」的功能,你可能會覺得很麻煩,但是有一個好消息! 那就是 OpenCV 其實是有提供現成的 Function 讓我們可以輕鬆提取整張影像的關鍵點。

僅依賴現有 Function 可能造成的問題

雖然有現成的 Function 可以供我們使用,但我們也不能只是呆版地套用 Function 在一整張圖上,這樣反而會丟失弱紋理區域的關鍵點,導致系統在運作時缺少一些可以表達空間幾何關係的資訊。接下來,我們會說明幾個提取關鍵點的重要步驟!

調整影像的尺寸非常重要

事實上,我們會先把目標影像調整成接近 640 * 480 的尺寸,如圖(一)所示,類似這樣的尺寸非常適合 ORB SLAM2,因為既保留一定的場景細節,也可以節省運算資源。你想,如果影像的解析度非常大,例如 3000 * 3000,那不僅對於定位精準度的提升不大,同時系統也要耗費非常多的時間在一張影像,因為光是一張影像,就包含了 9,000,000 個像素!

調整影像尺寸
圖(一)、調整影像尺寸,進一步節省運算資源的示意圖

把影像分成許多個小區塊

有了適當尺寸的影像後,我們必須把它分割成好幾個小區塊,如圖(二)所示,每個小區塊的尺寸最大為 30 * 30 ! 為什麼我們要這麼做呢? 如同前面所述,如果我們是對一整張圖提取關鍵點,那我們將會丟失弱紋理區域的重要資訊;相對的,如果我們針對一個個小區塊做關鍵點提取,那我們就可以更彈性地選擇閾值 – 如果該區域提取不到關鍵點,那我們就降低閾值、放寬標準後再提取一次 – 如此一來,就可以保證,不會浪費影像中,任何一個區塊能夠提供的資訊!

把目標影像分割成多個小區塊
圖(二)、把目標影像分割成多個小區塊

為何格子外面還有預留一些空間?

那你有注意到嗎? 以圖(二)為例,所有格子外面還有預留一些空間,這不是隨便亂畫的。後續我們要為每個提取出的關鍵點再計算一個描述子,而描述子的計算,會用到一個關鍵點周遭的像素資訊。如果關鍵點出現在影像邊邊,那計算描述子的時候就麻煩了,因為旁邊的像素被裁切掉,你需要額外修改一下演算法來應付這個狀況。所以,為了簡單起見,我們就不考慮影像邊邊的關鍵點囉!

描述子是什麼?

題外話,你可能會很好奇 :「描述子」是什麼? 顧名思義,描述子就是系統用來描述一個關鍵點特徵資訊的工具。有了描述子,不同影像之間的關鍵點就可以利用描述子的相似度來互相匹配,但前提是影像的空間距離要接近,你總不能把台灣和美國拍的影像的做特徵匹配吧。

以圖(三)為例,假設今天有一台相機以不同角度、不同地點,拍攝同一個物體,例如電腦螢幕,那我們就可以把螢幕的左上角當作關鍵點互相匹配。已知兩相機之間的距離,我們就可以根據三角量測法,計算場景中電腦螢幕左上角的空間位置,同時定位相機本身。

圖(三)、當今天有一台相機以不同角度、不同地點,拍攝同一個物體,例如電腦螢幕,那我們就可以把螢幕的左上角當作關鍵點互相匹配。已知兩相機之間的距離,我們就可以根據三角量測法,計算場景中電腦螢幕左上角的空間位置,同時定位相機本身。

當然,實際上一張影像會有上百個關鍵點,不同影像之間會產生多組匹配的關鍵點,ORB SLAM系統就是利用這樣的資訊,完成同時定位與地圖建構的任務!

對每個小格子提取關鍵點

雖然我們說是對每個小格子提取關鍵點,但我們還是要考慮到邊界的問題。如果我們只對小格子內的區域提取關鍵點,那會發生什麼事情呢? 我們並沒有提取到邊界上可能出現的關鍵點! 為了避免發生這種事情,我們實際上會把一小格的影像再向外擴充 3 pixels,藉此滿足提取關鍵點需要的半徑為 3 的圓形範圍,如圖(四)所示。

圖(四)、針對一小格區域提取時,為了避免丟失邊界上可能存在的關鍵點,實際上會把影像處理的範圍向外擴增 3 pixels,藉此滿足提取關鍵點需要的半徑為 3 的圓形範圍

把握這個原則,然後對每一個 Grid 進行關鍵點提取的工作。對於每個 Grid,我們會先使用較高的閾值提取關鍵點;如果沒有提取到任何關鍵點,我們便會降低閾值,放寬標準後再提取一次。如此一來,我們就可以確保在比較少紋理的地方也可以提取到關鍵點,不浪費任何有用的資訊!

ORB SLAM2 中的關鍵點提取參數

前面我們提到很多提取關鍵點的重要步驟和觀念,但是卻沒有詳細說明這些相關參數的具體數值,這邊為大家提供這些資訊 :

  • 向內填充的 pixels 數量 : 前面我們提到「所有格子外面還有預留一些空間」,這是為了後續可以計算描述子。在 ORB SLAM2 中,該值設定為 19。
  • 每個 Grid 的大小 : 在 ORB SLAM2 中預設是 30 * 30,但是會根據實際情況調整。例如可提取關鍵點的範圍,其寬高為 640 * 480,那我們會先評估總共可以分割成幾列、行。640.0/30.0 = 21.33480.0/30.0 = 16.0,所以得到是 21 行、16 列。此時,再用 640.0 / 21.0 = 30.47480.0/16.0 = 30.0,無條件進位,確保所有 Grid 涵蓋到所有可以提取關鍵點的區域,得到每個 Grid 的尺寸為 31 * 30
  • 比較嚴格的關鍵點提取閾值 : 20
  • 比較寬鬆的鍵點提取閾值 : 7

值得注意的是,如果連比較寬鬆的閾值都無法讓我們提取到關鍵點,那就放棄這個 Grid 吧! 因為繼續降低閾值所提取到的關鍵點品質會很差。

結語

本章節,我們介紹了有關 ORB SLAM2 中如何提取關鍵點的技巧,包括影像尺寸的調整、將影像分成多個小區塊等。還有一些瑣碎的知識,例如為什麼格子外面還有預留一些空間、描述子是什麼,這類的問題。之後,我們會進一步了解如何撰寫提取關鍵點的程式碼,其中會出現更瑣碎的小技巧,但你不用擔心,這些小技巧其實都非常地單純,只不過串在一起的時候,看起來沒那麼平易近人。

2 則留言

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *