【原理解密】多角度、多尺度、多目标的边缘模板匹配

学习《OpenCV应用开发:入门、进阶与工程化实践》一书

做真正的OpenCV开发者,从入门到入职,一步到位!

边缘模板匹配的基本原理

OpenCV中自带的模板匹配算法,完全是像素基本的模板匹配,特别容易受到光照影响,光照稍微有所不同,该方法就会歇菜了!搞得很多OpenCV初学者刚学习到该方法时候很开心,一用该方法马上很伤心,悲喜交加,充分感受到了理想与现实的距离,不过没关系,这里介绍一种新的模板匹配算法,主要是基于图像边缘梯度,它对图像光照与像素迁移都有很强的抗干扰能力,在工业应用场景中已经得到广泛使用。基本原理主要是基于梯度跟边缘实现NCC计算与匹配,首先计算梯度:
在这里插入图片描述
然后基于梯度,实现非最大抑制与边缘提取以后,就得到了所有的边缘点集,每个边缘点有三个值,分别是:

x方向梯度、
y方向梯度、
xy方向梯度

然后对输入的每张图像,根据模板图像的每个边缘点计算NCC,得到匹配阈值,开启匹配搜索:
在这里插入图片描述
如果其中任何一个点的匹配阈值小于minScore就停止搜索与匹配当前像素点,继续搜索下一个,直到遍历完成所有像素点,得到匹配得分图像。然后采用跟NCC相似的处理,去重以后得到最终匹配结果。

代码实现与演示

说实话我也不是从零开始的,之前我写过一个版本,但是我发现一个别人写好的一个原始版本,好像是这个算法的作者自己写,基于OpenCV3.x版本完成的,链接如下:

https://github.com/daxiaHuang/edge-template-match/tree/master

同时原始版本 不支持 多角度、多对象、多尺度,所以我在这个上面一通狂改,就让它各种支持了,这个大概花了我三天时间。最终我给他们封装成两个类,配合上Qt C++ 的一个界面,通过点点鼠标即可运行。客户端直接调用API即可,客户端代码如下:

task.initailization(tpl);
double start = (double)cv::getTickCount();
task.detect(target, results);
float time = (((double)cv::getTickCount() - start)) / cv::getTickFrequency();
std::cout << "edge template match execute time: " << time << std::endl;
for (auto item : results) {for (auto pt : item.pts) {cv::circle(result, pt, 1, cv::Scalar(0, 255, 0), 1, 8);}cv::RotatedRect rrt = cv::minAreaRect(item.pts);cv::Point2f minbox[4];rrt.points(minbox);for (int r = 0; r < 4; r++){cv::line(result, minbox[r], minbox[(r + 1) % 4], cv::Scalar(0, 0, 255), 2, 8);}std::cout << "conf: " << item.conf << std::endl;cv::putText(result, cv::format("conf:%.2f, angle:%d", item.conf, item.angle), item.center, cv::FONT_HERSHEY_SIMPLEX, .5, cv::Scalar(255, 0, 0), 1, 8);
}cv::imshow("边缘模板匹配", result);
cv::waitKey(0);

边缘匹配运行结果 - 测试一
在这里插入图片描述
速度测试数据:执行时间: 126.06 ms
在这里插入图片描述
速度测试数据:执行时间: 229.82 ms
在这里插入图片描述
速度测试数据:执行时间: 117.60 ms
在这里插入图片描述
速度测试数据:执行时间: 405.60 ms
最后一张测试目标图像大小为 830x822,目标数目为13

最后说明

演示基于QT + OpenCV C++ 完成,源码购买站内私信博主即可!

好书推荐

《OpenCV应用开发:入门、进阶与工程化实践》全书共计16个章节,重点聚焦OpenCV开发常用模块详解与工程化开发实践,提升OpenCV应用开发能力,助力读者成为OpenCV开发者,同时包含深度学习模型训练与部署加速等知识,帮助OpenCV开发者进一步拓展技能地图,满足工业项目落地所需技能提升。购买请点链接:
《OpenCV4 应用开发-入门、进阶与工程化实践》

学习课程有专属答疑群,负责贴身答疑解惑

读者专属QQ群 :657875553
进群暗号:OpenCV4读者

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

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

相关文章

Python一些可能用的到的函数系列124 GlobalFunc

说明 GlobalFunc是算网的下一代核心数据处理基础。 算网是一个分布式网络&#xff0c;为了能够实现真的分布式计算&#xff08;加快大规模任务执行效率&#xff09;&#xff0c;以及能够在很长的时间内维护不同版本的计算方法&#xff0c;需要这样一个对象/服务来支撑。Globa…

如何使用python在三天内制作出一个赛车游戏

制作一个赛车游戏是一个复杂的过程&#xff0c;涉及多个方面&#xff0c;如游戏设计、图形渲染、物理引擎、用户输入处理等。在三天内完成这个任务可能非常具有挑战性&#xff0c;特别是如果你是初学者。但如果你有基本的Python编程知识和一些游戏开发经验&#xff0c;以下是一…

尚硅谷最新Node.js 学习笔记(三)

目录 六、Node.js 模块化 6.1、介绍 什么是模块化与模块&#xff1f; 什么是模块化项目&#xff1f; 模块化好处 6.2、模块暴露数据 模块初体验 暴露数据 6.3、导入&#xff08;引入&#xff09;模块 6.4、导入模块的基本流程 6.5、CommonJS规范 七、包管理工具 7…

java数据结构前置知识以及认识泛型

目录 什么是集合框架 容器 时间复杂度 空间复杂度 包装类 装箱 拆箱 引出泛型 泛型类的使用 类型推导 泛型如何编译的 泛型的上界 泛型方法静态泛型方法以及泛型上界 什么是集合框架 Java 集合框架 Java Collection Framework &#xff0c;又被称为容器 containe…

变量与运算符

目录 1. 关键字&#xff08;keyword&#xff09; 2. 标识符( identifier) 3. 变量 3.1 为什么需要变量 3.2 初识变量 3.3 Java中变量的数据类型 3.4 变量的使用 3.4.1 步骤1&#xff1a;变量的声明 3.4.2 步骤2&#xff1a;变量的赋值 4. 基本数据类型介绍 4.1 整数…

cool Nodejs后端框架 如何快速入门 写一个接口

1.cool 框架 js前端开发者 想自己写后端接口 快速入门的就是node.js 了 可以用这个框架自己做一些东西 或者实现前后端的开发 2.目录结构 这个基本上 就是cool 框架的项目结构 主要是 这个src 中的modules 文件夹 这个文件夹 主要是一些接口模块 比如 business 中 相当于…

OJ_深度优先搜索

题干 c代码 #include <iostream> #include <algorithm> using namespace std; #define Max_M 100 #define Max_N 100 char a[Max_M][Max_N],M,N; void dfs(int x,int y) {//先把w替换成.//然后遍历8个方向a[x][y] .;for(int dx -1;dx < 1;dx){for(int dy -1…

基于 Python 的大数据的电信反诈骗系统

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

车载诊断协议DoIP系列 —— 车载以太网诊断需求规范(网关、路由)

车载诊断协议DoIP系列 —— 车载以太网诊断需求规范(网关、路由) 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师(Wechat:gongkenan2013)。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 本就是小人物,输了就是输了,不要在意别人怎么看自…

Springboot加载bootstrap和application原理

Springboot加载bootstrap和application原理 bootstrap.yml能被springboot加载导入依赖 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.4.6</version><rel…

Bitcoin Bridge:治愈还是诅咒?

1. 引言 主要参考&#xff1a; Bitcoin Bridges: Cure or Curse? 2. 为何需关注Bitcoin bridge&#xff1f; 当前的Bitcoin bridge&#xff0c;其所谓bridge&#xff0c;实际是deposit&#xff1a; 在其它链上的BTC情况为&#xff1a; 尽管当前约有43.7万枚BTC在其它链上…

PR:视频源素材的截取操作

导入素材后&#xff0c;双击视频素材&#xff0c;打开源视频 1&#xff1a;设置入点 2&#xff1a;设置出点&#xff0c;设置完出入点&#xff0c;抓取视频就可以将入点至出点的片段拖至时间轴上 3&#xff1a;转到入点 4&#xff1a;后退一帧 5&#xff1a;播放 6&#x…

全面理解JVM虚拟机

为什么要学JVM&#xff1f; ​ 首先&#xff1a;面试需要。面试题层出不穷&#xff0c;难道每次面试都靠背几百上千条面试八股&#xff1f; ​ 其次&#xff1a;基础决定上层建筑。自己写的代码都不知道是怎么回事&#xff0c;怎么可能写出靠谱的系统&#xff1f; ​ 然后&a…

【算法设计与分析】反转链表 ||

&#x1f4dd;个人主页&#xff1a;五敷有你 &#x1f525;系列专栏&#xff1a;算法分析与设计 ⛺️稳中求进&#xff0c;晒太阳 题目 给你单链表的头指针 head 和两个整数 left 和 right &#xff0c;其中 left < right 。请你反转从位置 left 到位置 right 的链表…

机器学习入门--循环神经网络原理与实践

循环神经网络 循环神经网络&#xff08;RNN&#xff09;是一种在序列数据上表现出色的人工神经网络。相比于传统前馈神经网络&#xff0c;RNN更加适合处理时间序列数据&#xff0c;如音频信号、自然语言和股票价格等。本文将介绍RNN的基本数学原理、使用PyTorch和Scikit-Learn…

【网络攻防实验】【北京航空航天大学】【实验四、防火墙配置(Firewall Configuration)实验】

实验四、防火墙配置(Firewall Configuration)实验 一、 实验环境搭建 1. Kali Linux网络配置 将Kali Linux虚拟机网卡1设置为NAT网络模式,ip地址为10.0.2.5,如下图所示: 配置NAT网络端口转发: 将Kali Linux网卡2设置为内部网络模式: 配置Kali Linux网卡1: 类似地,配…

在中国做 DePIN?你需要明白风险与机遇

撰文&#xff1a;肖飒团队 来源Techub News专栏作者 随着科技的发展&#xff0c;我们正在日益进入一个资源相对过剩的时代&#xff0c;这使我们在日常生活中虽然支付了该部分资源的使用费&#xff0c;但却时常不能将其「物尽其用」&#xff0c;难免出现资源浪费。例如&#x…

PHP+vue+mysql校园学生社团管理系统574cc

运行环境:phpstudy/wamp/xammp等 开发语言&#xff1a;php 后端框架&#xff1a;Thinkphp 前端框架&#xff1a;vue.js 服务器&#xff1a;apache 数据库&#xff1a;mysql 数据库工具&#xff1a;Navicat/phpmyadmin 前台功能&#xff1a; 首页&#xff1a;展示社团信息和活动…

C#,二项式系数(Binomial Coefficient)的七种算法与源代码

1 二项式系数&#xff08;binomial coefficient&#xff09; 二项式系数&#xff08;binomial coefficient&#xff09;&#xff0c;或组合数&#xff0c;在数学里表达为&#xff1a;(1 x)ⁿ展开后x的系数&#xff08;其中n为自然数&#xff09;。从定义可看出二项式系数的值…

立体库库存数量统计(SCL代码)

立体库库存物体检测由光电开关完成&#xff0c;每个储物格都有一个检测光电。5*6的仓库需要30个光电检测开关组成检测矩阵。找出矩阵中的最大元素并返回其所在的行号和列号和我们今天介绍的算法有很多相似的地方&#xff0c;大家可以对比学习。具体链接地址如下&#xff1a; h…