После внезапного обогащения энтузиастов, которые поиграли в начале года в приложение Notcoin в телеграм, подобные проекты стали расти как грибы. Да и грибников заметно поприбавилось. Но в данной статье мы не будем касаться тем блокчейна или финансов, а рассмотрим простой пример применения компьютерного зрения для фарма поинтов в самом популярном, после Notcoin, проекте - хомяке комбате. Название явно на что-то намекает, но да ладно.
Это не первый проект, который я автоматизирую, и не самый нуждающийся в этом. Да и без компьютерного зрения с автоматизацией хомяка можно спокойно обойтись. Но с ним, во-первых, интереснее, а во-вторых - это просто хороший пример с минимумом строк кода для демонстрации возможностей библиотеки cv2. Статья, соответственно, предназначена для энтузиастов и начинающих специалистов.
Начнем с того, что мы установим все необходимые зависимости и импортируем их в свой проект. Вот они, слева направо.
import pyautogui
import keyboard
import cv2
import numpy as np
import time
С помощью pyautogui наш бот будет управлять мышью. Keyboard пригодится для назначения горячих клавиш, чтобы управлять работой бота. cv2 наградит бота зрением, пусть и компьютерным, с помощью которого тот будет находить совпадения с искомым изображением. А numpy пригодится для работы с большими массивами, но тут он почти для галочки, не бойтесь. Модуль time тоже понадобится, чтобы ставить таймауты в работе программы.
Далее напишем небольшую конструкцию- переключатель.
def change():
global work
work = not work
work = False
Функция change при вызове всего лишь меняет значение переменной work, которая будет использована в бесконечном цикле. И если work будет False, работа нашего кода будет останавливаться. И наоборот запускаться, в противоположном случае.
Кстати, забыл упомянуть, что разработчики проекта, над которым мы сейчас проводим эксперимент, большие молодцы, и убрали возможность пользоваться приложением на десктопных устройствах. Поэтому для его запуска понадобится эмулятор Android.
Теперь определим основную логику работы бота:
Он ищет совпадение с изображением полностью заполненной энергии.
Если находит совпадение, ищет изображение монеты и кликает на неё энное количество раз.
И всё это работает в бесконечном цикле.
Значит со скриншота приложения необходимо вырезать две области, которые помечены красным, и разместить их в отдельные файлы, конечно же.
Теперь напишем функцию для кликов по монетке. Она будет принимать путь к исходному изображению, а так же порог чувствительности для компьютерного зрения и интервал (таймаут) в секундах.
def click(template_path, threshold=0.8, interval=0.0001):
template = cv2.imread(template_path, 0)
w, h = template.shape[::-1]
screenshot = pyautogui.screenshot()
screenshot = cv2.cvtColor(np.array(screenshot), cv2.COLOR_RGB2BGR)
# Переводим скриншот в оттенки серого.
gray_screenshot = cv2.cvtColor(screenshot, cv2.COLOR_BGR2GRAY)
# Находим изображение на экране.
result = cv2.matchTemplate(gray_screenshot, template, cv2.TM_CCOEFF_NORMED)
loc = np.where(result >= threshold)
# Кликаем по найденным координатам.
for pt in zip(*loc[::-1]):
center_x = pt[0] + w // 2
center_y = pt[1] + h // 2
for _ in range(260):
pyautogui.doubleClick(center_x, center_y)
break
Переменной template будет присвоено исходное изображение монетки, но в оттенках серого, так как мы указали в параметрах 0. Это необходимость, так как в оттенках серого компьютер зрит лучше. Сразу вычисляем высоту и ширину исходника, и присваиваем переменным. А далее по ходу исполнения кода он делает скриншот, сравнивает с исходником, получает координаты области с совпадением, и делает 260 даблкликов по ней. Координаты я ищу немного кривовато и в итоге loc содержит большой массив, из которого я использую лишь самые первые координаты, после чего цикл прерываю. Но лучше сделать не смог, извините.
А теперь напишем аналогичную функцию, но с задачей искать совпадение с картинкой полной энергии, после чего вызывать функцию click.
def find(template_path, threshold=0.9, interval=1):
keyboard.add_hotkey('`', change)
# Загружаем изображение, которое мы хотим найти на экране. 0- в градациях серого.
template = cv2.imread(template_path, 0)
w, h = template.shape[::-1]
try:
while True:
if work:
# Получаем скриншот экрана.
screenshot = pyautogui.screenshot()
screenshot = cv2.cvtColor(np.array(screenshot), cv2.COLOR_RGB2BGR)
# Переводим скриншот в оттенки серого.
gray_screenshot = cv2.cvtColor(screenshot, cv2.COLOR_BGR2GRAY)
# Находим изображение на экране.
result = cv2.matchTemplate(gray_screenshot, template, cv2.TM_CCOEFF_NORMED)
loc = np.where(result >= threshold)
for _ in zip(*loc[::-1]):
click('coin.bmp')
break
time.sleep(interval)
except KeyboardInterrupt:
print('\nВыход из программы')
В целом всё аналогично. Добавил лишь ожидание горячей клавиши, чтобы можно было остановить программу в любое время нажатием на тильду (Ё). Ну и для красоты заключил в try-except.
И это всё. Пишем последние строки и запускаем скрипт (не забыв нажать на Ё для запуска логики в цикле).
if __name__ == "__main__":
find('energy.bmp')
По сути, этот код многофункционален, и его без труда, с минимальными изменениями, можно переделать под любые другие задачи. На всякий случай оставлю и полную версию кода:
import pyautogui
import keyboard
import cv2
import numpy as np
import time
def change():
global work
work = not work
work = False
def find(template_path, threshold=0.9, interval=1):
keyboard.add_hotkey('`', change)
# Загружаем изображение, которое мы хотим найти на экране. 0- в градациях серого.
template = cv2.imread(template_path, 0)
w, h = template.shape[::-1]
try:
while True:
if work:
# Получаем скриншот экрана.
screenshot = pyautogui.screenshot()
screenshot = cv2.cvtColor(np.array(screenshot), cv2.COLOR_RGB2BGR)
# Переводим скриншот в оттенки серого.
gray_screenshot = cv2.cvtColor(screenshot, cv2.COLOR_BGR2GRAY)
# Находим изображение на экране.
result = cv2.matchTemplate(gray_screenshot, template, cv2.TM_CCOEFF_NORMED)
loc = np.where(result >= threshold)
for _ in zip(*loc[::-1]):
click('coin.bmp')
break
time.sleep(interval)
except KeyboardInterrupt:
print('\nВыход из программы')
def click(template_path, threshold=0.8, interval=0.0001):
template = cv2.imread(template_path, 0)
w, h = template.shape[::-1]
screenshot = pyautogui.screenshot()
screenshot = cv2.cvtColor(np.array(screenshot), cv2.COLOR_RGB2BGR)
# Переводим скриншот в оттенки серого.
gray_screenshot = cv2.cvtColor(screenshot, cv2.COLOR_BGR2GRAY)
# Находим изображение на экране.
result = cv2.matchTemplate(gray_screenshot, template, cv2.TM_CCOEFF_NORMED)
loc = np.where(result >= threshold)
# Кликаем по найденным координатам.
for pt in zip(*loc[::-1]):
center_x = pt[0] + w // 2
center_y = pt[1] + h // 2
for _ in range(260):
pyautogui.doubleClick(center_x, center_y)
break
if __name__ == "__main__":
find('energy.bmp')
Не судите меня строго по этому скрипту, большую часть жизни я вообще бегал с пистолетиком, и пристрастился к разработке сравнительно недавно, поэтому всего лишь юный падаван в возрасте. Хотя могу писать и большие скучные штуки, но вот писать о них получится дольше, чем сам код. А если будут вопросы- добро пожаловать в телеграм. У меня там небольшой клуб по интересам.
Комментарии (21)
SuperKozel
03.06.2024 11:15+2кажется, после ноткоина всё это - лютая хренотень? я ноткоин потэпал, всем друзьям советовал тоже попробовать). Сейчас все будут лезть с ботами и клоны/форки никогда не несли никакой ценности.
temabed Автор
03.06.2024 11:15+2Ноткоин задал вектор, но будут и еще достойные проекты с такой системой вознаграждений. Я хотел на примере другого проекта (от снг-руководства бинанс) статью писать, но там бот отрабатывает слишком стыдно. А хомяк- это да, чистый клон, однако вероятность эйрдропа высока, так как он поймал лютый хайп.
digtatordigtatorov
03.06.2024 11:15С каких это подаванских блогов было вычитано, что компьют зрение шарит лучше в оттенках серого? По-моему это нифига не так, все зависит от задачи.
temabed Автор
03.06.2024 11:15Если конкретно, я вычитал, что метод поиска шаблонов работает лучше с изображениями в градациях серого. А как установить истину, я без понятия)
fuckupyourface
03.06.2024 11:15Интересно в каких задачах тебе выгоднее хранить 3 канала и повлияет ли это существенно на результат, прям оч интересно
hexdrx
03.06.2024 11:15Чуть поменьше язвительности..
Делал cv бота для игры, нужно было различать обычные/редкие/эпические/легендарные шмотки, а отличаются они только цветом. Потому да, есть моменты когда это необходимо
losander
03.06.2024 11:15Сделал подобный на memefi, только он кликает по кд 60 секунд
Единственный жирный минус в этом всём это то что эмуль жрёт ресурс, у меня лично даже 1080ti на ~30% грузило. Может есть способ снизить нагрузку?
kuxwy
03.06.2024 11:15Блин я не увидел слово эмуль в комментарии поэтому искал можно ли через pyautogui перемещать мышку по координатам, нашел, прочитал твой коммент, обосрался. Про эмуль могу сказать что, можно просто снизить производительность эмулятора
Pirnazar
03.06.2024 11:15Зачем всё усложняет ( использования компьютерного зрения) ?? Можно же просто time.sleep() использовать так никогда не будет кончаться монеты
temabed Автор
03.06.2024 11:15Да и без компьютерного зрения с автоматизацией хомяка можно спокойно обойтись. Но с ним, во-первых, интереснее, а во-вторых - это просто хороший пример с минимумом строк кода для демонстрации возможностей библиотеки cv2. Статья, соответственно, предназначена для энтузиастов и начинающих специалистов.
Devastor87
03.06.2024 11:15Какие суммы удалось/возможно "заработать"?
Почему, если "всё так просто" и бота может написать любой (теперь ещё и скопипастить), это всё ещё будет работать?
temabed Автор
03.06.2024 11:15Статья не про заработок же, а про спорт) Но на самом деле интерес к таким проектам у меня проснулся после ноткоин. Мне их насыпали 20 000 за ничего неделание, т.е. я даже не играл толком. Актуальная цена чуть больше 2 центов за монету и растёт. Вот я и призадумался, надо было тогда писать скрипты, делать ферму и т.д.)))
А доверия к этим проектам всё равно нет, поэтому из прочитавших статью повторит 0.01%. Так что никаких минусов для разработчиков. Больше проблем им приносят фермеры, но там есть способы их высислять.
Но проектов таких будет всё больше, людей там будет всё больше, и вознагражления будут только расти, я считаю.
Alkhonor
03.06.2024 11:15Есть еще нюанс в том, что в Notcoin за кликеры по итогам срезали 99% нафармленного. Поэтому такая автоматизация может выйти выстрелом себе в ногу
monok8i
В данный момент развития всех этих крипто ботов этот скрипт очень полезен, и у меня в голове была идея касательно написания подобного, только для Blum. Но никак не мог сообразить как захватить экран для просмотра, поэтому спасибо ;)
temabed Автор
Blum обсуждали как раз в телеге. Жава-скриптеры в этом больше преуспели. Заходи, пообщайся.