关键词:Kinect;肤色模型;开源计算机视觉库;指尖检测;手势识别
中图分类号: TP391.41 文献标志码:A
英文摘要
英文关键词
Key words:Kinect; skin color model; Open Source Computer Vision Library (OPENCV); finger detection; gesture recognition
0 引言
1 手势提取
在手势识别过程中,准确快速地提取手势是实现对手势高效识别的前提。本文利用微软2010年发布的Kinect传感器,结合开源计算机视觉库(Open Source Computer Vision Library,OPENCV)库来采集和处理包含手部区域的彩色数据、深度数据以及骨骼数据[17],利用深度数据和骨骼数据大致定位包含手部区域的彩色感兴趣区域(Region of Interest,ROI),结合YCrCb颜色空间对ROI区域进行肤色检测并提取面积最大的肤色区域,即手的区域。
1.1 包含手部的ROI提取
通过Kinect传感器采集彩色图像、深度图像以及骨骼数据,将深度图像每个像素点的深度值存储到二维数组distance中。Kinect传感器的骨骼追踪引擎能够跟踪和获取每个用户的近20个点或者关节信息。
将distance二维数组与深度图进行映射,如果distance[i][j]=1,则深度图中对应坐标点的像素值取为0xff。如果distance[i][j]=0,则深度图中对应的像素值取为0x00。将映射处理后的深度坐标空间中的手势坐标点一一转化到彩色坐标空间中,将转化后的手势进行膨胀处理得到包含手势的区域ROI,从彩色图片中相应的ROI区域进行显示,其他区域设为0x00。整个过程如图1所示(图1(a)为深度手部区域图,图1(b)为将深度坐标空间中的图1(a)转化过来的彩色坐标空间中的手部区域图,图1(c)为图1(b)膨胀之后的ROI区域,图1(d)为在ROI区域显示的彩色图)。
肤色是人体表面最为显著的特征之一,是人脸及手部区别于其他部分的重要特征。肤色检测的效果将直接影响手势识别的结果。目前肤色检测的颜色空间主要有HSV、YUV、YCrCb、HIS以及归一化的RGB颜色空间。在这些颜色空间中,YCrCb颜色空间具有与人的视觉感知一致性,能够有效地从图像中分割出肤色区域。彩色分量Y、Cr、Cb由R、G、B分量经过线性变换得到,转换公式为:
2 指尖点检测
数字手势最明显的特征是手的指尖点,所以指尖点检测算法的好坏将直接影响后期手势识别的结果。有些研究者利用凸包算法来检测指尖点,该算法对于伸直的指尖点的检测没有问题,但是凸包算法不能准确地检测出手势9的弯曲指尖点。为解决手势9弯曲指尖点检测问题,本文利用分割出的手势进行掌心点计算以及对手势轮廓点进行顺时针提取,通过计算手势轮廓点与掌心点的距离并生成距离曲线,找出距离曲线中的波峰波谷点。通过手掌骨骼可以发现人类伸直后的指尖点和两相邻指尖点间凹处与掌心点距离的比值变化不大。利用上述这一特性,设定比例阈值找出指尖点候选点,再结合不同手势的其他特征判定该候选点是否是指尖点。
2.1 掌心点计算
要提取手势轮廓点,首先需要从手势区域中分离出轮廓边缘点以及内部点。利用十字型窗口遍历ROI区域的像素点,判断处于该十字型窗口的像素值是否都为0xff。判断结果为真则为内部点并去除,假则为轮廓候选点。遍历循环结束后ROI区域只剩下轮廓候选点。但是为实现顺时针提取轮廓点,需要判定像素值为0xff的三个连续点是否构成了直角,是则消除该伪轮廓点,并用3*3的窗口去判定整个窗口内是否只有两个像素值为0xff,是则去除该毛刺点,防止有毛刺点使得程序崩溃。使得最后得出的轮廓可以满足以下条件:遍历循环ROI区域像素值,当判定像素值为0xff时,以此像素为中心做3*3的窗口,可以发现窗口始终只有3个像素值为0xff,这有利于后面的顺时针轮廓点提取。上述步骤的大致过程如图5所示。
通过掌心点坐标计算出图像中同一行从左到右第一个像素值为0xff的坐标作为起始坐标start1存入轮廓点数组中,同一行从右到左第一个像素值为0xff的坐标作为终点坐标end。求取步骤如下所示:
2)然后以start2为中心坐标查看3*3窗口中像素值为0xff且点坐标不为start1的坐标start3存入轮廓点数组中;
3)接着以上start3为中心查看3*3窗口中像素值为0xff且坐标不为start2的坐标start4存入轮廓点数组中。
按如上步骤循环直到存入轮廓点数组的坐标点为end点,将轮廓点顺时针提取出来。接着轮廓点每隔4个点重新显示在图中,增加轮廓边缘的平滑度,减少后期处理的计算量。如图6所示。
2.3 候选指尖点检测
获得轮廓点后,按顺序计算每个轮廓点与掌心点的距离并生成距离直方图,利用波峰点上方的3*5窗口的像素值都为0x00以及波谷点下方3*5窗口的像素值为0xff的特点计算直方图的波峰点和波谷点(将start1点和end点判定为波谷点)。此时的波峰点和波谷点数据还不适合直接用来做指尖点判断,需要将数据经过下面的处理:
1)对求取出来的波峰点集进行局部波峰点抑制,当两个波峰点的横坐标相差在15个像素内,舍弃距离掌心点相对小的波峰点,将剩下的波峰点按横坐标从小到大排序。
2)对求取出来的波谷点集按横坐标从小到大排序,检测每两个相邻的波谷点之间是否有波峰点,如果没有波峰点,则舍弃距离掌心点相对大的波谷点。将检测完的波谷点集按横坐标从小到大排序。
3)检测每两个相邻的波峰点之间是否有波谷点,如果没有波谷点,则舍弃距离掌心点相对小的波峰点,将剩下的波峰点按横坐标从小到大排序。
经过以上三步的处理之后,每相邻两个波谷点之间都有一个波峰点,每相邻两个波峰点之间都有一个波谷点。设置判定条件波峰点距掌心点的距离比上两相邻波谷点距掌心点的距离大于threshold1时(经实验测定,阈值设为1.5时判定效果较好),则为指尖候选点。对于手势5,指尖候选点即为指尖点。将手势5检测出的距离曲线数据、波峰点数据和波谷点数据输出用Matlab显示,如图7所示。
3 手势识别
不同的手势所具有的特征是不一样的,通过检测这些特征可以分辨出不同的手势。本文所要识别的手势如图8所示。将要识别的手势的距离曲线数据输出用Matlab显示如图9所示(图9中(a)(b)横坐标表示轮廓点数组中的第n个轮廓点,纵坐标表示轮廓点到掌心点的像素距离h,距离单位为像素点)。
手势识别程序中的手势判定步骤如下:
1)对Kinect提取出的三种数据进行处理,获得手势最大内轮廓面积特征、指尖点特征。
2)判定最大内轮廓面积是否大于设定的阈值150个像素点,如果大于设定的阈值,则转入步骤3);否则转入步骤4)。
3)判定指尖点特征,如果指尖点数为3,则为手势OK,当前手势识别完成,转入步骤1)循环进行手势识别;如果指尖点数为0,则为手势0,当前手势识别完成,转入步骤1)循环进行手势识别;如果指尖点数不为3和0,则该手势不在识别范围内,转入步骤1)循环进行手势识别。
6)借助掌心点,判定2个指尖点的夹角以及轮廓曲线中两指尖点指尖是否有凸起。如果夹角小于60°时,则为手势2,当前手势识别完成,转入步骤1)循环进行手势识别;如果夹角大于60°且两指尖点之间有凸起,则为手势6,当前手势识别完成,转入步骤1)循环进行手势识别;如果夹角大于60°且两指尖点之间无凸起,则为手势8,当前手势识别完成,转入步骤1)循环进行手势识别。 由表1可以发现手势1、7和手势9相差一个弯曲特征以及手势9的候选指尖点并不是手势9真正的指尖点。因此需要判定手势弯曲特征并求出手势9的指尖点,其判定以及求取步骤如下:
1)当候选指尖点为1时,将手势轮廓点用直线连接起来,直线像素为0xff,其余像素为0x00;
3)在步骤2)设定的行内检测相邻像素点数值变化次数为6的行,寻找该行从左到右像素点数值第一次变化的点坐标,计算轮廓点与该点的距离,距离最小的轮廓点即为所求的指尖点。
4 实验结果与分析
本实验使用的计算机处理器为Intel Core i3 CPU M350 @2.27GHz,2.00GB内存,摄像头为第一代的Kinect XBOX摄像机。利用Microsoft Visual Studio 2010作为系统开发平台,并结合OpenCV和开放自然交互 (Open Natural Interaction,OpenNI)完成了本文算法的实现。
由表3可知本文算法对手势1~9的平均识别率98.43%高于文献[11]的平均识别率96.78%,略低于借助专业设备Leap Motion文献[15]的平均识别率98.75%。文献[11]中仅通过判断手指间的角度大小以及指尖点来识别手势,定义的手势7和手势9利用指尖点特征明显的手势来代替日常生活中使用的手势7和手势9,减少了识别难度。本文算法则通过增加对最大内轮廓面积特征以及弯曲特征的识别使得手势识别更准确,识别率更高。文献[15]使用隐马尔可夫(HMM)算法对手势进行识别,尽管识别率略高于本文算法,但该算法前期需要对大量的样本进行训练,对计算机性能要求高。而本文算法则不需要在前期对大量的样本进行训练,对于常用的手势1~9的识别率也能达到98%以上。
5 结语
由于本实验是在光照相对稳定以及手势离Kinect距离不变的条件下进行的,这句话逻辑不通,请修改因此后期将在不同的光照和距离条件下进行实验,确定不同条件下的阈值,实现算法在不同条件下阈值的自适应。
参考文献: