AI时代用脸玩“飞机大战”,PaddleHub让你秒变“脸控”游戏达人
AI时代还拿着手机打飞机游戏是不是out了?飞桨PaddleHub带你体验不一样的游戏玩法。
从世界上第一款游戏诞生开始,电玩都需要依赖手柄和按键进行,无论是PC游戏,还是 XBOX 、PS 这类主机游戏,控制器和手柄都是不可缺少的。
直到2009年微软发布了第一代 Kinect,将人体检测作为游戏控制,彻底颠覆了游戏的单一操作,开创了解放双手的先河,使人机互动的理念更加彻底地展现出来。但是之后,2018 年微软彻底弃用了 Kinect 实在让人惋惜!
大众流行的游戏文化中,人机互动的主流方式还是离不开手柄,即使到了手机和Pad 横行的移动时代,大多数的主流游戏依然利用的是虚拟键盘和虚拟手柄的交互方式。
人类发展的动力其实很大一部分来自于人类“懒惰”的天性,所以对我而言,如果能通过更简单、自由的交互方式玩游戏,将是非常有意思的事情。虽然我们离脑机接口和思维控制还有很长的路要走,但是随着深度学习的发展,相信不久的将来,交互方式也会产生天翻地覆的变化。
基于此,我尝试做了人脸打飞机的游戏项目!
效果展示
使用普通电脑自带的摄像头捕捉人体动作(这里主要是头部),进而转化为对于游戏的控制。
左转头部:飞机往左飞
右转头部:飞机往右飞
抬头:飞机向上
低头:飞机向下
张嘴:丢炸弹!
操作简单欢乐,据说还能治好程序猿们的颈椎病~~
而这一切的实现非常简单,只要使用 飞桨PaddleHub 封装好的深度学习模型即可,由此获得头部的角度检测,然后链接到游戏控制即可!
无需人工智能的高深技术理念,绝对小白同学也可以轻松搞定!!!
实现方法
打飞机游戏的实现需要完成分如下三个步骤:
使用PaddleHub中的 facelandmarklocalization 模型实现头部运动监测。
使用Pygame实现打飞机游戏主体程序。(这里用了最简单易上手,通常用来做 Python 入门初体验的 Pygame)
将头部运动监测模块加入游戏中。
下面我给大家详细介绍一下具体的代码实现。
01安装 PaddleHub
安装飞桨。
安装Paddlehub。
pip install paddlehub
在这个游戏中使用的是 PaddleHub 中的 facelandmarklocalization 模型,安装好 PaddleHub 以后就可以直接调用了!
模型的详细介绍参考:
https://www.paddlepaddle.org.cn/hubdetail?name=face_landmark_localization&en_category=KeyPointDetection
02 实现游戏主体程序
这里我使用的是自己初学 Python 时,用 Pygame 制作的打飞机游戏。素材上,无论图片、飞机模型还是背景音乐网上非常多,非常容易获取(因为是入门款嘛~)
pip install pygame
具体的文件和素材请参考AI Studio:
https://aistudio.baidu.com/aistudio/projectdetail/405645
文件夹中分别存放了图片,音乐和字体素材。通过pygame的各种模块和函数来定义各项游戏内容的参数,比如敌机出现的时间、运动的方向、运动速度、碰撞等事件监测等,这里就不一一赘述了。
然后开始实现最重要的游戏主体文件,定义整个游戏如何开始,如何循环,如何操作,如何结束。
原程序中,我是用 空格键、上下左右键来控制飞机,对应的程序片段如下:
if bomb_num and event.key == K_SPACE:bomb_sound_use.play()bomb_num -= 1
key_pressed = pygame.key.get_pressed()
if key_pressed[K_w] or key_pressed[K_UP]:myplane.move_up() # 飞机向上飞
elif key_pressed[K_s] or key_pressed[K_DOWN]:myplane.move_down() # 飞机向下飞
elif key_pressed[K_a] or key_pressed[K_LEFT]:myplane.move_left() # 飞机向左飞
elif key_pressed[K_d] or key_pressed[K_RIGHT]:myplane.move_right() # 飞机向右飞
03 将 PaddleHub 的头部运动监测模块加入游戏中
1. 加入人脸识别和头部姿态识别的类,先通过人脸检测找到视频画面中人脸的位置。
在第一版程序中,使用了ultralightfastgenericfacedetector1mb_640,虽然精度更高,但是和游戏程序结合起来后资源消耗太大,影响了速度。第二版听取专家的建议,降低为ultralightfastgenericfacedetector1mb_320,精度其实足够用了,同时大幅提升了游戏的流畅度!
class MyFaceDetector(object):"""自定义人脸检测器"""def __init__(self):self.module = hub.Module(name="ultra_light_fast_generic_face_detector_1mb_320")self.alpha = 0.75self.start_flag = 1def face_detection(self, images, use_gpu=False, visualization=False):# 使用GPU运行,use_gpu=True,并且在运行整个教程代码之前设置CUDA_VISIBLE_DEVICES环境变量result = self.module.face_detection(images=images, use_gpu=use_gpu, visualization=visualization)if not result[0]['data']:return resultface = result[0]['data'][0]if self.start_flag == 1:self.left_s = result[0]['data'][0]['left']self.right_s = result[0]['data'][0]['right']self.top_s = result[0]['data'][0]['top']self.bottom_s = result[0]['data'][0]['bottom']self.start_flag = 0else:# 加权平均上一帧和当前帧人脸检测框位置,以稳定人脸检测框self.left_s = self.alpha * self.left_s + (1 - self.alpha) * face['left']self.right_s = self.alpha * self.right_s + (1 - self.alpha) * face['right']self.top_s = self.alpha * self.top_s + (1 - self.alpha) * face['top']self.bottom_s = self.alpha * self.bottom_s + (1 - self.alpha) * face['bottom']result[0]['data'][0]['left'] = self.left_sresult[0]['data'][0]['right'] = self.right_sresult[0]['data'][0]['top'] = self.top_sresult[0]['data'][0]['bottom'] = self.bottom_sreturn result
然后通过头部姿态识别,来判定头部的动作状态。
在第一版程序中,使用了欧拉角的计算来获得人头部的运动状态,但是计算很复杂,对于数学基础不是很好的人非常难理解。第二版中,把头部运动状态的计算方式大幅简化,只采用了facelandmarklocalization识别出的68个人脸关键点中的7个就达到了很好的预期效果,而且算法更简洁明了,实际效果也非常流畅!
class HeadPostEstimation():"""头部姿态识别"""def __init__(self, face_detector=None):self.module = hub.Module(name="face_landmark_localization", face_detector_module=face_detector)def get_face_landmark(self, image):"""预测人脸的68个关键点坐标images(ndarray): 单张图片的像素数据"""try:# 选择GPU运行,use_gpu=True,并且在运行整个教程代码之前设置CUDA_VISIBLE_DEVICES环境变量res = self.module.keypoint_detection(images=[image], use_gpu=True)return True, res[0]['data'][0]except Exception as e:logger.error("Get face landmark localization failed! Exception: %s " % e)return False, Nonedef get_lips_distance(self, face_landmark):"""从face_landmark_localization的检测结果中查看上下嘴唇的距离"""lips_points = np.array([face_landmark[52], face_landmark[58]], dtype='float')head_points = np.array([face_landmark[25], face_landmark[8]], dtype='float')lips_distance = np.sum(np.square(lips_points[0] - lips_points[1]))head_distance = np.sum(np.square(head_points[0] - head_points[1]))relative_distance = lips_distance / head_distancereturn relative_distancedef get_nose_distance(self,face_landmark):"""从face_landmark_localization的检测结果中获得鼻子的位置,以此判断头部运动"""nose_point = np.array([face_landmark[31]], dtype='float')cheek_points = np.array([face_landmark[3], face_landmark[15]], dtype='float')left_distance = np.sum(np.square(nose_point[0] - cheek_points[0]))right_distance = np.sum(np.square(nose_point[0] - cheek_points[1]))nose_position_h = left_distance/(left_distance+right_distance)nose_position_v = nose_point[0][1]-cheek_points[0][1] # 获得鼻子和脸颊定位点的高度相对值,以此作为抬头/低头的判断return nose_position_h, nose_position_vdef classify_pose(self, video):"""video 表示不断产生图片的生成器"""for index, img in enumerate(video(), start=1):self.img_size = img.shapesuccess, face_landmark = self.get_face_landmark(img)if not success:logger.info("Get face landmark localization failed! Please check your image!")continueif not success:logger.info("Get rotation and translation vectors failed!")continue# 计算嘴唇距离lips_distance = self.get_lips_distance(face_landmark)# 计算鼻子左右位置nose_position_h, nose_position_v = self.get_nose_distance(face_landmark)# 转换成摄像头可显示的格式img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)# 本地显示预测视频框,AIStudio项目不支持显示视频框#cv2.imshow('Pose Estimation', img_rgb)return nose_position_h, nose_position_v, lips_distance
在游戏程序初始化时启动摄像头进行头部监测。
# 使用头部控制飞机face_detector = MyFaceDetector()# 打开摄像头capture = cv2.VideoCapture(0)def generate_image():while True:# frame_rgb即视频的一帧数据ret, frame_rgb = capture.read()# 按q键即可退出if cv2.waitKey(1) & 0xFF == ord('q'):breakif frame_rgb is None:breakframe_bgr = cv2.cvtColor(frame_rgb, cv2.COLOR_RGB2BGR)yield frame_bgrcapture.release()cv2.destroyAllWindows()head_post = HeadPostEstimation(face_detector)
在原来游戏程序主循环中,把控制算法都替换为头部监测后的输出。
# 获取头部运动数据,并控制飞机
nose_position_h, nose_position_v, lips_distance = head_post.classify_pose(video=generate_image)
#print(nose_position_h, nose_position_v, lips_distance) # 该语句用来查看评估参数如何设计
if nose_position_h < 0.22:myplane.move_left() # 由于摄像头演示中镜面关系,实际使用中请设置为myplane.move_right()
elif nose_position_h > 0.48:myplane.move_right() # 由于摄像头演示中镜面关系,实际使用中请设置为myplane.move_left()
elif nose_position_v < -40:myplane.move_up()
elif nose_position_v > -25:myplane.move_down()# 张嘴就是炸弹,dis_control<0.045 为闭嘴
if lips_distance < 0.045:flag = 1
if bomb_num and lips_distance > 0.055 and flag == 1:flag = 0bomb_sound_use.play()bomb_num -= 1
万事俱备,一键运行,见证奇迹的时刻到了
将所有的代码和素材下载到本地后,就可以启动 mani.py 一键运行啦!(电脑要有摄像头哦!)
大家也可以把其中的代码片段加入到自己的游戏程序里,相信你们的创意可以带来更多不同凡响的呈现效果!
在尝试的过程中,第一版和第二版的差距还是非常明显的,大家可以看看效果呈现对比:
https://www.bilibili.com/video/BV1uZ4y147ur
共同探讨
在实现过程中有几个下问题,还需要进一步研究和探讨:
由于调整参数的时候,是基于我自己的脸进行的,所以不知道别人的脸控制游戏时精度会不会有影响。
原来想再做一版人脸和飞机重叠的效果呈现,但是在 pygame 的框架下还没折腾出来怎么实现。
摄像头视角和人类视角是镜面关系,所以为了拍摄视频我调整成为了左右相反,实际中需要对调过来。
未来可期
第二版完成后,本来想做个第三版,利用 PaddleHub 的人体骨骼监测模块,实现通过人体运动来控制飞机,但是这个模块目前还没有办法直接接入实时的视频画面,所以作罢了。
不过好消息是,听说不久的将来 PaddleHub 会对各个模块的接口进行进一步的丰富,到时候应该可以实现了,有没有小伙伴愿意一起一试呢?
PaddleHub项目地址:
GitHub: https://github.com/PaddlePaddle/PaddleHub
Gitee: https://github.com/PaddlePaddle/PaddleHub
PaddleHub教程合集:
https://aistudio.baidu.com/aistudio/course/introduce/1070
PaddleHub实践分享:
https://aistudio.baidu.com/aistudio/personalcenter/thirdview/79927
如在使用过程中有问题,可加入飞桨官方QQ群进行交流:703252161。
如果您想详细了解更多飞桨的相关内容,请参阅以下文档。
官网地址:
https://www.paddlepaddle.org.cn
飞桨开源框架项目地址:
GitHub:
https://github.com/PaddlePaddle/Paddle
Gitee:
https://gitee.com/paddlepaddle/Paddle
END
AI时代用脸玩“飞机大战”,PaddleHub让你秒变“脸控”游戏达人相关推荐
- 如何训练AI玩飞机大战游戏
虽然没有谷歌强大的集群和DeepMind变态的算法的团队,但基于深度强化学习(Deep Q Network DQN )的自制小游戏AI效果同样很赞.先上效果图: 下面分四个部分,具体给大家介绍. /1 ...
- 体感游戏 | 手势识别玩飞机大战游戏(三) 使用OpenCV实现手势识别玩飞机大战游戏
后面将分四篇文章来介绍实现手势识别控制飞机大战游戏的功能,它们分别是: 使用Pygame实现简易飞机大战小游戏 使用Python+OpenCV实现简单手势识别 使用OpenCV实现手势识别玩飞机大战游 ...
- 体感游戏 | 手势识别玩飞机大战游戏(二) Python+OpenCV实现简易手势识别功能
后面将分四篇文章来介绍实现手势识别控制飞机大战游戏的功能,它们分别是: 使用Pygame实现简易飞机大战小游戏 使用Python+OpenCV实现简单手势识别 使用OpenCV实现手势识别玩飞机大战游 ...
- 体感游戏 | 手势识别玩飞机大战游戏(一) 用pygame实现飞机大战小游戏
Color Space OpenCV与AI深度学习 后面将分四篇文章来介绍实现手势识别控制飞机大战游戏的功能,它们分别是: 使用Pygame实现简易飞机大战小游戏 使用Python+OpenCV实现简 ...
- 手机版python3h如何自制游戏_Python 飞机大战|10 分钟学会用 python 写游戏
Python 飞机大战|10 分钟学会用 python 写游戏 2018 年 python 语言大火, 这把火看趋势已然延续到了 2019 年! 除了在科学计算领域 python 有用武之地之外, 在 ...
- 【Python游戏】坦克大战、推箱子小游戏怎么玩?学会这些让你秒变高高手—那些童年的游戏还记得吗?(附Pygame合集源码)
前言 下一个青年节快到了,想小编我也是过不了几年节日了呢!! 社交媒体上流传着一张照片--按照国家规定"14岁到28岁今天都应该放半天假!"不得不说, 这个跨度着实有点儿大,如果按 ...
- 刺激战场大神玩绝地求生端游为何秒变菜鸟?网友:这就是差距
刺激战场作为还原度最高的一款吃鸡手游,玩家非常多,菜鸟玩家和大神玩家也不少.但是很多刺激战场战神级别大神玩家再去玩绝地求生端游为何也会菜到不行?为什么手游比较简单端游比较难呢?今天就给大家分析一下刺激 ...
- 小白尝试c++编写飞机大战
前几天看大佬写了个神经网络训练AI玩飞机大战,我想,凭我现有知识能不能也写一个飞机大战,就进行了尝试,成果如下. #include<iostream> #include<ctime& ...
- Python程序设计,pygame飞机大战课程设计
*飞机大战游戏设计 摘 要:根据课程要求,以及面向对象程序设计的编程思想,在Windows操作系统环境下,运用PyCharm编译程序,以Python语言为开发语言,最终实现飞机大战游戏相应的游戏操作功 ...
最新文章
- [译] 沙箱中的间谍 - 可行的 JavaScript 高速缓存区攻击
- 移植opencv2.4.9到itop4412开发板
- 让dwz 的表格或者表单显示竖滚动条的代码
- 如何保护企业网络免受DDoS攻击?—Vecloud微云
- Codeforces 697C Lorenzo Von Matterhorn(严格二叉树的LCA) - xgtao -
- java f.lenth返回值_long length
- caffe模型文件解析_「机器学习」截取caffe模型中的某层
- Flutter基础—第一个Flutter实例
- 扩展ScriptBundle,支持混淆加密javascript
- solidity教程(三)高级 Solidity 理论
- vs窗体应用程序c语言,使用Visual Studio2019创建C#项目(窗体应用程序、控制台应用程序、Web应用程序)...
- C语言程序设计实践 4.4车牌号
- linux电容触摸屏驱动参数,linux 电容触摸屏驱动-1
- Python turtle库之QQ呲牙表情的绘制
- 坚果pro官方固件_坚果Pro线刷包_坚果Pro刷机包_坚果Pro固件包_坚果Pro救砖包 - 线刷宝ROM中心...
- 【bzoj4826】[Hnoi2017]影魔
- win8.1 更新后出现致命错误C0000034,无法进入安全模式和高级选项
- 微信内域名被多人投诉导致无法访问怎么办?
- adb是什么?如何安装配置adb?如何检验是否成功安装adb?
- 计算机课教案评语,信息技术教学的关键环节之三:教学评价