opencv+python实现图像匹配—-模板匹配、特征点匹配

opencv+python实现图像匹配—-模板匹配、特征点匹配文章目录模板匹配与特征匹配 python 的版本及依赖的库的安装 opencv python 模板匹配 1 匹配材料 TemplateMatc python 特征匹配 2 匹配材料 BFMatching 描述特征点运行结果不精确基于 FLANN 的匹配器 FLANNbasedMa 描述特征点基于 FLANN 的匹配器 FLANNbasedMa 定位图片参考资料模

模板匹配与特征匹配

  • 模板匹配:模板匹配是一种最原始、最基本的模式识别方法,研究某一特定对象物的图案位于图像的什么地方,进而识别对象物,这就是一个匹配问题。它是图像处理中最基本、最常用的匹配方法。模板匹配具有自身的局限性,主要表现在它只能进行平行移动,若原图像中的匹配目标发生旋转或大小变化,该算法无效。
  • 特征匹配:所谓特征匹配(FBM),就是指将从影像中提取的特征作为共轭实体,而将所提特征属性或描述参数(实际上是特征的特征,也可以认为是影像的特征)作为匹配实体,通过计算匹配实体之间的相似性测度以实现共轭实体配准的影像匹配方法。在匹配目标发生旋转或大小变化时,该算法依旧有效。

python的版本及依赖的库的安装

#版本python 3.7.1 pip install numpy==1.15.3 pip install matplotlib==3.0.1 pip install opencv-python==3.4.2.16 pip install opencv-contrib-python==3.4.2.16 

opencv+python模板匹配1

匹配材料

  • 目标图片:target.jpg
    target

  • 模板图片:template.jpg
    template

模板匹配Template Matching—-单目标匹配

#opencv模板匹配----单目标匹配 import cv2 #读取目标图片 target = cv2.imread("target.jpg") #读取模板图片 template = cv2.imread("template.jpg") #获得模板图片的高宽尺寸 theight, twidth = template.shape[:2] #执行模板匹配,采用的匹配方式cv2.TM_SQDIFF_NORMED result = cv2.matchTemplate(target,template,cv2.TM_SQDIFF_NORMED) #归一化处理 cv2.normalize( result, result, 0, 1, cv2.NORM_MINMAX, -1 ) #寻找矩阵(一维数组当做向量,用Mat定义)中的最大值和最小值的匹配结果及其位置 min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result) #匹配值转换为字符串 #对于cv2.TM_SQDIFF及cv2.TM_SQDIFF_NORMED方法min_val越趋近与0匹配度越好,匹配位置取min_loc #对于其他方法max_val越趋近于1匹配度越好,匹配位置取max_loc strmin_val = str(min_val) #绘制矩形边框,将匹配区域标注出来 #min_loc:矩形定点 #(min_loc[0]+twidth,min_loc[1]+theight):矩形的宽高 #(0,0,225):矩形的边框颜色;2:矩形边框宽度 cv2.rectangle(target,min_loc,(min_loc[0]+twidth,min_loc[1]+theight),(0,0,225),2) #显示结果,并将匹配值显示在标题栏上 cv2.imshow("MatchResult----MatchingValue="+strmin_val,target) cv2.waitKey() cv2.destroyAllWindows() 

模板匹配Template Matching—-多目标匹配

  • 目标图片:target.jpg
    多目标匹配目标图片

#opencv模板匹配----多目标匹配 import cv2 import numpy #读取目标图片 target = cv2.imread("target.jpg") #读取模板图片 template = cv2.imread("template.jpg") #获得模板图片的高宽尺寸 theight, twidth = template.shape[:2] #执行模板匹配,采用的匹配方式cv2.TM_SQDIFF_NORMED result = cv2.matchTemplate(target,template,cv2.TM_SQDIFF_NORMED) #归一化处理 #cv2.normalize( result, result, 0, 1, cv2.NORM_MINMAX, -1 ) #寻找矩阵(一维数组当做向量,用Mat定义)中的最大值和最小值的匹配结果及其位置 min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result) #绘制矩形边框,将匹配区域标注出来 #min_loc:矩形定点 #(min_loc[0]+twidth,min_loc[1]+theight):矩形的宽高 #(0,0,225):矩形的边框颜色;2:矩形边框宽度 cv2.rectangle(target,min_loc,(min_loc[0]+twidth,min_loc[1]+theight),(0,0,225),2) #匹配值转换为字符串 #对于cv2.TM_SQDIFF及cv2.TM_SQDIFF_NORMED方法min_val越趋近与0匹配度越好,匹配位置取min_loc #对于其他方法max_val越趋近于1匹配度越好,匹配位置取max_loc strmin_val = str(min_val) #初始化位置参数 temp_loc = min_loc other_loc = min_loc numOfloc = 1 #第一次筛选----规定匹配阈值,将满足阈值的从result中提取出来 #对于cv2.TM_SQDIFF及cv2.TM_SQDIFF_NORMED方法设置匹配阈值为0.01 threshold = 0.01 loc = numpy.where(result<threshold) #遍历提取出来的位置 for other_loc in zip(*loc[::-1]): #第二次筛选----将位置偏移小于5个像素的结果舍去 if (temp_loc[0]+5<other_loc[0])or(temp_loc[1]+5<other_loc[1]): numOfloc = numOfloc + 1 temp_loc = other_loc cv2.rectangle(target,other_loc,(other_loc[0]+twidth,other_loc[1]+theight),(0,0,225),2) str_numOfloc = str(numOfloc) #显示结果,并将匹配值显示在标题栏上 strText = "MatchResult----MatchingValue="+strmin_val+"----NumberOfPosition="+str_numOfloc cv2.imshow(strText,target) cv2.waitKey() cv2.destroyAllWindows() 

opencv+python特征匹配2

匹配材料

  • 目标图片:target.jpg
    target

  • 模板图片:template_adjst.jpg
    template_adjst

BFMatching描述特征点–运行结果不精确

#opencv----特征匹配----BFMatching import cv2 from matplotlib import pyplot as plt #读取需要特征匹配的两张照片,格式为灰度图。 template=cv2.imread("template_adjust.jpg",0) target=cv2.imread("target.jpg",0) orb=cv2.ORB_create()#建立orb特征检测器 kp1,des1=orb.detectAndCompute(template,None)#计算template中的特征点和描述符 kp2,des2=orb.detectAndCompute(target,None) #计算target中的 bf = cv2.BFMatcher(cv2.NORM_HAMMING,crossCheck=True) #建立匹配关系 mathces=bf.match(des1,des2) #匹配描述符 mathces=sorted(mathces,key=lambda x:x.distance) #据距离来排序 result= cv2.drawMatches(template,kp1,target,kp2,mathces[:40],None,flags=2) #画出匹配关系 plt.imshow(result),plt.show() #matplotlib描绘出来 

基于FLANN的匹配器(FLANN based Matcher)描述特征点

#  ''' 基于FLANN的匹配器(FLANN based Matcher) 1.FLANN代表近似最近邻居的快速库。它代表一组经过优化的算法,用于大数据集中的快速最近邻搜索以及高维特征。 2.对于大型数据集,它的工作速度比BFMatcher快。 3.需要传递两个字典来指定要使用的算法及其相关参数等 对于SIFT或SURF等算法,可以用以下方法: index_params = dict(algorithm = FLANN_INDEX_KDTREE, trees = 5) 对于ORB,可以使用以下参数: index_params= dict(algorithm = FLANN_INDEX_LSH, table_number = 6, # 12 这个参数是searchParam,指定了索引中的树应该递归遍历的次数。值越高精度越高 key_size = 12, # 20 multi_probe_level = 1) #2 ''' import cv2 as cv from matplotlib import pyplot as plt queryImage=cv.imread("template_adjust.jpg",0) trainingImage=cv.imread("target.jpg",0)#读取要匹配的灰度照片 sift=cv.xfeatures2d.SIFT_create()#创建sift检测器 kp1, des1 = sift.detectAndCompute(queryImage,None) kp2, des2 = sift.detectAndCompute(trainingImage,None) #设置Flannde参数 FLANN_INDEX_KDTREE=0 indexParams=dict(algorithm=FLANN_INDEX_KDTREE,trees=5) searchParams= dict(checks=50) flann=cv.FlannBasedMatcher(indexParams,searchParams) matches=flann.knnMatch(des1,des2,k=2) #设置好初始匹配值 matchesMask=[[0,0] for i in range (len(matches))] for i, (m,n) in enumerate(matches): if m.distance< 0.5*n.distance: #舍弃小于0.5的匹配结果 matchesMask[i]=[1,0] drawParams=dict(matchColor=(0,0,255),singlePointColor=(255,0,0),matchesMask=matchesMask,flags=0) #给特征点和匹配的线定义颜色 resultimage=cv.drawMatchesKnn(queryImage,kp1,trainingImage,kp2,matches,None,drawParams) #画出匹配的结果 plt.imshow(resultimage,),plt.show() 

基于FLANN的匹配器(FLANN based Matcher)定位图片

#基于FLANN的匹配器(FLANN based Matcher)定位图片 import numpy as np import cv2 from matplotlib import pyplot as plt MIN_MATCH_COUNT = 10 #设置最低特征点匹配数量为10 template = cv2.imread('template_adjust.jpg',0) # queryImage target = cv2.imread('target.jpg',0) # trainImage # Initiate SIFT detector创建sift检测器 sift = cv2.xfeatures2d.SIFT_create() # find the keypoints and descriptors with SIFT kp1, des1 = sift.detectAndCompute(template,None) kp2, des2 = sift.detectAndCompute(target,None) #创建设置FLANN匹配 FLANN_INDEX_KDTREE = 0 index_params = dict(algorithm = FLANN_INDEX_KDTREE, trees = 5) search_params = dict(checks = 50) flann = cv2.FlannBasedMatcher(index_params, search_params) matches = flann.knnMatch(des1,des2,k=2) # store all the good matches as per Lowe's ratio test. good = [] #舍弃大于0.7的匹配 for m,n in matches: if m.distance < 0.7*n.distance: good.append(m) if len(good)>MIN_MATCH_COUNT: # 获取关键点的坐标 src_pts = np.float32([ kp1[m.queryIdx].pt for m in good ]).reshape(-1,1,2) dst_pts = np.float32([ kp2[m.trainIdx].pt for m in good ]).reshape(-1,1,2) #计算变换矩阵和MASK M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 5.0) matchesMask = mask.ravel().tolist() h,w = template.shape # 使用得到的变换矩阵对原图像的四个角进行变换,获得在目标图像上对应的坐标 pts = np.float32([ [0,0],[0,h-1],[w-1,h-1],[w-1,0] ]).reshape(-1,1,2) dst = cv2.perspectiveTransform(pts,M) cv2.polylines(target,[np.int32(dst)],True,0,2, cv2.LINE_AA) else: print( "Not enough matches are found - %d/%d" % (len(good),MIN_MATCH_COUNT)) matchesMask = None draw_params = dict(matchColor=(0,255,0), singlePointColor=None, matchesMask=matchesMask, flags=2) result = cv2.drawMatches(template,kp1,target,kp2,good,None,draw_params) plt.imshow(result, 'gray') plt.show() 

参考资料


  1. 模板匹配英文版教程–opencv–version:3.4.2
    模板匹配中文版教程–opencv–version:2.3.2 ↩︎

  2. FLANN特征点匹配英文版教程–opencv–version:3.4.2
    FLANN特征点匹配中文版教程–opencv–version:2.3.2 ↩︎

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/210418.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月19日 上午7:38
下一篇 2026年3月19日 上午7:38


相关推荐

  • C++和java的区别和联系「建议收藏」

    C++和java的区别和联系「建议收藏」最近在看C++和java的基础知识,对它们面向对象编程的概念还不是很了解,但觉得它们之间有很多相通的地方,现在java比较热门,觉得使用java的框架可以做很多很多事情,而对C++的认识只知道在游戏开发上面用的比较多,自己接触编程还是太少,想要一点一点地积累进步,需要向很多大神和牛人学习经验。

    2022年7月7日
    31
  • 【从零开始自制CPU之学习篇02】555定时器

    【从零开始自制CPU之学习篇02】555定时器555定时器是一种集成电路芯片,常被用于定时器、脉冲产生器和震荡电路。在CPU制作中作为pc(程序计数器)的主要组成部分。以下是我购买的NE555实拍图:NE555的针脚示意图:555定时器各针脚

    2022年8月5日
    7
  • pycharm的配置环境

    pycharm的配置环境1 点开你的 pycharm 创建一个 python 文件 2 对文件进行命名 然后点击上面的 File 下的 settings3 进入设置后再点击 project 下的 interpreter4 点开 interpreter 会出现什么都没有的情况 我的是配置好的请忽略 点击上面类似齿轮的图标 5 你就会进入下个设置里面 会出现两栏 点击下面的 Exstingenvir 再点击后面的那个省略号 6 找到你下载 python 解释器的位置 找到 python exe 并点击 最后点击 OK 就可以了

    2026年3月27日
    2
  • python初级:基础知识-字符串

    python初级:基础知识-字符串

    2021年10月6日
    48
  • Oracle数据库运维方案及优化

    Oracle数据库运维方案及优化Oracle数据库优化运维优化文章目录Oracle数据库优化前言:Oracle数据库性能优化一为啥要运维,运维哪些内容?二检查数据库基本状况2.1检查Oracle实例状态2.2检查Oracle服务进程2.3检查Oracle监听状态三检查系统和oracle日志文件四检查Oracle对象状态前言:在上一篇文章中我们讲了关于Oracle数据库的性能方面的优化,这篇文章咱们讲讲关于运维方面的优化吧。上一篇文章的地址:Oracle数据库性能优化一为啥要运维,运维哪些内容?数据库的运维主

    2025年8月19日
    9
  • 安卓 使用Gradle生成正式签名apk文件「建议收藏」

    安卓 使用Gradle生成正式签名apk文件

    2022年3月2日
    39

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号