c# 实现多尺度的模板匹配

Cv2.MatchTemplate()方法在模板图像与测试图像分辨率不同的情况下会失效,因为模板匹配的原理是将模板从测试图片中从左到右,从上到下依次滑动来找到匹配度最高的地方;

因此,为了实现多尺度的模板匹配,需要对其进行改进;

主要思路:循环缩放模板图像的大小再与测试图像进行匹配(很暴力)。

实现的核心代码如下(c#): 

public void MultiSixeMatch(String sourceImagePath, bool isSaveResult, int samllResizeLoop = 20, double samllResize = 0.02, int largeResizeLoop = 40, double largeResize = 0.02, bool earlyStop = true, double stopConfidence = 0.8){Mat testPic = Cv2.ImRead(sourceImagePath, ImreadModes.Color);//用来存储每次匹配的结果:匹配信任度、最大匹配位置double tempConfidence = double.NegativeInfinity;Point tempMaxLocal = new Point();// 缩放模板 当前模版为最大尺寸,每次循环缩小2%,循环20次for (int index = -samllResizeLoop; index < 0; index++){Mat tempTemplate = templatePic.Clone();int newRows = (int)(templatePic.Rows + index * samllResize * templatePic.Rows);int newCols = (int)(templatePic.Cols + index * samllResize * templatePic.Cols);// resize模板图像大小Cv2.Resize(tempTemplate, tempTemplate, new Size(newCols, newRows));// 将得到的小模板进行与测试图像进行匹配Mat matchResult = new Mat();Cv2.MatchTemplate(testPic, tempTemplate, matchResult, TemplateMatchModes.CCoeffNormed);// 解析模板匹配的结果 最大匹配区域以及匹配度Cv2.MinMaxLoc(matchResult, out _, out tempConfidence, out _, out tempMaxLocal);Rect tempRect = new Rect(tempMaxLocal, tempTemplate.Size());// 判断当前匹配信任度 如果高于阈值 则结束匹配if(earlyStop && tempConfidence > stopConfidence){updateResult(index, tempMaxLocal, tempRect, tempConfidence);saveResult(testPic, sourceImagePath, isSaveResult);showPicture(testPic);return;}// 记录当前最好的结果if (tempConfidence > confidence){updateResult(index, tempMaxLocal, tempRect, tempConfidence);}}// 放大模板 当前模版为最小尺寸,每次循环放大2%,循环40次for (int index = 0; index < largeResizeLoop; index++){Mat tempTemplate = templatePic.Clone();int newRows = (int)(templatePic.Rows + index * largeResize * templatePic.Rows);int newCols = (int)(templatePic.Cols + index * largeResize * templatePic.Cols);// resize模板图像大小Cv2.Resize(tempTemplate, tempTemplate, new Size(newCols, newRows));// 将得到的小模板进行与测试图像进行匹配Mat matchResult = new Mat();Cv2.MatchTemplate(testPic, tempTemplate, matchResult, TemplateMatchModes.CCoeffNormed);// 解析模板匹配的结果 最大匹配区域以及匹配度Cv2.MinMaxLoc(matchResult, out _, out tempConfidence, out _, out tempMaxLocal);Rect tempRect = new Rect(tempMaxLocal, tempTemplate.Size());// 判断当前匹配信任度 如果高于阈值 则结束匹配if (earlyStop && tempConfidence > stopConfidence){updateResult(index, tempMaxLocal, tempRect, tempConfidence);saveResult(testPic, sourceImagePath, isSaveResult);showPicture(testPic);return;}// 记录当前最好的结果if (tempConfidence > confidence){updateResult(index, tempMaxLocal, tempRect, tempConfidence);}}saveResult(testPic, sourceImagePath, isSaveResult);showPicture(testPic);return;}private void saveResult(Mat testPic, String sourceImagePath, bool isSaveResult){if (!isSaveResult){return;}Cv2.Rectangle(testPic, rect, Scalar.Green, 3);Cv2.PutText(testPic, bestIndex.ToString() + ":" + Math.Round(confidence, 4).ToString(), new Point(maxLocal.X, maxLocal.Y - 50), HersheyFonts.HersheyDuplex, 2, Scalar.Red, 8);Cv2.ImWrite(sourceImagePath.Split('.')[0] + "_matchResult.jpg", testPic);}private void showPicture(Mat testPic){Cv2.NamedWindow("Result", WindowFlags.Normal);Cv2.ImShow("Result", testPic);Cv2.WaitKey(0);}/// <summary>/// 更新最佳的匹配结果/// </summary>/// <param name="index">最佳序号</param>/// <param name="tempMaxLocal">匹配点(左上角坐标)</param>/// <param name="tempRect">、匹配框</param>/// <param name="tempConfidence">匹配信任度</param>private void updateResult(int index, Point tempMaxLocal, Rect tempRect, double tempConfidence){bestIndex = index;maxLocal = tempMaxLocal;rect = tempRect;confidence = tempConfidence;return;}

写得不是很优雅,只能说能运行起来吧!

看网上很多方法都是通过对比模板与匹配区域图像之间的方差和直方图之类的信息,来选择最终的结果,这是为什么呢?为啥不直接用匹配的分数作为选择依据呢?(以上代码就是依据匹配的分数来选择最好的匹配结果)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/49057.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

计算机网络知识-面试点1

1. 三握四挥 定义&#xff1a; 在计算机网络中&#xff0c;特别是TCP/IP协议中&#xff0c;“三握”指的是三次握手&#xff08;Three-way Handshake&#xff09;&#xff0c;而“四挥”则指的是四次挥手&#xff08;Four-way Handshake&#xff09;。这两个过程分别用于TCP连接…

LangChain的使用详解

一、 概念介绍 1.1 Langchain 是什么&#xff1f; 官方定义是&#xff1a;LangChain是一个强大的框架&#xff0c;旨在帮助开发人员使用语言模型构建端到端的应用程序&#xff0c;它提供了一套工具、组件和接口&#xff0c;可简化创建由大型语言模型 (LLM) 和聊天模型提供…

Qt实战:专栏内容介绍及目录

1、专栏介绍 Qt相比Visual Studio (VS) 的优势主要体现在跨平台能力、‌丰富的功能、‌高性能、‌现代UI设计、‌社区支持和企业支持等方面。‌ 跨平台能力&#xff1a;‌Qt 允许应用程序在多个操作系统上编译和运行&#xff0c;‌无需为每个平台编写特定的代码&#xff0c;‌…

构建高效园区导览系统:基于3DGIS与物联网技术的实现方案

园区导航的挑战与机遇 在现代化的大型园区中&#xff0c;随着面积的不断扩张和布局的日益复杂&#xff0c;传统的纸质地图已难以满足日益增长的导航需求。每栋楼、每层楼都有着不同的办公室&#xff0c;不同的业务。这种低效的寻路过程不仅影响了客户的来访体验&#xff0c;也…

SSD基本架构与工作原理

SSD的核心由一个或多核心的CPU控制器、DRAM缓存以及多个NAND闪存芯片组成。CPU控制器负责管理所有读写操作&#xff0c;并通过DRAM缓存存储映射表等元数据&#xff0c;以加速寻址过程。 NAND闪存则是数据存储的实际介质&#xff0c;其组织结构从大到小依次为通道&#xff08;包…

MySQL_JDBC

目录 一、JDBC常用的接口和类 1.1 数据库连接 Connection 1.2 Statement 对象 二、JDBC的使用 总结 【Java 的数据库编程】 JDBC 即 Java Database Connectivity (Java数据库连接)&#xff0c;是一种用于执行 SQL 语句的 Java API。这个 API 由 java.sql.*,javax.sql.* …

数据结构(Java):七大排序算法【详解】

目录 1、排序的概念 1.1 排序 1.2 排序的稳定性 1.3 内部排序&外部排序 1.4 各排序算法总结对比 2、 插入排序 2.1 &#x1f338;直接插入排序 2.2 &#x1f338;希尔排序 3、 选择排序 3.1 &#x1f338;直接选择排序 3.2 直接选择排序优化 3.3 &#x1f338;…

基于rsync\unlink 等一套本机备份跨机备份历史备份清理shell 脚本

一 摘要 本文主要介绍一套本地备份、跨机器备份、历史备份清理脚本&#xff0c;使用场景如数据库备份等 二 环境 linux 系列系统 基本都支持&#xff0c;个别命令可能需要微调。 2.1 实验环境 [rootlocalhost rsync]# cat /etc/centos-release CentOS Linux release 7.9.2…

如何给7Z分卷文件设置密码?简单几步给文件加上安全锁

在压缩7Z文件的时候&#xff0c;如果文件比较大&#xff0c;很多小伙伴都会把文件压缩成7Z分卷文件&#xff0c;那想要保护7Z分卷文件&#xff0c;要如何设置密码呢&#xff1f;不清楚的小伙伴&#xff0c;一起来看看吧&#xff01; 我们可以使用7-Zip解压缩文件&#xff0c;在…

qt初入门9:qt记录日志的方式,日志库了解练习(qInstallMessageHandler,qslog, log4qt)

项目中用到qt&#xff0c;考虑有需要用到去记录日志&#xff0c;结合网络&#xff0c;整理一下&#xff0c;做记录。 简单了解后&#xff0c;qt实现日志模块思考&#xff1a; 1&#xff1a;借助qt自带的qInstallMessageHandler重定向到需要的目的地。 2&#xff1a;自己封装一…

openmv学习笔记(24电赛备赛笔记)

#openmv简介 openmv一种小型&#xff0c;可编程机器视觉摄像头&#xff0c;设计应用嵌入式应用和计算边缘&#xff0c;是图传模块&#xff0c;或者认为是一种&#xff0c;具有图像处理功能的单片机&#xff0c;提供多种接口&#xff08;I2C SPI UART CAN ADC DAC &#xff0…

高翔【自动驾驶与机器人中的SLAM技术】学习笔记(三)基变换与坐标变换;微分方程;李群和李代数;雅可比矩阵

一、基变换与坐标变换 字小,事不小。 因为第一反应:坐标咋变,坐标轴就咋变呀。事实却与我们想象的相反。这俩互为逆矩阵。 第一次读没有读明白,后面到事上才明白。 起因是多传感器标定:多传感器,就代表了多个坐标系,多个基底。激光雷达和imu标定。这个标定程序,网上,…

Web开发:xmlns解析

xmlns解析 什么是XML命名空间&#xff1f;为什么需要命名空间&#xff1f;命名空间的声明默认命名空间多命名空间的使用命名空间的作用范围在XHTML中的命名空间XML命名空间与XML Schema使用命名空间解析器举例单一命名空间多个命名空间默认命名空间与前缀命名空间结合命名空间覆…

Bootstrap5 Navbar多级下拉框

实现目标&#xff1a; 1、访问 Bootstrap5-navbar 2、修改dropdown为多级 <!DOCTYPE HTML> <html lang"en-US"> <head><meta charset"UTF-8"><title></title><link rel"stylesheet" href"https…

【DevOps系列】构建Devops系统

开始介绍 那就着手开始干吧。先介绍一下我们的工具链。 主要工具&#xff1a;GitHub、Jenkins、Kubernetes、Ansible、Prometheus和JMeter 着手动 1. 设置GitHub作为源代码仓库 登录GitHub: 打开浏览器并访问 https://github.com&#xff0c;使用您的GitHub账户登录。 创建…

(7) cmake 编译C++程序(二)

文章目录 概要整体代码结构整体代码小结 概要 在ubuntu下&#xff0c;通过cmake编译一个稍微复杂的管理程序 整体代码结构 整体代码 boss.cpp #include "boss.h"Boss::Boss(int id, string name, int dId) {this->Id id;this->Name name;this->DeptId …

05 HTTP Tomcat Servlet

文章目录 HTTP1、简介2、请求数据格式3、响应数据格式 Tomcat1、简介2、基本使用3、Maven创建Web项目4、IDEA使用Tomcat Servlet1、简介2、方法介绍3、体系结构4、urlPattern配置5、XML配置 HTTP 1、简介 HTTP概念 HyperText Transfer Protocol&#xff0c;超文本传输协议&am…

鸿蒙 动态共享包HSP的创建和引用

1.什么是动态共享包HSP HSP&#xff08;Harmony Shared Package&#xff09;是动态共享包&#xff0c;可以包含代码、C库、资源和配置文件&#xff0c;通过HSP可以实现代码和资源的共享。HSP不支持独立发布&#xff0c;而是跟随其宿主应用的APP包一起发布&#xff0c;与宿主应…

【Django5】模板引擎

系列文章目录 第一章 Django使用的基础知识 第二章 setting.py文件的配置 第三章 路由的定义与使用 第四章 视图的定义与使用 第五章 二进制文件下载响应 第六章 Http请求&HttpRequest请求类 第七章 会话管理&#xff08;Cookies&Session&#xff09; 第八章 文件上传…

【记录ubuntu22 安装ros1 noetic 与 ros2 humble共存】

记录ubuntu22 安装ros1 noetic 与 ros2 humble共存 基础环境介绍 qemu环境,目标系统是armv7l的32位系统,无法通过apt源安装上二进制的ros,所以只有编译安装ubuntu22 先安装ros2预先准备工作 更新系统源 # 默认注释了源码镜像以提高 apt update 速度,如有需要可自行取消注释…