Часто бывает в повседневной работе приходится сталкиваться с монотонными однообразными задачами. Монотонная работа изрядно надоедает, усталость приходит быстро. Хочется отвлечься, передохнуть после рабочего дня.
Открываем свой смартфон, запускаем игру и... минут 15 тратим на закрытие приставучих баннеров с акциями и другим "привлекательным" контентом. А если хочется улучшить свой игровой процесс добавлением новых вещей, тот тут либо к "привлекательным" акциям прибегать и тратить кровно заработанные, либо смотреть еще 15-20 минут горы рекламы. А там уже ни сил, ни желания играть нет. Знакомо? Эта статья как раз о том, как можно сэкономить свое время, отдав смартфон для просмотра рекламы своему личному боту!
Как сделать?
Реализовывать автоматический просмотр рекламы в игре мы будем достаточно топорно и громоздко, но зато просто! Громоздко - так это потому что для реализации нам понадобится не только смартфон, но и ПК (или еще один смартфон с OTG, хотя не проверялось), который будет подключаться к смартфону через ADB (usb-кабель или wifi - различие будет только в одной строчке кода). Ну а топорно, потому что алгоритм будет примерно следующий:
1) получаем скриншот со смартфона
2) распознаем на скриншоте все интересующие нас элементы
3) в зависимости от того, какие элементы видим выполняем нажатие в определенную область экрана.
Можно лучше нельзя
Сразу хочу оговориться о том, что для решения такого типа задачи есть множество других вариантов, при том лучших по скорости, количеству ресурсов и удобству использования. Но у каждого есть свои НО. Для демонстрации поиска картинки в картинке с применением библиотеки OpenCV выбранный подход будет показательным. Хотя считаю нужно упомянуть так же про то, что получать элементы с экрана можно с помощью uiautomator, а если говорить про windows, то через winAPI и дескрипторы можно делать много интересных вещей. Но сейчас мы будем считать что всего этого нет и есть только "экран", "мышка" и OpenCV.
Что же такое этот OpenCV?
Если кратко и своими словами - код, который позволяет достаточно просто взаимодействовать с изображениями. Если чуть сложнее - библиотека алгоритмов компьютерного зрения, обработки изображений и численных алгоритмов общего назначения с открытым кодом (Материал из Википедии — свободной энциклопедии).
Приступаем к реализации
1) Получаем скриншот со смартфона.
Самым простым будет использование ADB и команды "adb exec-out screencap -p > screenshot.png". Выполняется долго, но работает просто. После выполнения получаем файл screenshot.png на ПК. Напишем функцию для загрузки изображения на ПК и после в представление OpenCV:
2) Распознаем на скриншоте все интересующие нас элементы.
С OpenCV это делается буквально одной строкой. Но прежде чем найти интересующие нас элементы мы должны их подготовить. Делаем скриншоты и вырезаем элементы. Получаем что-то вроде этого:
И прописываем в коде, чтобы знать какие у нас есть: target_images:np.ndarray=['ad_enable', 'ruletka', 'ruletka_attemp', 'ruletka_end', 'get', 'ok', 'black_market', 'discount_special', 'ad_exit_next0', 'ad_exit_next1', 'ad_exit_next2', 'ad_exit0', 'ad_exit1', 'ad_exit2', 'box_open', 'main_menu', 'main_menu_exit', 'discount_banner0', 'discount_banner1', 'discount_banner2', 'back', 'bronze_box'].
Добавляем функцию для загрузки целевых картинок:
Половинные размеры понадобятся позже для вычисления центра элементов.
Добавляем распознавание на скриншоте целевых изображений:
Самое важное здесь это функция cv2.matchTemplate, в которой происходит сравнение скриншота с шаблоном (целевым изображением). И как ее продолжение функция cv2.minMaxLoc, которая берет наш результат корреляции и возвращает 4-кортеж, который включает минимальное значение корреляции, максимальное значение корреляции, (x, y)-координату минимального значения и (x, y)-координату максимального значения соответственно.
После выполнения recognize_screenshot() алгоритм образно будет видеть скриншоты как-то так (а мы в логе увидим то, что в подписях под скриншотами):
Так же в функции recognize_screenshot() есть отдельная проверка шаблона 'ad_enable'. Она понадобилась из-за того, что кнопка с данным шаблоном может быть неактивной, но отличается от активной лишь яркостью, что собственно и проверяет составное условие (1-что это 'ad_enable', 2-был найден шаблон, 3-вариант кнопки с левым расположением значка, 4-с правым).
3) В зависимости от того, какие элементы видим выполняем нажатие в определенную область экрана.
Для отправки нажатия на экран использовать будем так же ADB. Команда выглядит так: 'adb shell input tap 3 5', где 3 и 5 - координаты x, y соответственно.
Сами решения когда и куда нажимать - скучная алгоритмика и зависит от того, для чего и какой алгоритм работы мы хотим.
В данном случае при запуске закрываются все окна кроме тех, что с рекламой. Реклама просматривается всегда. После рекламы забираем призы (подтвердить вознаграждение и нажать "ок"). После попадание на главный экран (меню) игры сначала идем в рулетку, крутим пока не кончатся попытки. После идем в "специальное" и из вкладок просматриваем так же все, что доступно. После идем в коробки и открываем бесплатные пока есть разрешение на просмотр. Когда просмотрели все что было выходим в главное меню. Алгоритм завершает работу. Дополнительно если при просмотре рекламы не можем найти кнопку выхода после timeout_ad=90 секунд, то нажимаем в ту область, где она должна быть. Выглядит этот алгоритм так:
В цикле в основном методе (main) пытаемся получить скриншот, если получили, распознаем все что знаем и принимаем действия, а после выполнения действий даем время на анимацию (загрузку активити). Собственно на этом все.
Что можно было сделать иначе?
Ну тут целый список:
1) Искать только те шаблоны, которые должны быть на текущем экране
2) Получение скриншотов сразу в память в raw виде. Т.е. без промежуточного сохранения в файл и последующего чтения из файла.
3) Поиск шаблонов только в предполагаемых местах. Очевидно, что многие значки и кнопки всегда в одной области, а для некоторых достаточно считать цвет пикселя, чтобы понять есть ли в этой области экрана предполагаемый.
4) Использовать шаблоны с маской. Поможет избавиться от нескольких вариаций значка в зависимости от фона.
5) Для каждого шаблона свой порог распознавания. Например для крестиков. Для них важна форма, а не цвет или стиль обводки.
Исходный код можно найти на моем GitHub: проект wr_bot.
—————————————————————————
Спасибо, что дочитали статью!
Подпишитесь пожалуйста на мой канал "Заметки Электроника | Alexander.Chad", этим Вы очень сильно поможете мне. Канал существует только за счет наличия и участия подписчиков.
Если Вам понравился материал - поддержите его лайком или даже донатом (ЮMoney). Есть что сказать? Оставьте комментарий! Это тоже будет помощью.
Сейчас канал нуждается в Вас как никогда прежде!