python 模板匹配原理与实战

python 模板匹配原理与实战1 简述为了让大家不至于看到后面的公式就退却 我先简单描述一下模板匹配的原理 简单来说 模板匹配就是你拿一个模板 图片 在目标图片上依次滑动 每次计算模板与模板下方的子图的相似度 最后我们就计算出了非常多的相似度 如果你只是单个目标的匹配 那你只需要取相似度最大值所在的位置就可以得出匹配位置 如果你要匹配多个目标 那就设定一个阈值 就是说 只要咋俩的相似度大于比如 0 8 我就认为你是我要匹配的目标 2 原理 2 1 原理步骤你有一张模板图像 TTT 和一张较大的待搜索图像 III 模板匹配是

1. 简述

为了让大家不至于看到后面的公式就退却,我先简单描述一下模板匹配的原理:

  • 简单来说,模板匹配就是你拿一个模板(图片)在目标图片上依次滑动,每次计算模板与模板下方的子图的相似度,最后我们就计算出了非常多的相似度;
  • 如果你只是单个目标的匹配,那你只需要取相似度最大值所在的位置就可以得出匹配位置;
  • 如果你要匹配多个目标,那就设定一个阈值,就是说,只要咋俩的相似度大于比如0.8,我就认为你是我要匹配的目标。

2. 原理

2.1 计算步骤

  • 你有一张模板图像 T T T和一张较大的待搜索图像 I I I,模板匹配是一种用于在较大图像中搜索和查找模板图像位置的方法。
  • 具体就是将模板图​​像滑动到输入图像上(就像在卷积操作一样),然后在模板图像下比较模板和输入图像的子图的相似度(以下会介绍几种不同的相似度度量方法)。
  • 它返回一个灰度图像,其中每个像素表示该像素的邻域与模板匹配的相似度。如果输入图像的大小(WxH)和模板图像的大小(wxh),则输出图像的大小将为(W-w + 1,H-h + 1)
  • 获得相似度图像之后,在其上查找最大相似度所在的像素。将其作为匹配区域矩形的左上角,并以(w,h)作为矩形的宽度和高度。该矩形是与模板匹配的区域。
  • 下面放da张图,免得大家看得太枯燥。大概用省略号的方式表示滑动操作:
    在这里插入图片描述

2.2 相似度度量指标

  • 差值平方和匹配 CV_TM_SQDIFF
  • 标准化差值平方和匹配 CV_TM_SQDIFF_NORMED
  • 相关匹配 CV_TM_CCORR
  • 标准相关匹配 CV_TM_CCORR_NORMED
  • 相关匹配 CV_TM_CCOEFF
  • 标准相关匹配 CV_TM_CCOEFF_NORMED

下面的描述多数是公式,其中 T T T表示模板图像, I I I表示目标图像$, R R R表示相似度矩阵
为了简化表示,下述公式仅表示模板与图像中某个位置 ( x , y ) (x, y) (x,y)的相似度函数

2.2.1 差值平方和匹配 CV_TM_SQDIFF

  • 原理: 计算模板与某个子图的对应像素的差值平方和。
  • 越相似该值越小
  • R ( x , y ) = ∑ x ′ , y ′ ( T ( x ′ , y ′ ) − I ( x + x ′ , y + y ′ ) ) 2 R(x, y) = \sum_{x’,y’}{(T(x’, y’) – I(x+x’, y+y’))^2} R(x,y)=x,y(T(x,y)I(x+x,y+y))2

其中, ( x , y ) (x, y) (x,y)是相对于目标大图I左上角的坐标, ( x ′ , y ′ ) (x’, y’) (x,y)是相对于模板或者当前子图的左上角的坐标,那么 ( x + x ′ , y + y ′ ) (x+x’, y+y’) (x+x,y+y)就是当前子图上的某个点 ( x ′ , y ′ ) (x’, y’) (x,y)相对于目标大图的绝对坐标。

2.2.2 标准化差值平方和匹配 CV_TM_SQDIFF_NORMED

  • 标准化的差值平方和
  • 越相似该值越小
  • R ( x , y ) = ∑ x ′ , y ′ ( T ( x ′ , y ′ ) − I ( x + x ′ , y + y ′ ) ) 2 ∑ x ′ , y ′ T ( x ′ , y ′ ) 2 ∑ x ′ , y ′ I ( x + x ′ , y + y ′ ) 2 R(x, y) = \frac{\sum_{x’,y’}{(T(x’, y’) – I(x+x’, y+y’))^2}}{\sqrt{\sum_{x’, y’}{T(x’, y’)^2}\sum_{x’, y’}{I(x+x’, y+y’)^2}}} R(x,y)=x,yT(x,y)2x,yI(x+x,y+y)2
    x,y(T(x,y)I(x+x,y+y))2

这种标准化操作可以保证当模板和图像各个像素的亮度都乘上了同一个系数时,相关度不发生变化。也就是说当 I ( x , y ) I(x,y) I(x,y) T ( x , y ) T(x,y) T(x,y)变为 k × I ( x , y ) k×I(x,y) k×I(x,y) k × T ( x , y ) k×T(x,y) k×T(x,y)时, R ( x , y ) R(x,y) R(x,y)不发生变化。

2.2.3 相关匹配 CV_TM_CCORR

  • 模板与子图对应位置相乘,可以将其看作是差值平方和平方项展开之后中间的那个 2 a b 2ab 2ab
  • 越相似该值越大
  • R ( x , y ) = ∑ x ′ , y ′ ( T ( x ′ , y ′ ) × I ( x + x ′ , y + y ′ ) ) R(x, y) = \sum_{x’,y’}{(T(x’, y’) \times I(x+x’, y+y’))} R(x,y)=x,y(T(x,y)×I(x+x,y+y))

2.2.4 标准相关匹配 CV_TM_CCORR_NORMED

  • 标准化的相关匹配,
  • 和标准化差值平方和匹配类似,都是去除了亮度线性变化对相似度计算的影响。可以保证图像和模板同时变亮或变暗k倍时结果不变。
  • 越相似该值越大
  • R ( x , y ) = ∑ x ′ , y ′ ( T ( x ′ , y ′ ) × I ( x + x ′ , y + y ′ ) ) ∑ x ′ , y ′ T ( x ′ , y ′ ) 2 ∑ x ′ , y ′ I ( x + x ′ , y + y ′ ) 2 R(x, y) = \frac{\sum_{x’,y’}{(T(x’, y’) \times I(x+x’, y+y’))}}{\sqrt{\sum_{x’, y’}{T(x’, y’)^2}\sum_{x’, y’}{I(x+x’, y+y’)^2}}} R(x,y)=x,yT(x,y)2x,yI(x+x,y+y)2
    x,y(T(x,y)×I(x+x,y+y))

2.2.5 相关匹配 CV_TM_CCOEFF

  • 这种方法也叫做相关匹配,但是,这里是把图像和模板都减去了各自的平均值,使得这两幅图像都没有直流分量。
  • 越相似该值越大

T ′ ( x , y ) = T ( x , y ) − ∑ x ′ , y ′ T ( x ′ , y ′ ) w × h T'(x,y)=T(x,y)-\frac{\sum_{x’, y’}{T(x’, y’)}}{w \times h} T(x,y)=T(x,y)w×hx,yT(x,y)

I ′ ( x , y ) = I ( x , y ) − ∑ x ′ , y ′ I ( x ′ , y ′ ) w × h I'(x,y)=I(x,y)-\frac{\sum_{x’, y’}{I(x’, y’)}}{w \times h} I(x,y)=I(x,y)w×hx,yI(x,y)

R ( x , y ) = ∑ x ′ , y ′ ( T ′ ( x ′ , y ′ ) × I ′ ( x + x ′ , y + y ′ ) ) R(x, y) = \sum_{x’,y’}{(T'(x’, y’) \times I'(x+x’, y+y’))} R(x,y)=x,y(T(x,y)×I(x+x,y+y))

2.2.6 标准相关匹配 CV_TM_CCOEFF_NORMED

  • 具体的说,就是在减去了各自的平均值之外,还要各自除以各自的方差。
  • 经过减去平均值和除以方差这么两步操作之后,无论是我们的目标图像还是模板都被标准化了,这样可以保证图像和模板分别改变光照不影响计算结果。
  • 越相似该值越大
  • 计算出的相关系数被限制在了 -1 到 1 之间,1 表示完全相同,-1 表示两幅图像的亮度正好相反,0 表示两幅图像之间没有线性关系。

T ′ ( x , y ) = T ( x , y ) − ∑ x ′ , y ′ T ( x ′ , y ′ ) w × h ∑ x ′ , y ′ T ( x ′ , y ′ ) 2 T'(x,y)=\frac{T(x,y)-\frac{\sum_{x’, y’}{T(x’, y’)}}{w \times h}}{\sqrt{\sum_{x’, y’}{T(x’, y’)^2}}} T(x,y)=x,yT(x,y)2
T(x,y)w×hx,yT(x,y)

I ′ ( x , y ) = I ( x , y ) − ∑ x ′ , y ′ I ( x ′ , y ′ ) w × h ∑ x ′ , y ′ I ( x ′ , y ′ ) 2 I'(x,y)=\frac{I(x,y)-\frac{\sum_{x’, y’}{I(x’, y’)}}{w \times h}}{\sum_{x’, y’}{I(x’, y’)^2}} I(x,y)=x,yI(x,y)2I(x,y)w×hx,yI(x,y)

R ( x , y ) = ∑ x ′ , y ′ ( T ′ ( x ′ , y ′ ) × I ′ ( x + x ′ , y + y ′ ) ) R(x, y) = \sum_{x’,y’}{(T'(x’, y’) \times I'(x+x’, y+y’))} R(x,y)=x,y(T(x,y)×I(x+x,y+y))

3. python实战

3.1 单模板匹配单个目标(同时测试不同的相似度度量指标)

import cv2 from matplotlib import pyplot as plt img = cv2.imread('image3.png', 0) img2 = img.copy() template = cv2.imread('roi3.png', 0) w, h = template.shape[::-1] # All the 6 methods for comparison in a list methods = ['cv2.TM_CCOEFF', 'cv2.TM_CCOEFF_NORMED', 'cv2.TM_CCORR', 'cv2.TM_CCORR_NORMED', 'cv2.TM_SQDIFF', 'cv2.TM_SQDIFF_NORMED'] plt.subplot(4, 2, 1) plt.imshow(template, cmap='gray') plt.title('Template Image'), plt.xticks([]), plt.yticks([]) plt.subplot(4, 2, 2) plt.imshow(img, cmap='gray') plt.title('Target Image'), plt.xticks([]), plt.yticks([]) for i, meth in enumerate(methods): img = img2.copy() method = eval(meth) # Apply template Matching res = cv2.matchTemplate(img, template, method) min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res) # If the method is TM_SQDIFF or TM_SQDIFF_NORMED, take minimum if method in [cv2.TM_SQDIFF, cv2.TM_SQDIFF_NORMED]: top_left = min_loc else: top_left = max_loc bottom_right = (top_left[0] + w, top_left[1] + h) cv2.rectangle(img, top_left, bottom_right, 255, 2) plt.subplot(4, 2, i+3) plt.imshow(img, cmap='gray') plt.title('Matching Result by {}'.format(meth)), plt.xticks([]), plt.yticks([]) plt.show() 

在这里插入图片描述

3.2 单模板匹配多个目标

import cv2 import numpy as np from matplotlib import pyplot as plt img_rgb = cv2.imread('image1.jpg') img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY) template = cv2.imread('roi1.png', 0) w, h = template.shape[::-1] plt.subplot(131) plt.imshow(template) plt.subplot(132) plt.imshow(img_rgb) res = cv2.matchTemplate(img_gray,template,cv2.TM_CCOEFF_NORMED) threshold = 0.8 loc = np.where(res >= threshold) for pt in zip(*loc[::-1]): cv2.rectangle(img_rgb, pt, (pt[0] + w, pt[1] + h), (255, 255, 255), 2) plt.subplot(133) plt.imshow(img_rgb) plt.show() 

在这里插入图片描述

3.3 多模板匹配多个目标

import cv2 import numpy as np from matplotlib import pyplot as plt img_rgb = cv2.imread('image4.jpg') img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY) template1 = cv2.imread('roi4_1.png', 0) template2 = cv2.imread('roi4_2.png', 0) template3 = cv2.imread('roi4_3.png', 0) template_list = ['roi4_1.png', 'roi4_2.png', 'roi4_3.png'] w1, h1 = template1.shape[::-1] w2, h2 = template1.shape[::-1] w3, h3 = template1.shape[::-1] plt.subplot(131) plt.imshow(template1) plt.subplot(132) plt.imshow(template2) plt.subplot(133) plt.imshow(template3) plt.show() for i in range(len(template_list)): template = cv2.imread(template_list[i], 0) w, h = template.shape[::-1] res = cv2.matchTemplate(img_gray, template, cv2.TM_CCOEFF_NORMED) threshold = 0.65 loc = np.where(res >= threshold) for pt in zip(*loc[::-1]): gray = int(255/(i+1)) cv2.rectangle(img_rgb, pt, (pt[0] + w, pt[1] + h), (gray, gray, gray), 2) plt.imshow(img_rgb) plt.show() 

在这里插入图片描述
在这里插入图片描述

4. 算法优化

4.1 速度优化

这一块我没有看过opencv的优化方法,但是可想而知,直接滑动窗口效率是极其低下的,他们一定不会用这种方法。

  • 我看到的一些相关文章,我没仔细看,放个链接
    https://www.cnblogs.com/imageshop/p/6108764.html
  • 另外我自己的一点想法,因为之前看过卷积网络的卷积优化,而卷积操作的原理就是滑动窗口,那么,就可以将滑动窗口操作改成矩阵运算,具体可以看我之前写过的github博客:各种卷积操作及其矩阵运算。

4.2 精度优化

  • 多尺度模板匹配
  • 旋转目标模板匹配
  • 非极大值抑制
    https://juejin.im/post/5ee51d4546d72d42ce
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

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

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • UVA 12627 – Erratic Expansion

    UVA 12627 – Erratic Expansion

    2022年2月4日
    42
  • intellj 激活码2021(最新序列号破解)

    intellj 激活码2021(最新序列号破解),https://javaforall.net/100143.html。详细ieda激活码不妨到全栈程序员必看教程网一起来了解一下吧!

    2022年3月18日
    108
  • 超详细的ENSP安装教程附下载地址「建议收藏」

    超详细的ENSP安装教程附下载地址「建议收藏」下载完成后解压,可以得到如下图四个文件:这里面,我们先安装2、3、4,ensp需要下面软件安装完成后方可进行安装。VirtualBox虚拟机安装:这里我们双击运行程序,点击下一步这里面我们可以设置安装的路径,如需设置点击浏览选择安装的路径即可,建议默认,点击下一步这里面默认,选择下一步这里面开始安装,选择是点击安装等待安装完成安装完成后点击完成即可,这里虚拟机就安装完成了。下面我们开始安装Wireshark。……

    2022年10月14日
    2
  • Ubuntu中Unable to acquire the dpkg frontend lock (/var/lib/dpkg/lock-frontend)问题的解决「建议收藏」

    Ubuntu中Unable to acquire the dpkg frontend lock (/var/lib/dpkg/lock-frontend)问题的解决「建议收藏」环境:Ubuntu18.04-amd64问题描述:在ubuntu下安装mysql时,进行apt-get操作,出现了如下报错:参考了一篇博客,已经解决问题。现将步骤记录下来。解决办法:第一种情况: 进程中存在与apt相关的正在运行的进程: 首先检查是否在运行apt,apt-get相关的进程psaux|grep-iapt如果存在与apt相关的正在运行的进程…

    2022年10月7日
    4
  • Modelsim 安装步骤详解

    Modelsim 安装步骤详解Modelsim安装步骤详解目录一、modelsim简述及下载1、简介及特点2、modelsim版本3、modelsim下载二、安装步骤详解三、注册简述四、总结与参考资料1、总结2、参考资料目录本篇文章主要对ModelsimSE版本安装步骤的介绍。一、modelsim简述及下载1、简介及特点简介modelsim是Mentor公司开发的优秀的HDL语言仿真软件。它能提供友好的仿真环境,采用单内核支持VHDL和Verilog混合仿真的仿真器。它采用直接优化的编译技术、Tcl/Tk技术和单

    2022年5月10日
    54
  • latex IEEEtran bib参考文献title双引号

    latex IEEEtran bib参考文献title双引号1.我想在其他latex文档中,使用IEEEtran.bst所定义的格式去引用参考文献,我的参考文献的具体信息存放在cankao.bib文件中了;然后我就使用下面两句引用参考文献;文献也能引用,也能正常显示,就是title上没有双引号,与IEEE提供的模板出现的参考文献有些差异;\bibliographystyle{IEEEtran}\bibliography{IEEEabrv,cankao}{}2.我这个傻叉捣鼓了两天,发现我所使用的文档中有一个语句已经定义了参考文献的格式,语句的内容如下

    2022年6月25日
    44

发表回复

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

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