- 1 圖像查找(單應性矩陣)
- 2 單應性矩陣 應用舉例
- 3 單應性矩陣 代碼示例
P87 11
1 圖像查找(單應性矩陣)
特征匹配作為輸入,獲得單應性矩陣
點X
在img1和img2中的成像分別為x,x'
圖中H即為單應性矩陣
2 單應性矩陣 應用舉例
獲取一個矩陣,通過與圖像1就算可以得到圖像2對應點的位置;
圖像二通過計算可以得到點原始位置,同樣圖像一也可以經過計算得到點原始位置;
自動轉正
更換廣告牌中的內容
3 單應性矩陣 代碼示例
在一節FLANN特征匹配的基礎上增加了,單應性矩陣、透視變換、框圖
#獲取的單應性矩陣
#srcPts從匹配點good中獲取,每次遍歷都可以從kp1[m.queryIdx]中獲取一個關鍵點
#關鍵點需要轉成浮點型
#對獲取到的關鍵點要重新變換reshape(-1, 1, 2),x值隨意,y值1,z值2,即無數行,每行一個元素,每個元素有2個子元素
#queryIdx,trainIdx分別是第一幅圖,第二幅圖的描述子索引值
if len(good) >= 4:#單應性矩陣要求匹配點要大于等于4srcPts = np.float32([kp1[m.queryIdx].pt for m in good]).reshape(-1, 1, 2)#原關鍵點dstPts = np.float32([kp2[m.trainIdx].pt for m in good]).reshape(-1, 1, 2)#目標關鍵點#單應性矩陣H, mask = cv2.findHomography(srcPts, dstPts, cv2.RANSAC, 5.0)#cv2.RANSAC對錯誤匹配點過濾,閾值1~10,這里是5#透視變換#獲取要搜索的圖的四個角點(左上,左下,右下,右上),同樣需要轉成浮點型,然后reshapeh, w = img1.shape[:2]pts = np.float32([[0,0], [0, h-1], [w-1, h-1], [w-1, 0]]).reshape(-1, 1, 2)dst = cv2.perspectiveTransform(pts, H)#多邊形繪制,將找到的子圖在原圖中框出來吧cv2.polylines(img2, [np.int32(dst)], True, (0, 0, 255))#目標圖,32位整形,TRUE封口,
else:print('the number of good is less than 4.')exit()
效果如下:
完整代碼
import cv2
import numpy as np#讀文件
img1 = cv2.imread('opencv_search.png')
img2 = cv2.imread('opencv_orig.png')#灰度化
gray1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
gray2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)#創建sift對象
sift= cv2.xfeatures2d.SIFT_create()#進行檢測關鍵點,同時計算描述子
kp1 ,des1= sift.detectAndCompute(gray1, None)#掩碼設置為NONE,即對整張圖檢測
kp2 ,des2= sift.detectAndCompute(gray2, None)#掩碼設置為NONE,即對整張圖檢測#創建flann匹配器
index_params=dict(algorithm=1,tree=5)
search_params=dict(checks=50)flann=cv2.FlannBasedMatcher(index_params,search_params)#對描述子進行特征匹配
matches=flann.knnMatch(des1,des2,k=2)#對匹配點優化過濾
good=[]
for i,(m,n) in enumerate(matches):#對img1,img2中的匹配點進行遍歷if m.distance < 0.7* n.distance:#越小越精準good.append(m)#獲取的單應性矩陣
#srcPts從匹配點good中獲取,每次遍歷都可以從kp1[m.queryIdx]中獲取一個關鍵點
#關鍵點需要轉成浮點型
#對獲取到的關鍵點要重新變換reshape(-1, 1, 2),x值隨意,y值1,z值2,即無數行,每行一個元素,每個元素有2個子元素
#queryIdx,trainIdx分別是第一幅圖,第二幅圖的描述子索引值
if len(good) >= 4:#單應性矩陣要求匹配點要大于等于4srcPts = np.float32([kp1[m.queryIdx].pt for m in good]).reshape(-1, 1, 2)#原關鍵點dstPts = np.float32([kp2[m.trainIdx].pt for m in good]).reshape(-1, 1, 2)#目標關鍵點#單應性矩陣H, mask = cv2.findHomography(srcPts, dstPts, cv2.RANSAC, 5.0)#cv2.RANSAC對錯誤匹配點過濾,閾值1~10,這里是5#透視變換#獲取要搜索的圖的四個角點(左上,左下,右下,右上),同樣需要轉成浮點型,然后reshapeh, w = img1.shape[:2]pts = np.float32([[0,0], [0, h-1], [w-1, h-1], [w-1, 0]]).reshape(-1, 1, 2)dst = cv2.perspectiveTransform(pts, H)#多邊形繪制,將找到的子圖在原圖中框出來吧cv2.polylines(img2, [np.int32(dst)], True, (0, 0, 255))#目標圖,32位整形,TRUE封口,
else:print('the number of good is less than 4.')exit()#繪制匹配結果
img3=cv2.drawMatchesKnn(img1,kp1,img2,kp2,[good],None)cv2.imshow('img3', img3)
cv2.waitKey(0)