OpenCV学习笔记(十一)——模板匹配

article/2025/11/9 21:09:35

模板匹配是指在当前图像A内寻找与图像B最相似的部分,一般将图像A称为输入图像,将图像B称为模板图像。模板匹配的操作方法是将模板图像B在图像A上滑动,遍历所有像素以完成匹配。

OpenCV学习笔记(十一)

      • 1. 模板匹配基础
      • 2. 多模板匹配
        • 2.1 获取匹配位置的集合
        • 2.2 循环
        • 2.3 在循环中使用函数zip()
        • 2.4 调整坐标
        • 2.5 标记匹配图像的位置
        • 2.6 多模板匹配案例

1. 模板匹配基础

result = cv2.matchTemplate(image, templ, method[, mask ] )

  • image 为原始图像,必须是8 位或者32 位的浮点型图像。
  • templ 为模板图像。它的尺寸必须小于或等于原始图像,并且与原始图像具有同样的类型。
  • method 为匹配方法。该参数通过TemplateMatchModes 实现,有6种可能的值,如表所示。

在这里插入图片描述

  • mask 为模板图像掩模。它必须和模板图像templ 具有相同的类型和大小。通常情况下该值使用默认值即可。当前,该参数仅支持TM_SQDIFF 和TM_CCORR_NORMED 两个值。
  • result 是由每个位置的比较结果组合所构成的一个结果
    集,类型是单通道32 位浮点型。如果输入图像(原始图像)尺寸是W * H,模板的尺寸是w * h,则返回值的大小为(W-w+1)*(H-h+1)。

如下图所示,结果result 的大小满足(W-w+1)*(H-h+1),在下图中就是(10-2+1)×(10-2+1),即9×9。也就是说,模板图像要在输入图像内总计比较9×9 = 81 次,这些比较结果将构成一个9×9 大小的二维数组。在这里插入图片描述
这里需要注意的是,函数cv2.matchTemplate()通过参数method来决定使用不同的查找方法。对于不同的查找方法,返回值result 具有不同的含义。例如:

  • method 的值为cv2.TM_SQDIFF 和cv2.TM_SQDIFF_NORMED 时,result 值为0 表示匹配度最好,值越大,表示匹配度越差。
  • method 的值为cv2.TM_CCORR、cv2.TM_CCORR_NORMED、cv2.TM_CCOEFF 和cv2.TM_CCOEFF_NORMED 时,result 的值越小表示匹配度越差,值越大表示匹配度越好。

查找最值(极值)与最值所在的位置,可以使用cv2.minMaxLoc()函数实现。该函数语法格式如下:

minVal, maxVal, minLoc, maxLoc = cv2.minMaxLoc( src [, mask] )

  • src 为单通道数组。
  • minVal 为返回的最小值,如果没有最小值,则可以是NULL(空值)。
  • maxVal 为返回的最大值,如果没有最小值,则可以是NULL。
  • minLoc 为最大值的位置,如果没有最大值,则可以是NULL。
  • maxLoc 为最大值的位置,如果没有最大值,则可以是NULL。
  • mask 为用来选取掩模的子集,可选项。

综上所述,函数cv2.matchTemplate()返回值中的最值位置就是模板匹配的位置,可以理解为模板匹配的评分,最值越大/越小(取决于method),说明这个模板跟原图匹配的越好。当然,选用表中的不同参数值,匹配位置可能位于最大值所在的位置也可能位于最小值所在的位置。通过函数cv2.minMaxLoc()来查找函数cv2.matchTemplate()返回值中的最值位置,就可以找到最佳模板匹配的位置。

例如,当method 的值为cv2.TM_SQDIFF 和cv2.TM_SQDIFF_NORMED 时,0 表示最佳匹配,值越大,则表示匹配效果越差。因此,在使用这两种方法时,要寻找最小值所在的位置作为最佳匹配。如下语句能够找到cv2.matchTemplate()函数返回值中最小值的位置:

minVal, maxVal, minLoc, maxLoc = cv2.minMaxLoc(matchTemplate 函数的返回值)
topLeft = minLoc # 查找最小值所在的位置

以 topLeft 点为模板匹配位置的左上角坐标,结合模板图像的宽度w 和高度h 可以确定匹配位置的右下角坐标,代码如下所示:

bottomRight = (topLeft[0] + w, topLeft[1] + h) #w 和h 是模板图像的宽度和高度

通过上述方式,我们确定了模板匹配的矩形对角坐标位置,接下来可以借助函数cv2.rectangle()将该位置用白色标记出来。函数cv2.rectangle 的语法格式为:

Img = cv.rectangle( img, pt1, pt2, color[, thickness])

  • img 表示要标记的目标图像。
  • pt1 是矩形的顶点。
  • pt2 是pt1 的对角顶点。
  • color 是要绘制矩形的颜色或灰度级(灰度图像)。
  • thickness 是矩形边线的宽度。

因此,使用的标记语句为:

cv2.rectangle(img,topLeft, bottomRight, 255, 2)

#使用函数cv2.matchTemplate()进行模板匹配。要求参数method 的值设置为cv2.TM_SQDIFF,显示函数的返回结果及匹配结果。
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('lena512g.bmp',0)
template = cv2.imread('temp.bmp',0)
th, tw = template.shape[::]
rv = cv2.matchTemplate(img,template,cv2.TM_SQDIFF)
minVal, maxVal, minLoc, maxLoc = cv2.minMaxLoc(rv)
topLeft = minLoc
bottomRight = (topLeft[0] + tw, topLeft[1] + th)
cv2.rectangle(img,topLeft, bottomRight, 255, 2)
plt.subplot(121),plt.imshow(rv,cmap = 'gray')
plt.title('Matching Result'), plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(img,cmap = 'gray')
plt.title('Detected Point'), plt.xticks([]), plt.yticks([])
plt.show()

模板和原图如下:
在这里插入图片描述

运行上述代码,得到如图所示结果:
在这里插入图片描述
这里需要注意,在计算模板图像的宽度时,使用的语句为:

th, tw = template.shape[::]

返回值中的th 是模板图像的高度,tw 是模板图像的宽度。在OpenCV 官网的示例中,使用的语句形式为:

tw, th = template.shape[::-1]

该语句返回的也是模板图像的宽度和高度,只不过语句template.shape[::-1]将宽度和高度的顺序进行了调换。

2. 多模板匹配

在前面的例子中,我们在输入图像lena 中搜索其眼部子图,该子图在整个输入图像内仅出现了一次。但是,有些情况下,要搜索的模板图像很可能在输入图像内出现了多次,这时就需要找出多个匹配结果。而函数cv2.minMaxLoc()仅仅能够找出最值,无法给出所有匹配区域的位置信息。所以,要想匹配多个结果,使用函数cv2.minMaxLoc()是无法实现的,需要利用阈值进行处理。

下面分步骤介绍如何获取多模板匹配的结果。

2.1 获取匹配位置的集合

函数 where()能够获取模板匹配位置的集合。对于不同的输入,其返回的值是不同的。

  • 当输入(参数)是一维数组时,返回值是一维索引,只有一组索引数组。
  • 当输入是二维数组时,返回的是匹配值的位置索引,因此会有两组索引数组表示返回值的位置。

loc = np.where( res >= threshold)

  • res 是函数cv2.matchTemplate()进行模板匹配后的返回值。
  • threshold 是预设的阈值。
  • loc 是满足“res >= threshold”的像素点的索引集合。二维数组返回值loc中为两个元素,分别表示匹配值的行索引和列索引。
#一维数组
import numpy as np
a=np.array([3,6,8,1,2,88])
b=np.where(a>5)
print(b)该段代码返回的结果为:
(array([1, 2, 5], dtype=int64),)
#二维数组
import numpy as np
am=np.array([[3,6,8,77,66],[1,2,88,3,98],[11,2,67,5,2]])
b=np.where(am>5)
print(b)该段代码返回的结果为:
(array([0, 0, 0, 0, 1, 1, 2, 2], dtype=int64),
array([1, 2, 3, 4, 2, 4, 0, 2], dtype=int64))

2.2 循环

在获取匹配值的索引集合后,可以采用如下语句遍历所有匹配的位置,对这些位置做标记:

for i in 匹配位置集合:标记匹配位置。

2.3 在循环中使用函数zip()

函数 zip()用可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。

#例如
import numpy as np
am=np.array([[3,6,8,77,66],[1,2,88,3,98],[11,2,67,5,2]])
print(am)
b=np.where(am>5)
for i in zip(*b):print(i)上述代码的输出结果为:
[[ 3 6 8 77 66]
[ 1 2 88 3 98]
[11 2 67 5 2]]
(0, 1)
(0, 2)
(0, 3)
(0, 4)
(1, 2)
(1, 4)
(2, 0)
(2, 2)

2.4 调整坐标

函 数 numpy.where() 可以获取满足条件的模板匹配位置集合, 然后可以使用函数cv2.rectangle()在上述匹配位置绘制矩形来标注匹配位置。

使用函数numpy.where()在函数cv2.matchTemplate()的输出值中查找指定值,得到的形式为“(行号,列号)”的位置索引。但是,函数cv2.rectangle()中用于指定顶点的参数所使用的是形
式为“(列号,行号)”的位置索引。所以,在使用函数cv2.rectangle()绘制矩形前,要先将函数numpy.where()得到的位置索引做“行列互换”。可以使用如下语句实现loc 内行列位置的互换:

loc[::-1]

#如下语句将loc 内的两个元素交换位置:
import numpy as np
loc = ([1,2,3,4],[11,12,13,14])
print(loc)
print(loc[::-1])其中,语句print(loc)所对应的输出为:
([1, 2, 3, 4], [11, 12, 13, 14])
语句 print(loc[::-1])所对应的输出为:
([11, 12, 13, 14], [1, 2, 3, 4])

2.5 标记匹配图像的位置

函数 cv2.rectangle()可以标记匹配图像的具体位置,分别指定要标记的原始图像、对角顶点、颜色、矩形边线宽度即可。

关于矩形的对角顶点:

  • 其中的一个对角顶点A可以通过for 循环语句从确定的满足条件的“匹配位置集合”内获取。
  • 另外一个对角顶点,可以通过顶点A的位置与模板的宽(w)和高(h)进行运算得到。

因此,标记各个匹配位置的语句为:

for i in 匹配位置集合:cv2.rectangle(输入图像,i, (i[0] + w, i[1] + h), 255, 2)

2.6 多模板匹配案例

#使用模板匹配方式,标记在输入图像内与模板图像匹配的多个子图像。
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('lena4.bmp',0)
template = cv2.imread('lena4Temp.bmp',0)
w, h = template.shape[::-1]
res = cv2.matchTemplate(img,template,cv2.TM_CCOEFF_NORMED)
threshold = 0.9
loc = np.where( res >= threshold)
for pt in zip(*loc[::-1]):cv2.rectangle(img, pt, (pt[0] + w, pt[1] + h), 255, 1)
plt.imshow(img,cmap = 'gray')
plt.xticks([]), plt.yticks([])

模板及原始图像如下所示:

在这里插入图片描述
运行上述代码,得到如图所示结果:

在这里插入图片描述
大家可能已经注意到了,本来在函数cv2.rectangle()中设置的边界宽度为1,但实际上标记出来的宽度远远大于1。这是因为在当前的区域内,存在多个大于当前指定阈值(0.9)的情况,所以将它们都做了标记。这样,多个宽度为1 的矩形就合在了一起,显得边界比较粗。读者可以尝试修改阈值,调整宽度,观察不同的演示效果。


http://chatgpt.dhexx.cn/article/1lG7Daji.shtml

相关文章

opencv中的模板匹配

1 匹配函数 opencv 提供了一个专门用于模板匹配的函数 cv::matchTemplate();其调用方式如下: void cv::matchTemplate(cv::InputArray image, // 用于搜索的输入图像, 8U 或 32F, 大小 W-Hcv::InputArray templ, // 用于匹配的模板,和image类型相同&am…

【论文译文】BigGAN

译文仅供参考! 原文是pdf,想下载的话可以戳:http://www.gwylab.com/pdf/biggan_chs.pdf

WGAN、WGAN-GP、BigGAN

一、WGAN概述 WGAN论文地址:https://arxiv.org/abs/1701.07875 在这篇论文中,作者研究了不同的测量方法,来描述模型生成样本和证实样本之间分布差距,或者说,不同的散度定义,在对比之后,认为EM…

tf hub bigGan 猫变狗

原文链接: tf hub bigGan 猫变狗 上一篇: tf hub mobile_net 使用 下一篇: tf hub 使用缓存 数据 根据输入的标签和噪声生成指定类别的图片,类似infogan 每次向着目标前进一小步,将其中的过程变化记录下来 import tensorflow as tf import n…

(2018, BigGAN)用于高保真自然图像合成的大规模 GAN 训练

Large scale gan training for high fidelity natural image synthesis 公众号:EDPJ 目录 0. 摘要 1. 简介 2. 背景 3. 扩展 GAN 3.1 使用截断技巧权衡多样性和保真度 3.2 总结 4. 分析 4.1 表征不稳定性:生成器 4.2 表征不稳定性&#xff1…

深度解读DeepMind新作:史上最强GAN图像生成器—BigGAN

在碎片化阅读充斥眼球的时代,越来越少的人会去关注每篇论文背后的探索和思考。 在这个栏目里,你会快速 get 每篇精选论文的亮点和痛点,时刻紧跟 AI 前沿成果。 点击本文底部的「阅读原文」即刻加入社区,查看更多最新论文推荐。 这…

基于飞桨实现BigGAN生成动漫图像——为艺术创作赋能

点击左上方蓝字关注我们 【飞桨开发者说】艾梦,深度学习业余选手,热衷于用AI创造新的可能性,努力探索发现未知的神奇世界。玩AI,我是认真的。 作为学力不足、码力有余的深度学习业余玩家,笔者在工作中忙里偷闲&#xf…

GAN变种介绍 - DCGAN、InfoGAN、CycleGAN、WGAN、Self-Attention GAN、BigGAN

GAN变种介绍 - DCGAN、InfoGAN、CycleGAN、WGAN、Self-Attention GAN、BigGAN 一、DCGAN二、InfoGAN三、CycleGAN四、WGAN五、Self-Attention GAN六、BigGAN 在原始的 GAN 论文中,Ian Goodfellow 从理论层面分析了 GAN 网络的收敛性,并且在多个经典图片数…

基于飞桨PaddlePaddle实现BigGAN生成动漫图像——为艺术创作赋能

作为学力不足、码力有余的深度学习业余玩家,笔者在工作中忙里偷闲,借助AI Studio的免费GPU继续自己对于生成对抗网络落地应用的相关研究。尽管深度学习已在工业生成中广泛应用,但作为研究重头的视觉效果极佳的GAN的图像生成,却在应…

深度学习(四十六)——StarGAN, InfoGAN, ProGAN, StyleGAN, BigGAN, FUNIT, CVAE

StarGAN 论文: 《StarGAN: Unified Generative Adversarial Networksfor Multi-Domain Image-to-Image Translation》 CycleGAN的局限在于:对于两个Domain之间的变换,需要两个G网络。可以想象,当Domain的数量上升时,…

biggan:large scale gan training for high fidelity natural image synthesis

深度解读DeepMind新作:史上最强GAN图像生成器—BigGAN - 知乎本期推荐的论文笔记来自 PaperWeekly 社区用户 TwistedW。由 DeepMind 带来的 BigGAN 可谓是笔者见过最好的 GAN 模型了,这里的 Big 不单单是指模型参数和 Batch 的大,似乎还在暗示…

飞桨PaddlePaddle(论文复现)-BigGAN解读

飞桨PaddlePaddle(论文复现)-BigGAN解读 先来看看效果(左上脚为生成的图像) 论文在现有GAN的基础上对生成样本的保真度与多样性之间的权衡进行改进 在ImageNet的128*128分辨率下训练,我们的模型(BigGANs)得到了166…

深度学习系列43:引入注意力的SAGAN/BigGAN和big_sleep

1. 从SAGAN到BigGAN sa_gan是Self-Attention Generative Adversarial Networks的缩写。 动机:一般的dc_gan(deep convolution)模型擅长处理含有大量纹理的类型,比如天空、风景等,但在结构上的表现比较差,比如不能正确生成人脸、四…

【Large Scale Adversarial Representation Learning 大规模对抗学习(BigGAN) 】学习笔记

目录 1.背景 2.特点 3.BigGAN详细介绍 ①Batch size的增大------以提升IS ②增加网络深度,即增加每层的通道数------以提升IS ③BatchNorm共享嵌入条件标签c------增加参数,提升训练速度 ④将噪声向量 z 送到 G 的多个层而不仅仅是初始层-----提升…

ICLR 2019 Oral 论文 BigGAN 解读及源代码拆解

简称:BigGAN 全称:Large Scale GAN Training for High Fidelity Natural Image Synthesis 来源:ICLR 2019 Oral 一、概述 (一)概要说一下 BigGAN 的研究背景: 到 BigGAN 提出为止,虽然 GANs…

BigGAN-论文阅读笔记

BigGAN-论文阅读笔记 论文地址:Large Scale GAN Training for High Fidelity Natural Image Synthesis-ReadPaper论文阅读平台 文章目录 BigGAN-论文阅读笔记论文结构摘要原文核心 研究背景谱归一化(Spectral Normalization)条件判别 研究意…

BigGAN高保真自然图像合成的大规模GAN训练

2019-02-24 22:23:17 BigGAN-LARGE SCALE GAN TRAINING FOR HIGH FIDELITY NATURAL IMAGE SYNTHESIS 原文:https://arxiv.org/abs/1809.11096 作者:来自DeepMind & Heriot-Watt University 译者:Tony 时长:3K字&#xff…

BigGAN、BiGAN、BigBiGAN简单介绍

介绍 上一篇文章在介绍GAN的评价标准的时候提到了 BigGAN 在Inception Score上取得了巨大的进步,而最近 DeepMind 又基于 BiGAN 提出了 BigBiGAN,它在 ImageNet 上的无监督表示学习和无条件图像生成方面都取得了极为优秀的成绩。 本文主要对BigGAN和BiG…

【GANs学习笔记】(十三)BIGGAN

完整笔记:http://www.gwylab.com/note-gans.html ——————————————————————— 原paper及译文: http://www.gwylab.com/paper-biggan.html 4. BigGAN 4.1 BigGAN解决的问题 我们知道,GANs的终极目标是生成让人无法辨别真…

Paper Reading:BigGAN

URL: https://arxiv.org/pdf/1809.11096.pdf code: https://github.com/AaronLeong/BigGAN-pytorch https://tfhub.dev/s?qbiggan TL;DR 号称具有划时代意义的BigGAN,由DeepMind团队在ICLR2019上发表,将精度作出了跨越式提升。 将Inception Score (IS…