61ic电子在线 首页 技术 图像技术 查看内容

KCF跟踪算法代码整理

2017-6-13 17:33| 发布者: 61ic| 查看: 635| 评论: 0|原作者: Hutu|来自: 61ic

摘要: KCF: Kernelized correlation filter
KCF: Kernelized correlation filter
KCF是一种鉴别式追踪方法,这类方法一般都是在追踪过程中训练一个目标检测器,使用目标检测器去检测下一帧预测位置是否是目标,然后再使用新检测结果去更新训练集进而更新目标检测器。而在训练目标检测器时一般选取目标区域为正样本,目标的周围区域为负样本,当然越靠近目标的区域为正样本的可能性越大。

论文:High-Speed Tracking with Kernelized Correlation Filters
算法源码:opencv_contribe/modules//tracking/tackerkcf.cpp
调用:参考../opencv_contrib/modules/tracking/samples/kcf.cpp
备注: opencv3.1.0与opencv_contrib配置参考http://blog.csdn.NET/jay463261929/article/details/53197228;

        我原本也打算写一篇关于KCF算法原理的认知的,最后还是打算放弃,因为我学习参考的博主都写的很不错,所以还是打算把代码贴出。。。。

算法调用
      调用很简单就2个函数,但是在调用之前你需要将opencv3.1.0与opencv_contrib配置好。第一个函数初始化:init(Mat frame, Rect2d roi),  //frame 为输入的彩色图,roi是要跟踪的目标区域,大小为刚好将目标框住就OK, Rect2就是Rect(x,y,w,h);
       第二个函数的目的是训练检测,因为该算法的原因就是先训练再检测,再训练再检测,这样不断循环:update(Mat frame, Rect2d result); //frame 为输入的彩色图, result是跟踪到目标的区域,大小跟初始化时roi的大小相等。 
    主要的头文件:
     #include <opencv2/core/utility.hpp> 
     #include <opencv2/tracking.hpp> 

     例子:
    // 创建一个跟踪对象
    Ptr<Tracker> tracker = Tracker::create( "KCF" );
    // 设置输入的视频
     VideoCapture cap(“ETH-Linthescher.mp4”);

     Mat frame;
     cap >> frame;
  
     //quit if ROI was not selected
     if(roi.width==0 || roi.height==0)
         return 0;

      // 初始化
      tracker->init(frame,roi);

       //开始跟踪
       printf("Start the tracking process, press ESC to quit.\n");
      for ( ;; )
     {
         // get frame from the video
         cap >> frame;

         // stop the program if no more images
         if(frame.rows==0 || frame.cols==0)
          break;

         // 更新跟踪结果
          tracker->update(frame,roi);

          // draw the tracked object
          rectangle( frame, roi, Scalar( 255, 0, 0 ), 2, 1 );

         // show image with the tracked object
         imshow("tracker",frame);

         //quit on ESC button
         if(waitKey(1)==27)break;
  }

    学习完KCF算法的调用,是不是感觉该算法其实很简单,就2个函数而已,那你就错了,那是因为主角还没登场。。。大家以热烈的掌声有请我们的主角闪亮登场吧!
      初始化:
       这是算法中初始化函数的定义:bool TrackerKCFImpl::initImpl(const Mat& /*image*/, const Rect2d& boundingBox ),细心的朋友会发现其实初始化跟输入的图像没关系。
      初始化完成了4个任务:
      1)目标区域填充;
      2)创建汉宁窗;
      3)生成一个高斯响应;
      4)对高斯响应求傅里叶变换。

      1)目标区域填充
       目的是将输入的目标区域扩大2倍,因为后面的所有工作就是在扩大后的区域内进行的。
       //params.resize = true (true表示图像可以缩放),  max_patch_size=80*80; 
      if(params.resize && roi.width*roi.height>params.max_patch_size)
      {
           resizeImage=true; // 如果为true,表示后面都是缩小一倍的图像进行处理,所有的框也跟着缩小一倍         
           roi.x/=2.0;
           roi.y/=2.0;
           roi.width/=2.0;
           roi.height/=2.0;
     }

    roi.x-=roi.width/2;
    roi.y-=roi.height/2;
    roi.width*=2;
    roi.height*=2;     
     由于跟踪的区域是固定的,所有摄像机要与目标保持固定的距离。

      2))创建汉宁窗
         目的是采样时为不同的样本分配不同的权重,kcf算法实际是采样了一个样本作为base样本,别的样本都是通过对base样本的平移得到,虚拟出来的样本。一般对样本都采用非正即负的方法来标记训练样本,即正样本标签为1,负样本为0。这样标记样本的方法不能很好的反应每个负样本的权重,即对离中心目标远的样本和离中心目标近的样本等同看待。但是在实际中我们需要对不同的负样本不同的看待,就有了根据样本中心离目标的远近分别赋值 [0,1]范数的数。离目标越近,值越趋向于1,离目标越远,值越趋向于0. kcf就是根据汉宁窗来对不同样本分配不同的权重。
   
       hann(i,j) = 0.25 * [1 - cos( (2*pi*i) / (w-1))] * [1 - cos( (2*pi*j) / (h-1))]; 
       //(i,j) 是位置,(w,h)是创建汉宁窗的大小,0.25是为了归一化到[0,1],  hann(i,j) 的值就是每样样本的权重。
      函数是: createHanningWindow(hann, roi.size(), CV_64F);
       


       3)生成一个高斯响应
       //计算高斯函数的均方差
       output_sigma=sqrt(roi.width*roi.height)*params.output_sigma_factor;  //params.output_sigma_factor=1.0/16.0
       output_sigma=-0.5/(output_sigma*output_sigma);   //a=-1/(2*a^2)

       y(i,j) = exp(output_sigma × [ (i-w/2+1)^2 + (j-h/2+1)^2])
       //(i,j) 是位置,(w,h)是窗口大小,y(i,j) 的值就是每个样本的实际响应值。
      4)高斯响应的傅里叶变换
        fft2(y,yf);  //yf 是高斯响应的傅里叶变换

      训练:
     1)特征提取:在这个函数getSubWindow()完成,提取特征为彩色+灰度;彩色特征存放在这features_npca,灰度特征存放在features_pca。
     提取灰度特征:
       Mat  feat = frame(roi); //w*h*1
       feat=feat/255.0-0.5; // normalize to range -0.5 .. 0.5
       feat=feat.mul(hann); // hann window filter
      X[1] = feat; //w*h*1
     提取彩色特征:
     Mat patch= frame(roi); //w*h*3 
       extractCN(patch, feat); // feat  w*h*10, 该算法是将颜色划分的更细,内容在featureColorName.cpp
      feat=feat.mul(hann_cn); // hann window filter
     X[0] = feat; //w*h*10
     2)  将彩色特征feat(w*h*10)进行pca主成分分析,其实就是压缩,默认的参数设置压缩大小compress_size=2,压缩后彩色特征X[0]就变成w*h*2

    检测:
  1. 先提取特征;
  2.  // extract the maximum response
      minMaxLoc( response, &minVal, &maxVal, &minLoc, &maxLoc ); //maxLoc的位置代表跟踪到目标的中心点
      roi.x+=(maxLoc.x-roi.width/2+1);
      roi.y+=(maxLoc.y-roi.height/2+1); //跟踪结果,目标大小是固定的 
   
备注:
1. KCF跟踪算法是不带识别的,也不需要特定哪一类物体;
2.测试opencv_contrib带的KCF跟踪算法(灰色+彩色特征)与github中作者给出的hog特征,前者效果比较好,但是论文中给出后者效果好。


鲜花

握手

雷人

路过

鸡蛋

地址 :湖南省株洲市天元区利江花园
合作 Email: administration@61ic.com

  • 关注61ic官方微博
    了解最新动态

  • 关注61ic微信公众号
    这里有好玩的讯息

  • 加入61ic交流群
    不断在这里成长

© 2014-2017 HuNan 湖南索炜达电子科技有限公司 . All rights reserved.
湘公网安备 43020202000020号

Archiver|手机版|小黑屋||湘ICP备13001086号-2 QQ 
返回顶部