python学opencv|读取图像(五十三)原理探索:使用cv.matchTemplate()函数实现最佳图像匹配

ops/2025/2/7 12:20:53/

【1】引言

前序学习进程中,已经探索了使用cv.matchTemplate()函数实现最佳图像匹配的技巧,并且成功对两个目标进行了匹配。

相关文章链接为:python学opencv|读取图像(五十二)使用cv.matchTemplate()函数实现最佳图像匹配-CSDN博客

实际上,我们在这篇文章中重点体会了匹配效果,却没有真正剖析代码背后的运行逻辑。今天这篇文章的目标就是对代码背后逻辑稍微追溯一下。

【2】官网教程

【2.1】cv2.matchTemplate()函数

点击下方链接,直达cv2.matchTemplate()函数官网链接:

图1 cv2.matchTemplate()函数官网说明

图1所示的cv2.matchTemplate()函数官网说明中,有三处做了标记,它们彼此交织在一起。需要解读:

a.待匹配的大图像I大小为W X H,使用的模板T像素大小为w x h,获得的匹配效果R对应的的矩阵大小为(W-w+1,H-h+1);

b.使用不同的匹配方法后,再用minMaxLoc函数读取最佳匹配效果对应的左上角坐标时,有时候取最小值,如TM_SQDIFF,有时候取最大值,如TM_CCORR和TM_CCOEFF。

c.解读匹配方法请看第2.2节。

【2.2】cv2.matchTemplate()函数

点击链接,直达函数对匹配方法的解读:OpenCV: Object Detection

在这个页面,会看到不同的函数说明:

图2 匹配方法的数学公式

由图2可见,TM_SQDIFF采用的是减法计算,而TM_CCORR和TM_CCOEFF采用的乘法计算,所以相似度高的时候,TM_SQDIFF方法的计算值往往会接近0,而TM_CCORR和TM_CCOEFF方法就会在因为平方而取得更大的值。

所以“用minMaxLoc函数读取最佳匹配效果对应的左上角坐标时,有时候取最小值,如TM_SQDIFF,有时候取最大值,如TM_CCORR和TM_CCOEFF”就获得了解释。

【3】代码测试

【3.1】代码回顾

首先直接引用前一篇文章的完整代码:

import cv2 as cv # 引入CV模块
import numpy as np #引入numpy模块# 读取图片
srcm = cv.imread('srcm.png') #读取图像srcx.png
srcg = cv.imread('srcg.png') #读取图像srcp.png
srcc = cv.imread('srcc.png') #读取图像srcp.png
rows,cols,cans=srcg.shape #读取图像属性
rowsc,colsc,cansc=srcc.shape #读取图像属性#匹配结果
results=cv.matchTemplate(srcm,srcg,cv.TM_CCORR_NORMED)
results1=cv.matchTemplate(srcm,srcc,cv.TM_CCORR_NORMED)#取值
minValue,maxValue,minLoc,maxLoc=cv.minMaxLoc(results)
minValuec,maxValuec,minLocc,maxLocc=cv.minMaxLoc(results1)#取最大坐标
resultPoint1=maxLoc
print("resultPoint1=",resultPoint1)#取最大坐标
resultPoint2=maxLocc
print("resultPoint2=",resultPoint2)#定义新坐标
resultPoint3=(resultPoint1[0]+cols,resultPoint1[1]+rows)
print("resultPoint3=",resultPoint3)#定义新坐标
resultPoint4=(resultPoint2[0]+colsc,resultPoint2[1]+rowsc)
print("resultPoint4=",resultPoint4)#作标记
cv.circle(srcm,(250,250),30,(0,255,0))
cv.rectangle(srcm,resultPoint1,resultPoint3,(0,255,0),2)
cv.rectangle(srcm,resultPoint2,resultPoint4,(200,180,55),2)# 显示结果
cv.imshow('srcm ', srcm)
cv.imshow('srcg ', srcg)
cv.imshow('srcc ', srcc)
cv.imwrite('srcgc.png',srcm)#窗口控制
cv.waitKey()  # 图像不关闭
cv.destroyAllWindows()  # 释放所有窗口

待匹配的图像I为:

图3 待匹配图像I:srcm.png

图4 模板T1 srcg.png

图5 模板T2 srcc.png

图6 匹配效果 srcgc.png  

上述代码全部使用了cv2.TM_CCORR_NORMED方法,所以需要调用最大值来代表最佳匹配效果的左上角坐标。

未验证不用方法对应最佳匹配效果的左上角坐标,现在应增加匹配方法。

【3.2】代码扩展

在直接引用前一篇文章的完整代码的基础上,不仅要增加匹配方法,还要显示出匹配结果。

#匹配计算
results=cv.matchTemplate(srcm,srcg,cv.TM_SQDIFF_NORMED) #TM_SQDIFF匹配方法
results1=cv.matchTemplate(srcm,srcc,cv.TM_CCORR_NORMED) #TM_CCORR匹配方法
print("result=",results) #输出匹配结果
print("result1=",results1) #输出匹配结果

代码先后使用了TM_SQDIFF和TM_CCORR两种方法,并且要求输出了匹配结果。

然后读取了调用minMaxLoc()函数对结果渠道的各个参数值:

#取值
minValue,maxValue,minLoc,maxLoc=cv.minMaxLoc(results)
minValuec,maxValuec,minLocc,maxLocc=cv.minMaxLoc(results1)
print("result.minValue=",minValue)
print("result1.minValuec=",minValuec)
print("result.maxValue=",maxValue)
print("result1.maxValuec=",maxValuec)
print("result.minLoc=",minLoc)
print("result1.minLocc=",minLocc)
print("result.maxLoc=",maxLoc)
print("result1.maxLocc=",maxLocc)

然后根据先前的分析思路,取最佳匹配矩阵的左上角坐标。

这时候TM_SQDIFF取最小值,TM_CCORR方法取最大值,之后还要叠加模板的大小,来画出整个匹配区域:

#取最小坐标
resultPoint1=minLoc
print("resultPoint1=",resultPoint1)#取最大坐标
resultPoint2=maxLocc
print("resultPoint2=",resultPoint2)#定义新坐标
resultPoint3=(resultPoint1[0]+cols,resultPoint1[1]+rows)
print("resultPoint3=",resultPoint3)#定义新坐标
resultPoint4=(resultPoint2[0]+colsc,resultPoint2[1]+rowsc)
print("resultPoint4=",resultPoint4)

之后为了突出匹配点,以最小和最大坐标Wie圆心,分别绘制半径为10和20的圆形:

#作标记
cv.circle(srcm,(minLoc),10,(255,255,0))
cv.circle(srcm,(maxLoc),20,(255,255,0))
cv.circle(srcm,(minLocc),10,(0,255,255))
cv.circle(srcm,(maxLocc),20,(0,255,255))
cv.circle(srcm,(250,250),30,(0,255,0))
cv.rectangle(srcm,resultPoint1,resultPoint3,(0,255,0),2)
cv.rectangle(srcm,resultPoint2,resultPoint4,(200,180,55),2)

然后输出所有图像:

# 显示结果
cv.imshow('srcm ', srcm)
cv.imwrite('srcgcw.png',srcm)
#窗口控制
cv.waitKey()  # 图像不关闭
cv.destroyAllWindows()  # 释放所有窗口

代码运行后,获得的匹配效果为:

图7 匹配效果srcgcw.png

由图7可见,TM_SQDIFF取最小值,TM_CCORR方法取最大值获得的最佳匹配图像实现了预期效果。

【4】细节说明

上述3.2节读取到的部分匹配结果矩阵为:

 图8 匹配结果矩阵

由图8可见,每个矩阵内部给出了很多值,这表明在矩阵内部,图像和模板是按照像素点逐个进行比对匹配。

【5】总结

掌握了python+opencv调用使用cv.matchTemplate()函数实现最佳图像匹配的执行原理和过程。

 


http://www.ppmy.cn/ops/156432.html

相关文章

分布式光伏监控解决方案-并网柜保护装置

一、并网柜防孤岛保护 继电保护及安全自动装置 根据《光伏发电站接入电力系统的技术规定》GB/T 19964-2012的相关要求,光伏发电站应配置独立的防孤岛保护装置,动作时间应不大于2s。防孤岛保护还应与电网侧线路保护相配合。 孤岛islanding 包含负荷和电源…

第一章 语音识别概述

小爱同学,小度小度,天猫精灵,叮咚叮咚……我们身边好像突然就出现了一些可以和我们“聊天”的音箱,图所示为百度智能音箱。 智能音箱与传统音箱最大的区别就是能够听懂我们的语音,人们通过说话就能与电子设备沟通&…

udp和tcp的区别

目录 UDP 和 TCP 的区别 1. 连接性 2. 可靠性 3. 数据传输顺序 4. 流量控制和拥塞控制 5. 效率 6. 应用场景 UDP 和 TCP 的 C/C 代码实现区别 1. TCP 服务器端和客户端 TCP 服务器端(Server) TCP 客户端(Client) 2. U…

解析PHP文件路径相关常量

PHP文件路径相关常量包括以下几个常量: __FILE__:表示当前文件的绝对路径,包括文件名。 __DIR__:表示当前文件所在的目录的绝对路径,不包括文件名。 dirname(__FILE__):等同于__DIR__,表示当前…

结合R语言、ArcGIS Pro、ChatGPT+生态学模型(PLUS模型、InVEST模型)的生态系统服务的多情景模拟预测及其应用

随着全球城市化进程的加速与人类活动的频繁,土地利用及生态系统服务面临巨大的压力,水土流失、植被退化、生物多样性丧失等环境问题日益严重。如何在土地供需矛盾中维持生态安全、优化土地利用模式,成为当前生态学与土地规划领域的研究重点。…

堆(Heap)的原理与C++实现

1. 什么是堆? 堆(Heap)是一种特殊的树形数据结构,通常用于实现优先队列。堆可以分为两种类型: 最大堆(Max Heap):每个节点的值都大于或等于其子节点的值。最小堆(Min H…

被裁与人生的意义--春节随想

还有两个月就要被迫离开工作了十多年的公司了,整个中国分支全部干掉。不过我有幸安安稳稳的过了一个春节,很知足! 分六七批走人,我是最后一批离开,一百多号同事都没“活到”蛇年。看着一批批仁人志士被“秋后斩首”,马…

6.攻防世界 shrine

进入题目页面如下 是python代码 进行代码审计 # 从 flask 库中导入 Flask 类 from flask import Flask import os# 创建一个 Flask 应用实例 app Flask(__name__)# 从环境变量中获取名为 FLAG 的值,并将其设置为应用配置中的 FLAG 项,同时从环境变量中…