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算法实现及其优化[基础实现篇]的更多相关文章

  1. 游戏中的自动寻路-A*算法(第一版优化——走斜线篇)

    一.简述以及地图 G 表示从起点移动到网格上指定方格的移动距离 (暂时不考虑沿斜向移动,只考虑上下左右移动). H 表示从指定的方格移动到终点的预计移动距离,只计算直线距离,走直角篇走的是直角路线. ...

  2. 转:机器学习中的算法(2)-支持向量机(SVM)基础

    机器学习中的算法(2)-支持向量机(SVM)基础 转:http://www.cnblogs.com/LeftNotEasy/archive/2011/05/02/basic-of-svm.html 版 ...

  3. 【算法】342- JavaScript常用基础算法

    一个算法只是一个把确定的数据结构的输入转化为一个确定的数据结构的输出的function.算法内在的逻辑决定了如何转换. 基础算法 一.排序 1.冒泡排序 //冒泡排序function bubbleSo ...

  4. Java 排序算法-冒泡排序及其优化

    Java 排序算法-冒泡排序及其优化 什么是冒泡排序 基本写法 优化后写法 终极版本 源码及测试 什么是冒泡排序 这里引用一下百度百科上的定义: 冒泡排序(Bubble Sort),是一种计算机科学领 ...

  5. SSE图像算法优化系列二:高斯模糊算法的全面优化过程分享(一)。

    这里的高斯模糊采用的是论文<Recursive implementation of the Gaussian filter>里描述的递归算法. 仔细观察和理解上述公式,在forward过程 ...

  6. 小波学习之二(单层一维离散小波变换DWT的Mallat算法C++实现优化)--转载

    小波学习之二(单层一维离散小波变换DWT的Mallat算法C++实现优化)   在上回<小波学习之一>中,已经详细介绍了Mallat算法C++实现,效果还可以,但也存在一些问题,比如,代码 ...

  7. PLSQL优化基础和性能优化 (学习总结)

    PLSQL优化基础和性能优化 (学习总结) 网上有一篇关于PLSQL优化的文章,不错,个人根据自己的经验再稍加整理和归纳,总结PLSQL优化和性能调优 适合有一定PLSQL基础,需要进一步提高的学友看 ...

  8. 数据结构和算法(Golang实现)(9)基础知识-算法复杂度及渐进符号

    算法复杂度及渐进符号 一.算法复杂度 首先每个程序运行过程中,都要占用一定的计算机资源,比如内存,磁盘等,这些是空间,计算过程中需要判断,循环执行某些逻辑,周而反复,这些是时间. 那么一个算法有多好, ...

  9. 数据结构和算法(Golang实现)(10)基础知识-算法复杂度主方法

    算法复杂度主方法 有时候,我们要评估一个算法的复杂度,但是算法被分散为几个递归的子问题,这样评估起来很难,有一个数学公式可以很快地评估出来. 一.复杂度主方法 主方法,也可以叫主定理.对于那些用分治法 ...

  10. 【Java虚拟机4】Java内存模型(硬件层面的并发优化基础知识--缓存一致性问题)

    前言 今天学习了Java内存模型第一课的视频,讲了硬件层面的知识,还是和大学时一样,醍醐灌顶.老师讲得太好了. Java内存模型,感觉以前学得比较抽象.很繁杂,抽象. 这次试着系统一点跟着2个老师学习 ...

随机推荐

  1. 【Azure 环境】向Azure Key Vault中导入证书有输入密码,那么导出pfx证书的时候,为什么没有密码呢?

    问题描述 将pfx证书导入Key Vault的证书时,这个PFX需要输入正确的密码导入成功.但是当需要导出时,生成的pfx证书则不需要密码.这是正常的情况吗? 问题解答 是的,这是Azure Key ...

  2. 【Azure 存储服务】App Service 访问开启防火墙的存储账号时遇见 403 (This request is not authorized to perform this operation.)

    问题描述 需要 App Service 访问开启防火墙的存储账号.存储账号中设置为允许选中的VNET访问,同时允许了信任的Azure服务的访问,但是仍然报错 "403 (This reque ...

  3. gopkg.in/go-playground/validator中比较有用的标签

    -  忽略|  或omitempty 有则验证,空值则不验证dive  潜入到切片.数组.映射中,例如 NumList []int `validate:"len=2,dive,gt=18&q ...

  4. .NET开源功能强大的串口调试工具

    前言 今天大姚给大家分享一款.NET开源的.功能强大的串口调试工具:LLCOM. 工具介绍 LLCOM是一个.NET开源的.功能强大的串口调试工具.支持Lua自动化处理.串口调试.串口监听.串口曲线. ...

  5. sed 资源

    sed教程 菜鸟教程正则 MDN正则 正则测试工具 文本替换 s sed有多种分割符,比如你要替换路径字符串时,使用反斜杠很难看,则可以用 : 或者 _ 或者 | 这三个符号都可作为分隔符. & ...

  6. pdfz Vue-3-Cheat-Sheet-zh 官方要是能下载下来,我也就不放这里了。 VUE3 composition API cheat sheet

    https://files.cnblogs.com/files/pengchenggang/Vue-3-Cheat-Sheet-zh.zip 官方下载地址:https://www.vuemastery ...

  7. vue入门教程之-插槽

    vue入门教程之-插槽 欢迎关注博主公众号「java大师」, 专注于分享Java领域干货文章, 关注回复「资源」, 免费领取全网最热的Java架构师学习PDF, 转载请注明出处 https://www ...

  8. 从API到Agent:万字长文洞悉LangChain工程化设计

    我想做一个尝试,看看能不能用尽量清晰的逻辑,给"AI外行人士"(当然,我也是--)引入一下LangChain,试着从工程角度去理解LangChain的设计和使用.同时大家也可以将此 ...

  9. PAT 甲级【1013 Battle Over Cities】

    本题就是dfs.连通图个数-2: 但是java慢,最后一个case 超时 import java.io.*; import java.util.HashSet; import java.util.Se ...

  10. 记录--手把手教你,用electron实现截图软件

    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 背景 因为我们日常开发项目的时候,需要和同事对接api和文档还有UI图,所以有时候要同时打开多个窗口,并在多个窗口中切换,来选择自己要的信 ...