python opencv图像匹配_python opencv入门 特征匹配(38)

本文介绍了如何使用OpenCV进行图像特征匹配,包括暴力匹配(Brute-Force)和基于FLANN的匹配。通过ORB和SIFT算法,展示了如何创建BFMatcher对象并使用knnMatch进行比率测试以提高匹配准确性。同时,解释了FLANN匹配器在处理大数据集时的优势,以及如何设置其参数以优化搜索性能。
摘要由CSDN通过智能技术生成

内容来自OpenCV-Python Tutorials 自己翻译整理

目标:

学习匹配一副图片和其他图片的特征。

学习使用OpenCV中的Brute-Force匹配和FLANN匹配。

暴力匹配(Brute-Force)基础

暴力匹配很简单。首先在模板特征点描述符的集合当中找到第一个特征点,然后匹配目标图片的特征点描述符集合当中的所有特征点,匹配方式使用“距离”来衡量,返回“距离”最近的那个。

对于Brute-Force匹配,首先我们要使用cv2.BFMatcher()方法来创建一个BF匹配器的对象。

该方法包含两个可选参数

normType

crossCheck

normType指定了要使用的“距离”测量方法。缺省条件下,的参数是cv2.NORM_L2。

在使用SIFT方法和SURF方法等等进行匹配时,这种“距离”测量方法效果很好(cv2.NORM_L1也一样)。

在使用基于二进制字符串的描述符,像ORB,BRIEF,BRISK等等方法时,应该使用cv2.NORM_HAMMING,这种方法使用汉明距离来测量。如果ORB算法的参数设置为WAT_K==3或者4,那么应该使用cv2.NORM_HAMMING2。

crossCheck参数是boolean类型,缺省的情况下是false。如果crossCheck是true,那么匹配器返回只返回一个最佳的匹配(i,j),其中i在特征点描述符集合A当中,j在特征点描述符集合B当中,反之亦然。也就是两个集合当中的特征点都彼此配对。这种方法返回了一致的结果,并且可以很好的用来替代SIFT算法论文当中测试。

暴力匹配器有两个重要的方法,分别是BFMatcher.match() 和BFMatcher.knnMatch()。第一个返回最佳匹配,第二个返回前k个最佳的匹配,k值由用户指定。当我们需要做一些额外的工作时,这种方法会很有用。

就像在图像上绘制关键点的函数cv2.drawKeypoints()一样, cv2.drawMatches()函数可以绘制匹配结果。该方法将两张图片水平排列,然后从第一张图片到第二张图片绘制直线来现实最佳的匹配结果。cv2.drawMatchesKnn函数会画出所有k个最佳匹配。如果k=2,那么将会画出每个关键点之间的匹配直线。所以,如果我们想有选择的画出,那么要传递进一个蒙版。

下面的例子使用了SURF和ORB算法(分别使用了不同的“距离”测量方法)

ORB的暴力匹配:

下面的例子实现了匹配两个图片的特征点,本例子当中要去查询图片和训练图片。我们要在训练图片当中使用特征匹配来找到查询图片。

使用ORB描述符来匹配特征(文档里写成SIFT算法了)。

import numpy as np

import cv2

from matplotlib import pyplot as plt

img1 = cv2.imread('1.jpg',0)

img2 = cv2.imread('26.jpg',0)

orb = cv2.ORB_create()

kp1, des1 = orb.detectAndCompute(img1,None)

kp2, des2 = orb.detectAndCompute(img2,None)

bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)

matches = bf.match(des1,des2)

matches = sorted(matches, key = lambda x:x.distance)

img3=np.empty((300,300))

img3 = cv2.drawMatches(img1,kp1,img2,kp2,matches[:10], img3,flags=2)

plt.imshow(img3),plt.show()

原图

原来凤姐最美的是眼睛,不是嘴啊-_-|||

drawMatches函数的参数如下

outImg = cv.drawMatches( img1, keypoints1, img2, keypoints2, matches1to2, outImg[, matchColor[, singlePointColor[, matchesMask[, flags]]]] )

img1 第一张图片

keypoints1第一张图片的关键点

img2第二张图片

keypoints2第二章图片的关键点

matches1to2 选择第一张图到第二张图的多少个匹配点

outImg 输出图片

matchColor 匹配点颜色

singlePointColor 画出没匹配上的点

matchesMask 给出一个蒙版,表示那部分的匹配点不用画出来

flags DEFAULT = 0, DRAW_OVER_OUTIMG = 1, NOT_DRAW_SINGLE_POINTS = 2, DRAW_RICH_KEYPOINTS = 4

什么事匹配器对象?

matches = bf.match(des1,des2)结果返回一个列表,DMatch 有如下性质

DMatch.distance 描述符的“距离”,越小越好

DMatch.trainIdx 目标描述符的下标

DMatch.queryIdx 查询图像描述符的下标

DMatch.imgIdx 目标图像的下标

SIFT暴力匹配和比率测试

这次试用BFMatcher.knnMatch()来找到k个最佳匹配。在这个例子当中,我们选择k=2,这样可以使用Lowe论文中的比率测试了。

import numpy as np

import cv2

from matplotlib import pyplot as plt

img1 = cv2.imread('1.jpg',0)

img2 = cv2.imread('26.jpg',0)

sift = cv2.xfeatures2d.SIFT_create()

kp1, des1 = sift.detectAndCompute(img1,None)

kp2, des2 = sift.detectAndCompute(img2,None)

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])

img3=np.empty((300,300))

img3 = cv2.drawMatchesKnn(img1,kp1,img2,kp2,good, img3,flags=2)

plt.imshow(img3),plt.show()

不咋准…-_-

基于FLANN的匹配器

FLANN的意思是快速最近邻搜索库。它包含一个对大数据集合和高维特征实现最近邻搜索的算法集合,而且这些算法是优化固偶读。面对大数据集时,效果要比暴力搜索好。

FLANN要传递两个字典作为参数。

第一个参数是使用的搜索算法,详细内容见此处

第二个参数是搜索次数,次数越多,结果越精确,但是速度也越慢。

import numpy as np

import cv2

from matplotlib import pyplot as plt

img1 = cv2.imread('1.jpg',0)

img2 = cv2.imread('26.jpg',0)

sift = cv2.xfeatures2d.SIFT_create()

kp1, des1 = sift.detectAndCompute(img1,None)

kp2, des2 = sift.detectAndCompute(img2,None)

FLANN_INDEX_KDTREE = 0#kd树

index_params = dict(algorithm = FLANN_INDEX_KDTREE, trees = 5)

search_params = dict(checks=50) # or pass empty dictionary

flann = cv2.FlannBasedMatcher(index_params,search_params)

matches = flann.knnMatch(des1,des2,k=2)

# Need to draw only good matches, so create a mask

matchesMask = [[0,0] for i in range(len(matches))]

# ratio test as per Lowe's paper

for i,(m,n) in enumerate(matches):

if m.distance < 0.7*n.distance:

matchesMask[i]=[1,0]

draw_params = dict(matchColor = (0,255,0),

singlePointColor = (255,0,0),

matchesMask = matchesMask,

flags = 0)

img3=np.empty((300,300))

img3 = cv2.drawMatchesKnn(img1,kp1,img2,kp2,matches, img3,flags=2)

plt.imshow(img3),plt.show()

效果没有ORB算法实现的好呀

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值