Android | 通过机器学习实现精准字母手势识别

看过上一篇「一个很糙的字母手势识别方案」文章并尝试了的同学,就一定知道,「糙手势」的识别是有多糙,糙的只能识别字母「C」。

今天这篇就用 Android 自带的 gesture API 来实现更为精准的识别。

看到这里,有的同学可能就会说了,「标题党,哪有机器学习!」。别急,认真看,认真学。先上效果图,注意底部识别分数变化,至于为什么粉红色,这是「社会人」小猪佩奇的颜色好吧~

编不下去了,这个画板源码部分借鉴了 github 下面链接的控件,TA用的就是粉色,我没改~

https://github.com/imaiya/PainterView

PS:右上角按钮默认 load 的 26 字母数据集是我手动录入然后保存为文件的,每个字母大概画了 15-20个。此数据集文件大小为 287KB。可后台回复「精手势」获取。

故事的开端

即使在「糙手势」方案中学习到了手势识别的大概套路:「先存储后识别」,但心痛于其感人的识别率,在还没写上一篇文章之前,就开始搜寻更为精准的方案。

可能是从未接触过此类功能, 苦苦搜寻之下才找到了一个网友的帖子,其中的关键字「GestureLibrary」引起了我的注意。

我在 AndroidXref 中查询了一下,还真有这个类,大概了解并确定怎么用后,将「更精准的方案」之类的字眼写入前一篇文章的末尾,给大家留有悬念,并开始研究了起来。

送上一张 gesture API 的全家福:

一开始我直接投入研究如何使用这些API了,所以并未注意到其中的 「Instance.java」和「Learner.java」两个类。这两个类的命名是有玄机的。

如何使用?

我们知道,一个手势,是个平面,多数情况下是个字符,字则由笔画组成。笔画是一条线。笔画又是由点组成。

GesturePoint.java

-> 是「点」,它除了x,y属性还有时间戳属性。

GestureStroke.java

-> 是「线」,它由GesturePoint组成。

Gesture.java

-> 是「面」,它由一个或多个GestureStroke组成。

以上三个类是基本,构成了整个手势数据结构体系。如果你也想写个佩奇色的画板,那你就需要知道这三个类的关系。直接使用下面这个类就不需要关注。

GestureOverlayView.java

-> 为了方便画图,你可以在 xml 中直接使用 GestureOverlayView。使用这个 View 的好处是:不需要接触到 point 和 stroke 的概念,注册的回调会直接返回 Gesture。可以参考下面这个链接。

http://www.runoob.com/w3cnote/android-tutorial-gestures.html

无论哪种,手势数据采集好后都需要存储下来。

GestureStore.java

-> 提供存储手势的接口,以及识别接口。一个手势名,可对应多个手势数据。从addGesture()方法可以看出,一个手势名,对应着一个手势ArrayList。

GestureLibrary.java

-> 抽象类,持有GestureStore对象,封装了其大部分public方法。我认为目的是为了分离GestureStore中的复杂实现。每一个library对象都对应一个数据集文件。

GestureLibraries.java

-> 进一步封装了GestureLibrary,内部提供两个GestureLibrary私有实现类,以四个public static 方法暴露出来,方便数据的存储和加载,如下截图。

Prediction.java

-> 简单的类,代表预测结果值。name -> 手势名,score -> 得分。得分越高,越相似

更为详细的使用,后台回复「精手势」获取源码。

gesture API 中的机器学习

没错,gesture api 内部是通过机器学习来进行手势识别的,说是手势预测更贴切些。

一开始我是不知道的。由于好奇它的实现方式,以及对比方式,我阅读了它的源码,才得以发现。

机器学习中有三种学习技巧,分别是:

监督式学习(Supervised learning)

半监督式学习(Semi-supervised learning)

非监督式学习(Unsupervised learning)

其中难度从上到下依次递增。

gesture API 则为「监督式学习」。为什么?

为了更好的理解,先来了解下机器学习的基本术语。

机器学习术语:

监督式机器学习:机器学习系统通过学习如何组合输入信息来对从未见过的数据做出有用的预测。

标签:我们要预测的事物。在本篇文章中,假如我们要 A 字母进行识别预测,那 A 就是标签。更通俗点,每一个「手势名」就是一个「标签」。

特征:特征是输入的变量。这篇中,我们录入的每一个「手势数据」就是一个「特征」。

样本:样本表示数据的特定实例。样本分为两类:有标签样本无标签样本

有标签样本:同时包含「标签」和「特征」。在本篇中,一个有标签样本就是「手势名」+「你画的手势数据」。通常有标签样本用来进行模型的训练。

无标签样本:不包含「标签」,只包含「特征」的样本。在本篇中,无标签样本就是我后面要识别的手势,仅有「手势数据」。根据训练出来的模型推断出此样本的「标签」,也就是「手势名」。

模型:模型定义了特征与标签之间的关系。主要分为两个阶段:训练推断

训练:表示创建或学习模型。也就是说,向模型展示有标签样本,让模型逐渐学习特征与标签之间的关系。

推断:表示将训练后的模型应用于无标签样本,做出有用的预测。

对于不同的问题,模式种类也不同:对于连续性问题,使用回归模型;对于离散问题,使用分类模型。

gesture API 是一个分类模型,其中的分类器根据不同配置(超参数),采用取不同的相似性算法:欧氏距离(Euclidean Distance) 和 夹角余弦(Cosine)

涉及的类主要是:

有兴趣的同学可以继续研究。我没有太过于深入,因为已经到最深层的具体实现细节了。

最后

大家可以后台回复「精手势」获取 apk 和 26 字母数据集下载链接,尝试下。当然,不仅是 26 字母,任何手势录入训练数据后都可以识别。

要我说,机器学习其实是一种编程方式,无关语言。

我之前无形中形成了「机器学习用 Python」这样的观点,限制了思路,这次也算是无意破除了思想的禁锢。

我们平时写代码,都是想好了如何解决问题,通过一行行的逻辑形成针对问题的方案。这时你还是个程序猿。

而机器学习,是你写了一个傻子,你拿数据训练这个傻子,最后让他聪明了起来。这时候你不是程序猿,是个教书育人的老师。

原文发布于微信公众号 - 猿湿Xoong(skypeng-funny)

原文发表时间:2018-06-22

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

3 条评论
登录 后参与评论

相关文章

来自专栏大数据挖掘DT机器学习

[Python]从豆瓣批量获取看过电影的用户列表,并应用kNN算法预测用户性别

首先从豆瓣电影的“看过这部电影 的豆瓣成员”页面上来获取较为活跃的豆瓣电影用户。 链接分析 这是看过"模仿游戏"的豆瓣成员的网页链接:http://movie...

2904
来自专栏企鹅号快讯

输验证码输到崩溃?教你15分钟黑掉全球最流行的验证码插件

大数据文摘作品 编译:Katrine Ren、朝夕、钱天培 验证码这种东西真的是反人类。虽然它在保证账号安全、反作弊以及反广告有着至关重要的作用,但对于普通用户...

2178
来自专栏IT派

业界 | 谷歌开源「Tangent」:一个用于自动微分的源到源Python库(附API概述)

近日,谷歌在其官方博客上开源了「Tangent」,一个用于自动微分的源到源 Python 库;它通过 Python 函数 f 生成新函数,来计算 f 的梯度,从...

3426
来自专栏人工智能LeadAI

Keras同时用多张显卡训练网络

References 官方文档:multi_gpu_model(https://keras.io/utils/#multi_gpu_model)以及Google...

5258
来自专栏机器之心

ICLR 2018 | 彩云科技提出结合组合子抽象的神经编程器-解释器,提升通用性和可学习性

3259
来自专栏CSDN技术头条

AI 可能真的要代替插画师了……

事先声明,这篇文章的标题绝不是在耸人听闻。事情的起因是前段时间在朋友圈看到同学在转发一篇论文,名字叫《Create Anime Characters with ...

1858
来自专栏数据和云

深入内核丨12C 新特性之 TOP - N 频率柱状图原理和算法

作者简介 ? 黄玮(Fuyuncat) 资深 Oracle DBA,致力于数据库底层技术的研究,其作品获得广大同行的高度评价。 个人网站 www.HelloDB...

27312
来自专栏企鹅号快讯

外国网友如何使用机器学习将邮件分类?其实很简单

AiTechYun 编辑:Yining 背景:一名叫做Anthony Dm.的外国网友试图利用机器学习将一堆未标记的电子邮件进行分类,以下是他对这次操作发表的文...

1898
来自专栏jeremy的技术点滴

tensorflow学习笔记_01

2907
来自专栏机器之心

仅需15分钟,使用OpenCV+Keras轻松破解验证码

3449

扫码关注云+社区