最近在做毕业设计,其中一个部分要实现对视频序列中人手位置的跟踪。因此先写了人手的检测程序,下一步基于检测程序再用camshift算法做人手的跟踪。
目前完成的程序在我的笔记本上运行大概是一帧80-100ms,直接用检测算法来做跟踪算法其实也马马虎虎可以用了。
开发环境如下:
系统:Windows 10
IDE:Visual Studio 2013
语言:C++
算法库:OpenCV
程序思路如下
1)获取视频帧
2)将视频帧转换到YCrCb颜色空间,并分割通道
3)基于Cr和Cb两个通道做肤色区域的分割,得到肤色区域二值图像
4)将二值图像分别做膨胀和腐蚀处理,得到前景和背景的标记(marker)图像,应用分水岭算法,得到大块肤色区域的边缘轮廓
5)对4)中得到的边缘轮廓用8向种子算法处理,对不同的肤色区域做了标记,并返回了不同肤色区域的边界范围,这些肤色区域作为人手区域的候选区域
6)将5)中得到的候选区域与准备好的人手模板(Cr通道)进行模板匹配,匹配前先将候选区域缩放到与模板相同的大小;使用的方法是平方差匹配法,得到每个候选区域的匹配值(越小越接近)
7)对5)中得到的候选区域中肤色像素的比例进行统计
8)根据6)与7)中得到的结果对候选区域进行筛选,认为匹配值 <0.02(0为最匹配,1为最不匹配),且肤色区域比例<0.65的区域为人手区域(因为人脸区域一般肤色占比比较高)
9)在输出帧中对确定的人手区域画长方形框做标记
讨论:
1)之所以使用肤色区域比例的筛选方法,是因为基于肤色的情况下,人脸和人手非常容易混淆,经过尝试发现增进模板的数量效果并不好,因此采用了这种方法,但这种方法带来的问题就是人手必须张开(从而降低肤色在候选框中的比例)才能稳定被找到。
2)其实不做模板匹配只统计肤色比例应该也是可以的,但是稳定性会比较差。
3)分水岭算法的介绍见以下链接:
http://www.xuebuyuan.com/1014698.html
效果图如下:
#include "stdafx.h"
#include
#include
#include
#include
#include
其中的模板图片为
目前还存在诸多不如意之处,还待继续改进。若有表达不清或者有错误之处,烦请看到此文的朋友提出或指正~