TLD(Tracking-Learning-Detection)算法学习与源码解析(二)之runtld.cpp源码解析
来源:互联网 发布:阿里云建立个人网站 编辑:程序博客网 时间:2024/06/05 10:54
本序列文章的目的是总结一下这段时间所学到的,主要分为以下几部分,本章是第二部分。
1 算法概述
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
- TLD(Tracking-Learning-Detection)算法学习与源码解析(二)之runtld.cpp源码解析
- TLD(Tracking-Learning-Detection)算法学习与源码解析(三)之 tld.cpp源码解析
- TLD(Tracking-Learning-Detection)算法学习与源码解析(五)之FerNNClassifier.cpp源码解析
- TLD(Tracking-Learning-Detection)算法学习与源码解析(四)之LKTracker源码分析
- TLD(Tracking-Learning-Detection)算法学习与源码解析(一)之算法概述
- TLD(Tracking-Learning-Detection)学习与源码理解之
- TLD(Tracking-Learning-Detection)学习与源码理解之
- TLD(Tracking-Learning-Detection)学习与源码理解之(二)
- TLD(Tracking-Learning-Detection)学习与源码理解之(二)
- TLD(Tracking-Learning-Detection)学习与源码理解之(二)
- TLD(Tracking-Learning-Detection)学习与源码理解之(二)
- TLD(Tracking Learning Detection)算法解析
- TLD参考--TLD(Tracking-Learning-Detection)学习与源码理解之(一)
- 【Android】TLD(Tracking-Learning-Detection)学习与源码理解
- TLD(Tracking-Learning-Detection)学习与源码理解之(学习器)
- TLD(Tracking-Learning-Detection)学习与源码理解之(三) (转自zouxy09)
- TLD(Tracking-Learning-Detection)学习与源码理解之(一)
- TLD(Tracking-Learning-Detection)学习与源码理解之(三)
- Android系统手机端抓包方法
- Sicily 1443. Printer Queue
- c语言引用
- PostgreSQL允许远程访问设置方法
- 电子元件资料里管脚的"active low","active high"是什么意思?
- TLD(Tracking-Learning-Detection)算法学习与源码解析(二)之runtld.cpp源码解析
- 利用Google API 进行IP地址定位
- 判断输入的各个数字是奇数还是偶数
- Implementing In-app Billing(转)
- grails hasMany一对多HQL查询问题
- 腾讯、百度、网易游戏、华为Offer及笔经面经
- js原型
- 转载:hive parser
- 给定一个字符串输出其全部排列的方法