1.NCC算法实现及其优化[基础实现篇]
NCC算法实现及其优化
本文将集中探讨一种实现相对简单,效果较好的模板匹配算法(NCC)
\[R(x,y)= \frac{ \sum_{x',y'} (T'(x',y') \cdot I'(x+x',y+y')) }{ \sqrt{\sum_{x',y'}T'(x',y')^2 \cdot \sum_{x',y'} I'(x+x',y+y')^2} }
\\
\\
\begin{array}{l} T'(x',y')=T(x',y') - 1/(w \cdot h) \cdot \sum _{ x'',y''} T(x'',y'') \\ I'(x+x',y+y')=I(x+x',y+y') - 1/(w \cdot h) \cdot \sum _{x'',y''} I(x+x'',y+y'') \end{array}
\]具体原理是高中知识,也就是Spearma相关系数,这里就不赘述了。
基本实现代码
float MatchTemplateCPU(int8_t* pSearchImage,
int8_t* pTemplate,
int nSearchImageWidth,
int nSearchImageHeight,
int nTemplateWidth,
int nTemplateHeight,
int& nMatchPointX,
int& nMatchPointY
)
{
//R(x,y)= \frac{ \sum_{x',y'} (T'(x',y') \cdot I'(x+x',y+y')) }{ \sqrt{\sum_{x',y'}T'(x',y')^2 \cdot \sum_{x',y'} I'(x+x',y+y')^2} }
//T'(x', y')=T(x', y') - 1/(w \cdot h) \cdot \sum _{ x'',y''} T(x'',y'')
//I'(x + x',y+y') = I(x + x',y+y') - 1 / (w \cdot h) \cdot \sum _{ x'',y'' } I(x + x'', y + y'')
//预处理T和S
float fAvgT = 0;
for (int i = 0; i < nTemplateHeight; i++)
{
for (int j = 0; j < nTemplateWidth; j++)
{
fAvgT += pTemplate[i * nTemplateWidth + j];
}
}
fAvgT = fAvgT / (nTemplateHeight * nTemplateWidth);
float fSigmaT = 0;
float *fT=new float[nTemplateHeight*nTemplateWidth];
for (int i = 0; i < nTemplateHeight; i++)
{
for (int j = 0; j < nTemplateWidth; j++)
{
fT[i * nTemplateWidth + j] = pTemplate[i * nTemplateWidth + j] - fAvgT;
fSigmaT += fT[i * nTemplateWidth + j] * fT[i * nTemplateWidth + j];
}
}
//结束预处理
int nRetHeight=nSearchImageHeight-nTemplateHeight;
int nRetWidth=nSearchImageWidth-nTemplateWidth;
float* m_pRet=new float[nRetHeight*nRetWidth];
float fMaxScore = -1;
int sze_Template = nTemplateHeight * nTemplateWidth;
for (int i = 0; i < nRetHeight; i++)
{
for (int j = 0; j < nRetWidth; j++)
{
float fSigmaS=0;
for (int m = 0; m < nTemplateHeight; m++)
{
for (int n = 0; n < nTemplateWidth; n++)
{
fSigmaS += pSearchImage[(i + m) * nSearchImageWidth + j + n];
}
}
float fSigmaST = 0;
for (int m = 0; m < nTemplateHeight; m++)
{
for (int n = 0; n < nTemplateWidth; n++)
{
fSigmaST += fT[m * nTemplateWidth + n] * (pSearchImage[(i + m) * nSearchImageWidth + j + n] - fSigmaS/ sze_Template);
}
}
m_pRet[i * nRetWidth + j] = fSigmaST / sqrt(fSigmaS * fSigmaT);
if (m_pRet[i * nRetWidth + j] > fMaxScore)
{
fMaxScore = m_pRet[i * nRetWidth + j];
nMatchPointX = j;
nMatchPointY = i;
}
}
}
return fMaxScore;
}
这里的这段代码实际运行速度非常慢。下一章我将讲解如何使用FFT算法加速计算。
优化思路
根据公式不难得出NCC算法的复杂度为$$\O(n^4)$$,是一种计算复杂度很大的算法。在笔者 i9-13900HX 处理器单线程上仍需要将近12s才能完成(1000 * 1000上匹配100 * 100)。
因此需要先把复杂度降低再考虑其他方向的优化。
1.NCC算法实现及其优化[基础实现篇]的更多相关文章
- 游戏中的自动寻路-A*算法(第一版优化——走斜线篇)
一.简述以及地图 G 表示从起点移动到网格上指定方格的移动距离 (暂时不考虑沿斜向移动,只考虑上下左右移动). H 表示从指定的方格移动到终点的预计移动距离,只计算直线距离,走直角篇走的是直角路线. ...
- 转:机器学习中的算法(2)-支持向量机(SVM)基础
机器学习中的算法(2)-支持向量机(SVM)基础 转:http://www.cnblogs.com/LeftNotEasy/archive/2011/05/02/basic-of-svm.html 版 ...
- 【算法】342- JavaScript常用基础算法
一个算法只是一个把确定的数据结构的输入转化为一个确定的数据结构的输出的function.算法内在的逻辑决定了如何转换. 基础算法 一.排序 1.冒泡排序 //冒泡排序function bubbleSo ...
- Java 排序算法-冒泡排序及其优化
Java 排序算法-冒泡排序及其优化 什么是冒泡排序 基本写法 优化后写法 终极版本 源码及测试 什么是冒泡排序 这里引用一下百度百科上的定义: 冒泡排序(Bubble Sort),是一种计算机科学领 ...
- SSE图像算法优化系列二:高斯模糊算法的全面优化过程分享(一)。
这里的高斯模糊采用的是论文<Recursive implementation of the Gaussian filter>里描述的递归算法. 仔细观察和理解上述公式,在forward过程 ...
- 小波学习之二(单层一维离散小波变换DWT的Mallat算法C++实现优化)--转载
小波学习之二(单层一维离散小波变换DWT的Mallat算法C++实现优化) 在上回<小波学习之一>中,已经详细介绍了Mallat算法C++实现,效果还可以,但也存在一些问题,比如,代码 ...
- PLSQL优化基础和性能优化 (学习总结)
PLSQL优化基础和性能优化 (学习总结) 网上有一篇关于PLSQL优化的文章,不错,个人根据自己的经验再稍加整理和归纳,总结PLSQL优化和性能调优 适合有一定PLSQL基础,需要进一步提高的学友看 ...
- 数据结构和算法(Golang实现)(9)基础知识-算法复杂度及渐进符号
算法复杂度及渐进符号 一.算法复杂度 首先每个程序运行过程中,都要占用一定的计算机资源,比如内存,磁盘等,这些是空间,计算过程中需要判断,循环执行某些逻辑,周而反复,这些是时间. 那么一个算法有多好, ...
- 数据结构和算法(Golang实现)(10)基础知识-算法复杂度主方法
算法复杂度主方法 有时候,我们要评估一个算法的复杂度,但是算法被分散为几个递归的子问题,这样评估起来很难,有一个数学公式可以很快地评估出来. 一.复杂度主方法 主方法,也可以叫主定理.对于那些用分治法 ...
- 【Java虚拟机4】Java内存模型(硬件层面的并发优化基础知识--缓存一致性问题)
前言 今天学习了Java内存模型第一课的视频,讲了硬件层面的知识,还是和大学时一样,醍醐灌顶.老师讲得太好了. Java内存模型,感觉以前学得比较抽象.很繁杂,抽象. 这次试着系统一点跟着2个老师学习 ...
随机推荐
- centos8.x阿里源配置
>>> cd /etc/yum.repo.d >>> mkdir bak >>> mv *.repo bak/ >>> cd b ...
- linux基本命令--day02
目录树架构示意图 以下是对这些目录的解释: /bin: bin是Binary的缩写, 这个目录存放着最经常使用的命令. /boot: 这里存放的是启动Linux时使用的一些核心文件,包括一些连接文件以 ...
- 【Azure Function App】本地运行的Function发布到Azure上无法运行的错误分析
问题描述 Azure Function部署后未执行,查看日志发现错误信息: 2023-12-19T11:12:27.145 [Verbose] Host configuration applied.2 ...
- 【Azure 应用服务】App Service的运行状况检查功能失效,一直提示"实例运行不正常"
问题描述 为App Service配置了健康检查,单独访问Health Check Path的路径,返回代码为200.但为什么在App Service的页面上,一直提示"实例运行不正常&qu ...
- Taurus.MVC WebMVC 入门开发教程7:部分视图和页面片段(结束篇)
本系列的目录大纲为: Taurus.MVC WebMVC 入门开发教程1:框架下载环境配置与运行 Taurus.MVC WebMVC 入门开发教程2:一个简单的页面呈现 Taurus.MVC WebM ...
- C++ //vector容器嵌套容器
1 //vector容器嵌套容器 2 #include <iostream> 3 #include <string> 4 #include<fstream> 5 # ...
- Java求解汉诺塔
汉诺塔 汉诺塔(Tower of Hanoi),又称河内塔,是一个源于印度古老传说的益智玩具.大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘.大梵天命令婆罗 ...
- buntu中查看网卡信息的基础知识
ubuntunetworkexpress工具网络access Ubuntu 中,通常有线网卡为eth0,无线网卡则为wlan0,后续增加的以此类推(可能某些无线网卡型号命名为eth1,而非wlan0) ...
- Linux 文件权限、VIM、防火墙
Linux 文件权限.VIM.防火墙 目录 Linux 文件权限.VIM.防火墙 SSH连接 环境变量 权限 更改文件所属 更改文件权限 su和sudo 包管理器 VI/VIM iptables防火墙 ...
- 《TencentNCNN系列》 之param文件(网络结构文件)格式分析
PS:要转载请注明出处,本人版权所有. PS: 这个只是基于<我自己>的理解, 如果和你的原则及想法相冲突,请谅解,勿喷. 前置说明 本文作为本人csdn blog的主站的备份.(Bl ...