您的位置:首页 > 编程语言 > C语言/C++

TLD源码理解 run_tld.cpp

2014-04-24 17:34 267 查看
TLD 全名为tracking-learning-detection 是有英国萨里大学的一位博士提出,据说效果不错,所以想开始研究一下tlc的源码和具体的实现过程(未完待续)

#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 variables
Rect box;
bool drawing_box = false;
bool gotBB = false;
bool tl = false;
bool rep = false;
bool fromfile=false;
string video;
//读入初始化文件,初始化文件确定初始的跟踪目标框
void readBB(char* file){
  ifstream bb_file (file);  //以输入方式打开文件
  string line;  
  getline(bb_file,line);//将行读入字符串 默认终止符为\n
  istringstream linestream(line);//istringstream 创建一个对象,这个对象绑定一个行字符串,以空格为分隔符把该行分隔开来
  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"];//string.c_str将string转换为constan char* 因为atoi是c的库函数调用的参数是constant char*类型
  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
void 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");

}

//分析运行的命令行参数

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]);//是否指定初始化bounding_box

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);//读取参数文件parameters.yml

}

else

print_help(argv);

}

if (strcmp(argv[i],"-tl")==0){ //

tl = true;

}

if (strcmp(argv[i],"-r")==0){ //

rep = true;

}

}

/*

%To run from camera
./run_tld -p ../parameters.yml
%To run from file
./run_tld -p ../parameters.yml -s ../datasets/06_car/car.mpg
%To init bounding box from file
./run_tld -p ../parameters.yml -s ../datasets/06_car/car.mpg -b ../datasets/06_car/init.txt
%To train only in the firs frame (no tracking, no learning)
./run_tld -p ../parameters.yml -s ../datasets/06_car/car.mpg -b ../datasets/06_car/init.txt -no_tl 
%To test the final detector (Repeat the video, first time learns, second time detects)
./run_tld -p ../parameters.yml -s ../datasets/06_car/car.mpg -b ../datasets/06_car/init.txt -r
*/


int main(int argc, char * argv[]){
  VideoCapture capture;
  capture.open(0);
  FileStorage fs;
  //Read options
  read_options(argc,argv,capture,fs);
  //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());
  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);
  }

  ///Initialization
GETBOUNDINGBOX://获取bounding box
  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;
  }
//bounding必须要大于一定大小,以便对图片进行采样
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 );//如果已经获得第一帧的bounding box 则取消鼠标相应
  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");//输出数据到bounding_boxes.txt
  //TLD initialization
  tld.init(last_gray,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);
    //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);
    if (cvWaitKey(33) == 'q')
      break;
  }
  if (rep){
    rep = false;
    tl = false;
    fclose(bb_file);
    bb_file = fopen("final_detector.txt","w");
    //capture.set(CV_CAP_PROP_POS_***I_RATIO,0);
    capture.release();
    capture.open(video);
    goto REPEAT;
  }
  fclose(bb_file);
  return 0;
}





                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: