最近在做图像检测上的项目,需要进行图像匹配的相关内容,查阅了opencv的匹配方法,整理了模版匹配和特征点匹配的内容,并总结成博客。

模版匹配与特征点匹配

  • 模板匹配
    模版匹配是一种最原始、最基本的识别方法。简单来说,模板匹配就是用一幅已知的模板图片在目标图片上依次滑动(类似于滑窗法),每次滑动都计算模板与模板下方的目标子图的相似度
    但模板匹配具有一定的局限性,也是我在实际操作时发现的。局限性主要表现在模版图片只能在目标图标上进行平行移动,若原图像中的匹配目标发生旋转或大小变化,该算法无效。也就是说,如果模版图片和目标子图上的方向、大小不一致,则无法匹配成功。

  • 特征点匹配
    特征匹配(FBM),也称为角点匹配,就是指将从影像中提取的特征作为共轭实体,而将所提特征属性或描述参数(实际上是特征的特征)作为匹配实体,通过计算匹配实体之间的相似性测度以实现共轭实体配准的影像匹配方法。即指寻找两幅图像之间的特征像素点的对应关系,从而确定图像的位置关系。
    在匹配目标发生旋转或大小变化时,该算法依旧有效。

模版匹配

模板匹配就是用一幅已知的模板图片在目标图片上依次滑动(类似于滑窗法),每次滑动都计算模板与模板下方的目标子图的相似度

如果是单个目标的匹配,只需要取相似度最大值所在的位置就可以得到匹配位置。

如果要匹配多个目标,设定一个合理的阈值,只要相似度大于阈值则认为是匹配的目标。

# cv2中使用matchTemplate进行模版匹配
result = cv2.matchTemplate(target,template,cv2.method)

matchTemplate提供了六种模版匹配方法

  • cv2.TM_SQDIFF(差值平方和匹配):该方法计算模板与某个子图的对应像素的差值平方和。因此最佳的匹配结果在结果为0处,越相似值越小,值越大匹配结果越差。

  • cv2.TM_SQDIFF_NORMED(标准化差值平方和匹配):该方法使用归一化的平方差进行匹配,最佳匹配也在结果为0处。

  • cv2.TM_CCORR(相关匹配法):该方法使用源图像与模板图像的卷积结果进行匹配,因此,最佳匹配位置在值最大处,值越小匹配结果越差。

  • cv2.TM_CCORR_NORMED(归一化相关匹配):归一化的相关性匹配方法,去除了亮度线性变化对相似度计算的影响。可以保证图像和模板同时变量或变暗k倍时结果不变。与相关性匹配方法类似,最佳匹配位置也是在值最大处,越相似值越大。

  • cv2.TM_CCOEFF(相关性系数匹配方法):该方法使用源图像与其均值的差、模板与其均值的差二者之间的相关性进行匹配,最佳匹配结果在值等于1处,最差匹配结果在值等于-1处,值等于0直接表示二者不相关。

  • cv2.TM_CCOEFF_NORMED(归一化的相关性系数匹配方法):把图像和模板都减去了各自的平均值,再各自除以各自的方差,保证图像和模板分别改变光照不影响计算结果,计算出的相关系数限制在-1到1之间,1 表示完全相同,-1 表示两幅图像的亮度正好相反,0 表示没有线性关系。负值表示效果不好,正值表示匹配效果好。

#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)
#绘制矩形边框,将匹配区域标注出来
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()

FLANN特征点匹配

对图片提取SIFT特征并利用FLANN方法判别图像的相似度并可视化。

基于FLANN的匹配器(FLANN based Matcher)的特征匹配。FLANN库全称是Fast Library for Approximate Nearest Neighbors,它是目前最完整的(近似)最近邻开源库。不但实现了一系列查找算法,还包含了一种自动选取最快算法的机制。

  • 使用SIFT特征提取关键点;
  • 计算SIFT特征描述子;
  • 使用FLANN匹配器进行描述子向量匹配。

SIFT + Ratio Test

SIFT的大概流程描述:
在图中选择出一些比较有特色的点,并把他们编码成特征向量,现在要做两个图的特征点匹配,所以要用SIFT对两个图分别做特征点选择,并且每个特征点编码成相同维度的特征向量,比如都是长度为512的向量。两个图上的特征点数量是不一样的,比如第一个图有3个特征点,第二个图有5个特征点,要做特征点匹配的话,计算第一个图中3个点跟第二个图里的5个点两两之间的距离,这个距离一般就是向量的欧式距离。特征点匹配中,就是要找两个图中比较相似的特征点,特征点的特征向量越相近,说明这两个点附近的情况就越相似。

ratio test 筛选的思想:
首先找到图一中某一个特征点在图二中的最相似点和次相似点,然后把最相近点的距离跟次相近点的距离相除,获得一个ratio,这个值从直观上理解就是,最相近点比次相近点 更加相似的程度。ratio越小,就表示相近点比次相近点要更加相似很多,相反ratio越大,就表示相近点比次相近点都是一般相似。ratio test就是用ratio值去筛选,它认为:ratio小于一个特定的阈值,这对特征点匹配才会被接受,否则就筛选掉。因为ratio小的特征点对,说明最相近点比其它匹配点(次相近点在这里就代表了其它所有的特征点)都要明显很多,说明这一对匹配是非常有特色的,是可以保留的,保留了基本不会错,因为没有其它干扰因素;ratio比较大的时候,就说明这对匹配是存疑的,把最相近点换成次相近点的相似度也差不多,所以无法断定这一对特征点有没有匹配错,那么就把其筛选掉。Lowe推荐ratio的阈值为0.8。

FLANN特征匹配

我这边是有五个类的模版图,在目标图中进行特征匹配,判断属于哪一个类。我的思路则是依次进行特征匹配,比较最后特征点对点多少,从而判断更接近哪一类别。

import cv2
import os
from matplotlib import pyplot as pltdef FLANN():# flags=0 # 灰色读入目标图像targetPath = 'target.jpg'trainingImage = cv2.imread(targetPath, flags=0)# 灰色读所有模板图片templatePath = 'templatePath/'icons = os.listdir(templatePath)iconMatch= dict({'name': '未识别', 'value': 0})for icon in icons:queryImage = cv2.imread(templatePath + icon, 0)# 使用SIFT 检测角点sift = cv2.SIFT_create()kp1, des1 = sift.detectAndCompute(queryImage, None)kp2, des2 = sift.detectAndCompute(trainingImage, None)# 设置FLANN匹配器参数,定义FLANN匹配器,使用 KNN 算法实现匹配indexParams = dict(algorithm=0, trees=5)searchParams = dict(checks=50) flann = cv2.FlannBasedMatcher(indexParams,searchParams)matches = flann.knnMatch(des1,des2,k=2)# 根据matches生成相同长度的matchesMask列表,列表元素为[0,0]matchesMask = [[0,0] for i in range(len(matches))]matchNumber = 0# 去除错误匹配, 此处阈值设定为0.7for i,(m,n) in enumerate(matches):if m.distance < 0.7 * n.distance:matchesMask[i] = [1,0]matchNumber = matchNumber+1# 将图像显示# matchColor是两图的匹配连接线,连接线与matchesMask相关# singlePointColor是勾画关键点drawParams = dict(matchColor = (0,255,0), matchesMask = matchesMask[:50], flags = 0)resultImage = cv2.drawMatchesKnn(queryImage,kp1,trainingImage,kp2,matches[:50],None,**drawParams)if matchNumber > iconMatch['value']:iconMatch['name'] = icon.split('_')[0]iconMatch['value'] = matchNumberreturn resultImage, iconMatchif __name__ == '__main__':resultImage, res = FLANN()plt.imshow(resultImage)plt.show()

opencv+python图像匹配——模版匹配、特征点匹配相关推荐

  1. 基于树莓派opencv—Python的人脸面部特征框选(眼睛和微笑)

    广西●河池学院 广西高校重点实验室培训基地 系统控制与信息处理重点实验室 本篇博客来自河池学院: 智控无人机小组 写作时间: 2020年8月16日 一.测试相机 在树莓派上新建一个.py文件,将以下代 ...

  2. 特征点匹配——FREAK算法介绍

    FREAK算法是ICCV 2012上的一篇关于特征点检测与匹配的论文<FREAK: Fast Retina Keypoint>上提出的,从文章标题中可以看出来该算法的一个特点是快速,另外一 ...

  3. OpenCV—python 模板匹配与图像特征匹配

    文章目录 一.理论介绍与算法 二.算法代码 单目标匹配 多目标匹配 三 多尺度模板匹配 一.理论介绍与算法 模板匹配是在一幅图像中寻找一个特定目标的方法之一,这种方法的原理非常简单,遍历图像中的每一个 ...

  4. python opencv图片拼接、特征点匹配

    一.算法目的: 在同一位置拍摄的两幅或者多幅图像是单应性相关的的,使用该约束将很多图片缝补起来,拼成一个大的图像来创建全景图像.两张图片的拼接必须首先找到相同特征,也就是说两张照片必须要有重叠的部分才 ...

  5. Python+Opencv实现图像匹配——模板匹配

    1.原理 简单来说,模板匹配就是拿一个模板(图片)在目标图片上依次滑动,每次计算模板与模板下方的子图的相似度,最后就计算出了非常多的相似度: 如果只是单个目标的匹配,那只需要取相似度最大值所在的位置就 ...

  6. 【OpenCV + Python】模板匹配

    模板匹配是用来在一副大图中搜寻查找模版图像位置的方法.OpenCV 为我们提供了函数:cv2.matchTemplate().和2D 卷积一样,它也是用模板图像在输入图像(大图)上滑动,并在每一个位置 ...

  7. OpenCV + CPP 系列(卌一)图像特征匹配( FLANN 匹配)

    文章目录 一.FLANN简介 演示SURF--Flann 二.单应性矩阵 一.FLANN简介 FLANN库全称是Fast Library for Approximate Nearest Neighbo ...

  8. opencv上gpu版surf特征点与orb特征点提取及匹配实例

    opencv上gpu版surf特征点与orb特征点提取及匹配实例 标签: gpu版surfgpu orbsurf和orbgpu surf及orbsurf orb gpu 2016-09-25 23:4 ...

  9. OpenCV之feature2d 模块. 2D特征框架(2)特征描述 使用FLANN进行特征点匹配 使用二维特征点(Features2D)和单映射(Homography)寻找已知物体 平面物体检测

    特征描述 目标 在本教程中,我们将涉及: 使用 DescriptorExtractor 接口来寻找关键点对应的特征向量. 特别地: 使用 SurfDescriptorExtractor 以及它的函数  ...

  10. opencv 二维图像 特征检测 特征描述 特征匹配 平面物体识别跟踪

    github代码 一.Harris角点 cornerHarris() R = det(M) - k*(trace(M))^2  算法基本思想是使用一个固定窗口在图像上进行任意方向上的滑动,比较滑动前与 ...

最新文章

  1. 规格表管理之删除规格表数据
  2. 一步一步教你在 docker 容器下使用 mmdetection 训练自己的数据集
  3. python获取邮箱地址_Python操作邮箱
  4. 阿里秒杀系统架构优化思路
  5. 使用ACE_SOCK_SEQPACK_Association获取socket连接的本地及远程IP端口信息
  6. scala怎么做幂运算_Scala幂(幂)函数示例
  7. ASP.NET 用户控件自定义属性、方法、事件
  8. 开源 sql 代码提示工具_有关如何计划开源活动的提示
  9. 流量 起伏大_广西崇左的德天跨国大瀑布,一半是中国一半是越南,天下奇观!...
  10. 几种距离公式的总结思考
  11. C#二进制文件读取序列化与反序列化
  12. Win10系统(无GPU)环境/Anacoda:Python小白如何从入门到成功运行YoloV3图片+视频demo
  13. 诚诚富众选择投资理财产品
  14. IP数据报、TCP报文段
  15. html鼠标特效怎么设置到桌面,用CSS实现鼠标单击特效
  16. 手机上, 除了游戏, 还能做什么?
  17. 白盒测试方法|白盒测试的六种方法比较分析
  18. linux电脑访问android手机存储
  19. 操作系统课后答案第七章
  20. C++编程练习 计算一元二次方程组解判断是否测试过三种情况

热门文章

  1. java毕业设计网上教学系统mybatis+源码+调试部署+系统+数据库+lw
  2. wps带阴影的边框怎么设置_wps文字加阴影边框怎么设置
  3. ipython的用法详解
  4. ADF中在jspx页面加载的阶段添加自己的代码
  5. c语言中波浪线scanf,~scanf 波浪线
  6. 好货推荐!两款免费的 Linux 桌面录制工具
  7. 使用Rider和Emmylua进行UnLua配置
  8. Directx12 曲面细分详解
  9. 从零开始 DIY 智能家居 - 基于 ESP32 的智能语音合成播报模块
  10. excel计算机考试题库,2016年职称计算机考试题库EXCEL题库及答案