暴力匹配使用第一组中一个特征的描述符,并使用一些距离计算将其与第二组中的所有其他特征进行匹配,并返回最近的一个。
import numpy as np
import cv2 as cv
def test(target_path, match_path):
img_target = cv.imread(target_path, cv.IMREAD_GRAYSCALE)
img_match = cv.imread(match_path, cv.IMREAD_GRAYSCALE)
orb = cv.ORB_create()
kp_target, des_target = orb.detectAndCompute(img_target, None)
kp_match, des_match = orb.detectAndCompute(img_match, None)
bf = cv.BFMatcher(cv.NORM_HAMMING, crossCheck=True)
matches = bf.match(des_target, des_target)
matches = sorted(matches, key=lambda x: x.distance)
img_draw = cv.drawMatches(img_target, kp_target, img_match, kp_match, matches[:10], None,
flags=cv.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS)
img_draw = cv.resize(img_draw, None, fx=0.5, fy=0.5)
cv.imshow("", img_draw)
cv.waitKey()
if __name__ == '__main__':
test("peiqi.png", "peiqi_in_img.png")
import numpy as np
import cv2 as cv
def test(target_path, match_path):
img_target = cv.imread(target_path, cv.IMREAD_GRAYSCALE)
img_match = cv.imread(match_path, cv.IMREAD_GRAYSCALE)
sift = cv.SIFT_create()
kp_target, des_target = sift.detectAndCompute(img_target, None)
kp_match, des_match = sift.detectAndCompute(img_match, None)
bf = cv.BFMatcher()
matches = bf.knnMatch(des_target, des_match, k=2)
good = []
for m, n in matches:
if m.distance < 0.75 * n.distance:
good.append([m])
img_draw = cv.drawMatchesKnn(img_target, kp_target, img_match, kp_match, good, None,
flags=cv.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS)
img_draw = cv.resize(img_draw, None, fx=0.5, fy=0.5)
cv.imshow("", img_draw)
cv.waitKey()
if __name__ == '__main__':
test("peiqi.png", "peiqi_in_img.png")
对于大型数据集,Flann的速度快于Brute-force:
import cv2 as cv
def test(target_path, match_path):
img_target = cv.imread(target_path, cv.IMREAD_GRAYSCALE)
img_match = cv.imread(match_path, cv.IMREAD_GRAYSCALE)
sift = cv.SIFT_create()
kp_target, des_target = sift.detectAndCompute(img_target, None)
kp_match, des_match = sift.detectAndCompute(img_match, None)
idx_params = dict(algorithm=1, trees=5)
search_params = dict(checks=50) # search_params = {}
flann = cv.FlannBasedMatcher(idx_params, search_params)
matches = flann.knnMatch(des_target, des_match, k=2)
matches_mask = [[0, 0] for i in range(len(matches))]
for i, (m, n) in enumerate(matches):
if m.distance < 0.7 * n.distance:
matches_mask[i] = [1, 0]
draw_params = dict(matchColor=(0, 255, 0),
singlePointColor=(255, 0, 0),
matchesMask=matches_mask,
flags=cv.DrawMatchesFlags_DEFAULT)
img_draw = cv.drawMatchesKnn(img_target, kp_target, img_match, kp_match, matches, None, **draw_params)
img_draw = cv.resize(img_draw, None, fx=0.5, fy=0.5)
cv.imshow("", img_draw)
cv.waitKey()
if __name__ == '__main__':
test("peiqi.png", "peiqi_in_img.png")
参考文献
【1】Opencv中文文档。