模板匹配——基于模板与基于特征的两种模板匹配对比

news2024/10/9 2:25:47

概述

在人工智能(AI)的研究领域中,模板匹配不仅是一个重要的研究课题,也是解决图像处理中核心问题——定位兴趣区域的关键方法之一。通过模板匹配,可以准确地识别和定位给定图像中的特定对象。这项技术在对象检测、跟踪、监控、医学成像以及图像拼接等多个领域都有着广泛的应用。

模板匹配

模板匹配主要涉及两个核心要素:源图像和模板图像。源图像是期望在其中寻找模板图像匹配的图像,而模板图像则是用于与源图像的子图像进行比较的参考图像。

源图像:
在这里插入图片描述

模板图像:
在这里插入图片描述

在图像匹配算法可分为两大类别,基于模板的匹配和基于特征的匹配各具特色。
1.基于模板的方法,也被称作区域匹配法,适用于模板图像在图像中缺乏显著特征的情况。这种方法直接处理像素值,通过计算图像与模板的强度值来衡量匹配程度。
2.基于特征的方法则适用于源图像和模板图像在特征和控制点上有较高一致性的情况。此时,特征可以是点、曲线或表面模型,用于执行模板匹配。

基于模板

传统的模板匹配通过滑动模板图像与源图像进行对比。模板图像逐像素地在源图像上移动,通过计算重叠区域的相似性数值来寻找匹配。通常,两幅图像会被转换成二值或黑白图像,然后应用如归一化交叉相关、交叉相关和平方差和等匹配技术。
然而,基于模板的方法在处理尺度变化时面临挑战。源图像或模板图像的尺寸变化会影响匹配算法的效果。为了解决这个问题,一个常用的技巧是将模板图像调整到多个尺度,然后与源图像进行比较。在遍历所有尺度后,选择具有最高相关系数的区域作为“匹配”区域。但是,这种方法难以解决旋转不变性问题。为此,Kim, Hae & Araújo, Sidnei(2007年)提出了Ciratefi算法,该算法通过改进蛮力算法——即在每个角度旋转模板图像——来解决旋转问题。Ciratefi算法的计算速度比蛮力算法快400倍,且结果相同。

实现代码:

#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
#include <iostream>
 
using namespace std;
using namespace cv;
 
bool use_mask;
Mat img; Mat templ; Mat mask; Mat result;
const char* image_window = "Source Image";
const char* result_window = "Result window";
 
int match_method;
int max_Trackbar = 5;
 
void MatchingMethod( int, void* );
 
const char* keys =
"{ help h| | Print help message. }"
"{ @input1 | Template_Matching_Original_Image.jpg | image_name }"
"{ @input2 | Template_Matching_Template_Image.jpg | template_name }"
"{ @input3 | | mask_name }";
 
int main( int argc, char** argv )
{
 CommandLineParser parser( argc, argv, keys );
 samples::addSamplesDataSearchSubDirectory( "doc/tutorials/imgproc/histograms/template_matching/images" );
 
 img = imread( samples::findFile( parser.get<String>("@input1") ) );
 templ = imread( samples::findFile( parser.get<String>("@input2") ), IMREAD_COLOR );
 
 if(argc > 3) {
 use_mask = true;
 mask = imread(samples::findFile( parser.get<String>("@input3") ), IMREAD_COLOR );
 }
 
 if(img.empty() || templ.empty() || (use_mask && mask.empty()))
 {
 cout << "Can't read one of the images" << endl;
 return EXIT_FAILURE;
 }
 
 namedWindow( image_window, WINDOW_AUTOSIZE );
 namedWindow( result_window, WINDOW_AUTOSIZE );
 
 const char* 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";
 createTrackbar( trackbar_label, image_window, &match_method, max_Trackbar, MatchingMethod );
 
 MatchingMethod( 0, 0 );
 
 waitKey(0);
 return EXIT_SUCCESS;
}
 
void MatchingMethod( int, void* )
{
 Mat img_display;
 img.copyTo( img_display );
 
 int result_cols = img.cols - templ.cols + 1;
 int result_rows = img.rows - templ.rows + 1;
 
 result.create( result_rows, result_cols, CV_32FC1 );
 
 bool method_accepts_mask = (TM_SQDIFF == match_method || match_method == TM_CCORR_NORMED);
 if (use_mask && method_accepts_mask)
 { matchTemplate( img, templ, result, match_method, mask); }
 else
 { matchTemplate( img, templ, result, match_method); }
 
 normalize( result, result, 0, 1, NORM_MINMAX, -1, Mat() );
 
 double minVal; double maxVal; Point minLoc; Point maxLoc;
 Point matchLoc;
 
 minMaxLoc( result, &minVal, &maxVal, &minLoc, &maxLoc, Mat() );
 
 if( match_method == TM_SQDIFF || match_method == TM_SQDIFF_NORMED )
 { matchLoc = minLoc; }
 else
 { matchLoc = maxLoc; }
 
 rectangle( img_display, matchLoc, Point( matchLoc.x + templ.cols , matchLoc.y + templ.rows ), Scalar::all(0), 2, 8, 0 );
 rectangle( result, matchLoc, Point( matchLoc.x + templ.cols , matchLoc.y + templ.rows ), Scalar::all(0), 2, 8, 0 );
 
 imshow( image_window, img_display );
 imshow( result_window, result );
 
 return;
}

基于特征的方法

特征检测与匹配是许多计算机视觉都有应用,例如运动结构、图像检索、物体检测等。

特征检测与匹配的应用:

  • 自动化物体跟踪
  • 计算视差的点匹配
  • 立体校准(基础矩阵估计)
  • 基于运动的分割
  • 识别
  • 三维物体重建
  • 机器人导航
  • 图像检索和索引

特征:

特征是与解决特定应用相关的计算任务相关的信息。特征可能是图像中的特定结构,如点、边缘或物体。特征也可能是应用于图像的一般邻域操作或特征检测的结果。特征可以分为两大类:

  • 图像中特定位置的特征,如山峰、建筑物角落、门道或形状有趣的雪块。这些局部化的特征通常称为关键点特征(或角点),通常通过围绕点位置的像素块的外观来描述。
  • 可以根据其方向和局部外观(边缘轮廓)进行匹配的特征称为边缘,它们也可以作为图像序列中物体边界和遮挡事件的良好指示。

特征检测与匹配的主要组成部分:

  • 检测:识别兴趣点
  • 描述:每个特征点周围的局部外观以某种方式描述,理想情况下在光照、平移、尺度和平面旋转变化下是不变的。我们通常为每个特征点得到一个描述符向量。

兴趣点:

兴趣点或特征点是纹理表达丰富的点。兴趣点是物体边界方向突然改变的点或两条或多条边缘段的交点。

兴趣点的特性:

  • 它在图像空间中有明确定义的位置或很好地局部化。
  • 它在图像域的局部和全局扰动下稳定,如光照/亮度变化,以便可以可靠地计算兴趣点,并具有高度的重复性。
  • 应提供有效的检测。

可能的方法:

  • 基于图像的亮度(通常通过图像导数)。
  • 基于边界提取(通常通过边缘检测和曲率分析)。

识别算法:

  • 哈里斯角
  • SIFT(尺度不变特征变换)
  • SURF(加速稳健特征)
  • FAST(加速段测试特征)
  • ORB(定向FAST和旋转BRIEF)

特征描述符:

特征描述符是一种算法,它接受一张图像并输出特征描述符/特征向量。特征描述符将有趣的信息编码成一系列数字,并作为一种数值“指纹”,可以用来区分一个特征与另一个特征。
理想情况下,这些信息在图像变换下是不变的,因此即使图像以某种方式变换,我们也可以再次找到该特征。在检测到兴趣点后,我们继续为每个兴趣点计算描述符。描述符可以分为两类:

  • 局部描述符:它是点的局部邻域的紧凑表示。局部描述符试图仅在点周围的局部邻域中模仿形状和外观,因此在匹配方面非常适用。
  • 全局描述符:全局描述符描述整个图像。它们通常不太稳健,因为图像的一部分变化可能会导致它失败,因为它会影响生成的描述符。

算法:

  • SIFT(尺度不变特征变换)
  • SURF(加速稳健特征)
  • BRISK(二进制稳健不变可扩展关键点)
  • BRIEF(二进制稳健独立基本特征)
  • ORB(定向FAST和旋转BRIEF)

特征匹配:

特征匹配或通常的图像匹配,是许多计算机视觉应用的一部分,如图像注册、相机校准和物体识别,其任务是在两个相同场景/对象的图像之间建立对应关系。图像匹配的常见方法包括从图像数据中检测一组兴趣点,每个点都与图像描述符相关联。一旦从两个或多个图像中提取了特征及其描述符,下一步就是在这些图像之间建立一些初步的特征匹配。

通常,基于兴趣点的匹配方法的性能取决于底层兴趣点的特性和相关图像描述符的选择。因此,应使用适合图像内容的检测器和描述符在应用程序中。例如,如果图像包含细菌细胞,则应使用斑点检测器而不是角点检测器。但是,如果图像是城市的航拍图,则使用角点检测器适合找到人造结构。此外,选择一个能够解决图像退化的检测器和描述符非常重要。

算法:

  • 暴力匹配器
  • FLANN(快速近似最近邻库)匹配器

特征检测与匹配算法:

  • 找到一组独特的关键点
  • 为每个关键点定义一个区域
  • 提取并标准化区域内容
  • 从标准化区域计算局部描述符
  • 匹配局部描述符

在这里插入图片描述

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

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

相关文章

Golang | Leetcode Golang题解之第10题正则表达式匹配

题目&#xff1a; 题解&#xff1a; func isMatch(s string, p string) bool {m, n : len(s), len(p)matches : func(i, j int) bool {if i 0 {return false}if p[j-1] . {return true}return s[i-1] p[j-1]}f : make([][]bool, m 1)for i : 0; i < len(f); i {f[i] m…

多线程学习-线程安全

目录 1.多线程可能会造成的安全问题 2. static共享变量 3.同步代码块 4.同步方法 5.使用Lock手动加锁和解锁 6.死锁 1.多线程可能会造成的安全问题 场景&#xff1a;三个窗口同时售卖100张电影票&#xff0c;使用线程模拟。 public class MyThread extends Thread{//tic…

windows安装OpenUSD

一、下载OpenUSD git clone https://github.com/PixarAnimationStudios/OpenUSDOpenUSD&#xff0c;原名USD&#xff08;Universal Scene Description&#xff0c;通用场景描述&#xff09;&#xff0c;是由皮克斯动画工作室开发的一种开放数据格式。OpenUSD主要用于在虚拟世界…

Linux-程序地址空间

目录 1. 程序地址空间分布 2. 两个问题 3. 虚拟地址和物理地址 4. 页表 5. 解决问题 6. 为什么要有地址空间 1. 程序地址空间分布 测试一下&#xff1a; #include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<sys/types.h>int ga…

java中Date类,SimpleDateFormat类和Calendar类

Date类 public Date() 创建一个Date对象&#xff0c;代表的是系统当前此刻的日期时间 public Date(long date) Constructs a Date object using the given milliseconds time value. 把时间毫秒值转变成Date日期对象 public void setTime(long date) Sets an existing Date ob…

【Linux学习】Linux 的虚拟化和容器化技术

˃͈꒵˂͈꒱ write in front ꒰˃͈꒵˂͈꒱ ʕ̯•͡˔•̯᷅ʔ大家好&#xff0c;我是xiaoxie.希望你看完之后,有不足之处请多多谅解&#xff0c;让我们一起共同进步૮₍❀ᴗ͈ . ᴗ͈ აxiaoxieʕ̯•͡˔•̯᷅ʔ—CSDN博客 本文由xiaoxieʕ̯•͡˔•̯᷅ʔ 原创 CSDN 如…

进阶线段树之乘法线段树

1.乘法线段树 顾名思义&#xff0c;就是其中的区间修改为乘法&#xff0c;但是呢&#xff0c;如果只是一个乘法&#xff0c;把之前的加号变成*号&#xff0c;然后开long long即可&#xff08;因为乘法的数据超大&#xff0c;如果不在中间mod点儿东西还能直接超出64位&#xff…

【Java EE】Maven jar 包下载失败问题的解决方法

文章目录 1. 配置好国内的Maven源1.1配置当前项⽬setting1.2设置新项⽬的setting 2.重新下载jar包3.其他问题⭕总结 1. 配置好国内的Maven源 因为中央仓库在国外, 所以下载起来会⽐较慢, 所以咱们选择借助国内⼀些公开的远程仓库来下载资源 接下来介绍, 如何设置国内源 1.1配…

Java集合(个人整理笔记)

目录 1. 常见的集合有哪些&#xff1f; 2. 线程安全的集合有哪些&#xff1f;线程不安全的呢&#xff1f; 3. Arraylist与 LinkedList 异同点&#xff1f; 4. ArrayList 与 Vector 区别&#xff1f; 5. Array 和 ArrayList 有什么区别&#xff1f;什么时候该应 Array而不是…

Spring Boot Mockito (二)

Spring Boot Mockito (二) 基于第一篇Spring Boot Mockito (一) 这篇文章主要是讲解Spring boot 与 Mockito 集成持久层接口层单元测试。 1. 引入数据库 h2及其依赖包 <dependency><groupId>com.h2database</groupId><artifactId>h2</artifactId…

C语言----数据在内存中的存储

文章目录 前言1.整数在内存中的存储2.大小端字节序和字节序判断2.1 什么是大小端&#xff1f;2.2 练习 3.浮点数在内存中的存储3.1.引子3.2.浮点数的存储3.2.2 浮点数取的过程 前言 下面给大家介绍一下数据在内存中的存储&#xff0c;这个是一个了解c语言内部的知识点&#xf…

动规训练3

一、按摩师 1、题目解析 简而言之就是&#xff0c;找到一个按摩师的预约总是长的最长方案&#xff0c;还有一个限制条件&#xff0c;选取的预约两两不相邻。 2、算法原理 a状态表示方程 小技巧&#xff1a;经验题目要求 dp[i]表示以这个节点为结尾&#xff0c;最长的预约时…

【C语言】翻译环境与运行环境

一、前言 在我们学习C语言的时候&#xff0c;第一个接触的程序就是&#xff1a;在屏幕上打印” hello word! “&#xff0c;可当时的我们却未去深入的理解与感悟&#xff0c;一个程序代码是如何运行的&#xff1b;而这一期的博客&#xff0c;则是带着我们&#xff0c;通过C代码…

Python | SLP | EOF | 去除季节趋势

EOF & PC 前言 在计算EOF&#xff08;经验正交函数&#xff09;之前去除季节循环是为了消除数据中的季节变化的影响&#xff0c;使得EOF能够更好地捕捉数据中的空间变化模式。如果不去除季节循环&#xff0c;季节性信号可能会在EOF中占据较大的比例&#xff0c;从而影响对其…

材料物理 笔记-4

原内容请参考哈尔滨工业大学何飞教授&#xff1a;https://www.bilibili.com/video/BV18b4y1Y7wd/?p12&spm_id_frompageDriver&vd_source61654d4a6e8d7941436149dd99026962 或《材料物理性能及其在材料研究中的应用》&#xff08;哈尔滨工业大学出版社&#xff09; 离…

浙大恩特客户资源管理系统 RegulatePriceAction SQL注入漏洞复现

0x01 产品简介 浙大恩特客户资源管理系统是一款针对企业客户资源管理的软件产品。该系统旨在帮助企业高效地管理和利用客户资源,提升销售和市场营销的效果。 0x02 漏洞概述 浙大恩特客户资源管理系统 RegulatePriceAction接口存在 SQL 注入漏洞,攻击者可通过输入恶意 SQL …

信息传播的AI时代:机器学习赋能新闻出版业的数字化之旅

&#x1f9d1; 作者简介&#xff1a;阿里巴巴嵌入式技术专家&#xff0c;深耕嵌入式人工智能领域&#xff0c;具备多年的嵌入式硬件产品研发管理经验。 &#x1f4d2; 博客介绍&#xff1a;分享嵌入式开发领域的相关知识、经验、思考和感悟,欢迎关注。提供嵌入式方向的学习指导…

layui框架实战案例(26):layui-carousel轮播组件添加多个Echarts图标的效果

在Layui中&#xff0c;使用layui-carousel轮播组件嵌套Echarts图表来实现多个图表的展示。 css层叠样式表 调整轮播图背景色为白色&#xff1b;调整当个Echarts图表显示loading…状态&#xff1b;同一个DIV轮播项目添加多个Echarts的 .layui-carousel {background-color: #f…

黄锈水过滤器 卫生热水工业循环水色度水处理器厂家工作原理动画

​ 1&#xff1a;黄锈水处理器介绍 黄锈水处理器是一种专门用于处理“黄锈水”的设备&#xff0c;它采用机电一体化设计&#xff0c;安装方便&#xff0c;操作简单&#xff0c;且运行费用极低。这种处理器主要由数码射频发生器、射频换能器、活性过滤体三部分组成&#xff0c;…

GPT-3.5开放免费使用,这次OpenAI做到了真的open

本周一&#xff0c;OpenAI宣布&#xff0c;部分地区的ChatGPT网站访问者现在无需登录即可使用人工智能助手。 此前&#xff0c;该公司要求用户创建账户才能使用&#xff0c;即使是目前由GPT-3.5AI语言模型支持的免费版ChatGPT也是如此。 01.GPT-3.5开放免登录使用 众所周知&…