OpenCV——模板匹配

前言

模板匹配是一种在较大的图像中搜索和查找模板图像位置的方法。OpenCV带有一个函数cv.matchTemplate()用于此目的。它只是简单地将模板图像放在输入图像上(就像在2D卷积中那样),并在模板图像下对输入图像的模板和补丁进行比较。在OpenCV中实现了几种比较方法。它返回一个灰度图像,每个像素表示该像素区域与模板的匹配程度。
如果输入图像大小是(W x H)、模板图像大小是(w x h),输出的图像会有大小(W-w+1,H-h+1)。一旦得到了结果,就可以使用cv.minMaxLoc()函数来查找最大值/最小值的位置。将它作为矩形的左上角,并将(w,h)作为矩形的宽度和高度。这个矩形是你的模板区域。
如果你在使用cv.TM_SQDIFF作为比较方法,最小值提供了最佳匹配。(引自:python OpenCV学习笔记(二十六):模板匹配

正文

代码

import cv2 as cv
import numpy as np


# 模板匹配,就是在整个图像区域发现与给定子图像匹配的小块区域,
# 需要模板图像T和待检测图像-源图像S
# 工作方法:在待检测的图像上,从左到右,从上倒下计算模板图像与重叠子图像匹配度,
# 匹配度越大,两者相同的可能性越大。


def template_demo():
    tpl = cv.imread("../images/plane3.jpg")
    target = cv.imread("../images/plane.jpg")
    cv.imshow("template",tpl)
    cv.imshow("target",target)

    methods = [cv.TM_SQDIFF_NORMED,cv.TM_CCORR_NORMED,cv.TM_CCOEFF_NORMED]
    th,tw = tpl.shape[:2]

    for md in methods:
        print(md)
        result = cv.matchTemplate(target,tpl,md)
        min_val,max_val,min_loc,max_loc = cv.minMaxLoc(result)
        print(min_val,min_loc)
        if md == cv.TM_SQDIFF_NORMED:# 根据不同的方法选择不同的参考值,# cv.TM_SQDIFF_NORMED最小时最相似,其他最大时最相似
            tl = min_loc
        else:
            tl = max_loc

        br = (tl[0] +tw,tl[1]+th)#选到点后,
        cv.rectangle(target,tl,br,(0,0,255),2)#第2个点和第3个点参数分别代表矩形的左上角和右下角两个点
        cv.namedWindow("match-",cv.WINDOW_AUTOSIZE)
        cv.imshow("match",target)
        cv.resizeWindow("match", 540, 960)


src = cv.imread("../images/lena.jpg")
cv.namedWindow("input image",cv.WINDOW_AUTOSIZE)
cv.imshow('input image', src)
template_demo()
cv.waitKey(0)  # 等有键输入或者1000ms后自动将窗口消除,0表示只用键输入结束窗口

cv.destroyAllWindows()

理论

  1. 首先,模板匹配的方法如下:
    在这里插入图片描述
    这就是这些方法的数学原理,将模板图片的像素与待检测图片的各个像素做对应的数学操作,从而找出,我们要的点。

①TM_SQDIFF是平方差匹配;TM_SQDIFF_NORMED是标准平方差匹配。利用平方差来进行匹配,最好匹配为0.匹配越差,匹配值越大。
②TM_CCORR是相关性匹配;TM_CCORR_NORMED是标准相关性匹配。采用模板和图像间的乘法操作,数越大表示匹配程度较高, 0表示最坏的匹配效果。
③TM_CCOEFF是相关性系数匹配;TM_CCOEFF_NORMED是标准相关性系数匹配。将模版对其均值的相对值与图像对其均值的相关值进行匹配,1表示完美匹配,-1表示糟糕的匹配,0表示没有任何相关性(随机序列)。
总结:随着从简单的测量(平方差)到更复杂的测量(相关系数),我们可获得越来越准确的匹配(同时也意味着越来越大的计算代价)。

  1. 匹配的核心方法是:result = cv.matchTemplate(target,tpl,md)

opencv的目标匹配函数为matchTemplate,函数原型为:matchTemplate(image, templ, method[, result[, mask]]) -> result
image参数表示待搜索源图像,必须是8位整数或32位浮点。
templ参数表示模板图像,必须不大于源图像并具有相同的数据类型。
method参数表示计算匹配程度的方法。
result参数表示匹配结果图像,必须是单通道32位浮点。如果image的尺寸为W x H,templ的尺寸为w x h,则result的尺寸为(W-w+1)x(H-h+1)。
其中result是模板图像去匹配的区域位置图像

这里值得注意的是:cv2.matchTemplate返回一个相关图,本质上是一个灰度图像,其中每个像素表示该像素的邻域与模板匹配多少。

  1. 第三个比较重要的方法是:cv.minMaxLoc
    我们关于这个的代码行是:min_val,max_val,min_loc,max_loc = cv.minMaxLoc(result)
    MaxLoc表示matchTemplate返回的图像中强度最高的matchTemplate ,它与图像与模板的最佳匹配相对应(仅对于特定的相关方法,对于TM_SQDIFF或TM_SQDIFF_NORMED而言 ,最佳匹配是minVal )。
    所以,哪个方法比较好的话,要根据你具体采用的方法得出的值去判断。
  2. 接下来就是将那个地方给圈起来了:
    cv.rectangle(target,tl,br,(0,0,255),2)#第2个点和第3个点参数分别代表矩形的左上角和右下角两个点

参考文档

  1. OpenCV—模板匹配matchTemplate
  2. python OpenCV学习笔记(二十六):模板匹配
  3. cv2.minMaxLoc()中的最大值?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值