(以下某些部分转载常峰学长的“Mean Shift概述”) Mean Shift这个概念最早是由Fukunaga等人于1975年在一篇关于概率密度梯度函数的估计(The Estimation of the Gradient of a Density Function, with Applications in Pattern Recognition )中提出来的,其最初含义正如其名,就是偏移的均值向量,在这里Mean Shift是一个名词,它指代的是一个向量,但随着Mean Shift理论的发展,Mean Shift的含义也发生了变化,如果我们说Mean Shift算法,一般是指一个迭代的步骤,即先算出当前点的偏移均值,移动该点到其偏移均值,然后以此为新的起始点,继续移动,直到满足一定的条件结束.
然而在以后的很长一段时间内Mean Shift并没有引起人们的注意,直到20年以后,也就是1995年,另外一篇关于Mean Shift的重要文献(Mean shift, mode seeking, and clustering )才发表.在这篇重要的文献中,Yizong Cheng对基本的Mean Shift算法在以下两个方面做了推广,首先Yizong Cheng定义了一族核函数,使得随着样本与被偏移点的距离不同,其偏移量对均值偏移向量的贡献也不同,其次Yizong Cheng还设定了一个权重系数,使得不同的样本点重要性不一样,这大大扩大了Mean Shift的适用范围.另外Yizong Cheng指出了Mean Shift可能应用的领域,并给出了具体的例子。
Comaniciu等人在还(Mean-shift Blob Tracking through Scale Space)中把非刚体的跟踪问题近似为一个Mean Shift最优化问题,使得跟踪可以实时的进行。目前,利用Mean Shift进行跟踪已经相当成熟。
目标跟踪不是一个新的问题,目前在计算机视觉领域内有不少人在研究。所谓跟踪,就是通过已知的图像帧中的目标位置找到目标在下一帧中的位置。
下面主要以代码形式展现Mean Shift在跟踪中的应用。
void CObjectTracker::ObjeckTrackerHandlerByUser(IplImage *frame)//跟踪函数
{
m_cActiveObject = 0;
if (m_sTrackingObjectTable[m_cActiveObject].Status)
{
if (!m_sTrackingObjectTable[m_cActiveObject].assignedAnObject)
{
FindHistogram(frame,m_sTrackingObjectTable[m_cActiveObject].initHistogram);
m_sTrackingObjectTable[m_cActiveObject].assignedAnObject = true;
}
else
{
FindNextLocation(frame);//利用mean shift 迭代找出目标下一个位置点
DrawObjectBox(frame);
}
}
}
void CObjectTracker::FindNextLocation(IplImage *frame)
{
int i, j, opti, optj;
SINT16 scale[3]={-3, 3, 0};
FLOAT32 dist, optdist;
SINT16 h, w, optX, optY;
//try no-scaling
FindNextFixScale(frame);//找出目标的下一个大致范围
optdist=LastDist;
optX=m_sTrackingObjectTable[m_cActiveObject].X;
optY=m_sTrackingObjectTable[m_cActiveObject].Y;
//try one of the 9 possible scaling
i=rand()*2/RAND_MAX;
j=rand()*2/RAND_MAX;
h=m_sTrackingObjectTable[m_cActiveObject].H;
w=m_sTrackingObjectTable[m_cActiveObject].W;
if(h+scale[i]>10 && w+scale[j]>10 && h+scale[i]<m_nImageHeight/2 && w+scale[j]<m_nImageWidth/2)
{
m_sTrackingObjectTable[m_cActiveObject].H=h+scale[i];
m_sTrackingObjectTable[m_cActiveObject].W=w+scale[j];
FindNextFixScale(frame);
if( (dist=LastDist) < optdist ) //scaling is better
{
optdist=dist;
// printf("Next%f->\n", dist);
}
else //no scaling is better
{
m_sTrackingObjectTable[m_cActiveObject].X=optX;
m_sTrackingObjectTable[m_cActiveObject].Y=optY;
m_sTrackingObjectTable[m_cActiveObject].H=h;
m_sTrackingObjectTable[m_cActiveObject].W=w;
}
};
TotalDist+=optdist; //the latest distance
// printf("\n");
}