9439| 16
|
[项目分享] 深度学习目标检测之井字棋 |
【项目背景故事】 先看一下视频感受一下整体情况: 井子棋(tic-tac-toe)又称“过三关”,是一款历史悠久、流传广泛的益智游戏。棋盘是一个3*3=9的九宫格,棋子只有X和O两种,轮流下棋,直到某一方棋子在棋盘的纵横或斜线形成三子连线,即告获胜。如果双方轮流走子,直至棋盘摆满(9子)则宣告和棋。 由于井子棋简单、流传广泛,所以在棋类的AI(人工智能)学习中,井子棋成为比较常见的研究对象,有很多算法和攻略对其进行深入研究,被称为“已经解决”的棋类游戏。此类书籍也非常多。 Tic Tac Toe is a “solved” game, meaning that there aremathematically proven strategies which will give you the best results for eachgame. 井字棋是一款"已解决"的游戏,这意味着经过数学验证的策略,将为您提供每局比赛的最佳解。 本文研究的重点并不在于下棋算法,而是使用K210作为深度学习平台,通过模型训练,运用K210对井子棋的两类棋子(X,O)进行目标检测,返回棋子的类别以及在棋盘上的坐标。并且描绘成棋盘列表,将当前棋盘的棋子类别以及位置编制成json数据格式的字符串,通过串口(uart)传送给m5stack basic,后者是一个非常优秀成熟的基于esp32的开发平台,带有屏幕、按键并且适配了完整的软件库。 M5stack basic接收到了来自K210的数据后,会有两种玩法: 一是“双人对战裁判”。将收到的棋盘数据进行json解析。在屏幕上对两类棋子以及其位置进行展示,实时显示对弈战况,并且判定两位玩家的胜负以及是否平局。即充当了“AI裁判”。 二是“简单的人机对弈”。如前文所述,井子棋被称为“已经解决”的棋类游戏,也就是说,其算法已经被充分认知和破解,如使用minmax算法后,后手棋玩家将没有机会获胜,最好的结果也是平局。这样的对弈技术含量颇高,但是兴味不足。为了增加乐趣,我们引入了一个非常简单的算法,实现了简单的人机对弈。即;esp32主控会对当前棋盘进行分析,对当前剩余的所有空位编列成列表,然后从该列表中随机推荐下一步的步骤,这样以来,玩家在和机器对弈中,对方的下一步实际上是随机状态,玩家就有很大机会获胜。这样就增加了乐趣。后续我们可以通过对算法难度的调节,来丰富对弈的难度和乐趣。 【目标检测简要回顾】 本文使用的是k210的yolo2,yolo核心就是you only look once,它是通过一张图片直接得到目标的位置坐标和目标所属类别。一次操作最多可以可以预测几百个目标,检测时间不会随着目标的数量增长。其他的知识和k210的背景可以参考我其他文章或者网上资料。 【主要知识点以及难度评估】 本项目属于一个趣味4星★★★★☆,难度3星★★★☆☆的小项目,适合初学者尤其是对深度学习感兴趣的玩家入门级练手。主要知识点: ●K210(Sipeed Bit)侧 一是k210目标检测模型训练的;二是目标检测以及矩形遮罩绘制,AI工作区的概念;三是micropythonuart+json通信、解析; ●M5STACK basic侧: 一是uart+json通信、解析;二是剩余空位形成列表并且产生随机值;三是json解析后的变量转换为string。 硬件方面需要动手的地方不多,本次仍然是利用了一个吃灰的全新充电宝外壳,将K210进行包装,引出与m5stack basic通信的串口线即可。 【硬件准备】
【软件准备】
【制作步骤】 1、硬件连线
由于连线非常少,所以不再单独制作PCB板,用一个小型的面包板把sipeed bit与其屏幕装在一起,制作飞线并且用热缩处理,与m5stack basic进行连接。 2、硬件外壳制作 第一步:将外壳上多余的紧固件拆除 工具:电磨。 第二步:开孔 面板上对摄像头位置进行标记、开孔;在底板上对屏幕位置进行标记开孔。 装配好的sipeed bit视觉识别摄像头,放置在俯拍支架上后,是这样的: 3、模型训练 模型训练是按照sipeed 的目标检测说明来进行训练的(https://www.maixhub.com/ModelTrainingHelp_zh.html),我在写《深度学习之微信跳一跳》https://www.arduino.cn/thread-94433-1-1.html时,已经进行了详细介绍,玩家可以根据训练文档进行训练。有几个需要注意的问题,我在本文中简要串联一下。
注:所有图片放置在images目录下,如棋子O的照片从0~190.jpg,棋子X的照片x0~x190.jpg,所有标记后的xml文件也都放在xml目录下,棋子O的xml文件从0~190.xml,棋子X的xml文件x0~x190.xml。强烈建议,在上传之前,打开labelImg程序,再次验证一下,所有的标记框和xml是否对应(目标被方框所完整包裹,即为正确标记)。 4、软件编写 (1)k210侧软件框图以及代码 有两个好玩的点可以和玩家分享一下: 第一个点是矩形遮罩,我在进行目标检测调试时,发现目前k210的yolo2识别单个目标非常准确,无论是类别还是坐标都很准确,但是在多个目标同时进入画面时,尤其是距离较近时,会发生相互干扰,造成误识别或者漏识别,从而影响棋类玩家的用户体验。 目前我的解决办法是,将九宫格的棋盘分成了9个矩形遮罩,每当识别出来一个目标,就将这个位置对应的区块用一个矩形遮罩进行遮挡,即:在图片上绘制一个与期盼底色相近的白色矩形遮罩,然后将绘制了矩形遮罩的图片传入AI工作区(pix_to_AI函数),AI在工作的时候,并不知道它所识别的对象有一个人为绘制的遮罩,在其工作区里,只会看到下一个需要识别的棋子,这样识别率会非常高。这个方法并不是上策,只是对目前软硬件状况的一种折衷做法,期待在后续深度学习产品中性能能够不断提升,解决此类问题。 第二个点是棋盘生成。将棋子识别出来的目标坐标根据棋盘位置,转换为棋子位置(1~9),用于编列入json格式的数据串,从而用uart串口传送至esp32(m5stackbasic)进行后续处理。在下图的九宫格里,设置了一个矩形的判断区,一旦目标中心点坐标点落入此区域,即认定为棋子在该位置。注意:目标检测获取的坐标是在兴趣框的左上角,所以需要转换一下,才可以得到中心点坐标。 (2)M5STACK侧软件框图以及代码 5、测试情况 玩法一:双人对战、AI裁判模式 双人轮流走棋,一旦一方三子成一线,即判该方获胜,如果全部九宫格均填满,仍未分胜负,则判定和棋。 玩法二:人机对战模式 初始模式下即为人机对战模式,或者在对弈中,按BUTTON_B键,右侧绿色标签显示“machine”即为人机对战模式,在X方先手后,basic即将推荐的步骤标号显示在屏幕右侧,请玩家代机器走子,因为机器方为随机填补空位,所以人类玩家的获胜几率很大,在经受minimax算法荼毒之后,遇到这样的“人机对弈”,会有相当成就感。 【小结】 井子棋简单有趣,本文从素材采集、模型训练到井子棋对弈的数据处理、简单算法,进行了一个完整的串接,利于玩家学习了解。 后续的展望;(1)将对井子棋的人机对弈部分难度进行提升,比如在对手即将取胜(三子即将连线)时,进行阻挡等策略。当然也可以直接引入minmax算法,虽会降低游戏趣味,但是可以对棋类算法有更加深入的了解。另外,我们非常期待sipeed和m5satck后续推出的,基于cpu和linux系统的深度学习产品,大幅提升目标检测的用户体验。(2)目前人机对弈是有劳人类玩家代为走子,下一步也可以结合机械臂以及吸盘,进行落子。那样就更接近对弈的真实性。 感谢sipeed以及m5stack社区师兄们的指导和帮助,如:大佬鼠、点灯鼠、zyleon等,一并致谢。 清明已过,繁花似锦的春天毕竟到来了。 沧海抱拳。 代码分享如下(内有详细注释): code.zip |
本帖最后由 沧海笑 于 2021-4-8 16:49 编辑 木子呢 发表于 2021-4-8 10:01 我也没想到,目标检测还没有流程图更加关注。哈哈。 软件名字叫做:draw.io https://github.com/jgraph/drawio-desktop 里面有手绘和阴影风格。 |
© 2013-2024 Comsenz Inc. Powered by Discuz! X3.4 Licensed