托纳姆物语编程系列(1)——Python+openCV做图色定位
本来是为了教女朋友学python为了吸引兴趣做的教程,最近又刚好对机器视觉有一定需求,有兴趣的可以了解一下。
一丶环境准备
1. Pycharm+Anaconda
这个网上教程很多自己找一个新一点的装好就可以了
2.adb
这个用来控制手机,网上找一下安装好就可以了
3.软件包
安装好之后进入环境新建工程(不清楚也可以查一下,记得选conda解释器),然后打开终端
然后我们依次输入以下命令
pip install opencv.python
pip install --pre uiautomator2
pip install pillow
确保没有报错就OK了
新建完成之后我们输入以下代码,然后点击绿色三角运行,就可以在下面的调试框里看到打印出来的“hello 托纳姆物语”了
脚本有两种分别是“内存脚本”和“图色脚本”,其中图色脚本重要的就是找图找色,openCV用在这个地方肯定有点大财小用但是如果能勾起你的兴趣继续学习下去我觉得也很不错。这里我直接将图色匹配的代码贴出来,初期我们就把他当一个黑盒子用就可以了。
import cv2
import numpy as np
def sift_match(icon_image, screenshot_image):
# 初始化 SIFT 检测器
sift = cv2.SIFT_create()
# 提取图标和截图的特征点和描述符
icon_keypoints, icon_descriptors = sift.detectAndCompute(icon_image, None)
screenshot_keypoints, screenshot_descriptors = sift.detectAndCompute(screenshot_image, None)
# 创建 FLANN 匹配器
FLANN_INDEX_KDTREE = 1
index_params = dict(algorithm=FLANN_INDEX_KDTREE, trees=5)
search_params = dict(checks=50)
flann = cv2.FlannBasedMatcher(index_params, search_params)
# 进行特征匹配
matches = flann.knnMatch(icon_descriptors, screenshot_descriptors, k=2)
# 应用比率测试筛选匹配
good_matches = []
for m, n in matches:
if m.distance < 0.7 * n.distance:
good_matches.append(m)
if len(good_matches) < 5:
return -1
# 获取匹配点的位置
icon_points = np.float32([icon_keypoints[m.queryIdx].pt for m in good_matches])
screenshot_points = np.float32([screenshot_keypoints[m.trainIdx].pt for m in good_matches])
center_x = int(np.mean(screenshot_points[:, 0]))
center_y = int(np.mean(screenshot_points[:, 1]))
return center_x, center_y
新建一个SIFT.py文件将代码复制进去就可以了,效果如下:
二丶代码编写
1.模拟点击
为了自动化首先肯定需要用脚本做点击滑动这些指令。我们使用uiautomator2(一定要预先安装adb)这个软件包实现。具体可以自行了解这里我用模拟器做一个简单示范。
(a)打开模拟器
然后在终端输入
python -m uiautomator2 init
然后我们用代码连接手机
然后我们需要保存模拟器上的屏幕图像
然后我们需要把要找的图片保存下来,比如我想要找到托纳姆物语并点击启动它
我们首先在你工程的文件目录下新建一个traget的文件夹里面放托纳姆物语的图标
然后在文件夹里面放入图标(用系统自带的草图工具把模拟器的图标截取并保存就可以了)
回到Pycharm就可以看到如下效果了(回宿舍换了个电脑编译环境换了一下但是不影响)
完善代码
效果如下:
但是托纳姆物语是3D视角如果想在游戏里找到指定怪物,有一个解决方案是用YOLO这样的深度学习模型做图像分类,如果点赞多的话可以再写一下,最后的代码贴在后面
import cv2 as cv
import uiautomator2 as u2
import SIFT
d = u2.connect() #连接模拟器
print(d.info) #打印连接设备信息
image = d.screenshot(format='opencv') #手机截图并保存为opencv格式图像矩阵
image = cv.cvtColor(image, cv.COLOR_BGR2GRAY) #转为灰度图
target = cv.imread("traget/Tolm.png", cv.IMREAD_GRAYSCALE) #导入目标图像转为opencv格式图像矩阵并转换为灰度图
point = SIFT.sift_match(target, image) #调用最开始保持的函数对进行匹配,并返回坐标
if point != -1: #如果返回值不等于“-1”,界面上就有对应图标
d.click(point[0], point[1]) #点击对应坐标
else: #“else“否则的意思,如果返回值为”-1“,那么界面上没有对应图标
print("NOT FOUND!!!") #没有图标就打印没找到