点击上方蓝色“程序猿DD”,选择“设为星标”

回复“资源”获取独家整理的学习资料!

来源 | 公众号「开源中国」

随着经济社会的进步,人们对美好生活的追求也不断地刺激着电子娱乐行业的发展。但这些应用场景的人机交互方式却一直被束缚在通过键盘、鼠标、触摸屏的物理接触方式上。这些传统的交互方式将玩家的操作范围局限在简单的二维平面空间,也限制了游戏开发者创意的发挥。因此,我们引入了一种新的人机交互模式——手势识别交互。

手势交互方式符合人类思维逻辑,具有自然性和直观性等特点。使用者不需要有过高的门槛,便可以很好地体验到人机交互的乐趣。手势识别技术具有良好的应用前景——包括电子娱乐、智能家居、VR及自动驾驶等热点领域。这个项目设计的目的就是实现简单直观的人机交互方式,并促使该技术和产品在未来大规模民用成为可能。

我们的项目基于飞桨及其高性能端侧推理引擎Paddle Lite开发,实现了在基于Android系统的手机、平板电脑、嵌入式开发板上利用手势来实时控制贪吃蛇、神庙逃亡、地铁跑酷等交互式游戏,并可在大屏幕端进行投屏展示。

项目内容

手势识别交互系统采用分层架构、模块化方式进行设计,可满足系统定制及扩展的灵活要求。主要包括:前端采集模块、算法模块、通信模块。

01

采集模块

采集模块实现了Android设备上图像采集与设备运行状态的监控功能。通过高频调用关联相机来获取手势图片,将采集到的图片放入缓冲池中以供算法分析模块使用。此外,采集模块还负责对所连设备进行状态监测,如相机离线将及时产生预警,并支持自动重连等功能,保证系统的稳定性。

1. 拍照方法的实现

Android Camera是安卓系统提供的实现自定义相机功能的官方支持库,采集模块封装了一系列相关调用方法,实现了连续抓拍存储及浮窗实时预览的效果。

此外,对于没有自带摄像头的安卓设备(如嵌入式开发板),我们使用外接USB摄像头,并完成 USB摄像头的驱动模块的编写,实现了设备对外接摄像头的调用及相关配置功能。

2. 浮窗实时预览

为了便于调试,通过Service组件定制浮窗的方式来在实时显示当前摄像机的预览画面、手势识别结果、处理响应延时等信息,并设立了开关来一键控制程序,如图所示.

浮窗实时预览效果(镜像显示)

02

算法模块

算法模块负责对输入的手势图片进行分类,并将识别结果返还。此部分的开发流程如下所示。

1. 数据集的选取与采集

在数据集的选取上,从NUS Hand Posture Dataset II[1]中选择了5类作为手机、平板电脑等小型设备的手势。该数据集每一类手势由40名志愿者分别在不同的环境下拍摄,并重复5次;同时每类还含有75张有人类身体噪音的图片。共(200+75)×5=1375张图片。

在研究过程中,我们发现NUS数据集的手势不符合所应用游戏的正常操作习惯(即上下左右)。因此,我们重新设计并自己采集了数据集,用于电视端远距离的演示。该数据集同样有5种类别,每类由3名志愿者在6种场景下重复6次,共540张图片。但自己在实验室采集的数据集环境比较单一,只适用于特定环境的展示。

从NUS Hand Posture Dataset II选取的5中手势, 环境复杂、部分手势不符合游戏操作习惯:

从左至右分别对应控制命令:无控制、上、下、左、右

重新设计并自己采集的数据集示例,环境单一、手势符合游戏操作习惯:

从左至右分别对应控制命令:无控制、上、下、左、右

2. 数据集增广、划分与预处理

由于深度神经网络的训练需要足够的数据支持,规模过小的数据集会使得模型的泛化能力差,容易导致过拟合。因此,我们按以下步骤对NUS数据集进行了增广,并划分为训练集、测试集:

  • 从原始1000张无噪音图片、375张有噪音图片中都分别选择125张,共250张作为测试集,以保证数据集在有无噪音、类别等维度的分布相同;

  • 将剩余的875张无噪音图片、250张有噪音图片都分别扩充为3500张,共7000张图片形成训练集。增广方式有:0.8~0.9倍的随机裁剪、以图片中心为旋转中心的±10°的随机旋转。

此外,还通过padding的方式将图片调整为方形,以保持原始手势及背景的长宽比。最后,在将图片传入神经网络之前,对图片进行z-score归一化,以加快神经网络的收敛速度。

数据集增广及预处理效果如下图所示:

数据集增广、预处理示意图(左:padding后的原图为方形,中:随机裁剪,右:随机旋转)

3. 设计、搭建与训练神经网络

在卷积神经网络的选取与设计上,由于要将模型应用于计算资源非常受限的Android平台上,因此考虑选用轻量级神经网络MobileNet[2]。

MobileNet是目前常用的可以在移动设备端部署的轻量级神经网络。它将标准卷积用Depthwise Convolution和Pointwise Convolution代替,减少了模型参数与计算量。我们利用百度开源深度学习框架飞桨搭建MobileNet并进行训练。

较低延时是手势实时控制游戏的关键。为了降低算法延时,即尽可能减少模型参数量与计算量,但同时保证算法准确率,我们在MobileNet模型(

https://github.com/PaddlePaddle/models/blob/develop/PaddleCV/image_classification/models/mobilenet_v1.py)的基础上,通过调整网络结构(层数、各层通道数),设计多组实验进行对比,结果如表1所示。其中模型输入图片尺寸为120×120×3。最终选择了算法延时小,同时识别准确率较高的模型(序号3),其结构如表2所示。

4. 模型保存

在训练过程中,将模型进行保存,用于之后的推理预测。具体地,在训练时每个epoch都将神经网络的参数进行保存,并评估测试集准确率。训练完成后,选择测试集准确率最高的模型作为预测模型。

5. Android端推理

最后,基于Paddle Lite在Android端加载模型并进行推理预测。

首先我们要编译Android端能够调用的CPP库。本项目中编译的是Paddle Lite。编译时,参考Paddle Lite在GitHub平台上Android部分开发文档

(https://github.com/PaddlePaddle/Paddle-Lite/blob/develop/mobile/doc/development_android.md),基于Ubuntu系统,利用Android NDK及CMake交叉编译出符合我们Android硬件环境的库libpaddle-mobile.so文件。

之后,将采集模块中摄像头捕捉的图片按照训练模型前完全一致的方法进行预处理,并加载保存好的预测模型,通过调用刚才编译的libpaddle-mobile.so库提供的API,就能实现Android端的推理。

下面是没有运行游戏的演示效果。将识别结果和包括摄像头拍照、算法推理、控制的总延时显示在浮窗上,方便调试。

03

通信模块

通信模块根据算法不同的推理预测结果,向操作系统发送相对应的控制命令,就实现了应用程序的控制。

跨进程操作通常采用进程间通讯,可建立专用通讯管道实现,我们采用向Android系统直写shell命令模拟动作事件的方式来实现系统控制功能,这种方式快捷高效,但需先取得root权限。

实验中用到的设备参数如表3所示。

作品展示

01

手机端贪吃蛇游戏

02

平板电脑端神庙逃亡游戏

03

嵌入式板+电视投屏端神庙逃亡游戏

总结

我们的手势识别交互系统是面向人机交互的嵌入式应用程序,用户仅需使用带有摄像头的安卓设备便可以利用手势实现对界面(游戏)的控制。利用嵌入式主板丰富的接口带来的多平台投影功能,还可以得到更好的展示与体验效果。

本项目中手势指令发出、识别不依赖任何可穿戴的设备,可以使用户获得沉浸式体验,并可带动相关游戏开发、设备制造等产业的发展。相信手势识别等AI技术在未来会更加完善,改善人类生活。

参考文献

[1] Pisharady P K, Vadakkepat P, Loh A P. Attention Based Detection and Recognition of Hand Postures Against Complex Backgrounds[J]. International Journal of Computer Vision, 2013, 101(3): 403-419.

[2] Howard A G, Zhu M, Chen B, et al. MobileNets: Efficient Convolutional Neural Networks for Mobile Vision Applications[J]. arXiv: Computer Vision and Pattern Recognition, 2017.

往期推荐

如何画出优秀的架构图?

Apache ShardingSphere毕业成为顶级项目

200余行代码,让你实时从视频中隐身

为什么SpringBoot的 jar 可以直接运行?

改变世界的十大算法

扫一扫,关注我

一起学习,一起进步

深度学习手势识别带你玩转神庙逃亡相关推荐

  1. 飞桨手势识别带你玩转神庙逃亡

    随着经济社会的进步,人们对美好生活的追求也不断地刺激着电子娱乐行业的发展.但这些应用场景的人机交互方式却一直被束缚在通过键盘.鼠标.触摸屏的物理接触方式上.这些传统的交互方式将玩家的操作范围局限在简单 ...

  2. 百度飞桨七日深度学习手势识别

    百度飞桨七日深度学习手势识别,paddlepaddle免费GPU算力,以及很好的封装,对初学者灰常友好~~~~. 下面是其中的手势识别作业,采用LeNet网络,初步感受了调参的魅力(雾

  3. 【PyTorch】 99%程序员都不知道, 深度学习还能这样玩 (建议收藏)

    [PyTorch] 99%程序员都不知道, 深度学习还能这样玩 概述 迁移学习 入住 GitHub 项目详解 get_data.py (获取数据) get_model (获取模型) 参数详解 使用说明 ...

  4. 资源下载| 深度学习Pytoch1.0如何玩?这一门含900页ppt和代码实例的深度学习课程带你飞

    本文来自专知 近日,在NeurIPS 2018 大会上,Facebook 官方宣布 PyTorch 1.0 正式版发布了.如何用Pytorch1.0搞深度学习?对很多小白学生是个问题.瑞士非盈利研究机 ...

  5. 学习记录, 带你玩转Pyppeteer (全干货)

    别只用 Selenium,新神器 Pyppeteer 更强大! 现在大多数人在使用模拟浏览器进行数据获取的时候, 用的都是Selenium .以至于现在很多网站已经对它做了很多针对性的反爬(比如检测浏 ...

  6. 【毕业设计】深度学习手势识别检测系统 - python

    文章目录 1 前言 2 项目背景 3 任务描述 4 环境搭配 5 项目实现 5.1 准备数据 5.2 构建网络 5.3 开始训练 5.4 模型评估 6 识别效果 7 最后 1 前言

  7. 「修炼开始」一文带你入门深度学习

    来源 | Jack Cui 责编 | Carol 封图 | CSDN下载自视觉中国 前言 图解 AI 算法系列教程,不仅仅是涉及深度学习基础知识,还会有强化学习.迁移学习等,再往小了讲就比如拆解目标检 ...

  8. 干货回顾丨深度学习应用大盘点

      当首次介绍深度学习时,我们认为它是一个要比机器学习更好的分类器.或者,我们亦理解成大脑神经计算. 第一种理解大大低估了深度学习构建应用的种类,而后者又高估了它的能力,因而忽略了那些不是一般人工智能 ...

  9. 深度学习的40种应用

    当首次介绍深度学习时,我们认为它是一个要比机器学习更好的分类器.或者,我们亦理解成大脑神经计算. 第一种理解大大低估了深度学习构建应用的种类,而后者又高估了它的能力,因而忽略了那些不是一般人工智能应用 ...

最新文章

  1. 折叠屏就要来了,适配逼死 Android 开发?
  2. python特性编译语言_Python的动态语言特性; __slots__属性
  3. 自定义维护视图变量(Maintenance view variant)
  4. springboot使用原生servlet、filter、listener
  5. SQL Server资源管理之内存管理篇(上)
  6. Numpy-随机生成以及矩阵的运算
  7. 栈(顺序存储)C++模板实现
  8. Java Enterprise软件与应有的软件
  9. Vista修改默认字体
  10. 如何将1080P的腾讯视频QLV格式转换成MP4视频呢
  11. mysql网站倒计时代码_最简单的一个网页倒计时代码 时间到期后会显示出提醒内容 收藏版...
  12. Android Wear和二维码
  13. python 负数变正数_numpy正数相乘变负数的解决办法
  14. 2018 工作日节假日字典表
  15. 基于matlab双曲正割脉冲,光纤内脉冲信号传输仿真(包含matlab程序)
  16. 九龙证券|券商春季策略扎堆来袭 风格切换成焦点
  17. uniapp支付宝小程扫描二维码获取参数
  18. [再寄小读者之数学篇](2014-07-16 二阶中值)
  19. 2021-2025年中国健身训练软件行业市场供需与战略研究报告
  20. 影碟出租管理c语言程序,影碟出租管理系统

热门文章

  1. shodan 渗透测试 漏洞挖掘 一些用法
  2. java 反序列化 ysoserial exploit/JRMPListener 原理剖析
  3. linux c icmp协议 判断主机存活
  4. NTP时间服务器简介
  5. Win7 64位的SSDTHOOK(2)---64位SSDT hook的实现
  6. Android--相对布局
  7. 大学python选择题题库及答案_大学慕课用Python玩转数据题库及答案
  8. 为什么ppt图形卡配置不正确_电脑配置 | 赛博朋克2077什么配置能玩
  9. 什么是机器人的五点校正法_样品定量检测怎样选择内标法和外标法!
  10. 读取list java_java 分批次读取java.util.List 数据