N
N
Nilayer2021-11-04 21:13:46
numpy
Nilayer, 2021-11-04 21:13:46

How can I improve template matching performance with opencv?

I want the code to capture the part of the screen where the application window is located and find the template I need in this window. But since I know that this template is only in a certain part of the window, for performance reasons I want the code to look for the template only in this part, but display the entire window. I almost completed my task, but faced with the fact that the code draws a square in the wrong position, where exactly the template is, due to the fact that the window and its part have different coordinates.

Here is the whole code.

import time

import cv2
import mss
import numpy as np
from templates import death_img, defeat_img, exit_img, start_img, zero_img, death_h, death_w, defeat_h, defeat_w, exit_h, exit_w, start_w, start_h, zero_w, zero_h


with mss.mss() as sct:
    # Part of the screen to capture
    tmcheck = {"top": 100, "left": 37, "width": 409, "height": 76}
    mon = {"top": 35, "left": 2, "width": 480, "height": 270}

    while "Screen capturing":
        last_time = time.time()

        # Get raw pixels from the screen, save it to a Numpy array
        img = np.array(sct.grab(mon))
        tm = np.array(sct.grab(tmcheck))
        threshold = .60
        result = cv2.matchTemplate(tm, zero_img, cv2.TM_CCOEFF_NORMED)
        yloc, xloc = np.where(result >= threshold)

        rectangles = []
        for (x, y) in zip(xloc, yloc):
            rectangles.append([int(x), int(y), int(zero_w), int(zero_h)])
            rectangles.append([int(x), int(y), int(zero_w), int(zero_h)])

        rectangles, weights = cv2.groupRectangles(rectangles, 1, 0.2)

        for (x, y, zero_w, zero_h) in rectangles:
          img = cv2.rectangle(img, (x, y), (x + zero_w, y + zero_h), (0,255,255), 2)

        print(rectangles)

        # Display the picture
        cv2.imshow("AI Eyes", img)

        print("fps: {}".format(1 / (time.time() - last_time)))

        # Press "q" to quit
        if cv2.waitKey(25) & 0xFF == ord("q"):
            cv2.destroyAllWindows()
            break


And here is the result I get.
6184226dbb963085864439.png

And yes, maybe I can somehow improve the import of templates and their parameters? Because I am sure that my method is rather strange and inefficient.

from templates import death_img, defeat_img, exit_img, start_img, zero_img, death_h, death_w, defeat_h, defeat_w, exit_h, exit_w, start_w, start_h, zero_w, zero_h

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question