首页 > 编程语言 >1.NCC算法实现及其优化[基础实现篇]

1.NCC算法实现及其优化[基础实现篇]

时间:2023-10-21 16:22:24浏览次数:41  
标签:nTemplateWidth 实现 cdot sum float ++ int 算法 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)。
因此需要先把复杂度降低再考虑其他方向的优化。

标签:nTemplateWidth,实现,cdot,sum,float,++,int,算法,NCC
From: https://www.cnblogs.com/Icys/p/matchtemplate1.html

相关文章

  • 《信息安全系统设计与实现》第七周学习笔记
    《信息安全系统设计与实现》第七周学习笔记第三章Unix/Linux进程管理多任务处理多任务处理简单说,就是同一时间给多个程序运行处理数据。即使在系统中通常有许多其他的程序在运行,但进程也可以向每个程序提供一种假象,仿佛它在独占地使用处理器。但事实上进程是轮流使用处理器的......
  • Matching Network算法概述
    什么是MatchingNetwork1.论文地址:MatchingNetworksforOneShotLearning2.简介:基于MetricLearning部分思想,使用外部记忆来增强网络,提高网络的学习能力。3.创新点借鉴了注意力和外部记忆方面的经验来搭建网络基于meta-learning用task来训练,而不是metric-learning输入......
  • 20211325 2023-2024-1 《信息安全系统设计与实现(上)》第六周学习笔记
    202113252023-2024-1《信息安全系统设计与实现(上)》第六周学习笔记一、任务要求1.自学教材第3章,提交学习笔记(10分),评分标准如下1.知识点归纳以及自己最有收获的内容,选择至少2个知识点利用chatgpt等工具进行苏格拉底挑战,并提交过程截图,提示过程参考下面内容(4分)“我在学***X......
  • Vue进阶(幺玖玖):vue 输入框中按enter键实现搜索或表单提交
    在前端项目开发过程中,为优化用户体验,可考虑在用户输入查询条件后按回车键实现搜索效果。实现方法如下:el-input监听键盘按下状态得用@keyup.enter.native,如果是非el-input组件,可以直接用@keyup.enter。<[email protected]="search"v-model='form.searchAttr'></el......
  • 棋盘覆盖——分治算法的典例
    问题描述在一个\({2^k}\times{2^k}(K\geqslant0)\)个方格组成的棋盘中,恰有一个方格与其他方格不同,称该方格为特殊方格。棋盘覆盖问题要求用图所示的4种不同形状的\(L\)型骨牌覆盖给定棋盘上除特殊方格以外的所有方格,且任何2个\(L\)型骨牌不得重叠覆盖。问题分析算法设计......
  • 代码随想训练营第十天(Python)| 232.用栈实现队列 、 225. 用队列实现栈
    232.用栈实现队列classMyQueue:def__init__(self):self.stack_in=list()self.stack_out=list()defpush(self,x:int)->None:self.stack_in.append(x)defpop(self)->int:ifself.empty():......
  • vue实现点击复制功能(无需安装库)
     1.标签<buttonv-copy="text">复制文本</button>text是要复制的内容,在data函数中 2.在main.js中注册copy指令Vue.directive('copy',{bind:function(el,binding){el.$copy=function(){consttextarea=document.createElement('text......
  • Java List数据结构底层实现与常用实现类解析
    一、JavaList数据结构的底层实现原理List是Java中最常用的数据结构之一,它可以按照元素的插入顺序有序存储一组对象。在Java中,List接口有多种不同的实现方式,每种方式都有自己的底层实现机制。1.1数组实现ArrayList是List接口最常用的实现类之一,它使用数组作为底层数据结构。ArrayL......
  • 贪心算法实现
    贪心算法顾名思义,贪心算法总是作出在当前看来最好的选择。也就是说贪心算法并不从整体最优考虑,它所作出的选择只是在某种意义上的局部最优选择。当然,希望贪心算法得到的最终结果也是整体最优的。虽然贪心算法不能对所有问题都得到整体最优解,但对许多问题它能产生整体最优解。如单......
  • Spring Boot如何实现邮件发送附件?一文带你搞定它!
    前言随着互联网的发展,电子邮件已经成为人们日常工作中不可或缺的一部分。在软件开发领域中,发送邮件也是必不可少的一项功能。本文将介绍如何在SpringBoot中使用JavaMailSender发送带附件的邮件。摘要本文将从以下几个方面介绍如何在SpringBoot中发送带附件的邮件:配置Spring......