托拉姆物语背包识别编程攻略揭秘
托拉姆物语是一款深受玩家喜爱的角色扮演游戏。在本篇文章中,我们将继续托纳姆物语编程系列的第四篇,重点介绍如何通过编程方式检查背包。文章将详细讲解图像识别与处理技术,包括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