1. 前言
前段时间看到大神的博客 基于动态手势识别的酷狗音乐播放器控制, 非常感兴趣, 于是download 了大神的源码,http://download.csdn.net/detail/onezeros/2954830, 研究了一下, 并做了一定的调整。最终效果:
电脑截屏:
http://www.iqiyi.com/w_19ruiswqkp.html
手机拍摄:
http://www.iqiyi.com/w_19ruiswwjh.html
2. 实现思路
- 我们的实现思路和大神的比较类似, 毕竟是跟着大神的源码走过来的, 不过我们顺带把大神的opencv 1.0 版本的代码, 改成了 opencv 2.0 版本。
2.1 总体流程:
2.2 肤色检测
- OpenCV背景去除的几种方法
- 皮肤检测算法三种,示例与代码
- 我们这里采用的肤色检测的方法是采用YCrCb空间,进行二值化分割
这个效果和 http://blog.csdn.net/zhyh1435589631/article/details/53293211 中类似, 不再多说
2.3 提取手势区域中心点
- 这里大神原始的方法是采用 BFS 遍历得到 二值化后的 Cb 通道,并取最大的一个链接域作为手势区域, 这里, 我们采用了提取轮廓的方式处理, 找到包围面积最大的轮廓区域, 作为我们的手势区域
2.4 判断轮廓轨迹
原始工程中, 大神采用的是状态码记录当前的状态, 我们这里为了简化起见, 直接使用点的轨迹来识别手势,我们使用了一个 vector<Point>
的数据结构, 用来记录手势的中心位置的运动轨迹, 于是可以很容易的判断出手势的运动方向。
2.5 虾米播放器控制
- 虾米播放器设置中有关于他的hotkey的设置
- 也就是说, 我们只要根据不同的手势, 发送不同的快捷键即可
- 大神源码中使用的是 sendinput, 然而, 这个函数在我们这个系统中, 死活出不来效果, 于是改用了 keybd_event
- 核心代码如下:
void sendHotKey(BYTE key){
keybd_event(VK_CONTROL, 0, 0, 0);
keybd_event(VK_MENU, 0, 0, 0);
keybd_event(key, 0, 0, 0);
keybd_event(key, 0, KEYEVENTF_KEYUP, 0);
keybd_event(VK_MENU, 0, KEYEVENTF_KEYUP, 0);
keybd_event(VK_CONTROL, 0, KEYEVENTF_KEYUP, 0);
}
- 虚拟键表: http://www.cnblogs.com/del/archive/2007/12/07/987364.html
3. 代码工程地址
说明, 大神原始的项目中加入了音量控制, 切换歌曲, 播放暂停, 多个功能, 测试之后感觉不是特别灵活, 这里我们将大神的音量控制功能直接删去, 减少了功能职责, 简化了手势识别的难度, 使得程序更加容易使用~~
项目工程地址: https://github.com/zhyh2010/XMusic_control_by_hand