在OpenCV3中進行特征點篩選與優(yōu)化-Python版

在前面的記錄中對使用OpenCV2進行特征匹配的步驟做了一個簡單的介紹,詳見:http://www.reibang.com/p/5083f8d75439斗搞,使用了ORB提取特征點,但是匹配出的結(jié)果是非常粗糙的,結(jié)果顯然包含了很多錯誤的匹配贞谓,這就需要使用一些方法來過濾掉這些錯誤的匹配。因此繼續(xù)在這里記錄對特征點進行進一步篩選的過程熊尉,同時,也對幾個關(guān)鍵的計算流程做個更詳細的說明掌腰,方便將來參考狰住。

特征點匹配

OpenCV里面的二維特征匹配,有兩種常用的方法齿梁,

  • Brute Force Matcher

  • Flann based Matcher

繼承于DescriptorMatcher類催植,分別對應(yīng)BFMatcher和FlannBasedMatcher。

二者的區(qū)別: BFMatcher總是嘗試所有可能的匹配勺择,從而使得它總能夠找到最佳匹配创南。這也是Brute Force(暴力法)的原始含義。方法是計算某一個特征點描述子與其他所有特征點描述子之間的距離酵幕,然后將得到的距離進行排序扰藕,取距離最近的一個作為匹配點缓苛。 FlannBasedMatcher中FLANN的含義是Fast Library forApproximate Nearest Neighbors芳撒,它是一種近似法邓深,算法更快但是找到的是最近鄰近似匹配,當我們需要找到一個相對好的匹配但是不需要最佳匹配的時候可以用FlannBasedMatcher笔刹。當然也可以通過調(diào)整FlannBasedMatcher的參數(shù)來提高匹配的精度或者提高算法速度芥备,但是相應(yīng)地算法速度或者算法精度會受到影響。

此外舌菜,使用特征提取過程得到的特征描述符(descriptor)數(shù)據(jù)類型有的是float類型的萌壳,ORB和BRIEF特征描述子只能使用BruteForce匹配法。

具體matching的方法

  • match: 給定查詢集合中的每個特征描述子日月,尋找最佳匹配袱瓮,返回值按距離升序排列。

  • knnMatch:給定查詢集合中的每個特征描述子爱咬,尋找k個最佳匹配

  • radiusMatch:在特定范圍內(nèi)尋找特征描述子尺借,返回特定距離內(nèi)的匹配

特征點篩選

通過上述過程得到了raw_matches之后,接下來對其進行篩選精拟。

  • 交叉驗證(Cross-match filter)

這種方法只針對BFMatcher, 就是將BFMatcher的最后一個參數(shù)燎斩,交叉驗證聲明為true,即matcher = cv2.BFMatcher(cv2.NORM_HAMMING,crossCheck=True)蜂绎,如果圖1的一個特征點和圖2的一個特征點相匹配栅表,則進行一個相反的檢查,即從圖2上的特征點進行匹配圖1的特征點师枣,如果相互之間都匹配成功怪瓶,才認為是一個好的匹配。

cross-match filter 結(jié)果如圖(似乎還不夠好):


long-cross-match.jpg
  • knnMatch

knnMatch返回K個好的匹配践美,k可以自行指定劳殖。這里指定k=2,raw_matches = matcher.knnMatch(desc1, desc2,2) 拨脉,然后每個match得到兩個最接近的descriptor哆姻,再計算最接近距離和次接近距離之間的比值,當比值大于某個設(shè)定的值時玫膀,才作為最終的match矛缨。

knnMatch結(jié)果如圖:


long-knn-match.jpg
  • RANSAC

為了進一步提升精度,還可以采用隨機采樣一致性(RANSAC)來過濾錯誤的匹配帖旨,該方法是利用匹配點計算兩圖像之間的單應(yīng)矩陣箕昭,然后利用重投影誤差來判定某一個匹配是否是正確的匹配。OpenCV中封裝了求解單應(yīng)矩陣的方法 findHomography ,可以為該方法設(shè)定一個重投影誤差的閾值解阅,可以得到一個向量mask來指定那些是符合重投影誤差的匹配點對落竹,用來過濾掉錯誤的匹配。

RANSAC結(jié)果如圖货抄,左邊是ORB后未篩選的結(jié)果述召,右邊是篩選優(yōu)化后的:


ransac-1.jpg

ransac-2.jpg

可以看出朱转,優(yōu)化的作用還是很明顯的。最后积暖,貼項目代碼如下:

"""
Created on Fri Jan 12 17:59:06 2018
Ransac test
@author:wanqingfeng
"""

import numpy as np
import cv2

img1 = cv2.imread("pic/face1.jpg",0)
img2 = cv2.imread("pic/face2.jpg",0)

detector = cv2.ORB_create()

flann_params= dict(algorithm = 6,
 table_number = 6, # 12
 key_size = 12, # 20
 multi_probe_level = 1) #2

matcher = cv2.BFMatcher(cv2.NORM_HAMMING,crossCheck=False)

kp1,desc1 = detector.detectAndCompute(img1,None)
kp2,desc2 = detector.detectAndCompute(img2,None)

raw_matches = matcher.knnMatch(desc1, desc2,2) #2

good = []

for m,n in raw_matches:
 if m.distance < 0.7*n.distance:
 good.append(m)

if len(good)>10:
 src_pts = np.float32([ kp1[m.queryIdx].pt for m in good ]).reshape(-1,1,2)
 dst_pts = np.float32([ kp2[m.trainIdx].pt for m in good ]).reshape(-1,1,2)
 M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC,5.0)

 matchesMask = mask.ravel().tolist()

else:
 print("Not enough matches are found - %d/%d" % (len(good),10))
 matchesMask = None
draw_params = dict(matchColor = (0,255,0), # draw matches in green color
 singlePointColor = (0,0,255),
 matchesMask = matchesMask, 
 flags = 2)# draw only inliers 

vis = cv2.drawMatches(img1,kp1,img2,kp2,good,None,**draw_params)   

cv2.imshow("", vis)
cv2.imwrite("pic/face_brisk_bf_ransac_1519.jpg", vis)
cv2.waitKey()
cv2.destroyAllWindows()

?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末藤为,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子夺刑,更是在濱河造成了極大的恐慌缅疟,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,290評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件遍愿,死亡現(xiàn)場離奇詭異存淫,居然都是意外死亡,警方通過查閱死者的電腦和手機沼填,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評論 2 385
  • 文/潘曉璐 我一進店門纫雁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人倾哺,你說我怎么就攤上這事轧邪。” “怎么了羞海?”我有些...
    開封第一講書人閱讀 156,872評論 0 347
  • 文/不壞的土叔 我叫張陵忌愚,是天一觀的道長。 經(jīng)常有香客問我却邓,道長硕糊,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,415評論 1 283
  • 正文 為了忘掉前任腊徙,我火速辦了婚禮简十,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘撬腾。我一直安慰自己螟蝙,他們只是感情好,可當我...
    茶點故事閱讀 65,453評論 6 385
  • 文/花漫 我一把揭開白布民傻。 她就那樣靜靜地躺著胰默,像睡著了一般。 火紅的嫁衣襯著肌膚如雪漓踢。 梳的紋絲不亂的頭發(fā)上牵署,一...
    開封第一講書人閱讀 49,784評論 1 290
  • 那天,我揣著相機與錄音喧半,去河邊找鬼奴迅。 笑死,一個胖子當著我的面吹牛挺据,可吹牛的內(nèi)容都是我干的取具。 我是一名探鬼主播脖隶,決...
    沈念sama閱讀 38,927評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼者填!你這毒婦竟也來了浩村?” 一聲冷哼從身側(cè)響起做葵,我...
    開封第一講書人閱讀 37,691評論 0 266
  • 序言:老撾萬榮一對情侶失蹤占哟,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后酿矢,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體榨乎,經(jīng)...
    沈念sama閱讀 44,137評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,472評論 2 326
  • 正文 我和宋清朗相戀三年瘫筐,在試婚紗的時候發(fā)現(xiàn)自己被綠了蜜暑。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,622評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡策肝,死狀恐怖肛捍,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情拙毫,我是刑警寧澤,帶...
    沈念sama閱讀 34,289評論 4 329
  • 正文 年R本政府宣布棺禾,位于F島的核電站,受9級特大地震影響膘婶,放射性物質(zhì)發(fā)生泄漏缺前。R本人自食惡果不足惜悬襟,卻給世界環(huán)境...
    茶點故事閱讀 39,887評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望脊岳。 院中可真熱鬧肆良,春花似錦、人聲如沸逸绎。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽棺牧。三九已至巫糙,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間颊乘,已是汗流浹背参淹。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工醉锄, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人浙值。 一個月前我還...
    沈念sama閱讀 46,316評論 2 360
  • 正文 我出身青樓恳不,卻偏偏與公主長得像,于是被迫代替她去往敵國和親开呐。 傳聞我的和親對象是個殘疾皇子烟勋,可洞房花燭夜當晚...
    茶點故事閱讀 43,490評論 2 348