TLD(Tracking-Learning-Detection)算法学习与源码解析(二)之runtld.cpp源码解析

来源:互联网 发布:阿里云建立个人网站 编辑:程序博客网 时间:2024/06/05 10:54

         本序列文章的目的是总结一下这段时间所学到的,主要分为以下几部分,本章是第二部分。

算法概述

2 runtld.cpp源码解析

3 tld.cpp源码解析

4 LKTracker(重点)

5 FerNNClassifier.cpp源码解析(重点)

6 tld_utils.cpp源码解析


 runtld.cpp这个是main函数所在的文件,其实没什么好看的,就是一个框。知道下面这些就可以了:

程序从parameters.yml文件读取一些初始化参数(一些阈值什么的),

绑定鼠标事件(用户需要用鼠标画一个矩形来标志目标窗口),

每次从摄像头读取一帧图片,

然后通过tld算法预测和处理该图片,把目标窗口画出来,

处理过后,显示该图像。


#include <opencv2/opencv.hpp>#include <tld_utils.h>#include <iostream>#include <sstream>#include <TLD.h>#include <stdio.h>using namespace cv;using namespace std;//Global variablesRect box;bool drawing_box = false;bool gotBB = false;bool tl = true;bool rep = false;bool fromfile=false;string video;/** * 从一个文件中读出两个点的坐标,然后由这两点组成的box(矩形) */void readBB(char* file){  ifstream bb_file (file);  string line;  getline(bb_file,line);  istringstream linestream(line);  string x1,y1,x2,y2;  getline (linestream,x1, ',');  getline (linestream,y1, ',');  getline (linestream,x2, ',');  getline (linestream,y2, ',');  int x = atoi(x1.c_str());// = (int)file["bb_x"];  int y = atoi(y1.c_str());// = (int)file["bb_y"];  int w = atoi(x2.c_str())-x;// = (int)file["bb_w"];  int h = atoi(y2.c_str())-y;// = (int)file["bb_h"];  box = Rect(x,y,w,h);}/** *绑定鼠标事件 *///bounding box mouse callbackvoid mouseHandler(int event, int x, int y, int flags, void *param){  switch( event ){  case CV_EVENT_MOUSEMOVE:    if (drawing_box){        box.width = x-box.x;        box.height = y-box.y;    }    break;  case CV_EVENT_LBUTTONDOWN:    drawing_box = true;    box = Rect( x, y, 0, 0 );    break;  case CV_EVENT_LBUTTONUP:    drawing_box = false;    if( box.width < 0 ){        box.x += box.width;        box.width *= -1;    }    if( box.height < 0 ){        box.y += box.height;        box.height *= -1;    }    gotBB = true;    break;  }}void print_help(char** argv){  printf("use:\n     %s -p /path/parameters.yml\n",argv[0]);  printf("-s    source video\n-b        bounding box file\n-tl  track and learn\n-r     repeat\n");}/** * 解析命令行参数,该执行文件由很多种传参方式 * 其实只需要理解从parameters.yml读入参数就可以了 */void read_options(int argc, char** argv,VideoCapture& capture,FileStorage &fs){  for (int i=0;i<argc;i++){      if (strcmp(argv[i],"-b")==0){          if (argc>i){              readBB(argv[i+1]);              gotBB = true;          }          else            print_help(argv);      }      if (strcmp(argv[i],"-s")==0){          if (argc>i){              video = string(argv[i+1]);              capture.open(video);              fromfile = true;          }          else            print_help(argv);      }      if (strcmp(argv[i],"-p")==0){          if (argc>i){              fs.open(argv[i+1], FileStorage::READ);          }          else            print_help(argv);      }      if (strcmp(argv[i],"-no_tl")==0){          tl = false;      }      if (strcmp(argv[i],"-r")==0){          rep = true;      }  }}int main(int argc, char * argv[]){  VideoCapture capture;  capture.open(0);  FileStorage fs;  //Read options  read_options(argc,argv,capture,fs);//读参数  //fs.open("parameters.yml", FileStorage::READ);  //Init camera摄像头初始化  if (!capture.isOpened())  {cout << "capture device failed to open!" << endl;    return 1;  }  //Register mouse callback to draw the bounding box  cvNamedWindow("TLD",CV_WINDOW_AUTOSIZE);  cvSetMouseCallback( "TLD", mouseHandler, NULL );  //TLD framework  TLD tld;  //Read parameters file  tld.read(fs.getFirstTopLevelNode());//把文件中的相关参数传到tld对象中  Mat frame;  Mat last_gray;  Mat first;  if (fromfile){      capture >> frame;      cvtColor(frame, last_gray, CV_RGB2GRAY);      frame.copyTo(first);  }else{      capture.set(CV_CAP_PROP_FRAME_WIDTH,340);      capture.set(CV_CAP_PROP_FRAME_HEIGHT,240);  }  ///InitializationGETBOUNDINGBOX:  while(!gotBB)  {    if (!fromfile){      capture >> frame;    }    else      first.copyTo(frame);    cvtColor(frame, last_gray, CV_RGB2GRAY);    drawBox(frame,box);    imshow("TLD", frame);    if (cvWaitKey(33) == 'q')    return 0;  }  if (min(box.width,box.height)<(int)fs.getFirstTopLevelNode()["min_win"]){      cout << "Bounding box too small, try again." << endl;      gotBB = false;      goto GETBOUNDINGBOX;  }  //Remove callback  cvSetMouseCallback( "TLD", NULL, NULL );  printf("Initial Bounding Box = x:%d y:%d h:%d w:%d\n",box.x,box.y,box.width,box.height);  //Output file  FILE  *bb_file = fopen("bounding_boxes.txt","w");  //TLD initialization  tld.init(last_gray,box,bb_file);//tld初始化,参数为一个图像patch,目标box,保存box信息到bb_file  ///Run-time  Mat current_gray;  BoundingBox pbox;  vector<Point2f> pts1;  vector<Point2f> pts2;  bool status=true;  int frames = 1;  int detections = 1;REPEAT:  while(capture.read(frame)){//每读出一帧    //get frame    cvtColor(frame, current_gray, CV_RGB2GRAY);    //Process Frame    tld.processFrame(last_gray,current_gray,pts1,pts2,pbox,status,tl,bb_file);//用tld算法处理这一帧图像    //Draw Points    if (status){      drawPoints(frame,pts1);      drawPoints(frame,pts2,Scalar(0,255,0));      drawBox(frame,pbox);      detections++;    }    //Display显示被处理过后图像    imshow("TLD", frame);    //swap points and images    swap(last_gray,current_gray);    pts1.clear();    pts2.clear();    frames++;    printf("Detection rate: %d/%d\n",detections,frames);    char ch = cvWaitKey(33);    if ( ch== 'q')      break;  }  if (rep){    rep = false;    tl = false;    fclose(bb_file);    bb_file = fopen("final_detector.txt","w");    //capture.set(CV_CAP_PROP_POS_AVI_RATIO,0);    capture.release();    capture.open(video);    goto REPEAT;  }  fclose(bb_file);  return 0;}



注:

原作者是用matlab实现的,我分析的源码是其他大神用c++和opencv实现的,源码可以从

https://github.com/arthurv/OpenTLD或者https://github.com/alantrrs/OpenTLD下载

本序列参考了zouxy09同学的序列文章,在此表示感谢

http://blog.csdn.net/zouxy09/article/details/7893011




2 0