当前位置: 首页 > article >正文

008 OpenCV matchTemplate 模板匹配

目录

一、环境

二、模板匹配算法原理

三、代码演示


一、环境

本文使用环境为:

  • Windows10
  • Python 3.9.17
  • opencv-python 4.8.0.74

二、模板匹配算法原理

cv.matchTemplate是OpenCV库中的一个函数,用于在图像中查找与模板匹配的特征。它的主要应用场景是在图像处理、计算机视觉和模式识别等领域。

算法原理: cv.matchTemplate函数通过计算输入图像与模板图像之间的相似度来找到最佳匹配位置。它使用滑动窗口的方法在输入图像上移动模板图像,并计算每个窗口内的像素值差异。然后,根据所选的匹配方法(如平方差、归一化平方差、相关系数等),对差异进行加权求和,得到一个匹配得分矩阵。最后,函数返回得分矩阵中的最大值及其位置,作为最佳匹配位置。

函数API:

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

参数说明:

  • image:输入图像,通常是一个灰度图像。
  • templ:模板图像,可以是灰度图像或彩色图像。
  • method:匹配方法,常用的有:
    • cv2.TM_SQDIFF:平方差匹配法,计算结果越小表示匹配程度越高。
    • cv2.TM_SQDIFF_NORMED:归一化平方差匹配法,计算结果越接近0表示匹配程度越高。
    • cv2.TM_CCORR:相关系数匹配法,计算结果越接近1表示匹配程度越高。
    • cv2.TM_CCORR_NORMED:归一化相关系数匹配法,计算结果越接近1表示匹配程度越高。
    • cv2.TM_CCOEFF:相关系数匹配法,计算结果越接近1表示匹配程度越高。
    • cv2.TM_CCOEFF_NORMED:归一化相关系数匹配法,计算结果越接近1表示匹配程度越高。
  • mask:可选参数,mask是一个二值图,作用于参数temp1,有效区域则参与模板匹配计算

返回值说明:

  • result:匹配结果矩阵,每个元素表示对应位置的匹配程度。
  • minVal, maxVal, minLoc, maxLoc:最佳匹配位置的最小值、最大值、最小值位置和最大值位置。

下面是对 cv.matchTemplate() 算法的简单解释:

  1. 预处理:首先,将输入图像和模板图像转换为灰度图像。这是因为 cv.matchTemplate() 算法只支持灰度图像。
  2. 滑动模板:然后,算法会在输入图像上滑动模板。对于每个位置(从左到右、从上到下呗),都会计算一个匹配分数。这个分数取决于当前位置的图像和模板的相似性。
  3. 计算匹配分数:根据选择的匹配方法,计算当前位置的匹配分数。例如,如果选择的是归一化相关系数方法,那么算法会计算输入图像和模板在当前位置的相关系数。其他方法,如归一化相关、平方差等,会有不同的计算方式。
  4. 找到最匹配的位置:在所有位置中,算法会找到匹配分数最高的位置。这个位置就是最匹配的位置。
  5. 返回结果:最后,函数会返回一个包含所有匹配区域信息的结构。这个结构包含了每个匹配区域的坐标、匹配分数等信息。

需要注意的是,由于滑动窗口的限制,如果模板和图像的某些区域不匹配,这些区域将不会被计入匹配分数。这是通过使用掩码(mask)参数实现的。掩码是一个与模板大小相同的二维数组,值可以是0或1。在掩码中为1的位置将被计入匹配分数,为0的位置则不会被计入。

总的来说,cv.matchTemplate() 是一个强大的工具,可以用于在图像中查找和模板最匹配的区域。它广泛应用于图像处理、计算机视觉和模式识别等领域。

三、代码演示

代码中需要的三张图,这里给出来,lena_tmpl.jpg,以下是原图:

tmpl.png,以下是模板图,意思是:在原图中找到与其相似的区域,用矩形画出来。

mask.png,必须与tmp1.png尺寸相同,是一个二值图,用于表示:模板计算过程中,模板图中哪些区域用于模板匹配。

from __future__ import print_function
import sys
import cv2 as cv

# 全局变量
use_mask = False
img = None
templ = None
mask = None
image_window = "Source Image"
result_window = "Result window"

match_method = 0
max_Trackbar = 5

def main():
    # 读取三张图
    global img
    global templ
    img = cv.imread('data/lena_tmpl.jpg', cv.IMREAD_COLOR) # 图片1
    templ = cv.imread('data/tmpl.png', cv.IMREAD_COLOR) # 图片2

    global use_mask
    use_mask = True
    global mask
    mask = cv.imread('data/mask.png', cv.IMREAD_COLOR ) # 图片3

    if ((img is None) or (templ is None) or (use_mask and (mask is None))):
        print('Can\'t read one of the images')
        return -1
    cv.namedWindow( image_window, cv.WINDOW_AUTOSIZE )
    cv.namedWindow( result_window, cv.WINDOW_AUTOSIZE )
    # 创建滑条
    trackbar_label = 'Method: \n 0: SQDIFF \n 1: SQDIFF NORMED \n 2: TM CCORR \n 3: TM CCORR NORMED \n 4: TM COEFF \n 5: TM COEFF NORMED'
    cv.createTrackbar( trackbar_label, image_window, match_method, max_Trackbar, MatchingMethod )
    # 执行模板匹配
    MatchingMethod(match_method)
    cv.waitKey(0)
    return 0

def MatchingMethod(param):
    global match_method
    match_method = param
    img_display = img.copy()
    # 模板匹配
    method_accepts_mask = (cv.TM_SQDIFF == match_method or match_method == cv.TM_CCORR_NORMED)
    if (use_mask and method_accepts_mask):
        result = cv.matchTemplate(img, templ, match_method, None, mask)
    else:
        result = cv.matchTemplate(img, templ, match_method)
    # 将结果进行归一化到[0, 1]
    cv.normalize( result, result, 0, 1, cv.NORM_MINMAX, -1 )
    # 找到最佳匹配
    _minVal, _maxVal, minLoc, maxLoc = cv.minMaxLoc(result, None)
    # 得到的匹配位置,即:一个矩形框
    if (match_method == cv.TM_SQDIFF or match_method == cv.TM_SQDIFF_NORMED):
        matchLoc = minLoc
    else:
        matchLoc = maxLoc
    # 可视化
    cv.rectangle(img_display, matchLoc, (matchLoc[0] + templ.shape[0], matchLoc[1] + templ.shape[1]), (0,255,0), 2, 8, 0 )
    cv.rectangle(result, matchLoc, (matchLoc[0] + templ.shape[0], matchLoc[1] + templ.shape[1]), (0,0,255), 2, 8, 0 )
    cv.imshow(image_window, img_display)
    cv.imshow(result_window, result)
    pass
if __name__ == "__main__":
    main()

以下是不同算法运行效果,哪些算法吊,一眼就能看出来,自己可以玩一玩哈。

\n 0: SQDIFF

\n 1: SQDIFF

\n 2: TM CCORR

\n 3: TM CCORR

\n 4: TM COEFF

\n 5: TM COEFF


http://www.kler.cn/news/147919.html

相关文章:

  • 【UGUI】中Content Size Fitter)组件-使 UI 元素适应其内容的大小
  • 【嵌入式】开源shell命令行的移植和使用(2)——letter-shell
  • 贪心 376. 摆动序列
  • 顶象s_v3滑块
  • 设计师不可错过的免费素材网站,快快收藏!
  • 数据结构与算法之美代码:二分查找2
  • 分享几个可以免费使用GPT的网站
  • docker常见问题汇总
  • 建筑木模板厂家批发
  • Linux fork笔试练习题
  • C++STL——string类详解及其模拟实现
  • 【深度学习】学习率及多种选择策略
  • 前端学习网站推荐
  • c/c++ header_only 头文件实现的关键点
  • Spring加载Bean的多种方式
  • 红旗Asianux Server Linux V8 安装万里数据库(GreatSQL)
  • Spring Cloud,注册中心,配置中心,原理详解
  • 社区新零售:重塑零售业的全新模式
  • 使用Python+Redis实现文章投票网站后端功能
  • 【文献阅读笔记】关于GANomaly的异常检测方法
  • 【开源威胁情报挖掘1】引言 + 开源威胁情报挖掘框架 + 开源威胁情报采集与识别提取
  • C#,《小白学程序》第十九课:随机数(Random)第六,随机生成任意长度的大数(BigInteger)
  • PTA:百钱买百鸡 - C/C++ 数组及字符串
  • Vue组件的自定义事件$emit
  • ArcGIS10.x系列 Python工具箱教程
  • TypeScript和JavaScript有什么不同
  • 实战Flask+BootstrapTable最实用服务端分页查询动态表头及数据(ajax方式)
  • 群晖NAS配置之自有服务器ngrok实现内网穿透
  • bluez inquiry 流程梳理--从代码层面理解bluez架构
  • opencv-医学图像预处理