分水岭助威、蒙版提速,如何打造工程应用六中的高效率模板匹配算法?

摘要:关于模板匹配算法的最新几点杂谈: 1、用分水岭算法提取顶层金字塔的候选点,起到减少候选点的数量、加快函数速度的作用。2、形状匹配中蒙版功能的作用和实现细节。3、形状匹配的对比度参数自动实现。4、基于NCC的蒙版功能实现细节。
总是写很长的复杂的文章,目前发现真的有点无法静心去弄了,感觉写代码的动力要比写文章强大的多,所以,往后的文章还是写的剪短一点吧。 继续聊一聊模板匹配。 最近这方面也出了一些新的资料,说明还是有人关注他的。 我最近一个月的研究成果主要有以下几个方面。 一、顶层金字塔的候选点选择改由分水岭相关算法实现(用时10天)。   顶层的金字塔,我们是全图计算相关得分值的。当计算完所有的顶层金字塔得分后,我们得到了不同角度不同位置的一个全方位的候选点信息,接下来我们的目标就是从这些点中选择合适的候选点。 这里有几个指标可以作为初步筛选的依据: 1、最小的得分值。 2、重叠的区域。 在【工程应用一】 多目标多角度的快速模板匹配算法(基于NCC,效果无限接近Halcon中........)一文中,我曾分享过如下的代码: Point getNextMinLoc(Mat &result, Point minLoc, int maxValue, int templatW, int templatH) { int startX = minLoc.x - templatW / 3; int startY = minLoc.y - templatH / 3; int endX = minLoc.x + templatW / 3; int endY = minLoc.y + templatH / 3; if (startX < 0 || startY < 0) { startX = 0; startY = 0; } if (endX > result.cols - 1 || endY > result.rows - 1) { endX = result.cols - 1; endY = result.rows - 1; } int y, x; for (y = startY; y < endY; y++) { for (x = startX; x < endX; x++) { float *data = result.ptr<float>(y); data[x] = maxValue; } } double new_minValue, new_maxValue; Point new_minLoc, new_maxLoc; minMaxLoc(result, &new_minValue, &new_maxValue, &new_minLoc, &new_maxLoc); return new_minLoc; }   他通过不断的迭代,每次以剩余数据中最大值为候选点,并且逐步去除部分领域的方法来获取候选点。 我所能看到的开源项目里基本已这个代码为蓝图来实现他。 这个方法是可行的,我一直在用,但是他也是有缺陷的,当模板比较小的时候,我们的金字塔层数不够多,这个时候这个函数本身的计算的耗时就较为明显了,而且还有一个问题,就是他会返回相对来说较多的候选点。造成后续的进一步筛选的计算量加大。 我一直在寻找更为科学的办法,直到最近偶尔在一个地方看到一个这样的算法效果。 这不正是我们顶层金字塔需要的算法吗? 我尝试把几个测试图的顶层金字塔的得分数转换为图像,分别如下所示:   可以看到,他们都是类似的这种有局部最亮点的图像,那如何用算法实现呢,后来我在ImageJ里发现一个功能(如上图所示界面的Process菜单下的FindMaxma),基本就是这个功能的翻版:   于是我就去ImageJ里找这个算法的代码,在MaximumFinder.java里找到了相关的资料,代码有1300多行,说垛也不多,不过我去描了一下,还是过于复杂了,关键是没有相关