一尘不染

模板匹配的OpenCV性能

java

我正在尝试基本上在Java上进行模板匹配。我使用简单的算法来找到匹配项。这是代码:

minSAD = VALUE_MAX;
// loop through the search image
for ( int x = 0; x <= S_rows - T_rows; x++ ) {
    for ( int y = 0; y <= S_cols - T_cols; y++ ) {
        SAD = 0.0;

        // loop through the template image
        for ( int i = 0; i < T_rows; i++ )
            for ( int j = 0; j < T_cols; j++ ) {

                pixel p_SearchIMG = S[x+i][y+j];

                pixel p_TemplateIMG = T[i][j];

                SAD += abs( p_SearchIMG.Grey - p_TemplateIMG.Grey );
            }
    }

    // save the best found position 
    if ( minSAD > SAD ) {
        minSAD = SAD;
        // give me VALUE_MAX
        position.bestRow = x;
        position.bestCol = y;
        position.bestSAD = SAD;
    }
}

但这是非常缓慢的方法。我测试了2张图像(768×1280)和子图像(384 x
640)。这持续了很长时间。openCV是否可以使用现成的函数cvMatchTemplate()快速执行模板匹配?


阅读 526

收藏
2020-12-03

共1个答案

一尘不染

您会发现openCV
cvMatchTemplate()比您已实现的方法快得多。您创建的是一种统计模板匹配方法。这是最常见,最容易实现的方法,但是在大图像上极其缓慢。让我们看一下基本数学,您有一个768x1280的图像,您通过这些像素中的每个循环减去边缘,因为这是您的模板限制,因此(768-384)x(1280-640)就是384
x 640 =
245’在760个运算中,您将循环浏览模板的每个像素(另一个245‘760运算),因此在循环中添加任何数学运算之前,您已经具有(245‘760 x
245‘760)60‘397‘977‘600运算。超过600亿次操作仅遍历您的图像更令人惊讶的是,机器能够如此快速地完成操作。

但是请记住它的245‘760 x(245‘760 x数学运算),因此还有更多的运算。

现在,cvMatchTemplate()实际上使用了傅里叶分析模板匹配操作。这是通过在图像上应用快速傅立叶变换( FFT
)来实现的,在该图像中,构成像素强度变化的信号被分割成每个相应的波形。该方法很难很好地解释,但是图像被转换为​​复数的信号表示。如果您想了解更多信息,请在goggle上搜索快速傅里叶变换。现在,对模板执行相同的操作,形成模板的信号用于从图像中滤除任何其他信号。

简单来说,它可以抑制图像中与模板不具有相同特征的所有特征。然后使用快速傅里叶逆变换将图像转换回去,以生成图像,其中高值表示匹配,而低值表示相反。该图像通常被标准化,因此1表示匹配,0或左右表示对象不在附近。

请注意,如果它们的对象不在图像中,并且将其归一化,则会进行错误检测,因为计算出的最大值将被视为匹配项。关于该方法的工作方式以及它可能产生的好处或问题,我可能会继续存在很多年,但是…

这种方法之所以如此快速,是因为:1)opencv是高度优化的c
++代码。2)fft功能很容易让您的处理器处理,因为大多数功能都可以在硬件中执行此操作。GPU图形卡旨在每秒执行数百万次ftf操作,因为这些计算在高性能游戏图形或视频编码中同样重要。3)所需的操作量少得多。

在夏季,统计模板匹配方法比较缓慢且需要一定时间,而opencv FFT或cvMatchTemplate()则快速且高度优化。

如果没有对象,则统计模板匹配将不会产生错误,而opencv FFT可能会出错,除非在使用时小心。

希望这对您有所了解并回答您的问题。

干杯

克里斯

[编辑]

要进一步回答您的问题:

你好

cvMatchTemplate可以与CCOEFF_NORMED和CCORR_NORMED和SQDIFF_NORMED一起使用,包括它们的非标准化版本。这里显示了您可以预期的结果类型,并提供了可以使用的代码。

http://dasl.mem.drexel.edu/~noahKuntz/openCVTut6.html#Step%202

这3种方法被很好地引用,许多论文可以通过Google
Scholar获得
。我提供了以下几篇论文。每个人只是简单地使用一个不同的方程式来查找形成模板的FFT信号与图​​像中存在的FFT信号之间的相关性,根据我的经验,相关系数往往会产生更好的结果,并且更容易找到参考。平方差和是另一种可用于比较结果的方法。我希望其中一些帮助:

快速归一化互相关,用于缺陷检测
蔡笃明;Chien-Ta Lin;模式识别信函,第24卷,第15期,2003年11月,第2625-2631页

使用快速归一化互相关的模板匹配 Kai
Briechle; Uwe D.Hanebeck;

二维散斑跟踪技术的相对性能:归一化相关,非归一化相关和和绝对差
Friemel,BH; 伯恩斯(LN);通用电气Trahey;超声学研讨会,1995年。会议论文集,1995年IEEE

一类用于快速数字图像配准的算法
Barnea,丹尼尔·I。西尔弗曼,哈维。
计算机,IEEE交易,1972年2月

通常倾向于使用这些方法的规范化版本,因为等于1的任何内容都是匹配项,但是如果不存在对象,则可能会得到误报。该方法之所以能够快速运行,完全是因为它是计算机语言所倡导的。所涉及的操作非常适合处理器体系结构,这意味着它可以在几个时钟周期内完成每个操作,而无需在多个时钟周期内转移存储器和信息。处理器解决FFT问题已经有很多年了,就像我说过的那样,内置硬件可以做到这一点。基于硬件的速度总是快于软件,并且模板匹配的统计方法基于基本的软件。可以在这里找到有关硬件的良好阅读:

数字信号处理器
尽管Wiki页面上的参考值得一看,但实际上这是执行FFT计算的硬件

一种新的管道FFT处理器方法
Shousheng He Mats Torkelson;我的最爱,因为它显示了处理器内部发生的情况

高效的本地流水线FFT处理器
Liang Yang;张可为 刘红霞; 金煌 黄士坦

这些论文确实显示了实现时FFT的复杂性,但是过程的流水线使得可以在几个时钟周期内执行操作。这就是基于实时视觉的系统利用FPGA(您可以设计以实现既定任务的特定设计处理器)的原因,因为它们可以在架构中进行极其并行的设计,并且流水线更易于实现。

尽管我必须提到的是,对于图像的FFT,您实际上使用的是FFT2,即水平平原的FFT和垂直平原的FFT,所以当您参考它时不会感到困惑。我不能说我对方程的实现方式和FFT的实现有专业知识,我试图找到好的指南,但是很难找到一个好的指南,以至于我还没有找到一个(我无法理解的一个指南)。最小)。有一天,我可能会理解它们,但是我知道他们对它们如何工作以及可以预期的结果有很好的了解。

除此之外,如果您想实现自己的版本或了解它的工作原理,我真的无法为您提供更多帮助,现在该到该库了,但是我警告您,opencv代码已经过优化,您将很难提高其性能,但是知道您可能想出一种方法来获得更好的结果,祝一切顺利,祝您好运

克里斯

2020-12-03