云顶之奕 辅助 高亮显示
一、前言
本文提供一个简易的demo,用于对目标阵容的高亮显示,避免猪脑过载或慢速思考。基本流程由两部分组成,一是使用tesseract识别出卡牌池的名字列表,与目标阵容进行比较,得到需要的卡牌坐标;二是基于上述坐标,对卡牌高亮
二、环境设置
博主是在windows上运行,搭配Pycharm使用,使用该教程需要进行以下设置:
- 将英雄联盟客户端语言设置为英文
- 游戏内设置分辨率为1920*1080,无边框模式
- windows桌面,右键->显示设置->缩放与布局->更改文本、应用等项目的大小->100%
- 安装tesseract,并配置到系统环境变量
- 以管理员身份运行pycharm
三、卡牌识别
3.1 候选框截取
import pyscreenshot # Screenshot tool, PIL friendly
from ocr import get_text_from_image
from pynput import keyboard
def takeScreenshotROI(coordinates):
# Take a screenshot of the champion zone only
return pyscreenshot.grab(coordinates)
def get_champions():
width, height = (1920, 1080)
left, top, right, bottom = (int(width * 0.25), int(height * 0.96), int(width * 0.77), int(height * 0.99))
_width = (right-left)/5
champions_list = []
for idx in range(5):
coordinates = (int(left + idx*_width)+10, top, int(left + (idx+1)*_width)-55, bottom)
roi_example = takeScreenshotROI(coordinates)
# 用于测试 正式运行时将 以下两行代码 注释
# roi_example = Image.open('examples/ (9).png')
# roi_example = roi_example.crop(coordinates)
champion_name = get_text_from_image(roi_example)
champions_list.append(champion_name)
return champions_list
计算 左上 和 右下坐标coordinates,后根据坐标截取屏幕。由于卡池共有五张牌,需要循环五次
3.2 ocr识别
"""
Contains all code related to turning a screenshot into a string
"""
from typing import Any
import cv2
import numpy as np
from PIL import ImageGrab
import pytesseract
def image_grayscale(image: ImageGrab.Image) -> Any:
"""Converts an image to grayscale so OCR has an easier time deciphering characters"""
return cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
def image_thresholding(image: ImageGrab.Image) -> Any:
"""Applies thresholding to the image https://docs.opencv.org/4.x/d7/d4d/tutorial_py_thresholding.html"""
return cv2.threshold(image, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
def image_array(image: ImageGrab.Image) -> Any:
"""Turns the image into an array"""
image = np.array(image)
image = image[..., :3]
return image
def image_resize(image: int, scale: int) -> Any:
"""Resizes the image using the scale passed in argument two"""
(width, height) = (image.width * scale, image.height * scale)
return image.resize((width, height))
def get_text_from_image(image: ImageGrab.Image, whitelist: str = "") -> str:
"""Takes an image and returns the text"""
resize = image_resize(image, 3)
array = image_array(resize)
grayscale = image_grayscale(array)
thresholding = image_thresholding(grayscale)
return pytesseract.image_to_string(thresholding,
config=f'--psm 7 -c tessedit_char_whitelist={whitelist}').strip()
由3.1候选框截取到的图片将作为参数,传入函数get_text_from_image进行识别,得到卡牌名
四、高亮显示
基于第三章的函数,会得到现在卡牌池的名字列表,将该列表与目标阵容进行比较,得到需高亮位置的坐标,后使用Pyqt5显示
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import Qt
import sys
from PyQt5 import QtCore
class Window(QMainWindow):
def __init__(self, display_list):
super(Window, self).__init__(None, QtCore.Qt.WindowStaysOnTopHint)
# this will hide the title bar
self.setWindowFlag(Qt.FramelessWindowHint)
# set the title
self.setWindowTitle("no title")
self.setGeometry(500, 940, 950, 30)
for idx in display_list:
self.label = QLabel('recommend', self)
self.label.setStyleSheet("background-color: lightgreen; border: 3px solid green")
self.label.setGeometry(200*idx, 0, 100, 30)
# show all the widgets
self.show()
def keyPressEvent(self, e):
if e.key() == Qt.Key_D:
self.close()
App = QApplication(sys.argv)
# recommend i th champion
win1 = Window([0, 1, 3])
App.exec()
效果预览
参考资料
[1]TFT-OCR-BOT
[2]TFT-Auto-Buy
[3]TFT_zynp