ORB+暴力匹配测试
# orb特征点检测,暴力匹配
import cv2
import numpy as np
import matplotlib.pyplot as plt
# 也能输入RGB图像,不过匹配不到目标
train = cv2.imread('image/small.jpg', 0)
query = cv2.imread('image/big.jpg', 0)
exx = 1
exy = 1
# 不改变尺寸匹配不到
train = cv2.resize(train, dsize=None, fx=exx, fy=exy)
query = cv2.resize(query, dsize=None, fx=exx, fy=exy)
# 暴力匹配
orb = cv2.ORB_create()
kp1, des1 = orb.detectAndCompute(train, None)
kp2, des2 = orb.detectAndCompute(query, None)
# 针对ORB算法 NORM_HAMMING 计算特征距离 True判断交叉验证
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
# 特征描述子匹配
matches = bf.match(des1, des2)
matches = sorted(matches, key=lambda x: x.distance)
# 改变数组的表现形式,不改变数据内容,数据内容是每个关键点的坐标位置
src_pts = np.float32([kp1[m.queryIdx].pt for m in matches]).reshape(-1, 1, 2) # 测试图像的关键点的坐标位置
dst_pts = np.float32([kp2[m.trainIdx].pt for m in matches]).reshape(-1, 1, 2) # 样本图像的关键点的坐标位置
# findHomography 函数是计算变换矩阵
# 参数cv2.RANSAC是使用RANSAC算法寻找一个最佳单应性矩阵H,即返回值M
# 返回值:M 为变换矩阵,mask是掩模
M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 5.0)
# ravel方法将数据降维处理,最后并转换成列表格式
matchesMask = mask.ravel().tolist()
# 获取train的图像尺寸
h, w = train.shape
# pts是图像train的四个顶点
pts = np.float32([[0, 0], [0, h - 1], [w - 1, h - 1], [w - 1, 0]]).reshape(-1, 1, 2)
# 计算变换后的四个顶点坐标位置
# 使用得到的变换矩阵对原图像的四个角进行变换,获得在目标图像上对应的坐标
dst = cv2.perspectiveTransform(pts, M)
# 根据四个顶点坐标位置在query图像画出变换后的边框
query = cv2.polylines(query, [np.int32(dst)], True, (255, 255, 255), 3, cv2.LINE_AA)
img3 = cv2.drawMatches(train, kp1, query, kp2, matches[:20], None, flags=2)
plt.imshow(cv2.cvtColor(img3, cv2.COLOR_BGR2RGB))
plt.show()