分水岭助威、蒙版提速,如何打造工程应用六中的高效率模板匹配算法?
摘要:关于模板匹配算法的最新几点杂谈: 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多行,说垛也不多,不过我去描了一下,还是过于复杂了,关键是没有相关
