特征匹配的方法
- BF(Brute-Force),暴力特征匹配方法
- FLANN 最快邻近区特征匹配方法
暴力特征匹配方法的原理
- 它使用第一组中的每个特征的描述子,与第二组中的所有特征描述子进行匹配
- 计算他们之间的差距,然后将最接近一个匹配返回(也即计算他们之间的相似度)
Opencv特征匹配的步骤
- 创建匹配器,BFMatcher(normType, crossCheck)
- 进行特征匹配,bf.match(des1,des2)
- 绘制匹配点,cv2.drawMatches(img1,kp1,img2,k2)
BFMatcher
- normType:NORM_L1,NORM_L2,HAMMING1…
- crossCheck :是否进行交叉匹配匹配,默认为FALSE
match
- 参数为SIFT,SURF,OBR等计算的描述子
- 对两幅图的描述子进行计算
drawMatches
- 搜索img,kp
- 匹配图img,kp
- match()方法返回的匹配结果
import cv2 as cv
import numpy as np
img1 = cv.imread('1.png')
img2 = cv.imread('2.png')
gray1 = cv.cvtColor(img1, cv.COLOR_BGR2GRAY)
gray2 = cv.cvtColor(img2, cv.COLOR_BGR2GRAY)
sift = cv.xfeatures2d.SIFT_create()
kp1, des1 = sift.detectAndCompute(gray1, None)
kp2, des2 = sift.detectAndCompute(gray2, None)
bf = cv.BFMatcher(cv.NORM_L1)
match = bf.match(des1, des2)
img3 = cv.drawMatches(img1, kp1, img2, kp2, match, None)
cv.imshow('img1', img1)
cv.imshow('img2', img2)
cv.imshow('img3', img3)
cv.waitKey(0)
FLANN特征匹配
flann优缺点
- 在进行批量特征匹配时,FLANN速度更快
- 由于它使用的是邻近近似值,所以精度较差
使用FLANN特征匹配的步骤
- 创建FLANN匹配器,FlannBasedMatcher(…)
- 进行特征匹配,flann.match/knnMatch(…)
- 绘制匹配点,cv.drawMatches/drawMatchesKnn(…)
FlannBasedMatcher
- index_params字典:匹配算法KDTREE、LSH
- 如果选择sift/surf,选择KDTREE
- 如果选择ORB,选择LSH
- search_params字典:指定KDTREE算法中的遍历树的次数,50
- KDTREE
- index_params=dict(algorithm=FlANN_INDEX_KDTREE, trees=5)
- search_params=dict(checks=50)
knnMatch
- 参数为SIFT/SURF/OBR等计算描述子
- k,表示取欧式距离最近的前k个关键点
- 返回的是匹配的结果DMatch对象
- DMatch对象的内容如下
- distance,描述子之间的距离,值越低越好
- queryIdx,第一个图像的描述子索引值
- trainIdx,第二个图的描述子索引值
- imgIdx,第二个图的索引值
drawMatchesKnn
- 搜索img,kp
- 匹配图img,kp
- match()方法返回的匹配结果
import cv2 as cv
import numpy as np
img1 = cv.imread('luban1.png')
img2 = cv.imread('luban2.png')
gray1 = cv.cvtColor(img1,cv.COLOR_BGR2GRAY)
gray2 = cv.cvtColor(img2,cv.COLOR_BGR2GRAY)
sift = cv.xfeatures2d.SIFT_create()
kp1, des1 = sift.detectAndCompute(gray1, None)
kp2, des2 = sift.detectAndCompute(gray2, None)
index_params = dict(algorithm=1, trees=5)
search_params = dict(checks=50)
flann = cv.FlannBasedMatcher(index_params, search_params)
matches = flann.knnMatch(des1, des2, k=2)
good = []
for i, (m, n) in enumerate(matches):
if m.distance < 0.7*n.distance:
good.append(m)
ret = cv.drawMatchesKnn(img1,kp1,img2,kp2,[good],None)
cv.imshow('ret', ret)
cv.waitKey(0)