特征匹配和單應(yīng)性
使用? OpenCV ?中的蠻力(Brute-Force)匹配和 FLANN 匹配。
1:Brute-Force 匹配的基礎(chǔ)
蠻力匹配器是很簡單的。首先在第一幅圖像中選取一個關(guān)鍵點(diǎn)然后依次與第二幅圖像的每個關(guān)鍵點(diǎn)進(jìn)行(描述符)距離測試,最后返回距離最近的關(guān)鍵點(diǎn)。
對于 BF 匹配器,我們首先要使用 cv2.BFMatcher() 創(chuàng)建一個 BF-Matcher 對象。它有兩個可選參數(shù)。第一個是 normType。它是用來指定要使用的距離測試類型。默認(rèn)值為 cv2.Norm_L2。這很適合 SIFT 和 SURF 等(c2.NORM_L1 也可以)。對于使用二進(jìn)制描述符的 ORB,BRIEF,BRISK算法等,要使用 cv2.NORM_HAMMING,這樣就會返回兩個測試對象之間的漢明距離。如果 ORB 算法的參數(shù)設(shè)置為 V T A_K==3 或 4,normType就應(yīng)該設(shè)置成 cv2.NORM_HAMMING2。
第二個參數(shù)是布爾變量 crossCheck,默認(rèn)值為 False。如果設(shè)置為True,匹配條件就會更加嚴(yán)格,只有到 A 中的第 i 個特征點(diǎn)與 B 中的第 j 個特征點(diǎn)距離最近,并且 B 中的第 j 個特征點(diǎn)到 A 中的第 i 個特征點(diǎn)也是最近(A 中沒有其他點(diǎn)到 j 的距離更近)時才會返回最佳匹配(i,j)。也就是這兩個特征點(diǎn)要互相匹配才行。這樣就能提供統(tǒng)一的結(jié)果,這可以用來替代 D.Lowe在 SIFT 文章中提出的比值測試方法。
BFMatcher 對象具有兩個方法, BFMatcher.match() 和 BFMatcher.knnMatch()。第一個方法會返回最佳匹配。第二個方法為每個關(guān)鍵點(diǎn)返回 k 個最佳匹配(降序排列之后取前 k 個),其中 k 是由用戶設(shè)定的。如果除了匹配之外還要做其他事情的話可能會用上(比如進(jìn)行比值測試)。
就 像 使 用 cv2.drawKeypoints() 繪 制 關(guān) 鍵 點(diǎn) 一 樣, 我 們 可 以 使 用cv2.drawMatches() 來繪制匹配的點(diǎn)。它會將這兩幅圖像先水平排列,然后在最佳匹配的點(diǎn)之間繪制直線(從原圖像到目標(biāo)圖像)。如果前面使用的是 BF-Matcher.knnMatch(),現(xiàn)在我們可以使用函數(shù) cv2.drawMatchsKnn為每個關(guān)鍵點(diǎn)和它的 k 個最佳匹配點(diǎn)繪制匹配線。如果 k 等于 2,就會為每個關(guān)鍵點(diǎn)繪制兩條最佳匹配直線。如果我們要選擇性繪制話就要給函數(shù)傳入一個掩模。
2:FLANN 匹配器
FLANN 是快速最近鄰搜索包(Fast_Library_for_Approximate_Nearest_Neighbors)的簡稱。它是一個對大數(shù)據(jù)集和高維特征進(jìn)行最近鄰搜索的算法的集合,而且這些算法都已經(jīng)被優(yōu)化過了。在面對大數(shù)據(jù)集時它的效果要好于 BFMatcher。
使用 FLANN 匹配,我們需要傳入兩個字典作為參數(shù)。這兩個用來確定要使用的算法和其他相關(guān)參數(shù)等。第一個是 IndexParams。index p arams = dict(algorithm = F LAN N I N DEX K DT REE, trees = 5)
各種不同算法的信息可以在 FLANN 文檔中找到。
第二個字典是 SearchParams。用它來指定遞歸遍歷的次數(shù)。值越高結(jié) 果 越 準(zhǔn) 確, 但是消耗的時間也越多。 如果你想修改這個值, 傳入?yún)?數(shù):search p arams = dict(checks = 100)。
使用一個查詢圖像,在其中找到一些特征點(diǎn)(關(guān)鍵點(diǎn)),我們又在另一幅圖像中也找到了一些特征點(diǎn),最后對這兩幅圖像之間的特征點(diǎn)進(jìn)行匹配。簡單來說就是:我們在一張雜亂的圖像中找到了一個對象(的某些部分)的位置。這些信息足以幫助我們在目標(biāo)圖像中準(zhǔn)確的找到(查詢圖像)對象。
為了達(dá)到這個目的可以使用 calib3d 模塊中的 cv2.findHomography()函數(shù)。如果將這兩幅圖像中的特征點(diǎn)集傳給這個函數(shù),他就會找到這個對象的透視圖變換。然后就可以使用函數(shù)cv2.perspectiveTransform() 找到這個對象了。至少要 4 個正確的點(diǎn)才能找到這種變換。
我們已經(jīng)知道在匹配過程可能會有一些錯誤,而這些錯誤會影響最終結(jié)果。為了解決這個問題,算法使用 RANSAC 和 LEAST_MEDIAN(可以通過參數(shù)來設(shè)定)。所以好的匹配提供的正確的估計被稱為 inliers,剩下的被稱為outliers。cv2.findHomography() 返回一個掩模,這個掩模確定了 inlier 和outlier 點(diǎn)。
Python
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。