前面学习了MeanShift用于目标检测,现在来看看MeanShift如何用于目标跟踪。
OpenCV里的MeanShift跟踪方法涉及图像矩和反向投影的知识,如果不清楚可以先看我的另一篇博文“图像的几何矩”
1. MeanShift( )跟踪的流程
MeanShift是个迭代的算法,每次迭代会往概率密度大的方向移动,所以MeanShift算法得用在概率密度图上,而反向投影图就是一个典型的颜色概率密度图。下图是
meanshift算法的流程图。
图画麻烦了,其实编程很简单。
初始化:计算目标区域rect0的直方图hist0。
跟 踪:根据目标直方图hist0,计算整个搜索区域的反向投影图prohist1;
给定目标起始区域rect和终止条件,在反向投影图prohist1上调用meanshift函数,得到最终区域rectN。
2. cvMeanShift( )详解
OpenCV中进行MeanShift跟踪的函数是cvMeanShift( )。
函数原型见 ..\OpenCV249\sources\modules\video\src\camshift.cpp
int cvMeanShift( const void* imgProb, //输入概率密度图
CvRect windowIn, //初始目标区域
CvTermCriteria criteria, //迭代终止条件
CvConnectedComp* comp ) //可选条件,表示连通域结构体
函数有返回值,返回的是迭代次数,而这个windowIn则是最终目标区域。
CV_IMPL int
cvMeanShift( const void* imgProb, CvRect windowIn,
CvTermCriteria criteria, CvConnectedComp* comp )
{
//CvMoments是个结构体,存的是图像矩
CvMoments moments;
int i = 0, eps;
CvMat stub, *mat = (CvMat*)imgProb;
CvMat cur_win;
CvRect cur_rect = windowIn;
CV_FUNCNAME( "cvMeanShift" );
//初始化跟踪窗口
if( comp )
comp->rect = windowIn;
//把0阶矩和1阶矩先初始化置零
moments.m00 = moments.m10 = moments.m01 = 0;
__BEGIN__;
CV_CALL( mat = cvGetMat( mat, &stub )); //返回矩阵头,stub是临时值
//各种输入变量不符合要求时显示错误信息
if( CV_MAT_CN( mat->type ) > 1 )
CV_ERROR( CV_BadNumChannels, cvUnsupportedFormat );
if( windowIn.height <= 0 || windowIn.width <= 0 )
CV_ERROR( CV_StsBadArg, "Input window has non-positive sizes