至於比對的方法,官方文件就提 Brute-Force(暴力比對,因為就是一個一個試), 速度上應該會很慢,所以我就沒特別看。另一個就是FLANN 比對法,基本上要用FLANN 要給定不同的參數,例如如果用SIFT 那就要:
# FLANN parameters
FLANN_INDEX_KDTREE = 1
index_params = dict(algorithm = FLANN_INDEX_KDTREE, trees = 5)
search_params = dict(checks=50) # or pass empty dictionary
flann = cv2.FlannBasedMatcher(index_params,search_params)
matches = flann.knnMatch(des1,des2,k=2)
但如果是用ORB,參數就不一樣:
FLANN_INDEX_LSH = 6
index_params = dict(algorithm=FLANN_INDEX_LSH,
table_number=6, # 12
key_size=12, # 20
multi_probe_level=1) # 2
search_params = dict(checks=50) # or pass empty dictionary
flann = cv2.FlannBasedMatcher(index_params,search_params)
matches = flann.knnMatch(des1, des2, k=2)
我用6張蝦子的圖來測試,以圖6為 trainImage, 圖1-5為QueryImage,
其中SIFT 方法都有對應點,但可惜對應點都不對。例如頭對到尾,或對去不同蝦子。
但以ORB方法比對,有2張圖完全比對不出來,有2張圖比對點不對,但有一張圖的比對點準確率應該有9成以上,我覺得可以⋯⋯哈哈哈。
再回到上一篇用findHomography 的方法來找物體,大概看了一下,這篇對Homography(全像攝影)有比較淺顯的介紹。大概就是原始物件圖可以透過矩陣轉換來算出其投射在其他平面的樣貌,這個轉換可以findHomography 得出 H,所以原圖可以透過H 換算成旋轉和縮放的新
圖。上一篇用findHomography 的部分,就是用來找出新圖經轉換後的位置,以畫出綠框。
即以下:
if(len(goodMatch) > MIN_MATCH_COUNT):
tp = []
qp = []
for m in goodMatch:
tp.append(trainKP[m.trainIdx].pt)
qp.append(queryKP[m.queryIdx].pt)
tp, qp = np.float32((tp, qp))
H, status = cv2.findHomography(tp, qp, cv2.RANSAC, 3.0)
h, w = trainImg.shape
traingBorder = np.float32([[[0, 0], [0, h-1], [w-1, h-1], [w-1, 0]]])
queryBorder = cv2.perspectiveTransform(traingBorder, H)
cv2.polylines(QueryImgBGR, [np.int32(queryBorder)], True, (0, 255, 0), 5)
cv2.drawKeypoints(QueryImgBGR, queryKP,QueryImgBGR,flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
對於以SIFT 或 ORB 找出對應點,再以findHomography 畫出新圖的物件位置,對於使用者來說,會容易理解多了。
但至此為止,「物件」辨識都還算是在圖學的階段,還不到AI 的程度。因為至此為止,它就是辨識兩個圖形的相似度,來確認新物件是不是與原物件為同一物件,若新物件的拍攝角度不同,少了某些特徵,openCV 應該就認不出來了。如果是以AI,它又是怎麼去辨認的呢?我想到的是建立一個3*3*3 的原始物件拍攝角度的「基圖」,讓每個新圖都與其比對,應該可以,但似乎會太耗CPU 和 Memory,而且速度也不快。







