OpenCV "coordinate specific" 匹配模板

OpenCV "coordinate specific" match template

我有一张图像,需要尽快检测到物体。我也知道我只需要检测离中心最近的物体。

AFAIK Opencv 的 MatchTemplate 有点像这样(伪代码):

for(x in width):
    for(y in height):
        value = calcSimilarity(inputImage, searchedImage, x, y)
        matched[x][y] = value

之后,我必须循环遍历生成的图像并找到最靠近中心的点,这非常浪费。

所以我想知道我是否可以做类似的事情:

coordsGen = new CoordsGen() // a class that generates specific coords for me
while(!coordsGen.stop):
    x, y = coordsGen.next()
    value = calcSimilarity(inputImage, searchedImage, x, y)
    if(value > treshold)
        return x, y

基本上我在这里需要的是 calcSimilarity 函数。这将使我能够极大地优化流程。

模板匹配的相似度评分方法一般有多种选择。*

OpenCV 有 3 种可用的模板匹配模式:

  • 差平方和(欧氏距离)
  • 互相关
  • 皮尔逊相关系数

在 OpenCV 中,这三个版本也都有 normed/scaled 个版本:

  • 归一化平方差和
  • 归一化互相关
  • 归一化皮尔逊相关系数

您可以看到 OpenCV docs under TemplateMatchModes 中使用的实际公式,尽管这些公式与上述方法随处可见的通用公式一致。


您可以编写与自己匹配的模板,而不是使用 OpenCV。但是,请注意 OpenCV 针对这些操作进行了优化,并且通常在模板匹配方面速度非常快。 OpenCV 使用 DFT 来执行其中一些计算以减少计算负载。例如,参见:

您也可以使用 OpenCV 的 minMaxLoc() 来查找 min/maximum 值,而不是自己循环。此外,您没有指定如何访问您的值,但并非所有查找方法都像其他方法一样快。请参阅 How to scan images 以查看最快的 Mat 访问操作。剧透:原始指针。


优化的主要加速功能是提前终止函数。但是,我认为您通常不会通过自己编码来实现更快的速度,除非模板通常所在的原始图像的子集明显更小。

如果您的图像非常大,减少搜索时间的更好方法是使用金字塔分辨率方法。基本上,将模板和搜索图像设为图像的 1/2,因为 1/2,1/2,依此类推。然后你开始在一个小的 1/16 或任何大小的图像上进行模板匹配,并找到模板的一般位置。然后你对下一个图像尺寸做同样的事情,但你只搜索你的模板在之前比例的位置周围的一个小子集。然后,每次将图像尺寸增大到更接近原始尺寸时,您只是在寻找几个像素的微小差异,以更准确地确定位置。一般位置首先用最小缩放的图像找到,与原始图像大小相比只需要一小部分时间找到,然后你只需通过缩放来细化它。


* 请注意,OpenCV 不包括您可能在其他地方看到的其他模板匹配方法。特别是,OpenCV 有平方差和但没有绝对距离和方法。相位差也用作相似性度量,但在 OpenCV 中不存在。无论哪种方式,互相关和差平方和在图像处理中都非常常见,除非您有特殊的图像域,否则应该可以正常工作。