如何在FPS游戏中快速实现简单的人体定位算法

openlab_4276841a 更新于 2年前

概述


最近在很多B站的视频上看到大佬们分享的AI应用案例,其中有一个引起了我的兴趣:基于深度学习网络, 在CSGO中实现人体定位算法,并进行自动瞄准与射击。当然,这种明显有悖于游戏公平性的行为我是不会去做的,也不提倡大家去用这样的“外挂”软件。但在这其中我发现一个特别有趣的现象:由于这些软件都需要跑深度学习模型来进行AI分析,因此需要玩家配置较高的GPU显卡来运行AI推理,动不动就上3070,3080(当UP主这么有钱吗(lll¬ω¬)),甚至会造成与原本用于做画面渲染的GPU抢资源的现象,在开启识别软件后,游戏帧率的表现有明显下降。那有没有办法既能在游戏中实现人体定位算法,同时又不影响游戏画面性能呢?办法是当然有的啦!接下来我就一步步带大家实现一个在CPU平台下运行的人体检测应用。


图1: 网络上AI应用案例

在这个应用中,我会用到两个比较核心的组件,一个是Pygame,用于抓取显示器画面,并在显示器上绘制图案。第二个就是OpenVINO™ 工具套件(pip install openvino就可以搞定( ̄y▽ ̄)╭ Ohohoho…..),OpenVINO™是Intel第一方的深度学习框架,可以加速深度学习模型的推理效率。首先我们来看一下整个应用的流程设计(如下图),其实整个系统流程非常简单,就是不断地抓图,分析,再抓图,分析,不断循环的过程。其中问题的关键在于游戏是一个对延迟非常敏感的场景,推理延迟一高,框就会跟不上人,造成一些错误的识别,CPU作为一个低延时设备,本身在数据读取和写入的延迟性上就有比较高的优势,因此问题的核心就需要让模型推理消耗的时间到达最低,找到一个既能保证精度又可以实现低延时的模型。


图2:开发任务流程

好在OpenVINO™的Open Model Zoo里预置了丰富的预训练模型,这些模型都是基于大规模公开数据集训练,可以适用于不同的应用常见,最重要的是,这些模型都是可以免费下载的(●’◡’●)。我们可以通过OpenVINO™的官方网站了解到这些模型的适用场景、准确性、计算资源消耗等非常重要的信息,帮助我们更有效地选择合适自己硬件配置与应用需求的模型。

下载完整版OpenVINO™ :https://docs.openvino.ai/latest/get_started.html

Model Zoo地址:https://docs.openvino.ai/latest/model_zoo.html

这边我也比较好奇,现实场景的模型是否也能解决虚拟世界里的问题。既然我的目标是要实现人体检测,那我就在Open Model Zoo里找关于人体的预训练模型,随便搜了下(截图是其中一部分),乍一看还真不少,有只做人体检测的,也有既能检人又能检车的(如获至宝啊!!),其中第三列代表的是模型的准确度信息,一般用AP值来表示,第四第五列分别是模型的计算资源消耗和参数量,这里计算资源消耗越小也就意味着我们的模型推理延迟越低,所以我们要找一个准确度够用,同时够快的模型来进行部署。这里我挑选了两个模型做测试:0202和0203,可以通过OpenVINO™自带的模型下载工具Model Downloader下载你所指定的模型(https://docs.openvino.ai/latest/omz_tools_downloader.html#doxid-omz-tools-downloader),并通过DL Benchmark测试模型性能

(https://docs.openvino.ai/latest/openvino_inference_engine_tool***enchmark_tool_README.html?highlight=benchmark)。

试验环境是一套11代的i7处理器平台,这两个模型在CSGO这款游戏中的对于人体准确性的表现差不多,但明显0202的性能表现(FPS可以到40)要高于0203(FPS大概在10左右),因此我们选择用0203进行部署。


图3: Open Model Zoo里找关于人体的预训练模型

第二步,在找到合适的模型以后,我们就要开始为之匹配对应的输入数据。为此,我们可以在Open Model Zoo中每个模型的说明页面中找到关于此模型的输入信息:“This is a person detector that i***ased on MobileNetV2 backbone with two SSD heads from 1/16 and 1/8 scale feature maps and clustered prior boxes for 512x512 resolution.”


图4: 模型输入信息

可以看到该模型的输入为一个512x512大小,NCHW排布,BGR通道的图像数据,输出为[1,1,N,7]的数据组,由于该模型仅支持人体检测,因此我们可以判断其中的N为1。由于对于FPS射击游戏玩家来说,他们主要关注于瞄准镜附近的画面,同时为了减少图像缩放对模型准确性造成的影响,我们选择截取画面中心512x512的部分用做输入数据,并用绿色围栏在画面中进行标记。


图5:对画面中心512x512的部分做输入数据,并用绿色围栏在画面中进行标记

在这里我们使用python的mss对原始的1080p显示器画面进行截图,并引入pygame库,在画面实时标注截图区域。接下来就是正式开始我们模型推理任务的部署了。当拿到原始输入图像以后,我们需要对图像进行预处理,以匹配模型格式要求。


图6:对mss抓取截图的通道和layout进行了调整

模型推理部分,我们使用openvino的异构推理接口,至于这个异步推理怎么用,有什么用,大家可以参考贾老师的这个视频(https://www.bilibili.com/video/BV1Xq4y177Sw?p=11),或者参看OpenVINO™的官方说明(https://docs.openvino.ai/latest/openvino_docs_deployment_optimization_guide_dldt_optimization_guide.html#doxid-openvino-docs-deployment-optimization-guide-dldt-optimization-guide)。简单来说这个接口可以显著提升模型在处理连续输入数据的性能表现。

附上接口代码:

图7:开启异步推理,喂入数据,等待结果处理完成后,获得result

最后就是后处理和呈现部分了,我们需要把模型的推理结果以标注框的形式实时展现在游戏画面中,用于告诉玩家前方人物的位置。咱们直接贴代码:


图8:置信度高于0.5的结果数据

在得到模型输出后,我们先将原始的[1.1.1.7]排布的结果数据reshape到[1,7],根据Open Model Zoo中的模型说明文档,我们得知这里的7个数据,分别对应了人体的识别编号、标签(person=0)、置信度以及每个标记框的两个顶点坐标位置占比,此时我们筛选出置信度高于0.5的结果数据,并根据位置信息还原其在原始1920x1080画面上的左上顶点和对象长宽,最后通过pygame.draw.rect这个函数在显示器上进行绘制。


0个评论