手势识别代码详细说明2(衔接上一篇)

来源:互联网 发布:汽车用品淘宝 编辑:程序博客网 时间:2024/05/21 07:08

源代码请见链接

点击打开链接

第1节  静态视觉手势识别

识别算法是整个手势识别的核心,其算法的性能和鲁棒性等指标直接关系到识别系统的成功与否,本文采用的指尖识别算法是一种直观的、简便高效的算法,适合在 上用硬件来实现。

1.1识别算法分析

本手势识别系统的识别对象为简单的5种手势,如图5.1所示。据这些手势的特点提出此指尖识别算法,其核心为指尖(手指)的计数。表征在图像上,即为计数手部(轮廓)的凸起个数,凸起的个数即为手指的个数;表达在数学上,即为求解手部图像的极(大)值点的个数。


图5.1 试验用到的手势

此模块主要是利用指尖检测来实现静态手势识别,由于静态手识别需要更多的细节特征信息,需要的计算量更大,所以更难实现。我们通过阅读[25]文献,它采用的是指尖搜索的方法,既首先在一定的范围内确定一些指尖候选位置,然后在对概率最大的周边进行抑制,同时去除一些‘不可能’像素点。他的文章给予我们启迪,但是也存在着一些不足,比如需要的计算量比较大,鲁棒性不强等等,所以,本文提出一种改进的想法,具体是根据图片中手势的轮廓线的极值点,以及一些抗干扰约束进行指尖位置搜索的方法。具体的内容如下。

我们采用纵向扫描的办法,如图5.2 (b)所示,首先计算出分割区域从上到下首先出现手部的点的位置,然后对点的纵坐标进行存储,再对存储的值与像素的横坐标绘制出如图5.2 (c)中所示的蓝色曲线,通过与分割区域成比例的间距纵向扫描曲线,得出图5.2 (d)指尖候选位置,即圆上的位置。但是对于候选区域会出现一些错误的判断,如图5.2 (e)所示,手掌的关节处有突起,会被系统认为是手指尖的区域,所以,我们有必要做出如下约束:Pole(x)<3/5*height || x<1/2*width。x为指尖区域像素点的横坐标,Pole(x)为指尖区域像素点的纵坐标,由于前面有根据质心的手部分割,所以手指的区域一定在整体分割图像的上半部分,通过大量实验计算,我们把手指尖区域约束到图像的上3/5范围内,但是,大拇指的指尖,随着个人习惯的不同,有的人手掌张开的时候,其会向下弯曲,所以,我们在此位置或上约束:x<1/2*width。即我们在手心面对摄像头的时候,大拇指在图像的左边,对于此范围内是没有关节的,所以,我们约束在此位置去除3/5范围控制。


图5.2 (a)分割出来的手部区域(b)从上到下首次出现手部区域的点的坐标曲线(c)利用一定间距的分割线对(b)曲线进行等分取点(d)得到(c)图所取点的极值点(e)提高检测精度的附加约束的示意图

1.2 识别速度的的比对

我们实现的硬件系统识别速度为60fps,处理速度快,实时性好。如表1所示,为了验证我们的算法,我们对使用PC建模的算法及FPGA硬件实现的系统的速度进行对比。使用matlab建模,采集的图像的分辨率为640×480像素,使用处理速率在2.8G Hz的因特尔处理器进行一幅的处理与识别,速度是1.3s左右。我们使用FPGA实现的硬件系统的处理速度为60fps,是PC上软件实现的80倍,处理的速度非常可观,加之,我们构建的FPGA系统的各处时钟能够达到一致,图像处理与图像数据采集是同步的,说明了系统的实时性好,适合于实际应用。

表5.1 系统的FPGA硬件实现与PC机上建模的运行速度的比较

PC(software) 

CPU: Intel G840 @ 2.80 GHZ

Matlab version:2012B

1.3s/frame

FPGA(hardware)

Xilinx virtex-5 LX50T

All hardware design

60frame/s

1.3对所使用资源的分析讨论

    我们建立系统的片上资源使用情况如图5.3所示。我们可以看出,对于genesys开发版的virtex-5 XC5VLX50T的芯片,SLICE采用的架构是六输入查找表(LUT),可用的LUT数量为28800,我们使用了百分之43,少于整体资源的一半,说明我们对于系统结构的优化很好,节省了大量查找表资源。对于Slice单元,我们使用了百分之66,与LUT资源的使用率相差不多,说明设计的结构较为紧密,使用的slice上面的LUT资源得到了充分的利用。观察圈上的最后一项,由于我们在中值滤波的部分,用面积的消耗换取时序的同步,而且在静态手势识别算法部分需要大量的寄存器存储我们检测到的极值,我们把这些都放到一块芯片上面实现,即SOC。所以在此模块占用了大量的BRAM,导致系统的BRAM/FIFO资源占用率达到了百分之九十以上,但是片上的SliceRegisters占用的比例不高,只有百分之二十二,所以对于以后的系统扩展与升级可以有大量的SliceRegisters让我们使用。


图5.3 系统片上资源的使用情况汇总


第2节  手势轨迹识别

运动物体的轨迹识别是运动分析的一个最基本的问题.它可以被应用到生活,学习,工作中的各个领域,它的研究具有十分重要的理论意义及研究价值。

    在本文中一个新的轨迹识别算法被提出,只通过更改上文中提出架构的主要识别算法模块既可以实现.在手势轨迹识别算法模块中,我们采用状态机的描述方法。如图5.5所示,采用四个状态,分别为idle write clear hang 转换的条件有两个,分别为seg_num和dutyfactor。seg_num是分割出来的手部区域的边长大小,当其小于一定的值(Thres_a)的时候就认为手部从摄像头的有效区域内消失并做清除手写屏幕处理。dutyfactor是分割出的手部区域内非肤色像素点的总数占分割区域边长的比例,如果比例值较小,小于一定的阈值Thres_b时,就认为手部基本占据了整个分割区域,此时判断手处于握拳的状态。握拳状态判定为我们之前定义的hang状态,此状态就是完成抬笔的操作,就是手处在握拳的状态下面,不进行书写的操作,此定义可用来完成非连笔书写操作。四个状态配合,依次转换就完成了我们既定的手势轨迹识别操作,但是如果简化代码,我们发现idle状态和clear状态可以做等价处理。这样的话,就可以去除一个状态,从而在不降低识别效果的情况下,减少FPGA内部的资源浪费,减少代码设计的难度。转换到idle clear hang相应的状态时输出对应的状态编码,再由上位机完成相应的操作。但是转换到write状态时需要输出由上一个模块传输过来的手部区域的重心,从而完成手部运动轨迹的书写。


图5.5 手势轨迹识别的状态机描述

    手势轨迹识别的上位机采用labview设计,在上一段中我们能判断出手势所处的状态,并且在write状态下能输出手掌重心所在的位置。所以,上位机只需要把对应的状态执行为对应的操作,并把write状态下的运动轨迹显示出来。如下图5.6所示,为labview上位机的前面板,作为上位机,labview只需要把从串口采集过来的数据进行存储并实时显示最新的命令及点坐标。这部分也可以使用VGA进行显示,使用上位机的目的是便于调试和测试实验结果。


图5.6 labview上位机的前面板

     如图5.7所示,是上位机及开发板联合测试的结果,从图中可以看出,通过手部在空中的运动,可以写出英文字母H。结果显示系统工作正常,而且三个工作状态clear,hang,write能准确的判断,结果清晰,没有差错。如果在上位机中加入模式识别的算法,就能快速,准确的判断出空中写字的内容。


图5.7 上位机及开发板联合测试结果


第3节  动态视觉手势识别

动态手势识别被认为是人机交互领域中一个至关重要的解决方案. 在本文中,我采用基于FPGA的纯硬件结构实现了实时的动态手势识别,其整体采用并行结构,可以识别60fps视频流中的动态手势。如图所示,是本模块采用的状态机结构,从结构图中可以看出,本结构基于上部分,即图所示状态机,在其基础上进行设计与编写。首先检测上一层次输出的状态,即clear、hang或者write。如果输入为正常工作状态,就把手势重心值,即图中的‘cog’,存到8bit的寄存器reg1和reg2中,并且等待运动后的重心值。如果下一个状态依然为write,那么就顺序执行如下的操作,首先把新输入的重心值存到reg1中,代替原来的数值。然后,使用reg1中的数据减去reg2中的数据,并把结果和不同的条件进行比较,判断出满足的状态,即up、down、left或者right。最后,把reg1存储的值存到reg2中。需要注意的是上面的步骤一定要顺序执行。其它的转换条件及转换过程如下图5.8所示,不做详细解释。

 

图5.8 动态视觉手势识别系统的状态转换及转换条件

下图5.9为动态手势识别的上位机前面板界面,此时为手势运动,即开始判断的模式。和上一个模块相似,此部分也可以在下位机中硬件实现,并且用vga显示,但是为了调试和测试的便捷性,依然用labview实现。使用labview实现有一个注意事项,就是整体程序顺序执行中需要插入时间延时模块。因为系统采用硬件实现设计,速度可达到60fps,因此在此速度下,肉眼无法观察出来判断出的手势动作状态,上位机的显示会很快的由判断出的up,down,left,right状态转换为开始状态,因此为了观察,调试方便,在整体顺序化流程中加入了延时模块。


图5.9 动态手势识别的上位机前面板界面

此模块加入后,系统的整体结构不变。那么,系统的硬件结构就不在文中进行累述。