Python OpenCV append соответствует 'центральным координатам x, y в кортежах - PullRequest
0 голосов
/ 08 мая 2020

У меня есть эта простая функция сопоставления шаблонов opencv, написанная на Python.

изображение: enter image description here

шаблон: enter image description here

def find(object, sensitivity):
    screen = "tool.png"

    screen_read = cv2.imread(screen)
    screen_gray = cv2.cvtColor(screen_read, cv2.COLOR_BGR2GRAY)

    obj = cv2.imread(object, cv2.IMREAD_GRAYSCALE)
    w, h = obj.shape[::-1]

    location = np.where(cv2.matchTemplate(screen_gray, obj, cv2.TM_CCORR_NORMED) >= sensitivity)
    positions = []
    for xy in zip(*location[::-1]):
        cv2.rectangle(screen_read, xy, (xy[0] + w, xy[1] + h), (0, 0, 255), 1)
        x = random(xy[0], (xy[0] + w) - 2)
        y = random(xy[1], (xy[1] + h) - 2)
        print(x, y)
        positions.append(str(x) + ", " + str(y))
    #cv2.imshow("Test", screen_read)
    #cv2.waitKey(0)


find("enemylogo.png", 0.90)

Он найдет все шаблоны правильно, как показано здесь: enter image description here

Однако моя цель - передать координату центра как используется в l oop, вне функции. Для этого мне нужно сохранить координаты x, y в массиве (позициях) в виде кортежей.

Однако я не получаю желаемых результатов, он добавляет слишком много кортежей вместо только 2.

Я пытаюсь сделать следующее:

for x in find("enemylogo.png", 0.90):
    click(x) #x would be the coordinate of every template matched.

Кто-нибудь может мне помочь, пожалуйста?

1 Ответ

1 голос
/ 10 мая 2020

Строка location = np.where.... даст вам много совпадений, и многие из них будут рядом друг с другом. Другой способ - рекурсивно использовать minMaxLo c. Эта функция даст вам только лучший результат. Но если вы замените лучшее совпадение нулями при первом проходе, при втором проходе будет найдено другое совпадение.

import cv2
import numpy as np


def find_templates(obj, sensitivity):

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

    h, w = template.shape[:2]

    print('h', h, 'w', w)

    method = cv2.TM_CCORR_NORMED

    threshold = 0.90

    res = cv2.matchTemplate(image, template, method)
    res_h, res_w = res.shape[:2]

    # fake out max_val for first run through loop
    max_val = 1
    centers = []
    while max_val > sensitivity:
        min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
        if max_val > sensitivity:
            centers.append( (max_loc[0] + w//2, max_loc[1] + h//2) )

            x1 = max(max_loc[0] - w//2, 0)
            y1 = max(max_loc[1] - h//2, 0)

            x2 = min(max_loc[0] + w//2, res_w)
            y2 = min(max_loc[1] + h//2, res_h)

            res[y1:y2, x1:x2] = 0

            image = cv2.rectangle(image,(max_loc[0],max_loc[1]), (max_loc[0]+w+1, max_loc[1]+h+1), (0,255,0) )

    print(centers)

    cv2.imwrite('output.png', image)

find_templates("enemy_logo.png", 0.90)

, что дает

[(52, 52), (169, 52)]

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...