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

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

【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()函数实现最佳图像匹配的执行原理和过程。

 

相关文章:

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

【1】引言 前序学习进程中,已经探索了使用cv.matchTemplate()函数实现最佳图像匹配的技巧,并且成功对两个目标进行了匹配。 相关文章链接为:python学opencv|读取图像(五十二)使用cv.matchTemplate()函数实现最佳图像…...

win10部署本地deepseek-r1,chatbox,deepseek联网(谷歌网页插件Page Assist)

win10部署本地deepseek-r1,chatbox,deepseek联网(谷歌网页插件Page Assist) 前言一、本地部署DeepSeek-r1step1 安装ollamastep2 下载deepseek-r1step2.1 找到模型deepseek-r1step2.2 cmd里粘贴 后按回车,进行下载 ste…...

冯·诺依曼体系结构

目录 冯诺依曼体系结构推导 内存提高冯诺依曼体系结构效率的方法 你使用QQ和朋友聊天时,整个数据流是怎么流动的(不考虑网络情况) 与冯诺依曼体系结构相关的一些知识 冯诺依曼体系结构推导 计算机的存在就是为了解决问题,而解…...

本地部署 DeepSeek-R1 模型

文章目录 霸屏的AIDeepSeek是什么?安装DeepSeek安装图形化界面总结 霸屏的AI 最近在刷视频的时候,总是突然突然出现一个名叫 DeepSeek 的玩意,像这样: 这样: 这不经激起我的一顿好奇心,这 DeepSeek 到底是个…...

Mybatis——sql映射文件中的增删查改

映射文件内的增删查改 准备工作 准备一张数据表,用于进行数据库的相关操作。新建maven工程, 导入mysql-connector-java和mybatis依赖。新建一个实体类,类的字段要和数据表的数据对应编写接口编写mybatis主配置文件 public class User {priva…...

【开源免费】基于Vue和SpringBoot的流浪宠物管理系统(附论文)

本文项目编号 T 182 ,文末自助获取源码 \color{red}{T182,文末自助获取源码} T182,文末自助获取源码 目录 一、系统介绍二、数据库设计三、配套教程3.1 启动教程3.2 讲解视频3.3 二次开发教程 四、功能截图五、文案资料5.1 选题背景5.2 国内…...

nth_element函数——C++快速选择函数

目录 1. 函数原型 2. 功能描述 3. 算法原理 4. 时间复杂度 5. 空间复杂度 6. 使用示例 8. 注意事项 9. 自定义比较函数 11. 总结 nth_element 是 C 标准库中提供的一个算法&#xff0c;位于 <algorithm> 头文件中&#xff0c;用于部分排序序列。它的主要功能是将…...

DNS缓存详解(DNS Cache Detailed Explanation)

DNS缓存详解 清空DNS缓存可以让网页访问更快捷。本文将从什么是DNS缓存、为什么清空DNS缓存、如何清空DNS缓存、清空DNS缓存存在的问题四个方面详细阐述DNS缓存清空的相关知识。 一、什么是DNS缓存 1、DNS缓存的定义&#xff1a; DNS缓存是域名系统服务在遇到DNS查询时自动…...

课设:【ID0022】火车票售票管理系统(前端)

技术栈&#xff1a;Java&#xff0c;JavaSwing&#xff0c;MySQL 数据库表数量&#xff1a;12个 1.功能描述 管理员功能 管理员是系统的高级用户&#xff0c;拥有对整个系统的全面管理权限。管理员的功能模块包括以下六个方面&#xff1a; 对用户管理增删查改 对售票员…...

Ruby 类和对象

Ruby 类和对象 引言 在软件开发中,类和对象是面向对象编程(OOP)的核心概念。Ruby 作为一种动态、解释型编程语言,也以简洁的方式支持面向对象编程。本文将深入探讨 Ruby 中的类和对象,包括它们的定义、创建、使用以及一些高级特性。 类与对象的定义 类 在 Ruby 中,类…...

Java基础知识总结(三十八)--读取数据

使用Reader体系&#xff0c;读取一个文本文件中的数据。返回 -1 &#xff0c;标志读到结尾。 import java.io.*; class { public static void main(String[] args) throws IOException { /* 创建可以读取文本文件的流对象&#xff0c;让创建好的流对象和指定的文件相关联。…...

交错定理和切比雪夫节点的联系与区别

1. 交错定理 交错定理是切比雪夫逼近理论的核心内容&#xff0c;描述在区间[a,b]上&#xff0c;一个函数 f ( x ) f(x) f(x)的最佳一致逼近多项式 P n ( x ) P_n(x) Pn​(x)的特性。定理内容如下&#xff1a; 设 f ( x ) f(x) f(x)是区间[a,b]上的连续函数&#xff0c; P n ( …...

大数据相关职位介绍之三(数据挖掘,数据安全 ,数据合规师,首席数据官,数据科学家 )

大数据相关职位介绍之三&#xff08;数据挖掘&#xff0c;数据安全 &#xff0c;数据合规师&#xff0c;首席数据官&#xff0c;数据科学家 &#xff09; 文章目录 大数据相关职位介绍之三&#xff08;数据挖掘&#xff0c;数据安全 &#xff0c;数据合规师&#xff0c;首席数据…...

GitHub Actions定时任务配置完全指南:从Cron语法到实战示例

你好&#xff0c;我是悦创。 博客网站&#xff1a;https://blog.bornforthis.cn/ 本教程将详细讲解如何在GitHub Actions中配置定时任务&#xff08;Scheduled Tasks&#xff09;&#xff0c;帮助你掌握 Cron 表达式的编写规则和实际应用场景。 一、定时任务基础配置 1.1 核…...

Van-Nav:新年,将自己学习的项目地址统一整理搭建自己的私人导航站,供自己后续查阅使用,做技术的同学应该都有一个自己网站的梦想

嗨&#xff0c;大家好&#xff0c;我是小华同学&#xff0c;关注我们获得“最新、最全、最优质”开源项目和高效工作学习方法 Van-Nav是一个基于Vue.js开发的导航组件库&#xff0c;它提供了多种预设的样式和灵活的配置选项&#xff0c;使得开发者可以轻松地定制出符合项目需求…...

Easy系列PLC尺寸测量功能块ST代码(激光微距仪应用)

激光微距仪可以测量短距离内的产品尺寸,产品规格书的测量 精度可以到0.001mm。具体需要看不同的型号。 1、激光微距仪 2、尺寸测量应用 下面我们以测量高度为例子,设计一个高度测量功能块,同时给出测量数据和合格不合格指标。 3、高度测量功能块 4、复位完成信号 5、功能…...

Manacher 最长回文子串

方法&#xff1a;求字符串的 #include<bits/stdc.h> using namespace std; using lllong long; const int N1e69; char s[N]; int p[N];int main() {cin>>s1;int nstrlen(s1);s[0]^;s[2*n2]$; for(int i2*n1;i>1;i--){s[i](i&1)?#:s[i>>1];//右移表示…...

51单片机开发:独立键盘实验

实验目的&#xff1a;按下键盘1时&#xff0c;点亮LED灯1。 键盘原理图如下图所示&#xff0c;可见&#xff0c;由于接GND&#xff0c;当键盘按下时&#xff0c;P3相应的端口为低电平。 键盘按下时会出现抖动&#xff0c;时间通常为5-10ms&#xff0c;代码中通过延时函数delay…...

组件框架漏洞

一.基础概念 1.组件 定义&#xff1a;组件是软件开发中具有特定功能或特性的可重用部件或模块&#xff0c;能独立使用或集成到更大系统。 类型 前端 UI 组件&#xff1a;像按钮、下拉菜单、导航栏等&#xff0c;负责构建用户界面&#xff0c;提升用户交互体验。例如在电商 AP…...

OFDM系统仿真

1️⃣ OFDM的原理 1.1 介绍 OFDM是一种多载波调制技术&#xff0c;将输入数据分配到多个子载波上&#xff0c;每个子载波上可以独立使用 QAM、PSK 等传统调制技术进行调制。这些子载波之间互相正交&#xff0c;从而可以有效利用频谱并减少干扰。 1.2 OFDM的核心 多载波调制…...

避坑指南:OpenClaw对接nanobot镜像的3大常见错误与解决方法

避坑指南&#xff1a;OpenClaw对接nanobot镜像的3大常见错误与解决方法 1. 为什么需要这份避坑指南&#xff1f; 上周我在本地部署nanobot镜像时&#xff0c;原本以为半小时就能搞定的事情&#xff0c;硬是折腾了整整一个下午。这个超轻量级的OpenClaw镜像确实很吸引人——内…...

BM3D算法深度解析:为什么它至今仍是图像去噪的黄金标准?

BM3D算法深度解析&#xff1a;为什么它至今仍是图像去噪的黄金标准&#xff1f; 在数字图像处理领域&#xff0c;去噪技术一直是研究的热点与难点。从早期的均值滤波到小波变换&#xff0c;再到如今的深度学习&#xff0c;各种方法层出不穷。然而&#xff0c;在这片技术迭代的浪…...

LinkSwift网盘直链下载助手:2025年高效下载终极解决方案

LinkSwift网盘直链下载助手&#xff1a;2025年高效下载终极解决方案 【免费下载链接】Online-disk-direct-link-download-assistant 可以获取网盘文件真实下载地址。基于【网盘直链下载助手】修改&#xff08;改自6.1.4版本&#xff09; &#xff0c;自用&#xff0c;去推广&am…...

ROCm零基础入门实战指南:从环境搭建到高性能计算

ROCm零基础入门实战指南&#xff1a;从环境搭建到高性能计算 【免费下载链接】ROCm AMD ROCm™ Software - GitHub Home 项目地址: https://gitcode.com/GitHub_Trending/ro/ROCm AMD ROCm&#xff08;Radeon Open Compute&#xff09;是一套开源GPU计算平台&#xff0c…...

MPO光纤跳线:从结构解析到数据中心高密度布线实战

1. MPO光纤跳线&#xff1a;高密度布线的秘密武器 第一次接触MPO光纤跳线时&#xff0c;我被它的"小身材大容量"震惊了。这个看起来和普通SC连接器差不多大小的家伙&#xff0c;居然能塞下12根甚至24根光纤&#xff01;这就像在普通U盘大小的空间里装下了整个移动硬盘…...

OpenClaw内容创作流水线:nanobot镜像从选题到发布的自动化

OpenClaw内容创作流水线&#xff1a;nanobot镜像从选题到发布的自动化 1. 为什么需要内容创作自动化 作为一名技术博主&#xff0c;我每天都要面对一个永恒难题&#xff1a;如何在有限时间内持续产出高质量内容。传统写作流程需要经历选题调研、大纲设计、初稿撰写、SEO优化、…...

HTTP自动化测试架构:基于QD框架的HAR模板规模化治理策略

HTTP自动化测试架构&#xff1a;基于QD框架的HAR模板规模化治理策略 【免费下载链接】templates 基于开源新版 QD 框架站发布的公共har模板库&#xff0c;仅供示例 项目地址: https://gitcode.com/GitHub_Trending/templa/templates 在当今云原生和微服务架构盛行的时代…...

ParrelSync自定义参数功能:打造专属多人游戏测试环境的终极指南

ParrelSync自定义参数功能&#xff1a;打造专属多人游戏测试环境的终极指南 【免费下载链接】ParrelSync (Unity3D) Test multiplayer without building 项目地址: https://gitcode.com/gh_mirrors/pa/ParrelSync ParrelSync是一款专为Unity3D开发者设计的高效多人游戏测…...

触控板手势增强:告别跨系统痛点,实现macOS风格三指拖动无缝体验

触控板手势增强&#xff1a;告别跨系统痛点&#xff0c;实现macOS风格三指拖动无缝体验 【免费下载链接】ThreeFingersDragOnWindows Enables macOS-style three-finger dragging functionality on Windows Precision touchpads. 项目地址: https://gitcode.com/gh_mirrors/t…...

解密GPT:从架构解析到实战应用

1. GPT架构深度拆解 第一次接触GPT模型时&#xff0c;我被它流畅的文本生成能力震撼到了。记得当时用GPT-2生成了一篇伪莎士比亚风格的十四行诗&#xff0c;连文学系的朋友都分不清真假。这种"魔法"背后&#xff0c;其实是精妙的架构设计在支撑。 GPT的核心是Transfo…...