MiheiSV
@MiheiSV
Любитель интересных и забавных технологий

Как сравнить массивы в NumPy или обойтись без них?

Доброго времени суток, мудрые пользователи Хабра.
Недавно я наткнулся на видео об автоматизации рыбалки в ММО Albion Online / https://www.youtube.com/watch?v=92XnJ3s0vX8 / так же, есть статья на Хабре об этом. Так как я играю в эту игру я решил написать свой скрипт, определяющий красные ники(врагов) на краях экрана и нажимающий кнопку R, с помощью библиотек OpenCV и PyAutoGUI, это такая сфера игры, как ганг, но не будем вдаваться в подробности.
Исходный код -
spoiler
import time
import cv2
import mss
import numpy as np
import pyautogui

template = cv2.imread("red_nick.png", cv2.IMREAD_GRAYSCALE)
w, h = template.shape[::-1]

with mss.mss() as sct:
    monitor = {"top": 0, "left": 0, "width": 400, "height": 250}

    while "Screen capturing":
        last_time = time.time()
        img = np.array(sct.grab(monitor))
        empty_img = np.array(sct.grab(monitor))
        print("fps: {}".format(1 / (time.time() - last_time)))
        gray_frame = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        res = cv2.matchTemplate(gray_frame, template, cv2.TM_CCOEFF_NORMED)
        loc = np.where(res >= 0.999)
        for i in zip(*loc[::-1]):
            cv2.rectangle(img, i, (i[0] + w, i[1] + h), (0, 255, 255), 10)
        #cv2.imshow("Frame", img)
        #cv2.imshow("Frame2", empty_img)
        if cv2.waitKey(1) == 27:
            cv2.destroyAllWindows()
            break
        if (img != empty_img).any():
            pyautogui.press(keys='r')
            cv2.imshow("Frame", img)
            cv2.waitKey()
            break

Проблема сразу в нескольких вещах, начнем по порядку:
1) Я взял за основу код из статьи на Хабре, т.к. сам сейчас не сильно разбираюсь, поэтому код может быть в некоторых местах кривоват.
2) Вторая проблема в этих строчках кода -
if (img != empty_img).any():
            pyautogui.press(keys='r')
            break

Во первых, сделано на коленке, чтобы хотя бы не выдавало ошибку при запуске.
Во вторых, это задумывалось так, чтобы в переменную img записывался скриншот экрана(многоразово, чтобы было как видео), а в empty_img - тот же самый скриншот, но без изменений. То есть, находя с помощью OpenCV красный ник на img, мы выделяем его и сравниваем img с empty_img, чтобы узнать, если ли разница между ними(есть ли на скриншоте красный ник). И затем, если мы находили это - нажимали кнопку R, если нет - продолжали цикл. Но это не работает так, как задумывалось, потому что код иногда может просто не успеть записать в эти две переменные два одинаковых скриншота, что мешает его правильному выполненению. Я попробовал решить эту проблему, заменив
empty_img = np.array(sct.grab(monitor))
на
empty_img = img,
что, логически, должно было помочь, но возникла другая проблема - после выполнения строк
for i in zip(*loc[::-1]):
cv2.rectangle(img, i, (i[0] + w, i[1] + h), (0, 255, 255), 10)

эти две переменные становятся одинаковыми. Почему, я так и не понял.
Исходный код -
spoiler
import time
import cv2
import mss
import numpy as np
import pyautogui

template = cv2.imread("red_nick.png", cv2.IMREAD_GRAYSCALE)
w, h = template.shape[::-1]

with mss.mss() as sct:
    monitor = {"top": 0, "left": 0, "width": 400, "height": 250}

    while "Screen capturing":
        last_time = time.time()
        img = np.array(sct.grab(monitor))
        empty_img = np.array(sct.grab(monitor))
        print("fps: {}".format(1 / (time.time() - last_time)))
        gray_frame = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        res = cv2.matchTemplate(gray_frame, template, cv2.TM_CCOEFF_NORMED)
        loc = np.where(res >= 0.999)
        for i in zip(*loc[::-1]):
            cv2.rectangle(img, i, (i[0] + w, i[1] + h), (0, 255, 255), 10)
        #cv2.imshow("Frame", img)
        #cv2.imshow("Frame2", empty_img)
        if cv2.waitKey(1) == 27:
            cv2.destroyAllWindows()
            break
        if (img != empty_img).any():
            pyautogui.press(keys='r')
            cv2.imshow("Frame", img)
            cv2.waitKey()
            break

Прошу вас, друзья, помочь мне либо исправить данную версию решения этой задачи, либо придумать решение лучше этого, работающее без заморочек(или с ними :D). Заранее спасибо всем, кто откликнется!
  • Вопрос задан
  • 146 просмотров
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы