opencv学习十:模板匹配

模板匹配原理

模板匹配是在一幅图像中寻找一个特定目标的方法之一,这种方法的原理非常简单,遍历图像中的每一个可能的位置,比较各处与模板是否“相似”,当相似度足够高时,就认为找到了我们的目标。

其实模板匹配实现的思想也是很简单很暴力的,就是拿着模板图片在原图中从左上至右下依次滑动,直到遇到某个区域的相似度低于我们设定的阈值,那么我们就认为该区域与模板匹配了,也就是我们找到了要找的的位置,并把它标记出来。
用T表示模板图像,I表示待匹配图像,切模板图像的宽为w高为h,用R表示匹配结果,匹配过程如下图所示:
在这里插入图片描述
OpenCV提供了6种模板匹配算法:
在这里插入图片描述CV_TM_SQDIFF 平方差匹配法,最好的匹配为0,值越大匹配越差
CV_TM_SQDIFF_NORMED 归一化平方差匹配法
CV_TM_CCORR 相关匹配法,采用乘法操作,数值越大表明匹配越好
CV_TM_CCORR_NORMED 归一化相关匹配法
CV_TM_CCOEFF 相关系数匹配法,最好的匹配为1,-1表示最差的匹配
CV_TM_CCOEFF_NORMED 归一化相关系数匹配法
前面两种方法为越小的值表示越匹配,后四种方法值越大越匹配。

在这里插入图片描述

OpenCV模板匹配实现

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

image:待搜索图像
templ:模板图像
method:计算匹配程度的方法
result:匹配结果,是一个矩阵

cv2.minMaxLoc(src, mask=None)
src是一个矩阵。输入cv2.matchTemplate的返回值

函数功能:假设有一个矩阵a,现在需要求这个矩阵的最小值,最大值,并得到最大值,最小值的索引。索引即位置坐标

import cv2 as cv
import numpy as np

def template_demo():
    tpl = cv.imread("C:/Users/lenovo/Desktop/opencv/daima/banknum/template-matching-ocr/images/tpl.png") #模板
    target = cv.imread("C:/Users/lenovo/Desktop/opencv/daima/banknum/template-matching-ocr/images/credit_card_01.png")#待检测图
    cv.imshow("template image", tpl)
    cv.imshow("target image", target)
    methods = [cv.TM_SQDIFF_NORMED, cv.TM_CCORR_NORMED, cv.TM_CCOEFF_NORMED]#归一化均方误差,归一化相关匹配,归一化相关系数
    th, tw = tpl.shape[:2] #取出模板的高宽 [:n]表示此列表的前n维度
    for md in methods:
        print(md)
        result = cv.matchTemplate(target, tpl, md)
        min_val, max_val, min_loc, max_loc = cv.minMaxLoc(result)#寻找最小值,最大值。最小值位置,最大值位置
        if md == cv.TM_SQDIFF_NORMED:
            tl = min_loc #tl是矩形左上角的点
        else:
            tl = max_loc
        br = (tl[0] + tw, tl[1] + th);
        cv.rectangle(target, tl, br, (0, 0, 255), 2)#rectangle函数用法,第一个参数是在哪个图上绘图,第二个和第三个是左上、右下位置顶点坐标,颜色为红色,宽度为2
        #cv.imshow("match--"+np.str(md), target)
        cv.imshow("match--" + np.str(md), result)
#match1 是平方不同的归一化,3是相关性的归一化,5是相关性因子的归一化
#以0~255的灰度范围标记算法算出来的相关性,目标图像的区域越白,这个区域与template的相关性越大


cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)

template_demo()
cv.waitKey(0)
cv.destroyAllWindows()

运行截图:
match1 是平方不同的归一化,3是相关性的归一化,5是相关性因子的归一化
在这里插入图片描述
还可以运行result查看:
以0~255的灰度范围标记算法算出来的相关性,目标图像的区域越白,这个区域与template的相关性越大
在这里插入图片描述
为什么result的图像比待检测图像小?
因为result减去了模板的宽高,模板四个顶点全覆盖的区域,它的中心点刚好是宽高的二分之一处
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_44145452/article/details/112505445