首页 > 编程语言 >opencv-python特征匹配

opencv-python特征匹配

时间:2023-08-08 22:45:06浏览次数:40  
标签:匹配 python cv2 opencv 特征 img2 img1 match

本章节介绍暴力特征匹配,FLANN特征匹配等。

根据前面章节获取的图像特征点和描述子之后,可以将两幅图像进行特征匹配。

1 暴力特征匹配

通过枚举的方式进行特征匹配,使用第一幅图像中一个特征的描述子,并使用一些距离计算将其与第二幅图像中的所有其他特征匹配,返回最近的一个。

opencv中提供的函数是:BFMatcher(normType,crossCheck) 

normType表示计算距离的方式(L1距离,即绝对值;L2距离,即平方;汉明距离,ORB使用)

crossCheck:是否进行交叉匹配,默认false


然后使用match函数进行特征点匹配,返回的对象是DMatch对象,该对象具有以下属性:
DMatch.distance 描述符之间的距离,越小越好。
DMatch.trainIdx 训练描述符(第二幅图的)中描述符的索引。
DMatch.queryIdx 查询描述符(第一幅图的)中描述符的索引。

DMatch.imgIdx 训练图像的索引。

最后用 drawMatches 绘制匹配的特征点。( drawMatches(img1, keypoints1, img2, keypoints2, matches1to2, outImg) )

使用暴力特征匹配对下面两幅图像的特征进行匹配:

   

import cv2
import numpy as np 

img1 = cv2.imread('./crop.png')
img2 = cv2.imread('./contours.png')

img_gray1 = cv2.cvtColor(img1,cv2.COLOR_BGR2GRAY)
img_gray2 = cv2.cvtColor(img2,cv2.COLOR_BGR2GRAY)

#创建特征检测对象
sift = cv2.xfeatures2d.SIFT_create()

#检测关键点和计算描述子
kp1,des1 = sift.detectAndCompute(img1,None)
kp2,des2 = sift.detectAndCompute(img2,None)

#进行暴力匹配
bf = cv2.BFMatcher(cv2.NORM_L2)

#进行匹配
match = bf.match(des1,des2)  #match(queryDescriptors,trainDescriptors)

print(len(match))
print(type(match))
print(match[2].distance) #match[2]的描述符之间的距离
print('queryIdx:',match[2].queryIdx) #第一幅图的匹配的第三个特征点的索引
print('zuobiao1:',kp1[match[2].queryIdx].pt) ##第一幅图的匹配的第三个特征点的坐标

print('trainIdx:',match[2].trainIdx)  #第二幅图的匹配的第三个特征点的索引
print('zuobiao2:',kp2[match[2].trainIdx].pt) ##第二幅图的匹配的第三个特征点的坐标

#绘制特征匹配
res = cv2.drawMatches(img1,kp1,img2,kp2,match,None)

cv2.imshow('res',res)
cv2.waitKey(0)
cv2.destroyAllWindows()

 匹配结果如下:

匹配的时候除了使用match函数进行匹配,也可以用knnmatch进行匹配(knn:最近邻算法)。

import cv2
import numpy as np   #用knnmatch进行匹配

img1 = cv2.imread('./crop.png')
img2 = cv2.imread('./contours.png')

img_gray1 = cv2.cvtColor(img1,cv2.COLOR_BGR2GRAY)
img_gray2 = cv2.cvtColor(img2,cv2.COLOR_BGR2GRAY)

#创建特征检测对象
sift = cv2.xfeatures2d.SIFT_create()

#检测关键点和计算描述子
kp1,des1 = sift.detectAndCompute(img1,None)
kp2,des2 = sift.detectAndCompute(img2,None)

#进行暴力匹配
bf = cv2.BFMatcher(cv2.NORM_L2)

#进行匹配
#match = bf.match(des1,des2)  #match(queryDescriptors,trainDescriptors)
match = bf.knnMatch(des1,des2,k=2) #处理match进行匹配,还可以用knnmatch进行匹配,一般k=2

good = [] #选择两个匹配对象中好一些的保存下来
for m,n in match:
    if m.distance < n.distance*0.7: #设定阈值,距离小于对方的0.7倍,认为是好的匹配点
        good.append(m)

print('match:',len(match))
print('good match:',len(good))
print(type(match))
print(match)


#绘制特征匹配
#res = cv2.drawMatches(img1,kp1,img2,kp2,match,None)
res = cv2.drawMatchesKnn(img1,kp1,img2,kp2,[good],None)  #knn绘制特征匹配

cv2.imshow('res',res)
cv2.waitKey(0)
cv2.destroyAllWindows()

2 FLANN 特征匹配

FLANN 是快速最近邻搜索包,特征匹配记录下目标图像和待匹配图像的特征点(keypoint),并根据特征点集合构造特征量(descriptor),对这个特征量进行比较,筛选,最终得到一个匹配点的映射集合,可以根据这个集合的大小来衡量两幅图像的匹配程度。在面对大数据集的时候效果要好于BFmatch算法。
FLANN特征匹配的函数是:FlannBasedMatcher(index_params, search_params) 

import cv2
import numpy as np 

img1 = cv2.imread('./crop.png')
img2 = cv2.imread('./contours.png')

img_gray1 = cv2.cvtColor(img1,cv2.COLOR_BGR2GRAY)
img_gray2 = cv2.cvtColor(img2,cv2.COLOR_BGR2GRAY)

#创建特征检测对象
sift = cv2.xfeatures2d.SIFT_create()

#检测关键点和计算描述子
kp1,des1 = sift.detectAndCompute(img1,None)
kp2,des2 = sift.detectAndCompute(img2,None)

#创建FLANN特征匹配对象
index_params = dict(algorithm=1,tree=5)
search_params = dict(checks=50)
flann = cv2.FlannBasedMatcher(index_params,search_params)

#进行特征匹配
matches = flann.match(des1,des2)

print(len(matches))

#绘制特征匹配
res = cv2.drawMatches(img1,kp1,img2,kp2,matches,None)

cv2.imshow('res',res)
cv2.waitKey(0)
cv2.destroyAllWindows()

FLANN 特征匹配结果如下:

用knnmatch来进行匹配:

import cv2
import numpy as np 

img1 = cv2.imread('./crop.png')
img2 = cv2.imread('./contours.png')

img_gray1 = cv2.cvtColor(img1,cv2.COLOR_BGR2GRAY)
img_gray2 = cv2.cvtColor(img2,cv2.COLOR_BGR2GRAY)

#创建特征检测对象
sift = cv2.xfeatures2d.SIFT_create()

#检测关键点和计算描述子
kp1,des1 = sift.detectAndCompute(img1,None)
kp2,des2 = sift.detectAndCompute(img2,None)

#创建FLANN特征匹配对象
index_params = dict(algorithm=1,tree=5)
search_params = dict(checks=50)
flann = cv2.FlannBasedMatcher(index_params,search_params)

#进行特征匹配
# matches = flann.match(des1,des2)

match = bf.knnMatch(des1,des2,k=2) #处理match进行匹配,还可以用knnmatch进行匹配,一般k=2

good = [] #选择两个匹配对象中好一些的保存下来
for m,n in match:
    if m.distance < n.distance*0.7: #设定阈值,距离小于对方的0.7倍,认为是好的匹配点
        good.append(m)

# print(len(matches))


res = cv2.drawMatchesKnn(img1,kp1,img2,kp2,[good],None)  #knn绘制特征匹配

cv2.imshow('res',res)
cv2.waitKey(0)
cv2.destroyAllWindows()

 

  

 

标签:匹配,python,cv2,opencv,特征,img2,img1,match
From: https://www.cnblogs.com/libai123456/p/17615438.html

相关文章

  • python 测试框架中的数据库连接类(mysql示例)
     1.数据库信息yaml文件conf_env.yamlhost:doname:demo.pab.com.cnport:80database:host:"db.fat.qa.pab.com.cn"user:"deploy"password:"thess"dbname:"testdb"charset:"utf8"2.与数据库yaml文件同级目录,创建配置conf......
  • python计算一个整数列表中所有元素的平均值
    defcalculate_average(numbers):  total=sum(numbers)  average=total/len(numbers)  returnaverage#示例输入number_list=[1,2,3,4,5]#调用函数并打印结果average_value=calculate_average(number_list)print("平均值为:",average_value)......
  • python计算一个整数列表中所有元素的平均值
    defcalculate_average(numbers):  total=sum(numbers)  average=total/len(numbers)  returnaverage#示例输入number_list=[1,2,3,4,5]#调用函数并打印结果average_value=calculate_average(number_list)print("平均值为:",average_value)......
  • python入门
    环境搭建:官网下载,pycharm编译器用于开发          Jupyter沙箱 变量:定义变量,变量名=变量  标识符(变量名)命名规则:变量名中,只能由数字字母划线三类组成,   不能以数字开头。不能使用内置关键字(函数名,定义函数的DEF)。  严格区分大小写(小写大写......
  • Python基础day62 DjangoAjax的传输应用
    前后端数据传输的编码格式(contentType)前后端数据传输的请求方式有两种:get、post我们只研究post请求的编码格式三种编码格式urlencodedform-datajson发送post请求的方式form表单Ajaxpostman(第三方工具,需要下载) form表单发送post请求的时候数据的编码格式请求头conten......
  • opencv-python特征检测
    本章节介绍Harris角点检测,SIFT关键点检测,shi-Tomasi角点检测,SURF特征检测,ORB特征检测。特征检测是提取图像信息,决定每个图像的点是否属于一个图像特征。其结果是把图像上的点分为不同的子集,这些子集往往属于孤立的点,连续的曲线或连续的区域。特征检测包括边缘检测,角检测,区域检测......
  • python实现pdf转word
    frompdf2docximportConverterimportPySimpleGUIassgdefpdf2word(file_path):file_name=file_path.split('.')[0]doc_file=f'{file_name}.docx'p2w=Converter(file_path)p2w.convert(doc_file,start=0,end=None)......
  • Python 装饰器
    装饰器的基本语法装饰器本质上就是“定义一个闭包并用语法糖@简练地调用该闭包”,从而实现把一个方法对象当做参数,传入到另一个方法中,然后返回一个增强功能的新方法对象。在Python中允许在一个方法中嵌套另一个方法,这种特殊的机制就叫做「闭包」,这个内部方法可以保留外部方法......
  • 软件测试|Python random模块,超乎想象的强大
    Python的random模块是一个非常强大的工具,用于生成随机数和随机选择。它提供了许多函数和方法,可以满足各种随机化需求。本文将介绍random模块的基本功能和常见用法,以帮助读者更好地理解和利用这个模块。返回整数random.randange()语法如下:random.randrange(stop)random.randrange(s......
  • Python中文件操作的详细使用:open()、os.open()和with open()
    前言在编程语言中,文件读写是最常见的IO操作,Python内置了读写文件的函数,其中包括open()函数、os.open()函数以及withopen()语句。本文将详细介绍这三种方法的使用方式、区别和最佳实践。open()open()函数是Python内置的用于打开文件的函数,它接受一个文件路径和打开模式作为参数,并返......