您好,登錄后才能下訂單哦!
前面已經(jīng)學(xué)習(xí)特征查找和對應(yīng)匹配,接著下來在特征匹配之后,再使用findHomography函數(shù)來找出對應(yīng)圖像的投影矩陣。首先使用一個(gè)查詢圖片,然后在另外一張圖片里找到目標(biāo)對象,其實(shí)就是想在圖片里查找所需要目標(biāo)的一部分區(qū)域。為了實(shí)現(xiàn)這樣的功能,需要使用calib3d庫里的一個(gè)函數(shù)cv.findHomography()
,把從兩張圖片里找到的特征點(diǎn)當(dāng)作參數(shù),傳送給這個(gè)函數(shù),然后這個(gè)函數(shù)返回一個(gè)投影變換矩陣,我們就可以使用 cv.perspectiveTransform()
函數(shù)來對查找的目標(biāo)進(jìn)行投影,這樣就可以在復(fù)雜圖片里標(biāo)記出相應(yīng)的目標(biāo)位置。
我們已經(jīng)看到,在匹配時(shí)可能會有一些錯(cuò)誤,這可能會影響結(jié)果。為了解決這個(gè)問題,需要使用RANSAC 或 LEAST_MEDIAN算法。所以提供正確估計(jì)的良好匹配稱為內(nèi)聚,其余的稱為外聯(lián)。cv.findHomography()
函數(shù)返回一個(gè)值表示內(nèi)聚還是外聯(lián)的點(diǎn)。
在例子里,先使用ORB來尋找兩個(gè)圖片的特征點(diǎn),接著根據(jù)設(shè)置條件為10個(gè)匹配特征,如果滿足就會計(jì)算投影變換矩陣,一旦獲得3x3的矩陣,就可以把尋找的目標(biāo)對象在圖片里標(biāo)記出來。最后在復(fù)雜的圖片里用白色線條標(biāo)記出來。
參數(shù)詳解:
srcPoints 源平面中點(diǎn)的坐標(biāo)矩陣,可以是CV_32FC2類型,也可以是vector<Point2f>類型
dstPoints 目標(biāo)平面中點(diǎn)的坐標(biāo)矩陣,可以是CV_32FC2類型,也可以是vector<Point2f>類型
method 計(jì)算單應(yīng)矩陣所使用的方法。不同的方法對應(yīng)不同的參數(shù),具體如下:
0 - 利用所有點(diǎn)的常規(guī)方法
RANSAC - RANSAC-基于RANSAC的魯棒算法
LMEDS - 最小中值魯棒算法
RHO - PROSAC-基于PROSAC的魯棒算法
ransacReprojThreshold
將點(diǎn)對視為內(nèi)點(diǎn)的最大允許重投影錯(cuò)誤閾值(僅用于RANSAC和RHO方法)。如果
則點(diǎn)被認(rèn)為是個(gè)外點(diǎn)(即錯(cuò)誤匹配點(diǎn)對)。若srcPoints和dstPoints是以像素為單位的,則該參數(shù)通常設(shè)置在1到10的范圍內(nèi)。
mask
可選輸出掩碼矩陣,通常由魯棒算法(RANSAC或LMEDS)設(shè)置。 請注意,輸入掩碼矩陣是不需要設(shè)置的。
maxIters RANSAC算法的最大迭代次數(shù),默認(rèn)值為2000。
confidence 可信度值,取值范圍為0到1.
該函數(shù)能夠找到并返回源平面和目標(biāo)平面之間的轉(zhuǎn)換矩陣H,以便于反向投影錯(cuò)誤率達(dá)到最小。
演示使用的例子如下:
#python 3.7.4,opencv4.1 #蔡軍生 https://blog.csdn.net/caimouse/article/details/51749579 # import numpy as np import cv2 from matplotlib import pyplot as plt MIN_MATCH_COUNT = 10 #讀取文件 img1 = cv2.imread('rmb3.png') img2 = cv2.imread('rmb4.png') #初始化ORB檢測器 orb = cv2.ORB_create() #用ORB查找關(guān)鍵點(diǎn) kp1, des1 = orb.detectAndCompute(img1,None) kp2, des2 = orb.detectAndCompute(img2,None) # FLANN參數(shù) FLANN_INDEX_LSH = 6 index_params = dict(algorithm = FLANN_INDEX_LSH, table_number = 6, key_size = 12, multi_probe_level = 1) search_params = dict(checks=50) #或者使用一個(gè)空的字典 flann = cv2.FlannBasedMatcher(index_params,search_params) matches = flann.knnMatch(des1,des2,k=2) # 比率 good = [] for m,n in matches: if m.distance < 0.7*n.distance: good.append(m) if len(good)>MIN_MATCH_COUNT: 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() #進(jìn)行投影變換 h,w,d = img1.shape pts = np.float32([ [0,0],[0,h-1],[w-1,h-1],[w-1,0] ]).reshape(-1,1,2) dst = cv2.perspectiveTransform(pts,M) #畫變換后的外形 img2 = cv2.polylines(img2,[np.int32(dst)],True,(255,255,255),3, cv2.LINE_AA) else: print( "Not enough matches are found - {}/{}".format(len(good), MIN_MATCH_COUNT) ) matchesMask = Non draw_params = dict(matchColor = (0,255,0), # draw matches in green color singlePointColor = None, matchesMask = matchesMask, # draw only inliers flags = 2) img3 = cv2.drawMatches(img1,kp1,img2,kp2,good,None,**draw_params) #顯示圖片 cv2.imshow('img3',img3) cv2.waitKey(0) cv2.destroyAllWindows()
結(jié)果輸出如下:
總結(jié)
以上所述是小編給大家介紹的在OpenCV里使用特征匹配和單映射變換的代碼詳解,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時(shí)回復(fù)大家的。在此也非常感謝大家對億速云網(wǎng)站的支持!
如果你覺得本文對你有幫助,歡迎轉(zhuǎn)載,煩請注明出處,謝謝!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。