1、精选资料 Android移动终端的手势识别与控制系统 李干 (安徽大学,合肥) 摘要:本系统基于android 2.3.5版本,是一个能通过手势对手机等android设备进行操作的系统。手势与自然语言相同,能表达复杂信息,选择手势进行人机交互,不存在信息交流的困难。 主要的手势识别是通过色觉来实现的,通过肤色检测,在采集到的yuv格式图像进行条件判别,能确定手势的区域,得出二值化图像,这种方法比RGB和HSV省去了转换过程,提高了识别精度和速度。得到的二值图像是一个很大的数据,首先是信息提取,从中提取出 W*H像素点的得到量化区域,对量化后的数据进行边缘确定,边界是用一种简单有
2、效的边缘算法进行检测,最后通过边缘轮廓确定指尖位置,对指尖位置进行跟踪和处理,可完成操作。 采用指尖进行操控,指尖的轨迹和不同指尖间的配合,可以完成目前常用的操作。不采用整个手势进行识别,因为目前的针对复杂手势的识别方法还不成熟,无法进行精确的复杂手势识别,而对于移动终端,也不需要进行很复杂的操控,这样既增加了识别速度,也简化了操作。 关键词:移动终端 手势识别 android 边缘检测 指尖控制 目录 1引言 3 2现状及作品介绍 4 2.1 现状 4 2.2 作品介绍(核心) 5 3 Android平台及其camera框架 7 3.1 androi
3、d平台构架分析 7 应用程序层 8 应用程序框架 8 Android运行时 9 Linux内核 9 3.2 camera框架 9 3.2.1 框架概况 10 3.2.2 框架代码结构 11 4手势分割策略 13 4.1 手势分割常用方法 13 4.2 色彩空间选取 14 4.2.1 RGB色彩空间 14 4.2.2 YCrCb色彩空间 15 4.3 边缘检测 20 4.3.1 canny 边缘检测 20 4.3.2 原创边缘检测算法 22 5指尖检测策略 25 6 部分算法 26 (1):边缘检测: 26 (2):二值化: 29 7创新点 30 (1)
4、应用创新 30 (2)分割方法 30 (3)指尖控制 30 (4)算法 31 8附录 31 1引言 人对手机的依赖已经越来越严重,这种现象在大学校园尤为普遍。吸引人们关注手机的,早已不只是简单的收发信息,打电话着一些基本功能了,应用的爆发式增长,满足了人们对手机各种功能上的需求,而满足人们感官上需求的,就是良好的人机交互了。在目前广泛使用的图形接口中,主要的输入方式还是物理键盘和触屏输入,当然,触屏技术凭借其优点在移动终端占据主流。 然而,社会依然在发展,尤其是计算机领域,发展的尤为迅速,就像2007年那样,谁也没想到过触屏和智能会带来手机行业那么
5、巨大的变化,研究人机交互技术变得异常活跃,也取得了巨大的成就,人机交互迅速受到了各大厂家的重视,并成为计算机竞争行业的又一竞争领域。 手势作为自然的交互方式,在计算机领域取得了可喜的发展。而现在,移动终端的硬件也日趋强大,多媒体技术也在迅速发展,将手势应用到移动终端似乎成了一个顺水推舟的事。用手指的形态来进行标记和识别,从而达到控制的目的。手势的直观性和强大的语义使得人机交互变得尤为轻松。但由于识别的性能有待提高,目前还未得到很广泛的应用。 2现状及作品介绍 2.1 现状 根据设备采集数据资料的不同,目前的手势识别可以大体分为两种,基于数据手套的手势识别和基于视觉的手
6、势识别。基于数据手套的识别系统优点是识别效率高,但由于其要求使用者必须穿戴极不方便的设备,而且设备的造价不菲,所以此种识别方式不会是未来的主流。而基于视觉的手势识别系统凭借良好的适用性以及不需要其他的硬件设备,只是通过普通的摄像头,因而成了发展的主流(本系统就是基于视觉的识别)。但基于是觉得手势识别由于识别度一直不高,成为了其发展的瓶颈,国内外一些相关人士一直都致力于其发展,目前效果显著。 国外的发展是比较长久的。 (1)1991年富士通实验室完成了对46个手势符号的识别工作。 (2)Davis和Shah将戴在指间具有高亮标记的视觉手套的手势作为系的输入,完成了对七种手势的识别。 (3
7、Grobel和Assam从视频录像中提取特征,采用HMM技术识别262个孤立词,正确率达到91.3%。 (4)Stamert51等人使用隐马尔科夫模型(HMM)对输入视频序列中的是美国手势带有词性的40个词汇随机组成的句子进行了识别,其中HMM参数的估计采用的是EM算法。系统对分离的单词和5个单词组成的句子进行识别,正确率高达90%。 我国对手势识别的起步较晚,但近年来也取得了显著的成果。 (1)中科院的单彩峰提出了结合均值漂移的粒子滤波(The Mean ShiftEmbedded Particle Filter,MSEPF),通过在时序模板中引入时空轨迹,提出了时序模板轨迹概念
8、将跟踪得到的手势运动轨迹压缩到单幅图像中,实现了对预先定义的动态手势的识别。 (2)山东大学的徐立群等提出了一种基于颜色概率模型并融合运动信息进行手势跟踪的新方法,利用肤色概率查找表将图像序列转换为肤色概率分布图,用运动信息和肤色概率分布对搜索窗口进行初始化,然后对肤色概率分布图进行迭代运算,得到手势的位置和大小,从而实现了对六种孤立手势的识别。 2.2 作品介绍(核心) 本作品是一个基于移动终端的人机交互技术,它通过识别人手的关键点,并跟踪其轨迹,通过轨迹来识别人手势的意图,从而触发事件,并在屏幕或其他显示设备上做出反馈,达到交互目的。下面从作品的个特点做出分析: (1)与现在的p
9、c端手势识别技术相比,本作品注重的是手势的关键点位置变化信息,并且将其应用在了移动终端。众所周知,移动终端的人机交互技术发展最为迅速,新的交互技术往往能改变行业发展方向。 (2)从应用范围分析,全键盘由于携带不方便或占据较大空间,在移动终端很少使用了,触摸屏虽然是现在的主流,但其只能用在有介质的交互技术中,在未来的虚拟现实技术等一些无介质交互技术中还是有很大限制的,而手势操作,对介质要求不大,是可以适用在各种终端的一种新型的交互技术,本作品的核心就是微手势的应用,不仅是现在的手机,更是站在未来的角度,打造未来移动终端交互技术的雏形。 (3)本作品强调的是微手势,即手势中的关键点及其运动轨迹
10、组成的一套简化后的手势,其能更好的应用在移动终端,是交互变得更加简约和自然。 (4)本作品的完成完全由本人独立编码设计,未借助其他任何辅助工具,从手势的分割,边缘检测,质心、指尖检测,都是自己独立通过代码进行试验分析,其中手势的分割检测等,更是原创了一套适合处理能力不强的移动终端的方法。 (5)特色应用。本作品灵感是来自谷歌眼睛。谷歌眼睛是应用虚拟现实技术的一种未来移动终端的雏形,其显示是在一块眼镜镜片上,操作主要靠右手边镜框上的一个触摸板。笔者正是感觉触摸板式的人机交互已经不太适合一些已经到来的虚拟显示终端设备,而手势正好完美适用,所以才提出这种微手势的移动终端交互技术,应用了这种交互技
11、术之后,许多科幻电影中的一幕不再是科幻,而且马上就会到来。 3 Android平台及其camera框架 Android系统是一个开放性的手机和平板的操作系统,目前的发展势头十分迅猛。虽然android面世的时间不长,但目前已经发展到了巅峰,取代了symbian等传统手机平台,成为了目前应用最广泛的手机等移动终端的操作系统。 3.1 android平台构架分析 Android系统的底层建立在linux系统之上,该平台由操作系统、中间层、用户界面和应用软甲四层构成,它采用一种被称为软件叠层(software stack)的方式进行构建。这种软件叠层技术使得层与层之间相互分离
12、明确各自的分工。这种分工保证了层与层之间的低耦合,当下层的层内或层外发生变化时,上层的应用程序无需任何改变。 应用程序层 Android系统将会包含系列的核心应用程序,这些程序包括电子邮件客户端、SMS程序、日历、地图、浏览器、联系人等。这些应用程序都由java编写的。 应用程序框架 开发Android应用程序,就是面向底层的应用框架进行的。在一定意义上,android所有应用都是平等的,不管是系统的还是开发者的。应用程序框架除了作为开发的基础外,也是软件复用的重要手段,任何一个应用程序都可以发布他的功能模块—只要遵循框架的约定,那么其他应用就可以使用这个功能模块。
13、 Android运行时 Android运行时由两部分组成:android核心库集和Dalvik虚拟机。其中核心库提供了java语言核心库所包含的大部分功能,而虚拟机负责运行Android程序。 Linux内核 Android系统建立在Linux 2.6之上,Linux内核提供了安全性、内存管理、进程管理、网络协议栈和驱动模型等核心服务。除此之外,Linux内核也是系统硬件和软件叠层之间的抽象层。 3.2 camera框架 Android的SDK中提供了底层硬件的接口,其中包括底层的头文件、驱动、库文件,因此更方便系统的开发和移植。 Camera工作流程:
14、 景物 Scene’ 传感器 Sensor ADC DSP SD card Camera的成像原理可以简单概括如下: 景物(SCENE)通过镜头(LENS)生成的光学图像投射到图像传感器(Sensor)表面上,然后转为电信号,经过A/D(模数转换)转换后变为数字图像信号,再送到数字信号处理芯片(DSP)中加工处理,再通过IO接口传输到CPU中处理,通过DISPLAY就可以看到图像了。 3.2.1 框架概况 Android的Camera子系统提供一个拍照和录制视频的框架。 它将Camera的上层应用与Application Framework、用户库串接起来,而正
15、是这个用户库来与Camera的硬件层通信,从而实现操作camera硬件。 框架图: 3.2.2 框架代码结构 Android的Camera代码主要在以下的目录中: (1)Camera的JAVA部分 packages/apps/Camera/。其中Camera.java是主要实现的文件。这部分内容编译成为目标是Camera.apk com.android.camera这个包,几个主要的类文件如下: PhotoViewer:GalleryPicker.java(所有图片集)--->ImageGallery.java(某个Folder下图片列表)--->ViewIma
16、ge.java(看某张具体图片) VideoPlayer:GalleryPicker.java(所有视频集) --->MovieView.java(看某一个视频) Camera:Camera.java(Camera取景及拍照) VideoCamera:VideoCamera.java(VideoCamera取景及摄像) (2)Camera的framework供上层应用调用的部分 base/core/java/android/hardware/Camera.java 这部分目标是framework.jar (3)Camera的JNI部分 frameworks/base/c
17、ore/jni/android_hardware_Camera.cpp 这部分内容编译成为目标是libandroid_runtime.so。 (4)Camera UI库部分 frameworks/base/libs/ui/camera 这部分的内容被编译成库libcamera_client.so。 (5)Camera服务部分 frameworks/base/camera/libcameraservice/ 这部分内容被编译成库libcameraservice.so。 (6)Camera HAL层部分 hardware/msm7k/libcamera 或
18、vendor/qcom/android-open/libcamera2 为了实现一个具体功能的Camera,在HAL层需要一个硬件相关的Camera库(例如通过调用video for linux驱动程序和Jpeg编码程序实现或者直接用各个chip厂商实现的私有库来实现,比如Qualcomm实现的libcamera.so和libqcamera.so),实现CameraHardwareInterface规定的接口,来调用相关的库,驱动相关的driver,实现对camera硬件的操作。这个库将被Camera的服务库libcameraservice.so调用。 4手势分割策略
19、 所谓手势分割,后就是将对识别有用的区域从摄像机得到的图像中分割出来,为后面的手势特征提取等做准备。 手势分割是进行手势识别的第一步,其分割效果的好坏直接影响后面的识别效果,因而好的分割策略是最重要的第一步。在这个方面,已经有不少前人得到的方法。 4.1 手势分割常用方法 (1) 基于肤色模型的方法:chai和habibi的YCrCb颜色模型,将Du和Lew均一化的RGB模型,这些方法是用肤色信息来实现手势和背景的分离,本系统就是基于肤色的分割。 (2) 增加限制方法:如使用白色和黑色等色差较大的背景,通过加强前景来实现手和背景区域的划分,加深两者间的对比,此方法的缺点是限制了手
20、的自由区域。 (3) 建立手势数据库方法:建立一个数据库,其中有各种手势类在各个时刻、不同位置、不同比例下的手型图像,通过匹配的方法实现手势的分割。缺点是费时间。 (4) 轮廓跟踪方法:典型的又基于Snake模型的手势分割,利用Snake模型对噪声和对比度的敏感度来有效跟踪目标的形变和非刚性的复杂运动,打到将目标从复杂背景中分割出来的目的。这个方法比较好,但费时,不利于实时系统。 (5) 差影法:差影法就是讲目标图像和背景图像相减,此方法对消除背景有很明显的效果。但也有一个很明显的缺点,就是一定要保证背景图像和手势图像的对影像点唯一空间同意目标上,也就是视角和位置不能改变,否则误差极大。
21、 经前人经验得知,在色彩和对比度中,人眼对前者的敏感度要高于后者。原因是彩色图像具有很多的信息。在手势图像中肤色信息占主导,将肤色进行进行有效的提取可以得到分割图像。 4.2 色彩空间选取 4.2.1 RGB色彩空间 RGB颜色是红色(Red)、绿色(Green)和蓝色(Blue)三基色的字母缩写。RGB色彩模式是通过三种基本颜色的不同程度的迭加来产生各种各样的不同颜色。这个标准能够涵盖人类视力所能感知的所有颜色,是目前运用广泛的颜色系统之一。 RGB色彩模式使用的RGB模型。该模型为图象中的每个像素的RGB各个分量分配一个0~255的灰度值。因此RGB图象只要使用三种
22、颜色,按不同的比例混合就可以产生256*256*256=16581375种颜色。 RBG颜色的表示语法是(Red, Green, Blue), 因此各种颜色的标识值可以由公式计算得:65536*Blue+256*Green+Red。各个分量的数值越小,亮度越低;数值越大,亮度越高。(0,0,0)为黑色;(255,255,255)为白色。 RGB的格式有RGB565,RGB555,RGB24和RGB32等等。 4.2.2 YCrCb色彩空间 YCrCb即YUV,主要用于优化彩色视频信号传输。 Y表示明亮度(LUMA)。 U和V表示色度(Chrominance或Chroma), 由于
23、从android摄像头提取到的帧图像就是YUV色彩空间的,而其正好可作为一种优于RGB空间的一种色彩识别方法,因此YCrCb是我们所使用的色彩空间。 在YCrCb空间下,强度Y对色彩在CrCb平面的分布影响很小,由于肤色样本中存在很大的噪音,一般用线性近似值的办法找出肤色空间边界。 一个(r,g,b)表示下的像素点与一个(Y,Cr,Cb)表示下的像素点的转换方法为: Y=0.2990*R+0.5870*G+0.1140*B; Cr=0.5000*R-0.4187*G-0.08143*B+128; Cb=-0.1687*R-0.3313*G+0.5000*B+128; 在YUV空间中
24、最常用的肤色标准为: 77<=Cb<=127; 133<=Cr<=173; 在多次试验的基础上可得知,手机对浮点运算的速度很差,因此对肤色检测方法做了一些改进: a= (50*R-8*B-41*G); b= (17*R+33*G-50*B); 约束条件: a>500,a<4500; b>100,b<5100; 试验结果: 二值化之前: 二值化之后: 试验过程分析: 参数: 版本:android
25、 2.3.5 Cpu:1G 内存:256M 图像:1536*2048 运算时间:768ms 分析: 根据试验可知,手机配置主流的情况下,对一副300W像素的图像的二值化时间达到了0.77S,而视频的常用帧频率为25fps,所以这种情况下不足以进行实时识别。 为了改进速度,而又兼顾识别度的情况下,对图像进行了量化操作,在常用的480*800的显示屏上,量化为100*200,这样既加快了速度,有可以去除部分噪声。 改进后的图像为: 参数: 版本:android 2.3.5 Cpu:1G 内存:2
26、56M 图像:1536*2048 运算时间:86ms 分析:可以看出运算速度已经可以达到每秒10帧以上,而噪音仅为几个孤立的红点,手势部分全部覆盖; 4.3 边缘检测 4.3.1 canny 边缘检测 Canny边缘检测算子在灰度图像中得到广泛应用。根据边缘检测的有效性和定位的可靠性,canny研究了最优边缘检测器所需特性,推导出最优边缘检测器的数学表达式。 实现步骤为: (1):用高斯滤波器平滑图像,去除图像噪声。一般选择方差为1.4的高斯函数模板和图像进行卷积运算。 (2):用一阶偏导的有限差分来计算梯度的幅值和方向。使用 的梯度算子计算x和
27、y方向的偏导数 和 ,方向角 ,梯度幅值 。 (3):对梯度幅值应用非极大值抑制。幅值M越大,其对应的图像梯度值也越大,但这还不足以确定边缘,因为这里仅把图像快速变化的问题转化成求幅值局部最大值问题,为确定边缘,必须细化幅值图像中的屋脊带,只保留幅值局部变化最大的点,生成细化的边缘。 (4):用双阈值算法检测并且连接边缘。双阈值法使Canny算子提取的边缘点更具有鲁棒性,高低阈值分别表示为Hth和Lth,对于高阈值Hth的选折,基于计算出的图像梯度值对应的直方图进行选取。在一幅图像中,非边缘点数目在总图像像素点数目中占的比例表示为Hratio,根据图像梯度值对应的直方图累加,累加数目达
28、到总像素数目的Hratio时,对应的图像梯度值设置为Hth,在文中设定Hratio为0.7。低阈值Lth的选择通过Lth=Lratio*Hth得到,文中Lratio设定为0.4。最后通过对边缘点的标记和领域关系进行连接得到最后的边缘检测图。 试验结果: 参数: 版本:android 2.3.5 Cpu:1G 内存:256M 图像:1536*2048 运算时间:1234ms 分析:根据试验结果可知,canny虽然是一个很好的边缘检测算法,但对性能有限的手机,运算时间不尽人意,超过1S,对此,针对上节讲到的量
29、化二值化,我设计了自己的边缘检测算法。 4.3.2 原创边缘检测算法 针对一个量化后的二值图像,观察其边缘分布及噪声情况,可得知下面特点: 图像: (A) 二值化矩阵: 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 1 0 1 1 0 0 1 1 0 0 0 0 1 1 1 1 1 1 0 0 0 1 1 1 1 1 1 1 0 0 0 1 1 1 1 1 1
30、 1 0 0 0 0 1 1 1 1 1 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 (B) tl t tf l m f lb b bf (C) (1)假设图B中1标注的为待分割区域,图B为m点周围各个点的值,观察图B中的区域,可发现 1.边缘具有以下特性: t+l+f+b+tf+bf+lb+tl>2; t+l+f+b+tf+bf+lb+tl<7; 2.内部区域特性:
31、 t+l+r+f=4; 3.孤立的,不成区域的点具有特性: t+l+f+b+tf+bf+lb+tl<=2; 根据以上特点,可得住位于边缘的像素点提取方法: t+l+r+f!=4; t+l+f+b+tf+bf+lb+tl>2; t+l+f+b+tf+bf+lb+tl<7; 根据上述方法,提取到的区域边缘为: 参数: 版本:android 2.3.5 Cpu:1G 内存:256M 图像:1536*2048 运算时间:79ms
32、 分析:由结果可看出,边缘已较好的分割出,对噪声的处理也很理想,切运算速度快。 5指尖检测策略 由上面提取到的图像可知,提取到的人手轮廓可能同时包含几个弯曲度较大的值,因此,运用一般的曲率检测方法难免会有误差,比如会把检测到的任何曲率大的点都当做指尖。 因此,要想准确的判断指尖,还得结合质心距来检测; 设P={p0,p1,p2,…pn}的质心为pc, 质心距dis={d1,d2,d3…dn}; 曲率k={k1,k2,k3,…kn} 判定是否为指尖的阈值为k*dis,最大者为指尖。 为了判定未伸出指尖的情况,还得设定K*dis的范围,低于质心距平均值者不认为是指尖
33、 实验图像: 6 部分算法 (1):边缘检测: public static int[][] tocal(Bitmap bo,int ww,int hh) { final int h=bo.getHeight(); final int w=bo.getWidth(); int[][] back=new int[ww][hh]; int xc,yc; if(w%ww==0){ xc=w/ww; }else{ xc=w/ww+1; } if(h%hh==0){ yc
34、h/hh;
}else{
yc=h/hh+1;
}
int l=0,m=0;
// final int[] rgba = new int[h*w];
for(int y=0;y 35、olor);
int B = Color.blue(color);
int a=(int)(50*R-8*B-41*G);//a为100*v
// U =0.436*B-0.147*R-0.289*G
// V =0.615*R-0.515*G -0.100*B
// int b=(int)(17*R+33*G-50*B);//b为-100*u
int b=R+2*G-3*B;
36、 if((a>500&&a<4500)&&(b>5&&b<300)){
back[l][m]=1;
}else{
back[l][m]=0;
}
l++;
}
m++;
}
int[][] back1=new int[ww+1][hh];
for(int x1=0;x1 37、
for(int y1=0;y1 38、 y2++;
while(back[x2][y2]==1&&isBorder(back,x2,y2)){
back1[x2][y2]=1;
y2++;
}
xx++;
}
}
if(xx%2!=0){
fig++;
}
}
return back1;
}
39、
private static boolean isBorder(int[][] data,int l,int m){
boolean re=false;
int t1=data[l][m-1]+data[l-1][m]
+data[l+1][m]+data[l][m+1];
int t2=data[l-1][m-1]+data[l+1][m-1]+
data[l-1][m+1]+data[l-1][m+1];
if(t1!=4&&(t1+t2)>2&&(t1+t2)<7){
return true 40、
}
return re;
}
(2):二值化:
public static Bitmap toSIZEHSV(Bitmap bo,int aw,int ah) {
final int h=bo.getHeight();
final int w=bo.getWidth();
int xc,yc;
if(w%aw==0){
xc=w/aw;
}else{
xc=w/aw+1;
}
if(h%ah==0){
yc=h/ah;
}else{
yc=h/ah+1;
41、 }
int[] re = new int[ah];
int[] rgba = new int[aw*ah];
int l=0,m=0;
for(int y=0;y 42、 int B = Color.blue(color);
int a=(int) (50*R-8*B-41*G);
int b=(int) (17*R+33*G-50*B);
if((a>500&&a<4500)&&(b>100&&b<5100)){
rgba[m*aw+l]=Color.WHITE;
t++;
}else{
rgba[m*aw+l]=Color. 43、BLACK;
}
l++;
}
re[m]=t;
m++;
}
Bitmap bmp = Bitmap.createBitmap(aw, ah,Bitmap.Config.RGB_565);
bmp.setPixels(rgba,0,aw, 0, 0, aw,ah);
int[] tt=new int[2];
int[] b=max(re);
44、 tt[0]=b[1];
tt[1]=b[0];
return bmp;
}
7创新点
(1)应用创新
手势识别是计算机领域的一个重大课题,将手势应用在移动终端,及可穿戴设备终端,是一个新的尝试和机会。手势识别虽然发展很久了,但一直没有广泛应用,原因就是目前的识别不够精确,但对于移动终端,只要能跟踪到指尖轨迹,就能进行操作,所以目前的手势识别技术对于移动终端的大部分操作都可完成。
(2)分割方法
手势识别中首先解决的是手势分割,基于计算机视觉的是一个大趋势,从android摄像头采集的数据时YUV格式的,也就是yCrCb,基于此格式 45、的于肤色检测识别性较高,我们改进后的算法则弥补了识别性和移动终端处理能力的不足。
(3)指尖控制
对于移动终端,指尖是控制的核心,将控制集中在指尖,对人手的不确定性做出了限制,识别的精确度也有了提高。
(4)算法
原创的边缘分割方式,更适合在移动终端这样配置不高的情况下进行量化识别边缘,对执行速度和噪声的处理也是一个弥补。
8附录
u <