首页 > 其他分享 >模板匹配里的一些数学原理

模板匹配里的一些数学原理

时间:2024-02-21 14:24:27浏览次数:28  
标签:匹配 sum 数学原理 图像 Omega 模板 vec

模板匹配里的一些数学原理

我们知道,在openCV里,模板匹配中匹配度的计算公式有三类。SQDIFF、CCORR、CCOEFF。下面我们来简单介绍一下这三类计算方法,并比较其不同之处。


openCV里的模板匹配

SQDIFF

SQDIFF全称Sum of Squared Difference (SSD),即差的平方和。其离散形式为:

\[E(\vec{d}) = \sum_{\Omega}^{}\left |{I(\vec{x}+\vec{d})-T(\vec{x})}\right |^2 \\ 其中\Omega表示模板图像定义域,\vec{d}表示模板图像在输入图像里的位置向量,I(\vec{x})表示待匹配图像(大小与模板图像相等),T(\vec{x})表示模板图像 \]

我们将模板图像与待匹配图像均展开成一维向量,即一维离散信号:

\[I = (x_1, x_2,...,x_n)^T \\ T = (t_1, t_2, ..., t_n)^T \]

则E可以表示为:

\[E = \sum_{i}\left | x_i-t_i \right| ^ 2 \ \ \ (*) \]

这样就很好理解了,就是两个图像中每个像素之差的平方和,类似于线性回归中的MSE(Mean-Square Error)损失函数。

我们再写成向量形式:

\[E = \sum\left|| I-T \right||^2 \\ 其中||x||表示L_2范数,相当于x的模 \]

这样可以发现,SQDIFF其实就是用来度量模板图片与待匹配图片的欧式距离。

在 (*) 式中,我们将模板图片与待匹配图片均展成了一维向量,而这也充分表明了模板匹配的局限性:无法包含空间信息,如旋转、伸缩等

SQDIFF_NORMED就是对SQDIFF进行归一化,这里不多赘述。

CCORR

CCORR 的全称为 Cross Correlation,意即互相关,其离散形式为:

\[E(\vec{d}) = \sum_{\Omega}^{}{I(\vec{x}+\vec{d})*T(\vec{x})} \]

反映了待匹配图像与模板图像的相似性。

为什么这个式子可以反应两个图像的相似性呢?

我们还是将图像展成一维离散信号进行分析:

\[I = (x_1, x_2,...,x_n)^T \\ T = (t_1, t_2, ..., t_n)^T \]

则E可以表示为:

\[E = \sum_{i}x_i*t_i=I^TT=|I||T|cos\theta \\ 其中\theta表示I向量与T向量的夹角 \]

当模板图像与待匹配图像的相关性越好时,\(I\)与\(T\)之间的夹角越小,也就是两个向量靠得越近,此时\(cos\theta\)越大,\(E\)也就越大

其归一化形式:

\[E(\vec{d}) =\frac{\sum_{\Omega}^{}{I(\vec{x}+\vec{d})*T(\vec{x})}}{\sqrt{\sum_{\Omega}I^2(\vec{x}+\vec{d})*\sum_{\Omega}T^2(\vec{x})}} \]

其全称为Normalized Cross Correlation (NCC),意即归一化互相关.

我们还是将图像展成一维离散信号,则E可以表示为:

\[E=\frac{|I||T|cos\theta}{|I||T|} = cos\theta \]

也就是两个向量之间的夹角,范围为\([0,1]\),越接近1则相关性越好。

CCOEFF

CCOEFF 的全称为 Correlation Coefficient, 意即相关系数,也就是零均值互相关 (Zero-mean Cross Correlation; ZCC)

其离散形式:

\[E(\vec{d}) = \sum_{\Omega}(I(\vec{x}+\vec{d})-\bar{I}_\bar{d})(T(\vec{x})-\bar{T}) \\ 其中\ \ \bar{T} = \frac{1}{|\Omega|}\sum_{\Omega}T(\vec{x}),\ \ \bar{I}_\bar{d}=\frac{1}{|\Omega|}\sum_{\Omega}I(\vec{x}+\vec{d}) \]

可以发现,CCOEFF的计算相当于CCORR中的像素值替换成了(像素值-图像像素均值),这样做的好处就是减弱了光照对于图像匹配的影响,鲁棒性更强

标签:匹配,sum,数学原理,图像,Omega,模板,vec
From: https://www.cnblogs.com/Asaka-QianXiang/p/18025093

相关文章

  • vue3项目模板:新建一个vite+vue3项目,并做基础化建设
    原文地址:https://blog.csdn.net/weixin_43239880/article/details/130355138新建一个vite+vue3项目,并做基础化建设1.使用npmcreatvite@latest新建一个vue3项目2.生成git仓库3.将prettier的规则加入到eslint中(可选操作,建议有)4.添加commitLint(可选操作,建议有)5.加入UI组件库,以ele......
  • python 爬虫模板
    前言在我们写爬虫的时候,一般想要的数据都在详情页里面,一般代码进入详情页参数,需要首页里面寻找,所以爬这样的网站,需要定义一个模板我的模板如下: importrandomimporttimeimportrequestsfromauctionimportlogtoolfromauction.BaseCrawlerimportBaseCrawlercla......
  • 线段树—模板
    线段树常见操作build建树update更新query查询pushup向上回溯pushdown向下延迟更新(延迟标记)建线段树://预编译命令,做符号代换#definelson(gjd<<1)#definerson(gjd<<1|1)//gjd表示当前结点,[l,r]表示区间范围voidbuild(intgjd,intl,intr){tree[gjd]......
  • 请求接口生成导入模板
    这里介绍一种通过接口去生成导入数据Excel模板1、controller 2、serviceImpl@OverridepublicvoiddownloadOrderTemplate(HttpServletResponseresponse){List<WorkOrderVoImportDto>orderVoImports=newArrayList<>();try{List......
  • C++ 模板的笔记2
    C++模板的笔记2关于可变参函数模板借鉴了一部分笔记,感谢大佬类模板中的嵌套类模板可以嵌套其他类模板,就像普通类可以嵌套其他普通类一样。嵌套的类模板可以访问外部类模板的成员,包括私有成员。示例:#include<iostream>usingnamespacestd;template<typenameT>classO......
  • 线段树模板
    开局宏定义:#include<bits/stdc++.h>#defineintlonglong#definelson(now<<1)//现结点的左孩子#definerson(now<<1|1)//右孩子usingnamespacestd;结构体定义:structNode{intl,r;//表示左右区间intmax,sum;//其他数据域}tree[N<<2]//=N*......
  • sensitive-word v0.13 特性版本发布 支持英文单词全词匹配
    拓展阅读sensitive-word-adminv1.3.0发布如何支持分布式部署?sensitive-word-admin敏感词控台v1.2.0版本开源sensitive-word基于DFA算法实现的高性能敏感词工具介绍更多技术交流业务背景对于英文单词Disburse之类的,其中的sb字母会被替换,要怎么处理,能不......
  • password_encryption_type 和 pg_hba.conf 不匹配导致用户连不上
    问题概述xxx客户新上一套opengauss数据库,在测试中用户输入正确的密码,提示用户密码错误,导致用户被锁问题原因password_encryption_type和pg_hba.conf不匹配导致用户连不上模拟问题因没有opengauss的环境,测试环境选择Mogdb1、准备测试环境,修改password_encryption_type。......
  • **SiteServer CMS远程模板下载getshell漏洞导致的黑SEO利用分析**
    前言某日中午,收到上级下发的任务,涉及一代理商客户网站发现异常SQ内容,要求进行溯源分析并找出根本原因。0x01初步分析通过提供的链接(www.xxx.com.cn/2023j19tPLKn2/55151),确认涉及黑帽SEO活动,通过百度搜索进一步验证也证实了这一点。0x02日志分析黑客常常在植入菠菜或非......
  • 匹配括号&栈
     #include<iostream>#include<stack>usingnamespacestd;intmain(){ stringa; cin>>a; stack<char>m; for(inti=0;i<a.length();i++){ if(a[i]=='('||a[i]=='['||a[i]=='{'){ m.push(a[i]); ......