首先,关于论文 基于Camshift 和Kalman 滤波的仿人机器人手势跟踪 的学习笔记:
基于颜色跟踪的Camshif t (Continuously Adaptive Mean Shif t ) 算法
Camshif t 算法流程图:
http://www.cnblogs.com/tiandsp/archive/2012/11/22/2782500.html
做meanshift物体跟踪的时候中间有一步叫做直方图反向投影,所以我就先实现了这样一个步骤。
直方图反向投影说白了就是模板匹配,给定一个较小的目标模板,然后再逐个遍历原图像和模板图像相同的图像块的,对比图像块和模板的直方图,然后把比较结果存入一个新的图像中,新图像中的全局极值就是模板在原图像中所在的位置。这里主要麻烦的是怎么比较两个图像块的直方图,Opencv中实现了5种对比的方法,所以我在这里也对应的实现了5种方法。
5种方法分别是correl(相关)、chisqr(卡方)、intersect(相交)、bhattacharyya、emd(earth mover’s distance)。
参考资料:
https://en.wikipedia.org/wiki/Kernel_density_estimation
http://blog.youkuaiyun.com/yuanxing14/article/details/41948485
Mean Shift algorithm is a non-parametric density estimation algorithm. It was used in object tracking recently years, and the effect was well.
Mean Shift算法是一种非参数的密度梯度估计算法,近年来将其运用到目标跟踪上,并取得了较好的跟踪效果。
Non-parametric Density GRADIENT Estimation
(Mean Shift)
gradient英 [‘greɪdɪənt]美 [‘ɡredɪənt] n. [数][物] 梯度;坡度;倾斜度
无参数密度估计
给定任意一组观测数据或数据采样值,估计出样本的分布。
无参数密度估计,它对数据分布规律没有附加任何假设,而是直接从数据样本本身出发研究数据分布特征,对先验知识要求最少,完全依靠训练数据进行估计,而且能处理任意的概率分布。
例如:直方图法,最近邻域法,核密度估计方法。
有参数密度估计:高斯统计模型。
http://www.guokr.com/question/395017/
将三维向量映射为一维:(R,G,B)== 256*R+16*G+B
核函数是一种权值函数,其作用是将每个样本点按到中心clip_image009[13]点距离的远近进行加权,距离中心点近的样本点概率密度估计影响大,赋予大的权值,反之,赋予小的权值。
对密度函数求导,分析梯度变化
代码:鼠标选取跟踪区域
void onMouse( int event, int x, int y, int flags, void *param )
{
if (pause)
{
switch(event)
{
case CV_EVENT_LBUTTONDOWN:
//the left up point of the rect
drawing_box.x=x;
drawing_box.y=y;
break;
case CV_EVENT_LBUTTONUP:
//finish drawing the rect (use color green for finish)
drawing_box.width=x-drawing_box.x;
drawing_box.height=y-drawing_box.y;
cvRectangle(current,cvPoint(drawing_box.x,drawing_box.y),cvPoint(drawing_box.x+drawing_box.width,drawing_box.y+drawing_box.height),CV_RGB(255,0,0),2);
cvShowImage("Meanshift",current);
//目标初始化
hist1 = (double *)malloc(sizeof(double)*16*16*16);
m_wei = (double *)malloc(sizeof(double)*drawing_box.height*drawing_box.width);
init_target(hist1, m_wei, current);
is_tracking = true;
break;
}
return;
}
}
//全局变量
bool pause = false;
bool is_tracking = false;
CvRect drawing_box;
IplImage *current;
double *hist1, *hist2;
double *m_wei; //权值矩阵
double C = 0.0; //归一化系数
void init_target(double *hist1, double *m_wei, IplImage *current)
{
IplImage *pic_hist = 0;
int t_h, t_w, t_x, t_y;
double h, dist;
int i, j;
int q_r, q_g, q_b, q_temp;
t_h = drawing_box.height;
t_w = drawing_box.width;
t_x = drawing_box.x;
t_y = drawing_box.y;
h = pow(((double)t_w)/2,2) + pow(((double)t_h)/2,2); //带宽
pic_hist = cvCreateImage(cvSize(300,200),IPL_DEPTH_8U,3); //生成直方图图像
//初始化权值矩阵和目标直方图
for (i = 0;i < t_w*t_h;i++)
{
m_wei[i] = 0.0;
}
for (i=0;i<4096;i++)
{
hist1[i] = 0.0;
}
for (i = 0;i < t_h; i++)
{
for (j = 0;j < t_w; j++)
{
dist = pow(i - (double)t_h/2,2) + pow(j - (double)t_w/2,2);
m_wei[i * t_w + j] = 1 - dist / h;
//printf("%f\n",m_wei[i * t_w + j]);
C += m_wei[i * t_w + j] ;
}
}
//计算目标权值直方
for (i = t_y;i < t_y + t_h; i++)
{
for (j = t_x;j < t_x + t_w; j++)
{
//rgb颜色空间量化为16*16*16 bins
q_r = ((u_char)current->imageData[i * current->widthStep + j * 3 + 2]) / 16;
q_g = ((u_char)current->imageData[i * current->widthStep + j * 3 + 1]) / 16;
q_b = ((u_char)current->imageData[i * current->widthStep + j * 3 + 0]) / 16;
q_temp = q_r * 256 + q_g * 16 + q_b;
hist1[q_temp] = hist1[q_temp] + m_wei[(i - t_y) * t_w + (j - t_x)] ;
}
}
//归一化直方图
for (i=0;i<4096;i++)
{
hist1[i] = hist1[i] / C;
//printf("%f\n",hist1[i]);
}
//生成目标直方图
double temp_max=0.0;
for (i = 0;i < 4096;i++) //求直方图最大值,为了归一化
{
//printf("%f\n",val_hist[i]);
if (temp_max < hist1[i])
{
temp_max = hist1[i];
}
}
//画直方图
CvPoint p1,p2;
double bin_width=(double)pic_hist->width/4096;
double bin_unith=(double)pic_hist->height/temp_max;
for (i = 0;i < 4096; i++)
{
p1.x = i * bin_width;
p1.y = pic_hist->height;
p2.x = (i + 1)*bin_width;
p2.y = pic_hist->height - hist1[i] * bin_unith;
//printf("%d,%d,%d,%d\n",p1.x,p1.y,p2.x,p2.y);
cvRectangle(pic_hist,p1,p2,cvScalar(0,255,0),-1,8,0);
}
cvSaveImage("hist1.jpg",pic_hist);
cvReleaseImage(&pic_hist);
}
参考论文:
基于Camshift 和Kalman 滤波的仿人机器人手势跟踪
Mean ShiftTheory and Applications Yaron Ukrainitz & Bernard Sarel
MeanShift知识整理 http://blog.youkuaiyun.com/anymake_ren/article/details/25484059
https://en.wikipedia.org/wiki/Kernel_density_estimation
http://blog.youkuaiyun.com/yuanxing14/article/details/41948485
http://www.cnblogs.com/tiandsp/archive/2012/11/22/2782500.html
http://www.guokr.com/question/395017/
基于核函数的目标跟踪算法(上)
http://blog.youkuaiyun.com/yuanxing14/article/details/41971101