OpenCV中的特征匹配(Feature Matching)
OpenCV中的特征匹配(Feature Matching)
- 1. 效果圖
- 2. 原理
- 3. 源碼
- 3.1 SIFT關(guān)鍵點(diǎn)檢測(cè)+Knn近鄰匹配
- 3.2 ORB關(guān)鍵點(diǎn)檢測(cè)+蠻力特征匹配
- 3.3 SIFT關(guān)鍵點(diǎn)檢測(cè)+Knn近鄰及蠻力特征匹配
- 參考
這篇博客將介紹如何使用OpenCV將一個(gè)圖像中的特征與其他圖像中的特征進(jìn)行匹配。通過(guò)SIFT等關(guān)鍵點(diǎn)檢測(cè)、蠻力匹配器和 FLANN KNN匹配來(lái)實(shí)現(xiàn)。
- Brute-Force matcher 蠻力匹配器
- FLANN Fast Approximate Nearest Neighbor Search Library 快速最近鄰逼近搜索函數(shù)庫(kù)
- KNN K Nearest Neighbors K近鄰
1. 效果圖
要進(jìn)行匹配的倆張?jiān)紙D如下:
SIFT關(guān)鍵點(diǎn)檢測(cè)+Knn近鄰及蠻力匹配效果圖如下:
ORB關(guān)鍵點(diǎn)檢測(cè)及蠻力匹配效果圖如下:
SIFT關(guān)鍵點(diǎn)檢測(cè)+Knn近鄰匹配效果圖如下:
2. 原理
蠻力匹配器很簡(jiǎn)單。它采用第一個(gè)集合中一個(gè)特征的描述符,并通過(guò)一些距離計(jì)算與第二個(gè)集合中的所有其他特征匹配。返回最近的一個(gè)或者k個(gè)匹配符。
- cv2.BFMatcher() 創(chuàng)建BFMatcher對(duì)象;
參數(shù)一:normType,指定要使用的距離測(cè)量,默認(rèn)cv2.NORM_L2,適用于SURF、SIFT;對(duì)于基于二進(jìn)制字符串的描述符,如ORB、BRIENT、BRISK等,應(yīng)使用cv2.NORM_HAMMING,它使用HAMMING距離作為度量。如果ORB使用WTA_K==3或4,則應(yīng)使用cv2.NORM_HAMMING2。
參數(shù)二:交叉檢查bool變量,默認(rèn)false。如果為true,Matcher只返回那些具有值(i,j)的匹配,這樣集合A中的第i個(gè)描述符將集合B中的第j個(gè)描述符作為最佳匹配。
- BFMatcher.match() 返回最佳匹配;
- BFMatcher.knnMatch() 返回k個(gè)最佳匹配,其中k由用戶指定。
- cv2.drawKeypoints() 繪制關(guān)鍵點(diǎn);
- cv2.drawMatches() 繪制匹配項(xiàng)。它水平堆疊兩個(gè)圖像,并從第一個(gè)圖像到第二個(gè)圖像繪制線條,顯示最佳匹配。
- cv2.drawMatchesKnn() 它繪制所有k個(gè)最佳匹配。如果k=2,它將為每個(gè)關(guān)鍵點(diǎn)繪制兩條匹配線。
3. 源碼
3.1 SIFT關(guān)鍵點(diǎn)檢測(cè)+Knn近鄰匹配
# 基于SIFT描述符和比率檢驗(yàn)的蠻力匹配
import cv2
from matplotlib import pyplot as pltimg1 = cv2.imread('images/box.png') # 查詢圖像
img2 = cv2.imread('images/box_in_scene.png') # 訓(xùn)練圖像
plt.subplot(121)
plt.imshow(cv2.cvtColor(img1,cv2.COLOR_BGR2RGB)) # 通過(guò)for循環(huán)逐個(gè)顯示圖像
plt.xticks([]) # 去掉x軸的刻度
plt.yticks([]) # 去掉y軸的刻度
plt.title("origin box")
plt.subplot(122)
plt.imshow(cv2.cvtColor(img2,cv2.COLOR_BGR2RGB)) # 通過(guò)for循環(huán)逐個(gè)顯示圖像
plt.xticks([]) # 去掉x軸的刻度
plt.yticks([]) # 去掉y軸的刻度
plt.title("origin box_in_scene")
plt.show()img1 = cv2.imread('images/box.png', 0) # 查詢圖像
img2 = cv2.imread('images/box_in_scene.png', 0) # 訓(xùn)練圖像# 初始化SIFT檢測(cè)器
sift = cv2.xfeatures2d.SIFT_create()# 使用SIFT尋找關(guān)鍵點(diǎn)和描述符
kp1, des1 = sift.detectAndCompute(img1, None)
kp2, des2 = sift.detectAndCompute(img2, None)# 使用默認(rèn)參數(shù)初始化BFMatcher
bf = cv2.BFMatcher()
matches = bf.knnMatch(des1, des2, k=2)# 應(yīng)用比率測(cè)試
good = []
for m, n in matches:if m.distance < 0.75 * n.distance:good.append([m])# cv2.drawMatchesKnn:繪制Knn匹配結(jié)果
img3 = cv2.drawMatchesKnn(img1, kp1, img2, kp2, good, img1, flags=2)plt.imshow(img3)
plt.xticks([])
plt.yticks([])
plt.title("sift res")
plt.show()
3.2 ORB關(guān)鍵點(diǎn)檢測(cè)+蠻力特征匹配
# ORB關(guān)鍵點(diǎn)檢測(cè)+蠻力特征匹配
import cv2
from matplotlib import pyplot as pltimg1 = cv2.imread('images/box.png', 0) # 查找圖像
img2 = cv2.imread('images/box_in_scene.png', 0) # 訓(xùn)練圖像# 初始化ORB檢測(cè)器
orb = cv2.ORB_create()# 尋找關(guān)鍵點(diǎn)和描述符
kp1, des1 = orb.detectAndCompute(img1, None)
kp2, des2 = orb.detectAndCompute(img2, None)# 使用距離測(cè)量cv2.NORM_HAMMING創(chuàng)建一個(gè)BFMatcher對(duì)象(因?yàn)槲覀兪褂玫氖荗RB),并打開交叉檢查以獲得更好的結(jié)果。
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)# 使用Matcher.match()方法在兩幅圖像中獲得最佳匹配。
# 返回結(jié)果matches是一個(gè)DMatch對(duì)象列表。此DMatch對(duì)象具有以下屬性:
# DMatch.distance—描述符之間的距離。越低越好。
# DMatch.trainIdx—訓(xùn)練描述符中描述符的索引
# DMatch.queryIdx-查詢描述符中描述符的索引
# DMatch.imgIdx—訓(xùn)練圖像的索引。
matches = bf.match(des1, des2)# 按照距離的升序排序,以便最好的匹配項(xiàng)(距離較短的)出現(xiàn)在前面
matches = sorted(matches, key=lambda x: x.distance)# 只抽取前10場(chǎng)匹配繪制(只是為了更便于可視化)。
img3 = cv2.drawMatches(img1, kp1, img2, kp2, matches[:10], img1, flags=2)plt.imshow(img3)
plt.xticks([])
plt.yticks([])
plt.title("orb res")
plt.show()
3.3 SIFT關(guān)鍵點(diǎn)檢測(cè)+Knn近鄰及蠻力特征匹配
# ORB關(guān)鍵點(diǎn)檢測(cè)+蠻力特征匹配
import cv2
from matplotlib import pyplot as pltimg1 = cv2.imread('images/box.png', 0) # 查找圖像
img2 = cv2.imread('images/box_in_scene.png', 0) # 訓(xùn)練圖像# 初始化ORB檢測(cè)器
orb = cv2.ORB_create()# 尋找關(guān)鍵點(diǎn)和描述符
kp1, des1 = orb.detectAndCompute(img1, None)
kp2, des2 = orb.detectAndCompute(img2, None)# 使用距離測(cè)量cv2.NORM_HAMMING創(chuàng)建一個(gè)BFMatcher對(duì)象(因?yàn)槲覀兪褂玫氖荗RB),并打開交叉檢查以獲得更好的結(jié)果。
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)# 使用Matcher.match()方法在兩幅圖像中獲得最佳匹配。
# 返回結(jié)果matches是一個(gè)DMatch對(duì)象列表。此DMatch對(duì)象具有以下屬性:
# DMatch.distance—描述符之間的距離。越低越好。
# DMatch.trainIdx—訓(xùn)練描述符中描述符的索引
# DMatch.queryIdx-查詢描述符中描述符的索引
# DMatch.imgIdx—訓(xùn)練圖像的索引。
matches = bf.match(des1, des2)# 按照距離的升序排序,以便最好的匹配項(xiàng)(距離較短的)出現(xiàn)在前面
matches = sorted(matches, key=lambda x: x.distance)# 只抽取前10場(chǎng)匹配繪制(只是為了更便于可視化)。
img3 = cv2.drawMatches(img1, kp1, img2, kp2, matches[:10], img1, flags=2)plt.imshow(img3)
plt.xticks([])
plt.yticks([])
plt.title("orb res")
plt.show()
參考
- https://docs.opencv.org/3.0-beta/doc/py_tutorials/py_feature2d/py_matcher/py_matcher.html#matcher
總結(jié)
以上是生活随笔為你收集整理的OpenCV中的特征匹配(Feature Matching)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: SIFT和SURF的替换算法——ORB
- 下一篇: OpenCV中的立体图像创建深度图