OpenCV模板匹配,多模板

Sta*_*iek 6 python templates opencv template-matching

我正在尝试为游戏制作机器人。基本上它从地上捡起物品,事情是这些物品有时看起来不同,例如。角度不同,或者它们躺在不同颜色的地面上等。为了使一切正常,我需要多个模板。有没有办法做到这一点?如果你不明白,请在评论中告诉我。这是我到目前为止尝试过的:

files = ["bones_{}.png".format(x) for x in range(6)]

    for i in range(6):
        img_gray = cv2.cvtColor(imageGrab(), cv2.COLOR_BGR2GRAY)
        f = str(files[i])
        template = cv2.imread(f, 0)
        w, h = template.shape[:: -1]
        res = cv2.matchTemplate(img_gray, template, cv2.TM_CCOEFF_NORMED)
        threshhold = 0.70
        loc = np.where( res >= threshhold)
Run Code Online (Sandbox Code Playgroud)

这有效,但可能会更好。你有什么想法?

J.D*_*.D. 10

在您当前的代码中,有很多步骤执行多次,其中一次(每帧)就足够了。您可以通过将它们分开来提高效率。

您当前正在每一帧上重新加载模板,这是非常低效的,因为您每秒很容易获得 100 多个加载。相反,创建一个包含模板的列表,以便它们保留在内存中。从内存访问比从磁盘加载要快得多。
您可以对模板的宽度/长度执行相同的操作,但它实际上并未在您的代码中使用,因此也许您可以一起跳过它。
阈值只需设置一次。

templates = []
templ_shapes = []
threshold = 0.70

for i in range(6):
    templates.append(cv2.imread("bones_{}.png".format(i),0))
    templ_shapes.append(templates[i].shape[:: -1])
Run Code Online (Sandbox Code Playgroud)

所有模板都可以与同一个屏幕截图进行比较,因此您应该将其放在 for 循环之外。这是一场轻松但相当巨大的胜利。因此,在每一帧上,抓取屏幕一次,并匹配所有模板。为了清楚和方便起见,您可以将其放在一个函数中:

def doTemplateMatch():
    img_gray = cv2.cvtColor(imageGrab(), cv2.COLOR_BGR2GRAY)
    for template in templates: 
        res = cv2.matchTemplate(img_gray, template, cv2.TM_CCOEFF_NORMED)
        loc = np.where( res >= threshold)
Run Code Online (Sandbox Code Playgroud)