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, и с правильно обрезанным шаблоном можно поднимать порог выше, ещё сильнее сокращая случайные совпадения.
Аккуратные шаблоны, ограниченные регионы и тщательная проверка дадут предсказуемую, быструю и точную автоматизацию там, где несколько элементов интерфейса выглядят похожими.