2025, Dec 03 21:02

Точный поиск по изображению в pyautogui: обрезка шаблона и повышение confidence

Разбираем, почему pyautogui путает похожие иконки, и как это исправить: обрезка шаблона, повышение confidence до 0.99, ограничение региона и проверка locateAll.

Автоматизировать игровой интерфейс с помощью поиска по изображению может быть на удивление непросто. Типичная проблема возникает, когда на экране несколько элементов почти одинаковых размера и формы. В Cornerpond розовая кнопка заданий и оранжевая кнопка магазина обе имеют размер 34×34 и расположены в фиксированных местах. При использовании pyautogui.locateCenterOnScreen с порогом уверенности около 0.85 совпадение периодически попадает не туда, особенно если меняется фон (биом). На 0.9 совпадений нет, а locateAllOnScreen показывает, что в той же области в кандидаты попадают не только розовая цель, но и оранжевая, а иногда и зелёный значок экипировки.

Как воспроизвести проблему

Ниже фрагмент кода, который ищет в правом нижнем регионе и кликает по первому найденному совпадению. При confidence 0.85 он может нажать на оранжевую кнопку магазина вместо нужной розовой иконки заданий.

import pyautogui
import win32gui

def seek_icon():
    hwnd = win32gui.FindWindow(None, 'Cornerpond')
    hit_point = pyautogui.locateCenterOnScreen(r'C:\path\image.png', region=(1532, 718, 388, 322), confidence=0.85)
    if hit_point:
        print(hit_point)
        pyautogui.click(hit_point)

seek_icon()

Чтобы понять, что именно определяется, можно посмотреть все совпадения: получится несколько прямоугольников, сгруппированных вокруг кнопок, все размером 34×34, с минимальным разбросом координат примерно ±1 пиксель.

import pyautogui

spots = list(pyautogui.locateAllOnScreen(r'C:\path\image.png', confidence=0.85))

for box in spots:
    print(box)

Что происходит на самом деле

В шаблонном изображении для сопоставления была кнопка с чёрной рамкой и кусочками фона в углах. Именно этот лишний контекст и стал причиной. Когда за интерфейсом меняется биом/фон, весь фрагмент перестаёт быть уникальным, и визуально похожие кнопки того же размера начинают проходить по порогу схожести. Итог: один биом «тянет» совпадение к оранжевой иконке магазина, а другой — к нужной розовой иконке заданий, хотя сами кнопки никуда не смещаются.

Решение: сделать шаблон уникальным

Обрезка шаблона до содержимого кнопки с удалением рамки и любого фона сделала цель достаточно отличимой. С таким «ужатым» шаблоном сопоставление стало работать корректно и даже позволило поднять порог, например до confidence=0.99.

Ниже компактный способ проверить результаты на скриншоте: locateAll собирает все совпадения, а Pillow рисует рамки вокруг них для наглядной проверки.

import pyautogui
from PIL import Image, ImageDraw

print("pyautogui:", pyautogui.__version__)
print("OpenCV:", pyautogui.pyscreeze._useOpenCV)

snapshot_file = "screen.png"
# template_file = "button.png"       # с рамкой
template_file = "button-min.png"     # обрезано: без рамки и фона

hits = pyautogui.locateAll(template_file, snapshot_file, confidence=0.85)

canvas = Image.open(snapshot_file)
pen = ImageDraw.Draw(canvas)

for rect in hits:
    x, y, w, h = rect
    pen.rectangle((x, y, x + w, y + h), outline="lime", width=2)

canvas.save("output.png")
canvas.show()

Чтобы использовать улучшенный шаблон во время работы скрипта, сохраните прежний регион поиска и поднимите порог уверенности — теперь, когда шаблон «уже», это допустимо.

import pyautogui
import win32gui

def click_cropped_template():
    hwnd = win32gui.FindWindow(None, 'Cornerpond')
    center_xy = pyautogui.locateCenterOnScreen('button-min.png', region=(1532, 718, 388, 322), confidence=0.99)
    if center_xy:
        print(center_xy)
        pyautogui.click(center_xy)

click_cropped_template()

Почему это важно

Автоматизация GUI держится на стабильном и воспроизводимом распознавании. Шаблоны с рамками и фоном «подхватывают» шум окружения, а небольшие сходства в интерфейсе приводят к ложным срабатываниям. Чистый, минимальный шаблон снижает неоднозначность, позволяет поднять порог уверенности и делает поведение устойчивым при визуальных изменениях вроде смены биома.

Практические рекомендации и выводы

Держите шаблоны максимально «плотными»: убирайте рамки и вычищайте фон, чтобы визуальный сигнал был уникален для нужного элемента управления. Проверяйте совпадения, перебирая их через locateAll и, при необходимости, рисуя прямоугольники на сохранённом скриншоте — так вы увидите, что именно распознаётся. Если цель не двигается, кэшируйте или ограничивайте меньший регион вместо сканирования большой области; сужение окна поиска, например до границ кнопки, уменьшает риск ложных попаданий. Отличительный цвет розовой кнопки заданий также делает поиск по цвету на уровне пикселей рабочей тактикой; в pyautogui есть функции поиска пикселей по цвету. Наконец, управление порогом уверенности зависит от наличия OpenCV, и с правильно обрезанным шаблоном можно поднимать порог выше, ещё сильнее сокращая случайные совпадения.

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