
對於「關鍵點提取」的功能,你可能會覺得很麻煩,但是有一個好消息! 那就是 OpenCV 其實是有提供現成的 Function 讓我們可以輕鬆提取整張影像的關鍵點。
Table of Contents
僅依賴現有 Function 可能造成的問題
雖然有現成的 Function 可以供我們使用,但我們也不能只是呆版地套用 Function 在一整張圖上,這樣反而會丟失弱紋理區域的關鍵點,導致系統在運作時缺少一些可以表達空間幾何關係的資訊。接下來,我們會說明幾個提取關鍵點的重要步驟!
調整影像的尺寸非常重要
事實上,我們會先把目標影像調整成接近 640 * 480 的尺寸,如圖(一)所示,類似這樣的尺寸非常適合 ORB SLAM2,因為既保留一定的場景細節,也可以節省運算資源。你想,如果影像的解析度非常大,例如 3000 * 3000,那不僅對於定位精準度的提升不大,同時系統也要耗費非常多的時間在一張影像,因為光是一張影像,就包含了 9,000,000 個像素!

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

為何格子外面還有預留一些空間?
那你有注意到嗎? 以圖(二)為例,所有格子外面還有預留一些空間,這不是隨便亂畫的。後續我們要為每個提取出的關鍵點再計算一個描述子,而描述子的計算,會用到一個關鍵點周遭的像素資訊。如果關鍵點出現在影像邊邊,那計算描述子的時候就麻煩了,因為旁邊的像素被裁切掉,你需要額外修改一下演算法來應付這個狀況。所以,為了簡單起見,我們就不考慮影像邊邊的關鍵點囉!
描述子是什麼?
題外話,你可能會很好奇 :「描述子」是什麼? 顧名思義,描述子就是系統用來描述一個關鍵點特徵資訊的工具。有了描述子,不同影像之間的關鍵點就可以利用描述子的相似度來互相匹配,但前提是影像的空間距離要接近,你總不能把台灣和美國拍的影像的做特徵匹配吧。
以圖(三)為例,假設今天有一台相機以不同角度、不同地點,拍攝同一個物體,例如電腦螢幕,那我們就可以把螢幕的左上角當作關鍵點互相匹配。已知兩相機之間的距離,我們就可以根據三角量測法,計算場景中電腦螢幕左上角的空間位置,同時定位相機本身。

當然,實際上一張影像會有上百個關鍵點,不同影像之間會產生多組匹配的關鍵點,ORB SLAM系統就是利用這樣的資訊,完成同時定位與地圖建構的任務!
對每個小格子提取關鍵點
雖然我們說是對每個小格子提取關鍵點,但我們還是要考慮到邊界的問題。如果我們只對小格子內的區域提取關鍵點,那會發生什麼事情呢? 我們並沒有提取到邊界上可能出現的關鍵點! 為了避免發生這種事情,我們實際上會把一小格的影像再向外擴充 3 pixels,藉此滿足提取關鍵點需要的半徑為 3 的圓形範圍,如圖(四)所示。

把握這個原則,然後對每一個 Grid 進行關鍵點提取的工作。對於每個 Grid,我們會先使用較高的閾值提取關鍵點;如果沒有提取到任何關鍵點,我們便會降低閾值,放寬標準後再提取一次。如此一來,我們就可以確保在比較少紋理的地方也可以提取到關鍵點,不浪費任何有用的資訊!
ORB SLAM2 中的關鍵點提取參數
前面我們提到很多提取關鍵點的重要步驟和觀念,但是卻沒有詳細說明這些相關參數的具體數值,這邊為大家提供這些資訊 :
- 向內填充的 pixels 數量 : 前面我們提到「所有格子外面還有預留一些空間」,這是為了後續可以計算描述子。在 ORB SLAM2 中,該值設定為 19。
 
- 每個 Grid 的大小 : 在 ORB SLAM2 中預設是 
30 * 30,但是會根據實際情況調整。例如可提取關鍵點的範圍,其寬高為640 * 480,那我們會先評估總共可以分割成幾列、行。640.0/30.0 = 21.33、480.0/30.0 = 16.0,所以得到是 21 行、16 列。此時,再用640.0 / 21.0 = 30.47、480.0/16.0 = 30.0,無條件進位,確保所有 Grid 涵蓋到所有可以提取關鍵點的區域,得到每個 Grid 的尺寸為31 * 30。 
- 比較嚴格的關鍵點提取閾值 : 20
 
- 比較寬鬆的鍵點提取閾值 : 7
 
值得注意的是,如果連比較寬鬆的閾值都無法讓我們提取到關鍵點,那就放棄這個 Grid 吧! 因為繼續降低閾值所提取到的關鍵點品質會很差。
結語
本章節,我們介紹了有關 ORB SLAM2 中如何提取關鍵點的技巧,包括影像尺寸的調整、將影像分成多個小區塊等。還有一些瑣碎的知識,例如為什麼格子外面還有預留一些空間、描述子是什麼,這類的問題。之後,我們會進一步了解如何撰寫提取關鍵點的程式碼,其中會出現更瑣碎的小技巧,但你不用擔心,這些小技巧其實都非常地單純,只不過串在一起的時候,看起來沒那麼平易近人。



[…] : 邊緣向內部填充的 pixels 數量。前一篇文章我們有提到,所有 Grid […]
[…] article, Techniques of KeyPoint Extraction, mentions that descriptors are used for matching keypoints from different images. Before computing […]