两年前在Android平台上写的基于肤色分割特征提取的手势识别应用,源码在这里。
1、判别出手势区域
首先判别出手势区域,有利于之后的识别手势信息。对采集到的实时图像,采用中值滤波或高斯滤波减弱噪声,减少对之后的干扰。中值滤波:
g(x,y)=med{f(x-k,y-l),(k,l∈W)}
其中,f(x,y),g(x,y)分别为原始图像和处理后图像,W为二维滤波模板。
由于肤色在YCbCr颜色空间中有很好的聚类特性,可以利用这种特性来区分手势区域。基于YCbCr颜色空间的椭圆模型较好地表达了肤色的分布,但在时间上消耗太大,于是将椭圆模型拟合成平行四边形。平行四边形模型:
其中Cr、Cb为YCrCb颜色空间的Cr分量和Cb分量。颜色空间内被四条直线包围的区域判别为肤色,其余则判别为背景色。
运用C语言来编写程序,在算法中建立改进的平行四边形模型,根据此模型判别肤色与背景,再进行二值化处理,得到白色肤色和黑色背景的二值图像。之后删除较小的肤色区域,采用形态学运算处理空洞,找到手势区域。
2、手势识别
由于手势识别控制实时性较高,因此采用算法较为简单的链码来识别简单手势。
链码用于表示由顺次连接的像素点组成的边界线。如图1所示,它将3×3领域中心点(P)指向8个领域点(bi)的方向分别编码为0~7,一条曲线由若干像素点组成,最终此曲线链码可表示为{ai},ai∈{0,1,…,7},i为像素索引值,ai是像素i指向像素(i+1)的方向链码。
图1 点P的8领域的链码方向编号
假定ai是手势边界链码,定义k阶差分码
对称函数S(di)使得di具有图像旋转不变性(例如规定7-0=-1),则k阶差分链码计算方法为:
其中对称函数
给定阈值D(D>0),判断{ti}中大于D的区间数即指尖数,小于-D的区间数即指谷数,实现对简单手型的识别。
图2 手势识别的算法框图
图3 手势识别过程