Java OpenCV在模板匹配方面的性能

Java OpenCV在模板匹配方面的性能,java,image,templates,opencv,template-matching,Java,Image,Templates,Opencv,Template Matching,我尝试在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

我尝试在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;
    }
}
minSAD=VALUE\u MAX;
//循环搜索图像

对于(int x=0;x您将找到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图形卡设计为每秒执行数百万次fft运算,因为这些运算在高性能游戏图形或视频编码中同样重要。3) 所需的操作量要少得多

总之,统计模板匹配方法速度慢,耗时长,而opencv FFT或cvMatchTemplate()快速且高度优化

如果对象不存在,则统计模板匹配不会产生错误,而opencv FFT则会产生错误,除非在应用过程中小心

我希望这能给你一个基本的理解并回答你的问题

干杯

克里斯

[编辑]

要进一步回答您的问题:

cvMatchTemplate可以与CCOEFF_NORMED、CCORR_NORMED和SQDIFF_NORMED一起使用,包括这些的非规范化版本。显示您可以预期的结果类型,并为您提供可使用的代码

这三种方法都被很好地引用,许多论文都可以通过。我在下面提供了一些文件。每一个都只是使用一个不同的方程来找到构成模板的FFT信号和图像中存在的FFT信号之间的相关性。根据我的经验,相关系数往往会产生更好的结果,并且更容易找到参考。平方差之和是另一种可用于比较结果的方法。我希望其中一些有助于:

杜明才,;简大林,; 模式识别字母 第24卷,第15期,2003年11月,第2625-2631页

凯布里埃克尔;Uwe D.Hanebeck

弗里梅尔,B.H。;博斯,L.N。;特拉希,G.E。; 超声学专题讨论会,1995年。会议记录,1995年

巴尼娅,但以理一世。;西尔弗曼,哈维F
计算机,1972年2月IEEE交易

通常倾向于使用这些方法的标准化版本,因为任何等于1的东西都是匹配的,但是如果不存在对象,则可能会出现误报。这种方法的工作速度很快,仅仅是因为它是用计算机语言设计的。所涉及的操作是处理器体系结构的理想选择,这意味着它可以在几个时钟周期内完成每个操作,而不是在几个时钟周期内移动内存和信息。处理器已经解决FFT问题很多年了,就像我说的,有内置的硬件来解决这个问题。基于硬件的匹配总是比基于软件的快,而模板匹配的统计方法是基于基础软件的。有关硬件的详细信息,请参见:

虽然Wiki页面的参考资料值得一看,但这是执行FFT计算的硬件

何寿生,;Mats Torkelson; 这是我的最爱,因为它显示了处理器内部发生的事情

梁阳;张克伟;刘红霞;金黄;黄石滩

这些论文真实地展示了FFT在实现时的复杂性,然而,该过程的管道衬里允许在几个时钟周期内执行操作。这就是基于实时视觉的系统使用FPGA(特别是设计处理器,您可以设计这些处理器来实现一组任务)的原因,因为它们可以在体系结构中非常并行地设计,并且管道内衬更容易实现

虽然我必须提到,对于图像的FFT,实际上使用的是FFT2