orbslam2回環檢測簡介
由於回環檢測模組包含兩個部分的內容:其一是位置識別,即外觀驗證,通過影象間的相似度資訊進行判斷;其二是幾何驗證,通過回環候選幀與當前關鍵幀的幾何關係來做進一步驗證。
由於兩部分內容都較為繁瑣,因此筆者將回環檢測模組拆分成兩講,今天這一講主要介紹外觀驗證,下一講則繼續幾何驗證。
外觀驗證,或者叫位置識別,實際上是乙個影象檢索的問題,即輸入影象與地圖儲存的所有關鍵幀進行相似度比較,找出相似度分數最高的即是最優匹配。由於還有幾何驗證,因此在外觀驗證階段,通常會留下幾個相似度分數比較高的回環候選幀,以便幾何驗證選擇最合適的回環幀。
這一講,我們主要分下面幾個部分來介紹外觀驗證:
1. 詞袋模型;
2. 影象檢索;
詞袋模型
在講影象匹配的時候,我們曾提及詞袋模型,因為orbslam2中的影象匹配用到的詞袋模型,如果不稍微介紹一下,擔心大家不太理解它們是怎麼匹配的。值得注意的是,如何能保證高效且準確地找到正確匹配是乙個檢索問題的主要難題,而詞袋模型基本上能滿足這個要求。因此,本節將主要講講詞袋模型,之後再利用詞袋模型來介紹影象檢索。
詞袋的目的是用影象的某些特徵來描述一幅影象。從我們人的直觀感覺來看影象,我們會說這張**裡有乙個人,一張桌子這些特徵;而另一張**裡有乙隻狗,一張凳子和一張桌子等特徵來描述。根據這些特徵描述,我們就可以判斷這兩張影象的相似性了。如果我們將上述這些描述內容整合成字典,讓他們形成一一對映的關係,比如:
$v_$ 表示人,$v_$ 表示桌子,$v_$ 表示凳子,$v_$ 表示狗。那麼這字典的形式可以表示成 $d = [ v_, v_, v_, v_ ]$。
而對於第一張**,我們會表示成 $i_ = 1\cdot v_ + 1\cdot v_ + 0\cdot v_ + 0\cdot v_$,於是我們就可以用乙個向量來描述這個** $i_ = [ 1, 1, 0, 0 ]^$;
同理,第二張**表示成 $i_ = 0\cdot v_ + 1\cdot v_ + 1\cdot v_ + 1\cdot v_$,描述成向量形式 $i_ = [ 0, 1, 1, 1 ]^$。
對待這兩個向量,我們可以設定度量方式,就能得到兩張**的相似度了。
在這裡,我們提到了字典的概念,也用到了字典的方法,但是它是怎麼定義的,怎麼生成的?我們需要再稍微介紹一下。
----------字典------------
按照前面的介紹,字典是由很多單詞組成,每乙個單詞代表乙個概念。乙個單詞代表的不單單是乙個特徵點,他是一類具有相似性的特徵的組合,或者更明確的說是它們的聚類中心。因此,字典的生成問題就類似於乙個聚類問題。
聚類問題在無監督機器學習中非常常見,詞袋模型主要使用經典的k-means演算法來進行特徵的聚類,假設有 $n$ 個特徵點,我們需要將他分成 $k$ 類,下面的樣本就表示特徵點,具體流程如下:
1. 隨機選取 $k$ 個中心點:$c_, \cdots, c_$;
2. 對每個樣本,計算它和每個中心點之間的距離,取最小的作為它的歸類;
3. 重新計算每個類的中心點;
4. 如果每個中心點都變化很小,則演算法收斂,退出;否則返回第2步。
但是在slam問題中,需要面對的場景非常多,特徵的種類也非常多,如果只是非常籠統地將其分成幾大類,這種做法顯然是不夠準確地。因此有學者提出了 $k$ 叉樹的概念,類似於層次聚類,是k-means的直接拓展。同樣,假設我們有 $n$ 個特徵點,希望構建乙個深度為 $d$,每次分叉為 $k$ 的樹,那麼做法如下:
1. 在根節點,即 $n$ 個特徵點的集合,用k-means把所有樣本聚成 $k$ 類,這樣就得到了第一層;
2. 對第一層的每個節點,把屬於把節點的樣本再聚成 $k$ 類,得到下一層;
3. 以此類推,最後得到葉子層,葉子層即為所謂的詞彙。
這些詞彙就跟我們前面所講的那個例子差不多,比如桌子只是其中乙個詞彙。當然,這裡只是舉例說明而已,這裡的每乙個詞彙都是多個相似特徵聚類而成的聚類中心,直接表徵多個相似特徵。更直觀一些可以看下面這個圖,儘管我們在影象匹配的時候看過,但是加上這裡的描述,相信你可以更好地理解 $k$ 叉樹是個什麼東西。
我們在葉子層構建了單詞,樹結構中的中間節點僅供快速查詢時使用。實際上,我們構造了乙個深度為2,3個分支的樹,可以容納 $3^$ 個單詞。我們可以通過增加樹的深度和分支來增加字典的規模,達到更好的分類效果,這可以達到我們需要的準確率。此外,在檢索時,乙個特徵會與逐層的中間節點的聚類中心比較,最終找到最優的匹配詞彙,這個檢索過程能達到對數級別的查詢效率。
影象檢索
在介紹了詞袋模型這個工具以後,我們的影象檢索問題就簡單很多了。
檢索問題的描述其實很簡單:
輸入一幀影象,和已有的資料庫影象逐一對比,找到乙個最合適的或者說匹配分數最高的影象。
筆者這裡直接介紹orbslam2的外觀識別流程,因為它的意義是如此直觀,只是在實現的時候加了一些小技巧,筆者將其羅列出來,以便大家參考:
1. 利用一範數來度量當前幀與共檢視關鍵幀之間的相似度分數,假設共檢視中乙個關鍵幀的bow向量為 $w$,當前幀的bow向量為 $v$,則相似度分數的度量方式為:
$s(w-v) = 2\sum\limits_^\left|w_\right| + \left|v_\right| - \left|w_-v_\right|$
將所有相似分數進行排序,取最小的匹配分數 $s_$ 作為參考值,用於查詢回環候選幀。
2. 確定最小匹配分數後,排除當前幀共檢視的所有關鍵幀,我們回環的意義是確定當前相機看到的場景,在很久之前是不是見過。而近期看到的,比如當前幀的共檢視關鍵幀,我們通常是不考慮的,因為這對校正整個場景的誤差,實際上作用不大。
3. 對當前幀的bow向量中的詞彙逐個逆向索引在地圖中找到相關聯的關鍵幀,參考下圖。並統計各個關鍵幀中與當前幀相似的詞彙數量。排序確定最大的相似詞彙數量 $m$,並篩選相似詞彙數量大於$0.8\times m$的關鍵幀作為候選幀 $kf_^$;
4. 將當前幀與步驟3的候選幀進行bow向量計算匹配分數,取匹配分數高於步驟1計算的最小匹配分數 $s_$的候選幀作為新的候選幀 $kf_^$;
5. 統計候選幀集中 $kf_^$ 每個候選幀的共檢視關鍵幀與當前幀的bow匹配分數總和 $s_$,並取分數總和大於 $0.75\times s_$的候選幀組成新的候選幀 $kf_^$。筆者理解這也是為了確保在乙個範圍裡都能檢測到回環,增強回環的可靠性。
6. 在上述候選幀 $kf_^$ 的基礎上,我們檢測連續三幀都識別到同乙個回環,那麼就可以進一步縮小候選幀集,形成最終的候選幀集 $kf_^$ ,這在orbslam2中叫一致性驗證。
至此,我們的外觀驗證已經完成了。從步驟1開始到步驟6,orbslam2都是在不斷提高篩選條件進而縮小候選幀集。可以想見,這是在利用詞袋模型檢索和匹配效率極高的優勢,快速完成粗檢索,精細化的部分再交由幾何驗證去進一步確定最終的候選幀。
總結:
在這一講中,我們概述了orbslam2中採用的回環檢測方法,並著重講解了其中的外觀驗證方法,包括:
詳細介紹了詞袋模型的結構,以及生成方法;
詳細羅列了orbslam2中的視覺驗證中所採用的檢索方法;
下一講,我們將繼續回環檢測方法中的另一部分——幾何驗證。
碎碎念:
筆者這種記錄綱領的方法,在很多讀者看來可能是乙個記流水賬的過程,十分枯燥。但是筆者還是同其他博主一樣,優先寫出對應模組的關鍵技術,再進一步分析orbslam2中用這種關鍵技術,怎麼樣做優化,怎麼樣完成它想要完成的功能。
筆者認為這種列提綱的方式,可以幫助大家對這些細小的方法有乙個清晰的認識。筆者之前就困惑於如何提高位置識別的準確性,而orbslam2中這多種篩選方法可以給筆者提供多種參考方案。因此,筆者想傳遞給大家的也是這樣乙個資訊,羅列提綱的方式可以為大家提供的是orbslam2中某個模組採用的各種方法,讀者可以根據實際需要選擇提綱中的任意乙個或多個組合的方法完成自己想要的功能。若是本文能對讀者產生一兩點幫助,那筆者將是十分欣慰的。
ps:
我的github鏈結是:
ORB SLAM(六)回環檢測
這件事情就好比乙個人走在陌生的城市裡,一開始還能分清東南西北,但隨著在小街小巷轉來轉去,已經不知道自己在什麼地方了。通過認真辨識周邊環境,他可以建立起區域性的地圖資訊 區域性優化 再回憶以前走過的路徑,他可以糾正一些以前的地圖資訊 全域性優化 然而他還是不敢確定自己在城市的精確方位。直到他看到了乙個...
ORB SLAM(六)回環檢測
這件事情就好比乙個人走在陌生的城市裡,一開始還能分清東南西北,但隨著在小街小巷轉來轉去,已經不知道自己在什麼地方了。通過認真辨識周邊環境,他可以建立起區域性的地圖資訊 區域性優化 再回憶以前走過的路徑,他可以糾正一些以前的地圖資訊 全域性優化 然而他還是不敢確定自己在城市的精確方位。直到他看到了乙個...
orb slam2回環檢測初探1
1.detectloop 步驟1 如果距離上次閉環沒多久 小於10幀 或者map中關鍵幀總共還沒有10幀,則不進行閉環檢測 if mpcurrentkf mnidadd mpcurrentkf 將當前關鍵幀新增到資料庫中 mpcurrentkf seterase return false 步驟2 遍...