托拉姆物语背包识别编程攻略揭秘

37 0

托拉姆物语是一款深受玩家喜爱的角色扮演游戏。在本篇文章中,我们将继续托纳姆物语编程系列的第四篇,重点介绍如何通过编程方式检查背包。文章将详细讲解图像识别与处理技术,包括OCR识别、高斯模糊、边缘检测与形态学运算等关键步骤,帮助你实现自动化背包识别功能。

每天写作时间有限,加之此次内容稍有难度,我们先看效果,再逐步讲解。

从我们的视角来看,点击背包格子时,会不自觉地通过边框确定其中心位置,随后点击中心完成选择。我们先来整体观察一下背包的布局。

尽管边框与格子内部颜色存在差异,但整体色调一致,因此需要降低阈值进行二值化处理,虽然这会牺牲程序的鲁棒性。

二值化

可以看出,当前效果存在较多噪点和边框断点,因此还需进一步处理。首先进行去噪,通过高斯模糊进行过滤,具体操作可自行查阅相关资料,接着再进行边缘处理。

分别是二值化处理和高斯模糊处理后的效果。

边沿检测

最终的边缘检测图像非常清晰,接下来只需进行一次形态学闭运算,就能让整体轮廓更加突出。

闭运算处理后的图像

经过闭运算处理后,整体轮廓变得清晰可见,此时只需调用OpenCV的轮廓检测功能即可。

先查看一下代码

效果图

可以看出,当前已较为清晰地提取出了轮廓,但仍存在较多误判的情况。为了解决这一问题,我直接采用系列2的方法,通过计算轮廓面积来过滤掉那些不完整的轮廓。由于部分装备本身带有孔洞,导致光圈溢出,使得轮廓出现断裂,这部分数据也会被误认为是错误信息。

到这里,大部分内容已经结束,我们来看一下主函数的调用情况。

import cv2 as cv

import uiautomator2 as u2

import time

from paddleocr import PaddleOCR

import numpy as np

def gettext(ocr, img):

ocr_text = ocr_text[0]

if len(ocr_text):

out_text = ocr_text[-1][-1][0]

return out_text

else:

return ""

def knapsack(ocr, screen):

bpx, bpy, epx, epy = 630, 124, 1243, 640

img = screen[bpy:epy, bpx:epx]

binary = cv.inRange(HSV, lowerColor, upperColor)

median = cv.GaussianBlur(binary, (7, 7), 0, 0)

edges = cv.Canny(image=median, threshold1=100, threshold2=200)

kernel = np.ones((5, 5), np.uint8)

edges = cv.dilate(edges, kernel)

edges = cv.erode(edges, kernel)

contours, hierachy = cv.findContours(edges, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_NONE)

if len(contours) == 0:

return -1

contour_areas = {i: cv.contourArea(contour) for i, contour in enumerate(contours)}

sorted_contour_areas = dict(sorted(contour_areas.items(), key=lambda item: item[1], reverse=True))

sorted_contour_indices = list(sorted_contour_areas.keys())

for i in sorted_contour_indices:

if contour_areas[i]

break

M = cv.moments(contours[i])

if M["m00"] != 0:

cX = int(M["m10"] / M["m00"])

cY = int(M["m01"] / M["m00"])

托拉姆物语背包识别编程攻略揭秘

d.click(cX+bpx, cY+bpy)

text = d.screenshot(format=opencv)

延时0.05秒

print(gettext(ocr, text[429:463, 47:441]))

if __name__ == "__main__":

d = u2.connect()

print(d.info)

延时一秒

screen = d.screenshot(format=opencv)

Ocr = PaddleOCR(use_angle_cls=False, use_gpu=False,

while True:

screen = d.screenshot(format=opencv)

if np.equal(screen[624, 1266], np.array([149, 154, 154])).all():

break

knapsack(Ocr, screen)

d.swipe(1118, 500, 1118, 117, 0.05)

延时0.5s