资源描述:
《kinect+openni学习笔记之12(简单手势所表示的数字的识别)》由会员上传分享,免费在线阅读,更多相关内容在行业资料-天天文库。
1、前言 这篇文章是本人玩kinect时做的一个小实验,即不采用机器学习等类似AI的方法来做简单的手势数字识别,当然了,该识别的前提是基于本人前面已提取出手部的博文RobertWalter手部提取代码的分析的基础上进行的。由于是纯数学形状上来判别手势,所以只是做了个简单的0~5的数字识别系统,其手势的分割部分效果还不错(因为其核心代码是由OpenNI提供的),手势数字识别时容易受干扰,效果一般般,毕竟这只是个简单的实验。 实验基础 首先来看下本系统的流程图,如下所示: 其中轮廓的提取,多边形拟合曲线的求法,凸包集和
2、凹陷集的求法都是采用opencv中自带的函数。手势数字的识别是利用凸包点以及凹陷点和手部中心点的几何关系,简单的做了下逻辑判别了(可以肯定的是这种方法很烂),具体的做法是先在手部定位出2个中心点坐标,这2个中心点坐标之间的距离阈值由程序设定,其中一个中心点就是利用OpenNI跟踪得到的手部位置。有了这2个中心点的坐标,在程序中就可以分别计算出在这2个中心点坐标上的凸凹点的个数。当然了,http://sucai.qqq80.com这样做的前提是用人在做手势表示数字的同时应该是将手指的方向朝上(因为没有像机器学习那样通过样本来训练
3、,所以使用时条件要苛刻很多)。利用上面求出的4种点的个数(另外程序中还设置了2个辅助计算点的个数,具体见代码部分)和简单的逻辑判断就可以识别出数字0~5了。其它的数字可以依照具体的逻辑去设计(还可以设计出多位数字的识别),只是数字越多设计起来越复杂,因为要考虑到它们之间的干扰性,且这种不通用的设计方法也没有太多的实际意义。 OpenCV知识点总结 void convexityDefects(InputArray contour,InputArray convexhull,OutputArray convexityDefe
4、cts) 这个在函数在前面的博文RobertWalter手部提取代码的分析中已经介绍过,当时是这么解释的: 该函数的作用是对输入的轮廓contour,凸包集合来检测其轮廓的凸型缺陷,一个凸型缺陷结构体包括4个元素,缺陷起点坐标,缺陷终点坐标,缺陷中离凸包线距离最远的点的坐标,以及此时最远的距离。参数3即其输出的凸型缺陷结构体向量。 其凸型缺陷的示意图如下所示: 不过这里需要重新对这3个参数做个详细的说明: 第1个参数虽然写的是contour,字面意思是轮廓,但是本人实验过很多次,发现如果该参数为目标通过轮廓检测
5、得到的原始轮廓的话,则程序运行到onvexityDefects()函数时会报内存错误。因此本程序中采用的不是物体原始的轮廓,而是经过多项式曲线拟合后的轮廓,即多项式曲线,这样程序就会顺利地运行得很好。http://www.xinxingfuhao.com另外由于在手势识别过程中可能某一帧检测出来的轮廓非常小(由于某种原因),以致于少到只有1个点,这时候如果程序运行到onvexityDefects()函数时就会报如下的错误: 查看opencv源码中对应错误提示的位置,其源码如下: 表示在1969行的位置出错,也就是CV_
6、Assert(ptnum>3);出错,说明出错时此处的ptnum<=3;看上面一行代码ptnum=points.checkVector(2,CV_32S);所以我们需要了解checkVector()函数的功能,进入opencv中关于checkVector的源码,如下:intMat::checkVector(int_elemChannels,int_depth,bool_requireContinuous)const{return(depth()==_depth
7、
8、_depth<=0)&&(isContinuous()
9、
10、!_r
11、equireContinuous)&&((dims==2&&(((rows==1
12、
13、cols==1)&&channels()==_elemChannels)
14、
15、(cols==_elemChannels)))
16、
17、(dims==3&&channels()==1&&size.p[2]==_elemChannels&&(size.p[0]==1
18、
19、size.p[1]==1)&&(isContinuous()
20、
21、step.p[1]==step.p[2]*size.p[2])))?(int)(total()*channels()/_ele
22、mChannels):-1;} 该函数源码大概意思就是说对应的Mat矩阵如果其深度,连续性,通道数,行列式满足一定条件的话就返回Mat元素的个数和其通道数的乘积,否则返回-1;而本文是要求其返回值大于3,有得知此处输入多边形曲线(即参数1)的通道数为2,所以还需要求其元素的