OpenCV中的特征匹配(Feature Matching)
Posted 程序媛一枚~
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OpenCV中的特征匹配(Feature Matching)相关的知识,希望对你有一定的参考价值。
OpenCV中的特征匹配(Feature Matching)
这篇博客将介绍如何使用OpenCV将一个图像中的特征与其他图像中的特征进行匹配。通过SIFT等关键点检测、蛮力匹配器和 FLANN KNN匹配来实现。
- Brute-Force matcher 蛮力匹配器
- FLANN Fast Approximate Nearest Neighbor Search Library 快速最近邻逼近搜索函数库
- KNN K Nearest Neighbors K近邻
1. 效果图
要进行匹配的俩张原始图如下:
SIFT关键点检测+Knn近邻及蛮力匹配效果图如下:
ORB关键点检测及蛮力匹配效果图如下:
SIFT关键点检测+Knn近邻匹配效果图如下:
2. 原理
蛮力匹配器很简单。它采用第一个集合中一个特征的描述符,并通过一些距离计算与第二个集合中的所有其他特征匹配。返回最近的一个或者k个匹配符。
- cv2.BFMatcher() 创建BFMatcher对象;
参数一:normType,指定要使用的距离测量,默认cv2.NORM_L2,适用于SURF、SIFT;对于基于二进制字符串的描述符,如ORB、BRIENT、BRISK等,应使用cv2.NORM_HAMMING,它使用HAMMING距离作为度量。如果ORB使用WTA_K==3或4,则应使用cv2.NORM_HAMMING2。
参数二:交叉检查bool变量,默认false。如果为true,Matcher只返回那些具有值(i,j)的匹配,这样集合A中的第i个描述符将集合B中的第j个描述符作为最佳匹配。
- BFMatcher.match() 返回最佳匹配;
- BFMatcher.knnMatch() 返回k个最佳匹配,其中k由用户指定。
- cv2.drawKeypoints() 绘制关键点;
- cv2.drawMatches() 绘制匹配项。它水平堆叠两个图像,并从第一个图像到第二个图像绘制线条,显示最佳匹配。
- cv2.drawMatchesKnn() 它绘制所有k个最佳匹配。如果k=2,它将为每个关键点绘制两条匹配线。
3. 源码
3.1 SIFT关键点检测+Knn近邻匹配
# 基于SIFT描述符和比率检验的蛮力匹配
import cv2
from matplotlib import pyplot as plt
img1 = cv2.imread('images/box.png') # 查询图像
img2 = cv2.imread('images/box_in_scene.png') # 训练图像
plt.subplot(121)
plt.imshow(cv2.cvtColor(img1,cv2.COLOR_BGR2RGB)) # 通过for循环逐个显示图像
plt.xticks([]) # 去掉x轴的刻度
plt.yticks([]) # 去掉y轴的刻度
plt.title("origin box")
plt.subplot(122)
plt.imshow(cv2.cvtColor(img2,cv2.COLOR_BGR2RGB)) # 通过for循环逐个显示图像
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) # 训练图像
# 初始化SIFT检测器
sift = cv2.xfeatures2d.SIFT_create()
# 使用SIFT寻找关键点和描述符
kp1, des1 = sift.detectAndCompute(img1, None)
kp2, des2 = sift.detectAndCompute(img2, None)
# 使用默认参数初始化BFMatcher
bf = cv2.BFMatcher()
matches = bf.knnMatch(des1, des2, k=2)
# 应用比率测试
good = []
for m, n in matches:
if m.distance < 0.75 * n.distance:
good.append([m])
# cv2.drawMatchesKnn:绘制Knn匹配结果
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关键点检测+蛮力特征匹配
# ORB关键点检测+蛮力特征匹配
import cv2
from matplotlib import pyplot as plt
img1 = cv2.imread('images/box.png', 0) # 查找图像
img2 = cv2.imread('images/box_in_scene.png', 0) # 训练图像
# 初始化ORB检测器
orb = cv2.ORB_create()
# 寻找关键点和描述符
kp1, des1 = orb.detectAndCompute(img1, None)
kp2, des2 = orb.detectAndCompute(img2, None)
# 使用距离测量cv2.NORM_HAMMING创建一个BFMatcher对象(因为我们使用的是ORB),并打开交叉检查以获得更好的结果。
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
# 使用Matcher.match()方法在两幅图像中获得最佳匹配。
# 返回结果matches是一个DMatch对象列表。此DMatch对象具有以下属性:
# DMatch.distance—描述符之间的距离。越低越好。
# DMatch.trainIdx—训练描述符中描述符的索引
# DMatch.queryIdx-查询描述符中描述符的索引
# DMatch.imgIdx—训练图像的索引。
matches = bf.match(des1, des2)
# 按照距离的升序排序,以便最好的匹配项(距离较短的)出现在前面
matches = sorted(matches, key=lambda x: x.distance)
# 只抽取前10场匹配绘制(只是为了更便于可视化)。
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关键点检测+Knn近邻及蛮力特征匹配
# ORB关键点检测+蛮力特征匹配
import cv2
from matplotlib import pyplot as plt
img1 = cv2.imread('images/box.png', 0) # 查找图像
img2 = cv2.imread('images/box_in_scene.png', 0) # 训练图像
# 初始化ORB检测器
orb = cv2.ORB_create()
# 寻找关键点和描述符
kp1, des1 = orb.detectAndCompute(img1, None)
kp2, des2 = orb.detectAndCompute(img2, None)
# 使用距离测量cv2.NORM_HAMMING创建一个BFMatcher对象(因为我们使用的是ORB),并打开交叉检查以获得更好的结果。
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
# 使用Matcher.match()方法在两幅图像中获得最佳匹配。
# 返回结果matches是一个DMatch对象列表。此DMatch对象具有以下属性:
# DMatch.distance—描述符之间的距离。越低越好。
# DMatch.trainIdx—训练描述符中描述符的索引
# DMatch.queryIdx-查询描述符中描述符的索引
# DMatch.imgIdx—训练图像的索引。
matches = bf.match(des1, des2)
# 按照距离的升序排序,以便最好的匹配项(距离较短的)出现在前面
matches = sorted(matches, key=lambda x: x.distance)
# 只抽取前10场匹配绘制(只是为了更便于可视化)。
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()
参考
以上是关于OpenCV中的特征匹配(Feature Matching)的主要内容,如果未能解决你的问题,请参考以下文章