特征匹配
特征匹配,又可以稱之為數據關聯。在圖像領域中,特征匹配的作用非常大。比如:
- 在圖像拼接中,需要進行特征匹配,方便求出單應矩陣以拼接兩幅圖像;
- 在三維重建中,需要進行特征匹配,方便求出變換矩陣以及三角化特征點;
- 在圖像檢索中,可以通過特征點在數據庫中檢索,查找到特征匹配數量最多的識別結果;
- ...
檢索部分暫時不提,畢竟涉及到了復雜的數據結構。並且在SLAM中用的並不多,雖然在回環檢測中需要用到。但是,這是后續的事情了。
> >
特征匹配的前提:
特征描述子的特異性和可重復性:特征描述子是在圖像中利用鄰域信息對關鍵點進行描述,得到一組描述向量。通常對於兩幀具有部分重復紋理的地方,同一個位置的特征描述子應該是一樣的。但是由於光照、遮擋、旋轉和尺度等變化,導致同樣的地方看起來卻又不太一樣。但是總體來說,只要是同一個地方,特征描述子的差別就不應該太大。
相似度度量方法:基於這個事實,特征匹配的目的就是在兩個有重復紋理的圖像中,將同一個位置的特征描述子關聯起來。通常特征描述子是一組向量,比如 $x = {x_1, x_2, ...,x_n}$,同理,另一張圖像中的同個位置描述向量為 $y = {y_1, y_2, ..., y_n} $,將其在超平面中畫出來,就可以通過度量其距離來判斷其相似度。比如 $n = 2/3$ 時,在坐標系中畫出來,可以非常直觀的看出來兩個向量的距離。
>> 特征匹配的方法:
在本文中,只介紹兩種常用的方法。
- Flann快速最近鄰搜索匹配法;
- BruteForce暴力匹配法;
暴力匹配法
假設兩幀圖像 $I_{1}, I_{2}$ 中,各自提取了 $500$ 個特征點,暴力匹配法通過對圖像 $I_{1}$ 中任意一個特征點 $f_{i}^{1}$,都與圖像 $I_{2}$ 中的所有特征點計算匹配分數。相似度度量方法如前所述,通過對每對特征點計算歐式距離(ORB度量漢明距離),選擇與當前特征點 $f_{i}^{1}$ 歐式距離最短的特征點作為最優匹配。
暴力匹配法讓圖像 $I_{1}$ 中的所有特征點都能在圖像 $I_{2}$ 中找到匹配點,這也是其被稱之為暴力匹配法的原因。
很明顯,這樣的匹配方法盡管可以獲得足夠多的匹配對,但是摻雜着非常多的錯誤匹配,這些錯誤匹配在后續的應用當中會導致不可挽回的后果。(沒錯,就算用全局優化也很難救回來的那種)試想一下,在SLAM當中,由於出現了很多錯誤匹配,在估計幀間相對運動時,進行非線性優化算約束時,因為錯誤匹配約束的加入,將導致幀間運動估計錯誤,甚至不收斂。
而經過實踐,人們發現可以用經驗值來將這些錯誤的匹配盡可能的過濾掉。比如特征點間的距離小於最大距離的一半,或者大於最小距離的兩倍等。對初始匹配進行一次過濾,可以得到較好的匹配結果。比如下圖所示:

暴力匹配法,通常搜索時間是 $O(n)$,即 $1$ 對 $n$。不僅搜索效率比較低,並且其匹配效果比較差。
快速最近鄰搜索匹配法
快速最近鄰搜索匹配是相比暴力匹配法,在搜索策略上有所改進。
FLANN的搜索匹配主要分兩步,第一步便是建立索引,第二步是根據索引進行搜索。
- 索引方式包括:線性索引、KD-Tree索引、K均值索引、復合索引、LSH方法索引、自動索引六種。具體介紹可以詳見:[OpenCV——KD Tree](https://blog.csdn.net/ErenTuring/article/details/72983405?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task)。
- 搜索方式包括:搜索K近鄰,搜索半徑近鄰。搜索K近鄰可以指定返回查詢到的最相似的幾個。而搜索半徑近鄰可以設置搜索半徑,在搜索半徑中找匹配點。
FLANN匹配效率根據索引類型有所變化,比如選擇線性的搜索索引時,就是暴力匹配法。而如果選擇KD-tree作為索引時,就會有對數級的匹配效率,相比暴力匹配法有所提高。此外,匹配效果也有所提高。比如下圖所示:
PS:兩種匹配方法我已經上傳到github上的特征匹配模塊中,歡迎參考。
參考資料:
2. FLANN特征匹配;
3. OpenCV——KD Tree;