发布时间:2025-12-11 03:16:49 浏览次数:6
1. OpenCV:模板匹配。 获得小跳棋中心位置
2. OpenCV:边缘检测。 获得下一方块中心位置
Python+ADB+OpenCv,实现「 跳一跳 」自动化。
/ 01 / ADB
ADB工具即Android Debug Bridge(安卓调试桥) tools。
ADB 是一个命令行窗口,用于通过电脑端与模拟器或者真实设备交互。
与之前小F接触过的Appium有点相似。
ADB的安装很简单,就是将安装包解压后,将路径添加到系统的环境变量中即可。
然后使用Python的os模块执行ADB命令。
defget_screenshot():#截取手机的屏幕os.system('adbshell/system/bin/screencap-p/sdcard/screencap.png')#把模拟器里面的文件或文件夹传到电脑上os.system('adbpull/sdcard/screencap.pngscreencap.png')defjump(distance):#设置按压时间,系数为1.35press_time=int(distance*1.35)#生成随机手机屏幕模拟触摸点,防止成绩无效#生成随机整数(0-9),最终数值为(0-90)rand=random.randint(0,9)*10#adb长按操作,即在手机屏幕上((320-410),(410-500))坐标处长按press_time毫秒cmd=('adbshellinputswipe%i%i%i%i'+str(press_time))%(320+rand,410+rand,320+rand,410+rand)#输出adb命令print(cmd)#执行adb命令os.system(cmd)本次涉及到的ADB命令,就只有三个,不多。
一个截屏,一个推送手机截图到电脑上,最后模拟长按手机屏幕。
/ 02 / 跳动实现
先检测游戏结束画面。
判断是否需要结束游戏程序。
#游戏结束的模板图像temp_end=cv2.imread('end.jpg',0)defgame_over(img):"""模板匹配,检测是否要将程序结束"""#如果在游戏截图中匹配到带"再玩一局"字样的模板,则循环中止res_end=cv2.matchTemplate(img,temp_end,cv2.TM_CCOEFF_NORMED)ifcv2.minMaxLoc(res_end)[1]>0.95:print('Gameover!')returnTrue模板匹配原理图如下。
当返回的最大矩阵值大于0.95时,则认为原始图像中肯定出现了再玩一局字样。
则游戏结束,程序也随之结束。
小跳棋的模板匹配代码如下。
主要是获取小跳棋的位置,即「跳一跳」起点位置参数。
#读取小跳棋模板图像temple=cv2.imread('temple.png',0)#获取小跳棋模板图像的高和宽th,tw=temple.shape[:2]defget_start(img):"""模板匹配,获取跳一跳起点的位置参数(小跳棋)"""#使用标准相关系数匹配,1表示完美匹配,-1表示糟糕的匹配,0表示没有任何相关性result=cv2.matchTemplate(img,temple,cv2.TM_CCOEFF_NORMED)#使用函数minMaxLoc,确定匹配结果矩阵的最大值和最小值(val),以及它们的位置(loc)min_val,max_val,min_loc,max_loc=cv2.minMaxLoc(result)#得到小跳棋的中心位置参数returnmax_loc[0]+47,max_loc[1]+208得到结果如下。
下面通过OpenCV的边缘检测获取「跳一跳」的终点位置。
defget_end(img):"""边缘检测,获取跳一跳终点的位置参数(方块)"""#高斯模糊img_rgb=cv2.GaussianBlur(img,(5,5),0)#边缘检测canny_img=cv2.Canny(img_rgb,1,10)#获得边缘检测图像的高和宽H,W=canny_img.shape#第一个顶点的高度y_top=np.nonzero([max(row)forrowincanny_img[400:]])[0][0]+400#第一个顶点的宽度x_top=int(np.mean(np.nonzero(canny_img[y_top])))#跳过小白圈,然后遍历y_bottom=y_top+80forrowinrange(y_bottom,H):ifcanny_img[row,x_top]!=0:y_bottom=rowbreak#得到方块的中心点x_center,y_center=x_top,(y_top+y_bottom)//2returnx_center,y_center
边缘检测原理图如下。
最后便是主程序啦。
#循环直到游戏失败结束foriinrange(10000):#将安卓手机上的截图移到电脑当前文件夹下get_screenshot()#读取截图图像img=cv2.imread('screencap.png',0)#游戏结束ifgame_over(img):break#得到起点位置参数x_start,y_start=get_start(img)#获取终点位置参数x_end,y_end=get_end(img)#将起点位置绘制出来,一个圆cv2.circle(img,(x_start,y_start),10,255,-1)#将终点位置绘制出来,一个圆img_end=cv2.circle(img,(x_end,y_end),10,255,-1)#保存图片cv2.imwrite('end.png',img_end)#计算起点和终点的直线距离,勾三股四弦五distance=(x_start-x_end)**2+(y_start-y_end)**2distance=distance**0.5#根据获得的距离来设置按压时长jump(distance)time.sleep(1.3)下面就来看一下「跳一跳」自动跳跃的视频。
轻轻松松得分,毫无问题。
/ 03 / 总结
相关工具及代码已上传网盘,公众号回复 「跳一跳」 即可获取。
安装好ADB工具,然后通过数据线将安卓手机和电脑连接。
最后运行代码, 亲测有效。
当然代码还是有待优化的,如下图~