使用 cv.matchTemplate 查找多个最佳匹配项

Using cv.matchTemplate to find multiple best matches

我正在使用函数 cv.matchTemplate 来尝试查找模板匹配项。

result = cv.matchTemplate(img, templ, match_method)

在我 运行 函数之后,我在列表 result 中得到了一堆答案。我想过滤列表以找到最佳 n 匹配项。 result 中的数据只是一大堆数字,所以我不知道要根据什么条件进行过滤。在将结果列表转换为位置之前,使用 extremes = cv.minMaxLoc(result, None) 以不希望的方式过滤结果列表。

match_method 是 cv.TM_SQDIFF。我想:

我怎样才能做到这一点?

您可以对 matchTemplate 的结果进行阈值处理,以找到具有足够匹配度的位置。 This tutorial 应该可以帮助您入门。阅读页面底部以查找多个匹配项。

import numpy as np

threshold = 0.2
loc = np.where( result <= threshold) # filter the results
for pt in zip(*loc[::-1]): #pt marks the location of the match
    cv2.rectangle(img_rgb, pt, (pt[0] + w, pt[1] + h), (0,0,255), 2)

请记住,您使用的功能将决定您的过滤方式。随着匹配质量的提高,cv.TM_SQDIFF 趋于零,因此将 threshold 设置得更接近零会过滤掉更差的结果。 cv.TM CCORR cv.TM_CCORR_NORMED cv.TM_COEFFcv.TM_COEFF_NORMED 匹配方法相反(更好地趋向于1)

以上答案没有找到所问问题的最佳 N 匹配项。它根据阈值过滤掉答案,使您仍然有超过 N 个结果或零个结果超过阈值的(可能)可能性保持开放。

为了找到 N 'best matches',我们正在寻找二维数组中 N 个最大的数字并检索它们的索引,以便我们知道位置。我们可以使用 nump.argpartition to find the highest N indexes in a 1d array and numpy.ndarray.flatten with numpy.unravel_index 在二维和一维数组之间来回切换,如下所示:

find_num = 5
result   = cv.matchTemplate(img, templ, match_method)
idx_1d   = np.argpartition(result.flatten(), -find_num)[-find_num:]
idx_2d   = np.unravel_index(idx_1d, result.shape)

从这里您可以看到前 5 场比赛的 x,y 位置。