Kinect+OpenNI学习笔记之12(简单手势所表示数字识别).doc

Kinect+OpenNI学习笔记之12(简单手势所表示数字识别).doc

  1. 1、本文档共28页,可阅读全部内容。
  2. 2、有哪些信誉好的足球投注网站(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
  前言   这篇文章是本人玩kinect时做的一个小实验,即不采用机器学习等类似AI的方法来做简单的手势数字识别,当然了,该识别的前提是基于本人前面已提取出手部的博文Robert Walter手部提取代码的分析的基础上进行的。由于是纯数学形状上来判别手势,所以只是做了个简单的0~5的数字识别系统,其手势的分割部分效果还不错(因为其核心代码是由OpenNI提供的),手势数字识别时容易受干扰,效果一般般,毕竟这只是个简单的实验。 ?   实验基础   首先来看下本系统的流程图,如下所示:    ?   其中轮廓的提取,多边形拟合曲线的求法,凸包集和凹陷集的求法都是采用opencv中自带的函数。手势数字的识别是利用凸包点以及凹陷点和手部 中心点的几何关系,简单的做了下逻辑判别了(可以肯定的是这种方法很烂),具体的做法是先在手部定位出2个中心点坐标,这2个中心点坐标之间的距离阈值由 程序设定,其中一个中心点就是利用OpenNI跟踪得到的手部位置。有了这2个中心点的坐标,在程序中就可以分别计算出在这2个中心点坐标上的凸凹点的个 数。当然了, 这样做的前提是用人在做手势表示数字的同时应该是将手指的方向朝上(因为没有像机器学习那样通过样本来训练,所以使用时条件要苛刻很多)。利 用上面求出的4种点的个数(另外程序中还设置了2个辅助计算点的个数,具体见代码部分)和简单的逻辑判断就可以识别出数字0~5了。其它的数字可以依照具 体的逻辑去设计(还可以设计出多位数字的识别),只是数字越多设计起来越复杂,因为要考虑到它们之间的干扰性,且这种不通用的设计方法也没有太多的实际意 义。 ?   OpenCV知识点总结   void?convexityDefects(InputArray?contour, InputArray?convexhull, OutputArray?convexityDefects)   这个在函数在前面的博文Robert Walter手部提取代码的分析中已经介绍过,当时是这么解释的:   该函数的作用是对输入的轮廓contour,凸包集合来检测其轮廓的凸型缺陷,一个凸型缺陷结构体包括4个元素,缺陷起点坐标,缺陷终点坐标,缺陷中离凸包线距离最远的点的坐标,以及此时最远的距离。参数3即其输出的凸型缺陷结构体向量。   其凸型缺陷的示意图如下所示:    ?   不过这里需要重新对这3个参数做个详细的说明:   第1个参数虽然写的是contour,字面意思是轮廓,但是本人实验过很多次,发现如果该参数为目标通过轮廓检测得 到的原始轮廓的话,则程序运行到onvexityDefects()函数时会报内存错误。因此本程序中采用的不是物体原始的轮廓,而是经过多项式曲线拟合 后的轮廓,即多项式曲线,这样程序就会顺利地运行得很好。 另外由于在手势识别过程中可能某一帧检测出来的轮廓非常小(由于某种原因),以致于少到只有1个 点,这时候如果程序运行到onvexityDefects()函数时就会报如下的错误:   查看opencv源码中对应错误提示的位置,其源码如下:      表示在1969行的位置出错,也就是CV_Assert( ptnum 3 );出错,说明出错时此处的ptnum =3;看上面一行代码ptnum = points.checkVector(2, CV_32S);所以我们需要了解checkVector()函数的功能,进入opencv中关于checkVector的源码,如下: int Mat::checkVector(int _elemChannels, int _depth, bool _requireContinuous) const { return (depth() == _depth || _depth = 0) (isContinuous() || !_requireContinuous) ((dims == 2 (((rows == 1 || cols == 1) channels() == _elemChannels) || (cols == _elemChannels))) || (dims == 3 channels() == 1 size.p[2] == _elemChannels (size.p[0] == 1 || size.p[1] == 1) (isContinuous() || step.p[1] == step.p[2]*size.p[2]))) ? (int)(total()*channels()/_elemChannels) : -1; }   该函数源码大概意思就是说对应的Mat矩阵如果其深度,连续性,

文档评论(0)

kehan123 + 关注
实名认证
内容提供者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档