10

在阅读了文档并在整个互联网上搜索之后,我仍然不明白如何解释 openCV 的 matchTemplate 函数的输出。

我的理解:

result = cv2.matchTemplate(img, template, cv2.TM_CCOEFF_NORMED)

我知道我得到了一种矩阵,其中的每个部分都具有匹配值。这个矩阵中的每个元素决定了它与模板的相似度。

例如,我可以过滤所有匹配值低于 0.7 的位置

numpy.where(result >= 0.7)

我不明白的是这些信息如何存储在我从 matchTemplate 函数获得的输出中,以及如何从输出中提取匹配的位置。

基本上我想做的是将多个模板匹配到一个图像,然后确定哪个模板与哪个位置最匹配(具有一个位置的所有应用模板的最大匹配值)。

我的想法是将匹配值提取到每个模板的矩阵中,然后将矩阵(它们的元素)相互比较以找到最佳匹配。

感谢您的帮助,请纠正我错的地方,

问候唐

4

3 回答 3

2

我不明白的是这些信息如何存储在我从 matchTemplate 函数获得的输出中,以及如何从输出中提取匹配的位置。

此结果将返回图像中每个像素的可能性,例如模板的顶角像素当您执行此操作时

loc =numpy.where(result >= 0.7)

我们将通过上述方法过滤掉可能性。我们将得到x坐标,y坐标为模板顶角的可能性大于0.7的图像像素

#(array([202, 203, 203, 203, 204]), array([259, 258, 259, 260, 259]))

现在我们得到的图像位置类似于左上角模板的可能性大于或等于0.7

在我们的示例输出中,您可以看到我们可以根据阈值获得大量匹配点。我们需要循环它们以找到每个位置。

由于我们知道 loc 变量是一个包含两个 NumPy 数组(Y 坐标 NumPy 数组和 X 坐标 NumPy 数组)的元组,我们需要将元组解包并颠倒数组的顺序以获得模板的实际位置,如下所示。

基本上我想做的是将几个模板匹配到一个图像,然后确定哪个模板与哪个位置最匹配(具有一个位置的所有应用模板的最大匹配值)。

问题是,每个结果的形状都不相同,因为它取决于模板的 height 和 width

我们可以轻松做的是使用 cv2.resize 方法将所有模板制作成相同的形状(可以近似于所有模板)

'''
my original  template shapes
img (1256, 1300)
tempate (215, 223)
tempate (217, 204)
tempate (207, 203)
width =220
height = 225
temp  =  cv2.resize(temp,(width,height),cv2.INTER_CUBIC)

这使我们的结果与下面的形状相同

res = cv2.matchTemplate(gray, temp,cv2.TM_CCOEFF_NORMED)
print(res.shape) #output (1032, 1081)

**我的方法**

1.我将阈值设置为0.7(您的选择)小于此阈值我将它们设置为零``` res[res
  • 我找到了所有结果列表的最大可能性数组。所有资源都添加到结果列表中
  • maximum_values_array = np.maximum(*results)
    
    1. 我发现哪个 res 具有该特定位置的最大值
    maximum_value_contains_array =np.array(results).argmax(axis=0)     
    
    1. 我迭代每个大于零的可能性值(阈值> 0.7)。根据哪个数组具有该最大值来选择颜色。
    
    for i in range(len(maximum_values_array)):
      for j in range(len(maximum_values_array[i])):
        if maximum_values_array[i][j]>0:
          colour = colours[maximum_value_contains_array[i][j]]
          top_lect = (j,i)
          bottom_right = (j+width, i+height)
          cv2.rectangle(img,top_lect,bottom_right, colour, 2)
    

    完整的python代码

    import cv2
    import numpy as np
    img  = cv2.imread('test.jpg')
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    templates = [cv2.imread('blue_temp.jpg', 0), cv2.imread('yellow_temp.jpg', 0), cv2.imread('red_temp.jpg', 0)]
    colours =[(255,0,0), (0,255,0),(0,0,255)]
    
    results =[]
    for temp in templates:
      print(temp.shape)
      width =205
      height = 205
      # temp  =  cv2.resize(temp,(width,height),cv2.INTER_CUBIC)
      res = cv2.matchTemplate(gray, temp,cv2.TM_CCOEFF_NORMED)
      res[res<0.9] =0
      results.append(res)
    maximum_values_array = np.maximum(*results)
    maximum_value_contains_array =np.array(results).argmax(axis=0)     
    print(maximum_values_array.shape)
    print(maximum_value_contains_array.shape)
    
    for i in range(len(maximum_values_array)):
      for j in range(len(maximum_values_array[i])):
        if maximum_values_array[i][j]>0:
          print(maximum_values_array[i][j])
          colour = colours[maximum_value_contains_array[i][j]]
          top_lect = (j,i)
          bottom_right = (j+width, i+height)
          cv2.rectangle(img,top_lect,bottom_right, colour, 2)
    cv2_imshow(img)
    cv2.imwrite('output.png', img)
    
    
     
    
    于 2020-10-06T05:01:28.413 回答
    0

    它只是将模板图​​像滑到输入图像上(如在 2D 卷积中),并在模板图像下比较输入图像的模板和补丁。

    如果输入图像的大小为 (WxH),模板图像的大小为 (wxh),则输出图像的大小为 (W-w+1, H-h+1)。

    于 2020-05-19T14:30:13.857 回答
    0

    您可以使用以下代码:

    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
    

    使用 cv2.TM_CCOEFF_NORMED 时,max_loc 将是模板在您的 img 中的位置。而 max_val 将是匹配的相关性

    于 2016-10-17T21:41:00.993 回答