Camshift文献学习与研究

首先,关于论文 基于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.csdn.net/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.csdn.net/anymake_ren/article/details/25484059
https://en.wikipedia.org/wiki/Kernel_density_estimation
http://blog.csdn.net/yuanxing14/article/details/41948485
http://www.cnblogs.com/tiandsp/archive/2012/11/22/2782500.html
http://www.guokr.com/question/395017/
基于核函数的目标跟踪算法(上)
http://blog.csdn.net/yuanxing14/article/details/41971101

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值