OpenCV进阶篇

sss

OpenCV进阶篇

第10章 模板匹配

模板匹配是一种最原始、最基本的识别方法,可以在原始图像中寻找特定图像的位置。模板匹配经常应用于简单的图像查找场景中,例如,在集体合照中找到某个人的位置。本章将介绍如何利用OpenCV实现模板匹配。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8Qunwp3k-1639056667651)(OpenCV进阶篇.assets/image-20211122082012339.png)]

10.1 模板匹配方法

模板是被查找目标的图像,查找模板在原始图像中的哪个位置的过程就叫模板匹配。OpenCV提供的matchTemplate()方法就是模板匹配方法,其语法如下:

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

参数说明:

image:原始图像。

templ:模板图像,尺寸必须小于或等于原始图像。

method:匹配的方法,可用参数值如表10.1所示。

表10.1

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yTgvDiwC-1639056667652)(OpenCV进阶篇.assets/image-20211122082047351.png)]

匹配方法的参数值

mask:可选参数。掩模,只有cv2.TM_SQDIFF和cv2.TM_CCORR_NORMED支持此参数,建议采用默认值。

返回值说明:

result:计算得出的匹配结果。如果原始图像的宽、高分别为W、H,模板图像的宽、高分别为w、h,result就是一个W-w+1列、H-h+1行的32位浮点型数组。数组中每一个浮点数都是原始图像中对应像素位置的匹配结果,其含义需要根据method参数来解读。
在模板匹配的计算过程中,模板会在原始图像中移动。模板与重叠区域内的像素逐个对比,最后将对比的结果保存在模板左上角像素点索引位置对应的数组位置中。计算过程如图10.1所示。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-q6lurtRV-1639056667652)(OpenCV进阶篇.assets/image-20211122082229394.png)]

​ 图10.1 模板在原始图像中移动并逐个匹配

使用cv2.TM_SQDIFF(平方差匹配)方法计算出的数组格式如下(其他方法计算出的数组格式相同,仅数值不同):

 [[0.10165964 0.10123613 0.1008469  ... 0.10471864 0.10471849 0.10471849]
  [0.10131165 0.10087635 0.10047968 ... 0.10471849 0.10471834 0.10471849]
  [0.10089004 0.10045089 0.10006084 ... 0.10471849 0.10471819 0.10471849]
  ...
  [0.16168603 0.16291814 0.16366465 ... 0.12178455 0.12198001 0.12187888]
  [0.15859096 0.16000605 0.16096526 ... 0.12245651 0.12261643 0.12248362]
  [0.15512456 0.15672517 0.15791312 ... 0.12315679 0.1232616  0.12308815]]

模板将原始图像中每一块区域都覆盖一遍,但结果数组的行、列数并不等于原始图像的像素的行、列数。假设模板的宽为w,高为h,原始图像的宽为W,高为H,如图10.2所示。
模板移动到原始图像的边缘之后就不会继续移动了,所以模板的移动区域如图10.3所示,该区域的边长为“原始图像边长-模板边长+1”,最后加1是因为移动区域内的上下、左右的2个边都被模板覆盖到了,如果不加1会丢失数据。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-egJKRmNg-1639056667653)(OpenCV进阶篇.assets/image-20211122085327267.png)]

​ 图10.2 模板和原始图像的宽、高

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vEnbCYJW-1639056667653)(OpenCV进阶篇.assets/image-20211122085350483.png)]

​ 图10.3 模板移动的范围

10.2 单模板匹配

匹配过程中只用到一个模板场景叫单模板匹配。原始图像中可能只有一个和模板相似的图像,也可能有多个。如果只获取匹配程度最高的那一个结果,这种操作叫作单目标匹配。如果需要同时获取所有匹配程度较高的结果,这种操作叫作多目标匹配。

10.2.1 单目标匹配

单目标匹配只获取一个结果即可,就是匹配程度最高的结果(如果使用平方差匹配,则为计算出的最小结果;如果使用相关匹配或相关系数匹配,则为计算出的最大结果)。本节以平方差匹配为例介绍。
matchTemplate()方法的计算结果是一个二维数组,OpenCV提供了一个minMaxLoc()方法专门用来解析这个二维数组中的最大值、最小值以及这2个值对应的坐标,minMaxLoc()方法的语法如下:

 minValue, maxValue, minLoc, maxLoc = cv2.minMaxLoc(src, mask)

参数说明:

src:matchTemplate()方法计算得出的数组。

mask:可选参数,掩模,建议使用默认值。

返回值说明:

minValue:数组中的最小值。

maxValue:数组中的最大值。

minLoc:最小值的坐标,格式为(x, y)。

maxLoc:最大值的坐标,格式为(x, y)。
平方差匹配的计算结果越小,匹配程度越高。minMaxLoc()方法返回的minValue值就是模板匹配的最优结果,minLoc就是最优结果区域左上角的点坐标,区域大小与模板大小一致。

【实例10.1】 为原始图片中匹配成功的区域绘制红框。
将图10.4作为模板,将图10.5作为原始图像,使用cv2.TM_SQDIFF_NORMED方式进行模板匹配,在原始图像中找到与模板一样的图案,并在该图案上绘制红色方框。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rar15A3x-1639056667654)(OpenCV进阶篇.assets/image-20211122085451979.png)]

​ 图10.4 模板

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gEC0AtkX-1639056667654)(OpenCV进阶篇.assets/image-20211122085539068.png)]

​ 图10.5 原始图片
具体代码如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2A0hJfRU-1639056667655)(OpenCV进阶篇.assets/image-20211122085602382.png)]

上述代码的运行结果如图10.6所示。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nO5y7aFc-1639056667655)(OpenCV进阶篇.assets/image-20211122085749850.png)]

​ 图10.6 模板匹配的效果

在许多综艺节目里,导演组给选手们一幅图像,让选手在指定区域内寻找图像中的某一静物。为了增加游戏难度,导演组可能会让选手们从2个或者多个相似的场景中选择最佳的匹配结果。接下来,使用模板匹配的相应方法模拟这个游戏。

【实例10.2】 从2幅图像中选择最佳的匹配结果。
将图10.7作为模板,将图10.8和图10.9作为原始图像,使用cv2.TM_SQDIFF_NORMED方式进行模板匹配,在2幅原始图像中找到与模板匹配结果最好的图像,并在窗口中显示出来。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kAeDADkx-1639056667656)(OpenCV进阶篇.assets/image-20211122085811909.png)]

​ 图10.7 模板

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6Y2C8Uz6-1639056667656)(OpenCV进阶篇.assets/image-20211122085837681.png)]

​ 图10.8 原始图像221

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-F0efgzCT-1639056667656)(OpenCV进阶篇.assets/image-20211122085907444.png)]

​ 图10.9 原始图像222
具体代码如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Iun44Nij-1639056667657)(OpenCV进阶篇.assets/image-20211122085934422.png)]

上述代码的运行结果如图10.10所示。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2okGh7GG-1639056667657)(OpenCV进阶篇.assets/image-20211122090014973.png)]

​ 图10.10 从2幅图像中选择最佳的匹配结果

网速的提升让容量较大的文件更容易在互联网上传播,最明显结果就是现在用户计算机里被堆满了各种各样的图像文件。
图像文件与其他文件不同,相同内容的图像可能保存在不同大小、不同格式的文件中,这些文件的二进制字节码差别较大,很难用简单的程序识别。在没有高级识别软件的情况下想要找出内容相同的图像就只能一个一个打开用肉眼识别了。
OpenCV能够打破图像文件规格、格式的限制来识别图像内容。

【实例10.3】 查找重复的图像。
图10.11所示的文件夹中有10幅图像,这些图像不仅有JPG格式的,还有PNG格式的,而且这些图像的分辨率也各不相同。接下来将编写一个程序,在该文件夹中找出哪些是重复的照片。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bny5k3Mh-1639056667657)(OpenCV进阶篇.assets/image-20211122090116485.png)]

​ 图10.11 文件夹中的所有照片文件
想要解决这个问题,可以使用OpenCV提供的matchTemplate()方法来判断2幅图像的相似度,如果相似度大于0.9,就认为这2幅图像是相同的。
具体代码如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0MWgYl4D-1639056667658)(OpenCV进阶篇.assets/image-20211122090219888.png)]

上述代码的运行结果如下:

 相同的照片:10.png, 4.jpg,
 相同的照片:2.jpg, 5.jpg, 9.png,

10.2.2 多目标匹配

多目标匹配需要将原始图像中所有与模板相似的图像都找出来,使用相关匹配或相关系数匹配可以很好地实现这个功能。如果计算结果大于某值(例如0.999),则认为匹配区域的图案和模板是相同的。

【实例10.4】 为原始图片中所有匹配成功的图案绘制红框。
将图10.12作为模板,将图10.13作为原始图像。原始图像中有很多重复的图案,每一个与模板相似的图案都需要被标记出来。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sPJngqiS-1639056667658)(OpenCV进阶篇.assets/image-20211122090300666.png)]

​ 图10.12 模板

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-z3YHi9fS-1639056667658)(OpenCV进阶篇.assets/image-20211122090321173.png)]

​ 图10.13 包含重复内容的原始图像
使用cv2.TM_CCOEFF_NORMED方法进行模板匹配,使用for循环遍历matchTemplate()方法返回的结果,找到所有大于0.99的计算结果,在这些结果的对应区域位置绘制红色矩形边框。编写代码时要注意:数组的列数在图像坐标系中为横坐标,数组的行数在图像坐标系中为纵坐标。
具体代码如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9AHVz1kN-1639056667658)(OpenCV进阶篇.assets/image-20211122090346039.png)]

上述代码的运行结果如图10.14所示,程序找到了3处与模板相似的图案。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Z1Eg2Ozz-1639056667659)(OpenCV进阶篇.assets/image-20211122090426271.png)]

​ 图10.14 匹配结果
多目标匹配在实际生活中有很多应用场景。例如,统计一条快轨线路的站台总数;同一地点附近有2个地铁站,优先选择直线距离最短的地铁站等。

【实例10.5】 统计一条快轨线路的站台总数。
将图10.15作为模板,图10.16作为原始图像,在原始图像中标记快轨线路各个站台,统计这条快轨线路的站台总数。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qnkqoHAG-1639056667659)(OpenCV进阶篇.assets/image-20211122090450906.png)]

​ 图10.15 模板

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TKvqjLpo-1639056667659)(OpenCV进阶篇.assets/image-20211122090516424.png)]

​ 图10.16 原始图像
使用cv2.TM_CCOEFF_NORMED方法进行模板匹配,使用for循环遍历matchTemplate()方法返回的结果,找到所有大于0.99的计算结果,在这些结果的对应区域位置绘制蓝色矩形边框,代码如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PcXPP4GV-1639056667660)(OpenCV进阶篇.assets/image-20211122090545588.png)]

上述代码的运行结果如图10.17所示。
实例10.5第6行中的results包含所有蓝色矩形边框左上角的横、纵坐标。利用这一特点,还可以模拟“同一地点附近有2个地铁站,优先选择直线距离最短的地铁站”这一生活场景,模板如图10.18所示。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FOlMVoCl-1639056667660)(OpenCV进阶篇.assets/image-20211122090628716.png)]

​ 图10.17 统计一条快轨线路的站台总数

【实例10.6】 优先选择直线距离最短的地铁站。
如图10.19所示,坐标为(62, 150)的地点附近有人民广场和解放大路两个地铁站,如何优先选择直线距离最短的地铁站呢?首先将图10.18作为模板,将图10.19作为原始图像,然后在原始图像中标记出这两个地铁站,最后计算并比较坐标为(62, 150)这个地点与这两个地铁站的直线距离。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sZTp2jPj-1639056667660)(OpenCV进阶篇.assets/image-20211122090830746.png)]

​ 图10.18 模板

​ 图10.19 原始图像
使用cv2.TM_CCOEFF_NORMED方法进行模板匹配,使用for循环遍历matchTemplate()方法返回的结果,找到所有大于0.99的计算结果,在这些结果的对应区域位置绘制蓝色矩形边框,分别计算(62,150)到蓝色矩形边框左上角的距离,用绿色线段标记出直线距离最短的地铁站,代码如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0DHd3yX7-1639056667660)(OpenCV进阶篇.assets/image-20211122091313117.png)]

上述代码的运行结果如图10.20所示。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-v9DG7tnQ-1639056667661)(OpenCV进阶篇.assets/image-20211122091347963.png)]

​ 图10.20 优先选择直线距离最短的地铁站

10.3 多模板匹配

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值