Skip to content

Commit

Permalink
本地角色配置文件可随版本角色配置自动更新(不覆盖自我修改部分);
Browse files Browse the repository at this point in the history
不同分辨率定位矫正;
ocr优化行首字识别不到的问题;
更新了readme;
v0.7.0 release
  • Loading branch information
SkeathyTomas committed Feb 7, 2023
1 parent 508a4b6 commit f950334
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 41 deletions.
44 changes: 23 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,35 +24,33 @@

## 环境与准备

### OCR引擎
### ~~OCR 引擎~~

1. OCR引擎[tesserect](https://github.com/tesseract-ocr/tesseract),安装过程详见原项目,或者参考[这篇文章](https://www.jianshu.com/p/f7cb0b3f337a),安装链接[tesseract-ocr-w64-setup-v5.3.0.20221214.exe](https://digi.bib.uni-mannheim.de/tesseract/tesseract-ocr-w64-setup-v5.3.0.20221214.exe)(64位)。如果你使用`scoop`,可以使用`scoop install tesseract`快速安装。安装完成后,可在命令行输入`tesseract`检验是否安装成功。
2. [tesseract中文简体数据文件](https://github.com/tesseract-ocr/tessdata_fast/blob/main/chi_sim.traineddata),下载完成后保存到tesseract数据目录`tessdata`中(如果是`scoop`安装的话,放在`./scoop/persist/tesseract/tessdata`文件夹中)。
注:v0.7.0 版本开始更换 paddleocr 为 OCR 引擎,已不需要手动安装 OCR 环境。paddleocr 在识别率上有更好的效果,可以处理后续主词条、名称识别等需求。

### 如果你需要直接运行python程序
1. ~~OCR引擎[tesserect](https://github.com/tesseract-ocr/tesseract),安装过程详见原项目,或者参考[这篇文章](https://www.jianshu.com/p/f7cb0b3f337a),安装链接[tesseract-ocr-w64-setup-v5.3.0.20221214.exe](https://digi.bib.uni-mannheim.de/tesseract/tesseract-ocr-w64-setup-v5.3.0.20221214.exe)(64位)。如果你使用`scoop`,可以使用`scoop install tesseract`快速安装。安装完成后,可在命令行输入`tesseract`检验是否安装成功。~~
2. ~~[tesseract中文简体数据文件](https://github.com/tesseract-ocr/tessdata_fast/blob/main/chi_sim.traineddata),下载完成后保存到tesseract数据目录`tessdata`中(如果是`scoop`安装的话,放在`./scoop/persist/tesseract/tessdata`文件夹中)。~~

1. Python 3.7+ (作者开发环境Python 3.11)。
### 如果你需要直接运行 python 程序

1. Python 3.7~3.10 (作者开发环境 Python 3.10.9,onnxruntime 暂不支持 3.11)。
2. 必备的Python包:
1. PySide6,GUI框架
1. PySide6,GUI 框架
2. pynput,监听游戏窗口内鼠标操作
3. pywin32,获取设备分辨率、缩放信息,用于兼容不同分辨率
4. Pillow,截图
5. pytesseract,tesseract的python接口
6. pyqtdarktheme,GUI样式
7. requests,联网查询最新版本信息
4. pyqtdarktheme,GUI 样式
5. ppocr-onnx,paddleocr 使用 onnx 模型接口

### 使用打包的exe文件
### 使用打包好的 exe 程序

1. 在release中下载最新的压缩包。
1. 含with-tesseract的打包文件已包含tesseract引擎,无需再自行安装。
2. 若已手动安装OCR引擎,可下载不含OCR引擎的压缩包。
1. 在 release 中下载最新的压缩包。
2. 解压。

## 使用教程

1. 打开游戏,使用`ALT+ENTER`使游戏窗口切换为窗口模式(顶部出现标题栏,因为全屏状态下评分结果贴图无法置顶。),或手动在设置-图像-显示模式中调整为窗口模式。现已支持自定义窗口模式,支持窗口16:10, 16:9, 3:2分辨率,**请确定游戏窗口化打开且不要最小化,在工具启动后也不要移动游戏窗口,否则捕捉窗口定位错误会使识别出错**

2. 方式1:运行打包好的程序。解压压缩包完成后,找到并用管理员模式运行keqing.exe(必须,否则程序运行中无法监听游戏中的鼠标操作)。
2. 方式1:运行打包好的程序。解压压缩包完成后,找到并用管理员模式运行 keqing.exe(必须,否则程序运行中无法监听游戏中的鼠标操作)。

![keqing.exe](https://raw.githubusercontent.com/SkeathyTomas/img/main/img/20220805144258.png)

Expand All @@ -61,7 +59,7 @@
5. 打开背包-圣遗物或角色-圣遗物装配(需在主程序中对应选择背包或角色),随意选择圣遗物,点击`右键`进行圣遗物评分,评分结果随后标记在对应圣遗物右下角,并在主程序展示副词条识别结果。
6. 选中某个贴图结果,使用快捷键`Ctrl+Z`删除该贴图;使用全局快捷键`Ctrl+Shift+Z`删除所有贴图,可进行新一批圣遗物的评估。
7. 支持对选中的圣遗物(主面板跟随更新)进行手动修正识别结果,点击`确认修改`可保存修改结果,不过我觉得还是再点一次右键比较方便。
8. 当前屏幕上的贴图结果可通过取一个名称(比如「火伤杯」),再通过保存按钮本地储存(`src/archive.json`),可从下拉框中选择已保存的结果并贴图展示(包括下次打开程序)。
8. 当前屏幕上的贴图结果可通过取一个名称(比如「火伤杯」),再通过保存按钮本地储存(`文档/keqing/archive.json`),可从下拉框中选择已保存的结果并贴图展示(包括下次打开程序)。

![主程序示意](https://raw.githubusercontent.com/SkeathyTomas/img/main/img/20221212182324.png)

Expand All @@ -71,6 +69,8 @@

具体每一个角色的有效词条和词条的评分系数可参考[character.json](src/character.json)[score.py](score.py)中的配置,如与需求不符可自行前往源文件修改参数。

首次使用软件,角色评分系数配置文件`character.json`会复制一份到`文档/keqing/character.json`中,并优先使用此文件作为角色最终配置文件。如有需要修改角色配置,请修改以上文件,方便程序更新后保留用户个人配置。

评分结果参考:

- 30分:勉强够用
Expand All @@ -83,7 +83,7 @@

### 分辨率适配

已适配游戏窗口16:10,16:9,3:2分辨率。分辨率适配框架已经搭好,若有分辨率适配问题,可查看程序目录中的`src/grab.png`识别截图是否准确,并提供一些不同分辨率的截图做坐标定位和测试了。
已适配游戏窗口 16:10,16:9,3:2 分辨率。分辨率适配框架已经搭好,若有分辨率适配问题,可查看程序目录中的`src/grab.png`识别截图是否准确,并提供一些不同分辨率的截图做坐标定位和测试了。

如使用多屏设备(如笔记本外接显示器),请把游戏窗口置于第一屏。

Expand All @@ -104,14 +104,16 @@

- [x] 2160 * 1440

其他不支持的分辨率可在游戏内将显示模式调整为1920`*`1080窗口,然后重启该软件。
其他不支持的分辨率可在游戏内将显示模式调整为 1920`*`1080 窗口,然后重启该软件。

### 角色面板识别问题

背景飘过的白点和文字重叠可能会导致识别出错(感觉这个解决起来还是有点难度的,就算人眼去识别遮挡的文字可能也会出错,可能需要上下文,牵扯到数字可能就更没办法了)。

一般情况下再识别一次即可,可根据主程序面板的识别结果对比识别是否准确,手动校正与本地储存已识别结果功能~~正在筹备中~~已上线。

P.S. 更换 OCR 引擎后此问题已大幅改善。

### 关于GUI

暂未对滚动条进行适配,若下拉滚动条使第一行圣遗物显示不全,或者在角色面板点击靠下的圣遗物,因为游戏系统自动会移动滚动条,贴图结果可能会有垂直方向的偏移。
Expand All @@ -125,14 +127,14 @@
## 声明与支持

- 本程序不收集任何用户信息,所有数据保留在本地。
- 理论上未对任何游戏数据进行非法获取和修改,仅通过截图和OCR技术实现相关分析,且没有使用自动化程序帮助玩家获取游戏内资源,应该不在官方打击范围。如若官方觉得不妥,我就删库跑路。
- 最近在xx软件园之类的网站看到了自己的软件,并看到了完全对不上的功能介绍。在此声明并非本人上传,不确定是否做过恶意修改,请谨慎在release以外渠道下载本软件/工具(除了本人b站视频贴的方便GitHub访问困难用户的度盘链接)。
- 理论上未对任何游戏数据进行非法获取和修改,仅通过截图和 OCR 技术实现相关分析,且没有使用自动化程序帮助玩家获取游戏内资源,应该不在官方打击范围。如若官方觉得不妥,我就删库跑路。
- 最近在 xx 软件园之类的网站看到了自己的软件,并看到了完全对不上的功能介绍。在此声明并非本人上传,不确定是否做过恶意修改,请谨慎在 release 以外渠道下载本软件/工具(除了本人 b 站视频贴的方便 GitHub 访问困难用户的度盘链接,以及本文档留下的 QQ 群)。

如果觉得有用/帮到了您的话,欢迎推荐给您的好友!

## 问题反馈

使用中有任何问题可以提Issue,最好提供下命令行的输出(如识别错误、环境错误等)。
使用中有任何问题可以提 Issue,最好提供下命令行的输出(如识别错误、环境错误等)。

QQ群:119633609

Expand Down
10 changes: 10 additions & 0 deletions doc.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,16 @@
if os.path.exists(folder):
if not os.path.exists(character_path):
shutil.copy('src/character.json', character_path)
else:
with open('src/character.json', 'r', encoding = 'utf-8') as fp:
default = json.load(fp)
with open(character_path, 'r', encoding = 'utf-8') as fp:
user = json.load(fp)
diff = default.keys() - user.keys()
for item in diff:
user[item] = default[item]
with open(character_path, 'w', encoding = 'utf-8') as fp:
json.dump(user, fp, ensure_ascii = False)
if not os.path.exists(archive_path):
with open(archive_path, 'w', encoding = 'utf-8') as fp:
artifacts = {'背包':{}, '角色': {}}
Expand Down
14 changes: 9 additions & 5 deletions location.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
x_initial_A, y_initial_A, x_offset_A, y_offset_A = (300 / 2560 * w_width + w_left, (386 - 48) / 1600 * w_hight + SCALE * 24 + w_top, 195 / 2560 * w_width, 234 / 1600 * w_hight) # 第一个贴图坐标,y需要根据SCALE的标题栏高度做偏移
x_left_A, x_right_A, y_top_A, y_bottom_A = (161 / 2560 * w_width + w_left, 326 / 2560 * w_width + w_left, (208 - 48) / 1600 * w_hight + SCALE * 24 + w_top, (412 - 48) / 1600 * w_hight + SCALE * 24 + w_top) # 第一个圣遗物坐标
# x_grab_A, y_grab_A, w_grab_A, h_grab_A = (1808 / 2560 * w_width + w_left, (677 - 48) / 1600 * w_hight + SCALE * 24 + w_top, 377 / 2560 * w_width, 214 / 1600 * w_hight) # 截图x, y, w, h,y需要根据SCALE的标题栏高度做适配
x_grab_A, y_grab_A, w_grab_A, h_grab_A = (1776 / 2560 * w_width + w_left, (214 - 48) / 1600 * w_hight + SCALE * 24 + w_top, 409 / 2560 * w_width, 677 / 1600 * w_hight) # 截图x, y, w, h,y需要根据SCALE的标题栏高度做适配
x_grab_A, y_grab_A, w_grab_A, h_grab_A = (1776 / 2560 * w_width + w_left, (214 - 48) / 1600 * w_hight + SCALE * 24 + w_top, 602 / 2560 * w_width, 677 / 1600 * w_hight) # 截图x, y, w, h,y需要根据SCALE的标题栏高度做适配
row_A, col_A = (6, 8) #圣遗物行列数

x_initial_B, y_initial_B, x_offset_B, y_offset_B = (198 / 2560 * w_width + w_left, (397 - 48) / 1600 * w_hight + SCALE * 24 + w_top, 189 / 2560 * w_width, 225 / 1600 * w_hight)
Expand All @@ -48,24 +48,28 @@
elif ratio > 1.7 and ratio < 1.8:
x_initial_A, y_initial_A, x_offset_A, y_offset_A = (224 / 1920 * w_width + w_left, (289 - 36) / 1080 * w_hight + SCALE * 24 + w_top, 146 / 1920 * w_width, 175 / 1080 * w_hight)
x_left_A, x_right_A, y_top_A, y_bottom_A = (121 / 1920 * w_width + w_left, 246 / 1920 * w_width + w_left, (157 - 36) / 1080 * w_hight + SCALE * 24 + w_top, (311 - 36) / 1080 * w_hight + SCALE * 24 + w_top)
x_grab_A, y_grab_A, w_grab_A, h_grab_A = (1359 / 1920 * w_width + w_left, (511 - 36) / 1080 * w_hight + SCALE * 24 + w_top, 271 / 1920 * w_width, 156 / 1080 * w_hight)
# x_grab_A, y_grab_A, w_grab_A, h_grab_A = (1359 / 1920 * w_width + w_left, (511 - 36) / 1080 * w_hight + SCALE * 24 + w_top, 271 / 1920 * w_width, 156 / 1080 * w_hight)
x_grab_A, y_grab_A, w_grab_A, h_grab_A = (1334 / 1920 * w_width + w_left, (161 - 36) / 1080 * w_hight + SCALE * 24 + w_top, 450 / 1920 * w_width, 506 / 1080 * w_hight)
row_A, col_A = (5, 8)

x_initial_B, y_initial_B, x_offset_B, y_offset_B = (144 / 1920 * w_width + w_left, (293 - 36) / 1080 * w_hight + SCALE * 24 + w_top, 142 / 1920 * w_width, 168 / 1080 * w_hight)
x_left_B, x_right_B, y_top_B, y_bottom_B = (39 / 1920 * w_width + w_left, 166 / 1920 * w_width + w_left, (162 - 36) / 1080 * w_hight + SCALE * 24 + w_top, (315 - 36) / 1080 * w_hight + SCALE * 24 + w_top)
x_grab_B, y_grab_B, w_grab_B, h_grab_B = (1490 / 1920 * w_width + w_left, (384 - 36) / 1080 * w_hight + SCALE * 24 + w_top, 257 / 1920 * w_width, 141 / 1080 * w_hight)
# x_grab_B, y_grab_B, w_grab_B, h_grab_B = (1490 / 1920 * w_width + w_left, (384 - 36) / 1080 * w_hight + SCALE * 24 + w_top, 257 / 1920 * w_width, 141 / 1080 * w_hight)
x_grab_B, y_grab_B, w_grab_B, h_grab_B = (1464 / 1920 * w_width + w_left, (147 - 36) / 1080 * w_hight + SCALE * 24 + w_top, 343 / 1920 * w_width, 378 / 1080 * w_hight)
row_B, col_B = (5, 4)

# 3:2窗口模式
elif ratio > 1.45 and ratio < 1.55:
x_initial_A, y_initial_A, x_offset_A, y_offset_A = (254 / 2160 * w_width + w_left, (318 - 36) / 1440 * w_hight + SCALE * 24 + w_top, 165 / 2160 * w_width, 197 / 1440 * w_hight)
x_left_A, x_right_A, y_top_A, y_bottom_A = (136 / 2160 * w_width + w_left, 276 / 2160 * w_width + w_left, (173 - 36) / 1440 * w_hight + SCALE * 24 + w_top, (344 - 36) / 1440 * w_hight + SCALE * 24 + w_top)
x_grab_A, y_grab_A, w_grab_A, h_grab_A = (1528 / 2160 * w_width + w_left, (564 - 36) / 1440 * w_hight + SCALE * 24 + w_top, 297 / 2160 * w_width, 186 / 1440 * w_hight)
# x_grab_A, y_grab_A, w_grab_A, h_grab_A = (1528 / 2160 * w_width + w_left, (564 - 36) / 1440 * w_hight + SCALE * 24 + w_top, 297 / 2160 * w_width, 186 / 1440 * w_hight)
x_grab_A, y_grab_A, w_grab_A, h_grab_A = (1500 / 1920 * w_width + w_left, (175 - 36) / 1080 * w_hight + SCALE * 24 + w_top, 508 / 1920 * w_width, 571 / 1080 * w_hight)
row_A, col_A = (6, 8)

x_initial_B, y_initial_B, x_offset_B, y_offset_B = (160 / 2160 * w_width + w_left, (326 - 36) / 1440 *w_hight + SCALE * 24 + w_top, 160 / 2160 * w_width, 189 / 1440 * w_hight)
x_left_B, x_right_B, y_top_B, y_bottom_B = (43 / 2160 * w_width + w_left, 186 / 2160 * w_width + w_left, (178 - 36) / 1440 * w_hight + SCALE * 24 + w_top, (350 - 36) / 1440 * w_hight + SCALE * 24 + w_top)
x_grab_B, y_grab_B, w_grab_B, h_grab_B = (1676 / 2160 * w_width + w_left, (429 - 36) / 1440 * w_hight + SCALE * 24 + w_top, 321 / 2160 * w_width, 160 / 1440 * w_hight)
# x_grab_B, y_grab_B, w_grab_B, h_grab_B = (1676 / 2160 * w_width + w_left, (429 - 36) / 1440 * w_hight + SCALE * 24 + w_top, 321 / 2160 * w_width, 160 / 1440 * w_hight)
x_grab_B, y_grab_B, w_grab_B, h_grab_B = (1649 / 1920 * w_width + w_left, (165 - 36) / 1080 * w_hight + SCALE * 24 + w_top, 382 / 1920 * w_width, 421 / 1080 * w_hight)
row_B, col_B = (6, 4)

else:
Expand Down
23 changes: 12 additions & 11 deletions ocr.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,12 +106,13 @@ def ppocr(x, y, w, h):
ocr = TextSystem()
result = ocr.detect_and_ocr(img)
txt = [item.ocr_text for item in result]
print(txt)

# 中文和数字正则
pattern_chinese = '[\u4e00-\u9fa5]+'
pattern_digit = '\d+(\.\d+)?'

# 逐行识别
# 副属性倒数四行逐行识别
result = {}
for item in txt[-4:]:
print(item)
Expand All @@ -121,25 +122,25 @@ def ppocr(x, y, w, h):
name = name[0]
# 数值
digit = float(re.search(pattern_digit, item).group())
if name == '暴击率':
if name in '暴击率':
result['暴击率'] = digit
elif name == '暴击伤害':
elif name in '暴击伤害':
result['暴击伤害'] = digit
elif name == '元素精通':
elif name in '元素精通':
result['元素精通'] = digit
elif name == '攻击力' and '%' in item:
elif name in '攻击力' and '%' in item:
result['攻击力百分比'] = digit
elif name == '攻击力':
elif name in '攻击力':
result['攻击力'] = digit
elif name == '生命值' and '%' in item:
elif name in '生命值' and '%' in item:
result['生命值百分比'] = digit
elif name == '生命值':
elif name in '生命值':
result['生命值'] = digit
elif name == '防御力' and '%' in item:
elif name in '防御力' and '%' in item:
result['防御力百分比'] = digit
elif name == '防御力':
elif name in '防御力':
result['防御力'] = digit
elif name == '元素充能效率':
elif name in '元素充能效率':
result['元素充能效率'] = digit
else:
result[item] = 0
Expand Down
9 changes: 9 additions & 0 deletions src/character.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,15 @@
"元素精通": 1,
"元素充能效率": 0.55
},
"种门-纯精通": {
"生命值": 0,
"攻击力": 0,
"防御力": 0,
"暴击率": 0,
"暴击伤害": 0,
"元素精通": 1,
"元素充能效率": 0
},
"----风----": {},
"鹿野院平藏": {
"生命值": 0,
Expand Down
13 changes: 9 additions & 4 deletions test/paddleocr_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,16 @@

ocr = TextSystem()
# single line
# img = cv2.imread('test/test_img/test_line.png')
# result = ocr.ocr_single_line(img)
# print(result)
start = time.time()
img = cv2.imread('test/test_img/character_all.png')
img = cv2.imread("D:/Application/keqing/yas-train-main/test.png")
result = ocr.ocr_lines([img, img, img, img, img, img, img, img, img])
end = time.time()
print(end - start)
print(result)

# multiline
start = time.time()
img = cv2.imread('test/test_img/bag_all.png')
result = ocr.detect_and_ocr(img)
end = time.time()
print(end - start)
Expand Down

0 comments on commit f950334

Please sign in to comment.