当前位置: 首页>后端>正文

opencv 物体跟踪 opencv kcf跟踪

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配置参考;

我原本也打算写一篇关于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)对高斯响应求傅里叶变换。

目标区域填充
所有工作就是在扩大后的区域内进行的。
//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;          由于跟踪的区域是固定的,所有摄像机要与目标保持固定的距离。

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

      

opencv 物体跟踪 opencv kcf跟踪,opencv 物体跟踪 opencv kcf跟踪_opencv 物体跟踪,第1张

生成一个高斯响应

      

//计算高斯函数的均方差
        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,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);
       
 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特征,前者效果比较好,但是论文中给出后者效果好。

参考:

http://www.jianshu.com/p/9aacd075a689

http://www.360doc.com/content/16/0302/13/25664332_538789414.shtml


     


https://www.xamrdz.com/backend/3hv1938758.html

相关文章: