Как я могу быстро найти что-то на моем экране в Python?

Я пробовал использовать модуль pyautogui и функцию i, которая находит изображение на экране.

pyautogui.locateOnScreen()

но время обработки составляет около 5-10 секунд. Есть ли другой способ быстрее найти изображение на экране? По сути, мне нужна более быстрая версия locateOnScreen().


person Darth Vador    schedule 23.03.2017    source источник


Ответы (4)


В официальной документации говорится, что это должно занять 1-2 секунды. на экране 1920x1080, поэтому ваше время кажется немного медленным. Я бы попробовал оптимизировать:

  • Используйте оттенки серого, если информация о цвете не важна (предполагается, что grayscale=True дает 30%-ное ускорение)
  • Используйте меньшее изображение для поиска (например, только часть, если оно уже однозначно определяет положение, которое вам нужно получить)
  • Не загружайте изображение, которое вам нужно найти из файла каждый раз, когда оно новое, а держите его в памяти.
  • Передайте аргумент региона, если вы уже знаете что-то о возможных местоположениях (например, из предыдущих запусков).

Все это описано в документации по ссылке выше.

Если это все еще недостаточно быстро, вы можете проверить источники pyautogui обратите внимание, что для поиска на экране используется специальный алгоритм (алгоритм поиска Кнута-Морриса-Пратта), реализованный в Python. Так что реализация этой части на C может привести к весьма заметному ускорению.

person Trilarion    schedule 23.03.2017
comment
этот ответ был действительно полезен, но после того, как я попробовал все это, кроме последнего, о реализации алгоритма поиска в c, я получил около 10% настройки производительности! - person Mo Ganji; 19.10.2018
comment
@MohammadGanji Вы можете попробовать Cython, чтобы ускорить алгоритм при разумных затратах на реализацию. - person Trilarion; 19.10.2018
comment
Спасибо, я на самом деле добился желаемой скорости, уменьшив масштаб страницы, которую мне нужно было обработать, и с меньшей уверенностью в сопоставлении с изображением. - person Mo Ganji; 19.10.2018
comment
LocateOnScrren и Кнут-Моррис-Пратт, как поиск изображения связан с алгоритмом поиска подстроки? Также я вижу поиск шаблона cv2 в журналах ошибок. - person Vishesh Mangla; 18.09.2020

сделать функцию и использовать уверенность в многопоточности (требуется opencv)

import pyautogui
import threading

def locate_cat():
    cat=None
    while cat is None:
        cat = pyautogui.locateOnScreen('Pictures/cat.png',confidence=.65,region=(1722,748, 200,450)
        return cat

вы можете использовать аргумент региона, если вы знаете примерное местоположение, где он находится на экране

могут быть некоторые случаи, когда вы можете найти на экране и назначить регион переменной и использовать region=somevar в качестве аргумента, чтобы он выглядел в том же месте, что и в прошлый раз, чтобы помочь ускорить процесс обнаружения.

eg:

import pyautogui

def first_find():
    front_door = None
    while front_door is None:
        front_door_save=pyautogui.locateOnScreen('frontdoor.png',confidence=.95,region=1722,748, 200,450)
        front_door=front_door_save
        return front_door_save


def second_find():
    front_door=None
    while front_door is None:
        front_door = pyautogui.locateOnScreen('frontdoor.png',confidence=.95,region=front_door_save)
        return front_door

def find_person():
    person=None
    while person is None:
        person= pyautogui.locateOnScreen('person.png',confidence=.95,region=front_door)


while True:
    first_find()
    second_find()
    if front_door is None:
        pass
    if front_door is not None:
        find_person()
person user11335084    schedule 07.10.2020

Если вам нужно распознавание изображений, вы можете использовать Sikuli. Ознакомьтесь с руководством по Hello World.

person Varad    schedule 23.03.2017

Я столкнулся с той же проблемой с pyautogui. Хотя это очень удобная библиотека, она довольно медленная.

Я получил ускорение x10, полагаясь на cv2 и PIL:

def benchmark_opencv_pil(method):
    img = ImageGrab.grab(bbox=REGION)
    img_cv = cv.cvtColor(np.array(img), cv.COLOR_RGB2BGR)
    res = cv.matchTemplate(img_cv, GAME_OVER_PICTURE_CV, method)
    # print(res)
    return (res >= 0.8).any()

Там, где использование TM_CCOEFF_NORMED работало хорошо. (очевидно, вы также можете настроить порог 0,8)

Источник : Быстрый поиск на экране с помощью Python

Для полноты картины вот полный тест:

import pyautogui as pg
import numpy as np
import cv2 as cv
from PIL import ImageGrab, Image
import time

REGION = (0, 0, 400, 400)
GAME_OVER_PICTURE_PIL = Image.open("./balloon_fight_game_over.png")
GAME_OVER_PICTURE_CV = cv.imread('./balloon_fight_game_over.png')


def timing(f):
    def wrap(*args, **kwargs):
        time1 = time.time()
        ret = f(*args, **kwargs)
        time2 = time.time()
        print('{:s} function took {:.3f} ms'.format(
            f.__name__, (time2-time1)*1000.0))

        return ret
    return wrap


@timing
def benchmark_pyautogui():
    res = pg.locateOnScreen(GAME_OVER_PICTURE_PIL,
                            grayscale=True,  # should provied a speed up
                            confidence=0.8,
                            region=REGION)
    return res is not None


@timing
def benchmark_opencv_pil(method):
    img = ImageGrab.grab(bbox=REGION)
    img_cv = cv.cvtColor(np.array(img), cv.COLOR_RGB2BGR)
    res = cv.matchTemplate(img_cv, GAME_OVER_PICTURE_CV, method)
    # print(res)
    return (res >= 0.8).any()


if __name__ == "__main__":

    im_pyautogui = benchmark_pyautogui()
    print(im_pyautogui)

    methods = ['cv.TM_CCOEFF', 'cv.TM_CCOEFF_NORMED', 'cv.TM_CCORR',
               'cv.TM_CCORR_NORMED', 'cv.TM_SQDIFF', 'cv.TM_SQDIFF_NORMED']


    # cv.TM_CCOEFF_NORMED actually seems to be the most relevant method
    for method in methods:
        print(method)
        im_opencv = benchmark_opencv_pil(eval(method))
        print(im_opencv)

И результаты показывают улучшение в 10 раз.

benchmark_pyautogui function took 175.712 ms
False
cv.TM_CCOEFF
benchmark_opencv_pil function took 21.283 ms
True
cv.TM_CCOEFF_NORMED
benchmark_opencv_pil function took 23.377 ms
False
cv.TM_CCORR
benchmark_opencv_pil function took 20.465 ms
True
cv.TM_CCORR_NORMED
benchmark_opencv_pil function took 25.347 ms
False
cv.TM_SQDIFF
benchmark_opencv_pil function took 23.799 ms
True
cv.TM_SQDIFF_NORMED
benchmark_opencv_pil function took 22.882 ms
True
person RUser4512    schedule 15.06.2021