7

我试图在大图中找到小图并使用 MatchTemplate()

img = cv2.imread("c:\picture.jpg")
template = cv2.imread("c:\template.jpg")

result = cv2.matchTemplate(img,template,cv2.TM_CCOEFF_NORMED)
y,x = np.unravel_index(result.argmax(), result.shape)

工作正常我总是得到左上角的坐标,但这只是一点。如果我在大图上有多个匹配项,我如何才能获得所有匹配项?

4

2 回答 2

8

就是这样:

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

#the get the best match fast use this:
(min_x, max_y, minloc, maxloc) = cv2.minMaxLoc(result)
(x,y) = minloc

#get all the matches:
result2 = np.reshape(result, result.shape[0]*result.shape[1])
sort = np.argsort(result2)
(y1, x1) = np.unravel_index(sort[0], result.shape) # best match
(y2, x2) = np.unravel_index(sort[1], result.shape) # second best match

这是最快的方法,因为上面对所有匹配项进行了排序,甚至是完全错误的匹配项。如果性能对您很重要,您可以改用瓶颈的partsort函数。

于 2013-02-06T12:36:09.413 回答
5

@b_m 的答案会起作用,但它会找到太多匹配项。匹配过程在图像上滑动模板,在每个像素上进行比较。(或几乎每个像素。扫描区域因模板的大小而减小)。这意味着在一个好的匹配附近,你会得到很多其他的匹配,它们相差一个像素。如果你制作匹配结果的图像,你可以看到你得到了很多匹配。

import cv2
import numpy as np

image = cv2.imread('smiley.png', cv2.IMREAD_COLOR )
template = cv2.imread('template.png', cv2.IMREAD_COLOR)

h, w = template.shape[:2]

method = cv2.TM_CCOEFF_NORMED

threshold = 0.95

res = cv2.matchTemplate(image, template, method)
# min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)

cv2.imwrite('output.png', 255*res)

输入图像:

在此处输入图像描述

使用眼睛作为模板:

在此处输入图像描述

并查看输出。两只眼睛附近有很多白色像素。你会得到不少高分的答案:

在此处输入图像描述

在同一图像中查找模板的多个副本的另一种方法是通过覆盖找到的区域来修改图像,然后再次匹配。但比这更好的是修改结果并重新运行minMaxLoc此答案中演示了这两种技术。

于 2019-10-23T03:49:16.373 回答