博客:http://blog.csdn.net/qianxin_dh
邮箱:qianxin_dh@163.com
本人水平有限,代码理解难免有不正确的地方,希望大家能够见谅。
main.cpp
/*
* Struck: Structured Output Tracking with Kernels
*
* Code to accompany the paper:
* Struck: Structured Output Tracking with Kernels
* Sam Hare, Amir Saffari, Philip H. S. Torr
* International Conference on Computer Vision (ICCV), 2011
*
* Copyright (C) 2011 Sam Hare, Oxford Brookes University, Oxford, UK
*
* This file is part of Struck.
*
* Struck is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Struck is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Struck. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "Tracker.h"
#include "Config.h"
#include <iostream>
#include <fstream>
#include <opencv/cv.h>
#include <opencv/highgui.h>
#include "vot.hpp"
using namespace std;
using namespace cv;
static const int kLiveBoxWidth = 80;
static const int kLiveBoxHeight = 80;
void rectangle(Mat& rMat, const FloatRect& rRect, const Scalar& rColour)
{
IntRect r(rRect);
rectangle(rMat, Point(r.XMin(), r.YMin()), Point(r.XMax(), r.YMax()), rColour);
}
int main(int argc, char* argv[])
{
// 读取文件对程序参数进行初始化
string configPath = "config.txt";
if (argc > 1)
{
configPath = argv[1];
}
Config conf(configPath); //Config类主要读取config.txt中的参数
if (conf.features.size() == 0)
{
cout << "error: no features specified in config" << endl;
return EXIT_FAILURE;
}
Tracker tracker(conf);
//Check if --challenge was passed as an argument
bool challengeMode = false;
for (int i = 1; i < argc; i++) {
if (strcmp("--challenge", argv[i]) == 0) { //判断是否有挑战模式(vot挑战)
challengeMode = true;
}
}
if (challengeMode) { //VOT(Visual object tracking)挑战,它提供了一个公共平台,目标是比较各种跟踪算法再短期跟踪内的性能,讨论视觉跟踪领域的发展。
//load region, images and prepare for output
Mat frameOrig;
Mat frame;
VOT vot_io("region.txt", "images.txt", "output.txt");
vot_io.getNextImage(frameOrig);
resize(frameOrig, frame, Size(conf.frameWidth, conf.frameHeight));
cv::Rect initPos = vot_io.getInitRectangle();
vot_io.outputBoundingBox(initPos);
float scaleW = (float)conf.frameWidth/frameOrig.cols;
float scaleH = (float)conf.frameHeight/frameOrig.rows;
FloatRect initBB_vot = FloatRect(initPos.x*scaleW, initPos.y*scaleH, initPos.width*scaleW, initPos.height*scaleH);
tracker.Initialise(frame, initBB_vot);
while (vot_io.getNextImage(frameOrig) == 1){
resize(frameOrig, frame, Size(conf.frameWidth, conf.frameHeight));
tracker.Track(frame);
const FloatRect& bb = tracker.GetBB();
float x = bb.XMin()/scaleW;
float y = bb.YMin()/scaleH;
float w = bb.Width()/scaleW;
float h = bb.Height()/scaleH;
cv::Rect output = cv::Rect(x,y,w,h);
vot_io.outputBoundingBox(output);
}
return 0;
}
ofstream outFile;
if (conf.resultsPath != "")
{
outFile.open(conf.resultsPath.c_str(), ios::out); //将程序写入resultpath
if (!outFile)
{
cout << "error: could not open results file: " << conf.resultsPath << endl;
return EXIT_FAILURE;
}
}
// if no sequence specified then use the camera
bool useCamera = (conf.sequenceName == "");
VideoCapture cap;
int startFrame = -1;
int endFrame = -1;
FloatRect initBB;
string imgFormat;
float scaleW = 1.f;
float scaleH = 1.f;
if (useCamera)
{
if (!cap.open(0))
{
cout << "error: could not start camera capture" << endl;
return EXIT_FAILURE;
}
startFrame = 0;
endFrame = INT_MAX; /* maximum (signed) int value */
Mat tmp;
cap >> tmp;
scaleW = (float)conf.frameWidth/tmp.cols;
scaleH = (float)conf.frameHeight/tmp.rows;
initBB = IntRect(conf.frameWidth/2-kLiveBoxWidth/2, conf.frameHeight/2-kLiveBoxHeight/2, kLiveBoxWidth, kLiveBoxHeight);
cout << "press 'i' to initialise tracker" << endl;
}
else
{
// parse frames file
string framesFilePath = conf.sequenceBasePath+"/"+conf.sequenceName+"/"+conf.sequenceName+"_frames.txt"; //girl_frames.txt的文件路径,该文件放在girl文件夹里,内容为0,501。
ifstream framesFile(framesFilePath.c_str(), ios::in);
if (!framesFile)
{
cout << "error: could not open sequence frames file: " << framesFilePath << endl;
return EXIT_FAILURE;
}
string framesLine;
getline(framesFile, framesLine);
sscanf(framesLine.c_str(), "%d,%d", &startFrame, &endFrame); //startFrame=0;endFrame=501;
if (framesFile.fail() || startFrame == -1 || endFrame == -1)
{
cout << "error: could not parse sequence frames file" << endl;
return EXIT_FAILURE;
}
imgFormat = conf.sequenceBasePath+"/"+conf.sequenceName+"/imgs/img%05d.png";
// read first frame to get size
char imgPath[256];
sprintf(imgPath, imgFormat.c_str(), startFrame); //sprintf把格式化的数据写入某个字符串缓冲区(imgPath);
Mat tmp = cv::imread(imgPath, 0);
scaleW = (float)conf.frameWidth/tmp.cols; //=1;
scaleH = (float)conf.frameHeight/tmp.rows; //=1;
// read init box from ground truth file
string gtFilePath =