一、前言
本文提供一个简易的demo,用于对目标阵容的高亮显示,避免猪脑过载或慢速思考。基本流程由两部分组成
- 使用 tesseract 识别卡牌池名字,与目标阵容进行比较,得到卡牌坐标
- 基于坐标对卡牌高亮显示
二、环境设置
博主是在 windows 上运行,搭配 Pycharm 使用,使用该教程需要进行以下设置:
- 将英雄联盟客户端语言设置为 英文
- 游戏内设置分辨率为 1920*1080,无边框模式
- windows桌面,右键->显示设置->缩放与布局->更改文本、应用等项目的大小->100%
- 通过参考资料 [1] 安装 tesseract,并配置到 系统环境变量
- 以 管理员 身份运行pycharm
三、卡牌识别
3.1 候选框截取
import pyscreenshot
from ocr import get_text_from_image
from pynput import keyboard
def takeScreenshotROI(coordinates):
# 根据坐标截图
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)
# 函数get_text_from_image对截图进行ocr识别
champion_name = get_text_from_image(roi_example)
champions_list.append(champion_name)
return champions_list
计算左上和右下坐标 coordinates,后根据坐标截取屏幕。由于卡池共有五张牌,需要循环五次
3.2 ocr识别
from typing import Any
import cv2
import numpy as np
from PIL import ImageGrab
import pytesseract
# 转为灰度图
def image_grayscale(image: ImageGrab.Image) -> Any:
return cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 阈值分割
def image_thresholding(image: ImageGrab.Image) -> Any:
return cv2.threshold(image, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
# 转numpy
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))
# 对卡牌池截图进行ocr识别
def get_text_from_image(image: ImageGrab.Image, whitelist: str = "") -> str:
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)
self.setWindowFlag(Qt.FramelessWindowHint)
self.setWindowTitle("no title")
self.setGeometry(500, 940, 950, 30)
# 卡牌池有四个位置,display_list表示需要标记recommen的卡牌
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)
self.show()
def keyPressEvent(self, e):
if e.key() == Qt.Key_D:
self.close()
App = QApplication(sys.argv)
win1 = Window([0, 1, 3])
App.exec()
效果预览