Commit bf0c8712 authored by Vadim Pisarevsky's avatar Vadim Pisarevsky

Merge pull request #341 from Auron-X:TLD/VOT2015_Datasets_Support

parents d255138c 1db7b6e6
...@@ -477,6 +477,27 @@ To run benchmark execute: ...@@ -477,6 +477,27 @@ To run benchmark execute:
./opencv/build/bin/example_datasets_tr_svt_benchmark -p=/home/user/path_to_unpacked_folders/svt/svt1/ ./opencv/build/bin/example_datasets_tr_svt_benchmark -p=/home/user/path_to_unpacked_folders/svt/svt1/
~~~ ~~~
@defgroup datasets_track Tracking
### VOT 2015 Database
Implements loading dataset:
"VOT 2015 dataset comprises 60 short sequences showing various objects in challenging backgrounds.
The sequences were chosen from a large pool of sequences including the ALOV dataset, OTB2 dataset,
non-tracking datasets, Computer Vision Online, Professor Bob Fisher’s Image Database, Videezy,
Center for Research in Computer Vision, University of Central Florida, USA, NYU Center for Genomics
and Systems Biology, Data Wrangling, Open Access Directory and Learning and Recognition in Vision
Group, INRIA, France. The VOT sequence selection protocol was applied to obtain a representative
set of challenging sequences.": <http://box.vicos.si/vot/vot2015.zip>
Usage:
-# From link above download dataset file: `vot2015.zip`
-# Unpack `vot2015.zip` into folder: `VOT2015/`
-# To load data run:
~~~
./opencv/build/bin/example_datasets_track_vot -p=/home/user/path_to_unpacked_files/VOT2015/
~~~
@} @}
*/ */
......
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2014, Itseez Inc, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Itseez Inc or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#ifndef OPENCV_DATASETS_TRACK_VOT_HPP
#define OPENCV_DATASETS_TRACK_VOT_HPP
#include <string>
#include <vector>
#include "opencv2/datasets/dataset.hpp"
#include "opencv2/datasets/util.hpp"
using namespace std;
namespace cv
{
namespace datasets
{
//! @addtogroup datasets_track
//! @{
struct TRACK_votObj : public Object
{
int id;
std::string imagePath;
vector <Point2d> gtbb;
};
class CV_EXPORTS TRACK_vot : public Dataset
{
public:
static Ptr<TRACK_vot> create();
virtual void load(const std::string &path) = 0;
virtual int getDatasetsNum() = 0;
virtual int getDatasetLength(int id) = 0;
virtual bool initDataset(int id) = 0;
virtual bool getNextFrame(Mat &frame) = 0;
virtual vector <Point2d> getGT() = 0;
protected:
vector <vector <Ptr<TRACK_votObj> > > data;
int activeDatasetID;
int frameCounter;
};
//! @}
}
}
#endif
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2014, Itseez Inc, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Itseez Inc or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "opencv2/datasets/track_vot.hpp"
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <cstdio>
#include <cstdlib>
#include <string>
#include <vector>
#include <set>
using namespace std;
using namespace cv;
using namespace cv::datasets;
int main(int argc, char *argv[])
{
const char *keys =
"{ help h usage ? | | show this message }"
"{ path p |true| path to folder with dataset }"
"{ datasetID id |1| Dataset ID}";
CommandLineParser parser(argc, argv, keys);
string path(parser.get<string>("path"));
int datasetID(parser.get<int>("datasetID"));
if (parser.has("help") || path == "true")
{
parser.printMessage();
getchar();
return -1;
}
Ptr<TRACK_vot> dataset = TRACK_vot::create();
dataset->load(path);
printf("Datasets number: %d\n", dataset->getDatasetsNum());
for (int i = 1; i <= dataset->getDatasetsNum(); i++)
printf("\tDataset #%d size: %d\n", i, dataset->getDatasetLength(i));
dataset->initDataset(datasetID);
for (int i = 0; i < dataset->getDatasetLength(datasetID); i++)
{
Mat frame;
if (!dataset->getNextFrame(frame))
break;
//Draw Ground Truth BB
vector <Point2d> gtPoints = dataset->getGT();
for (int j = 0; j < (int)(gtPoints.size()-1); j++)
line(frame, gtPoints[j], gtPoints[j + 1], Scalar(0, 255, 0), 2);
line(frame, gtPoints[0], gtPoints[(int)(gtPoints.size()-1)], Scalar(0, 255, 0), 2);
imshow("VOT 2015 DATASET TEST...", frame);
waitKey(100);
}
getchar();
return 0;
}
\ No newline at end of file
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2014, Itseez Inc, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Itseez Inc or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "opencv2/datasets/track_vot.hpp"
#include <sys/stat.h>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
using namespace std;
namespace cv
{
namespace datasets
{
class TRACK_votImpl : public TRACK_vot
{
public:
//Constructor
TRACK_votImpl()
{
activeDatasetID = 1;
frameCounter = 0;
}
//Destructor
virtual ~TRACK_votImpl() {}
//Load Dataset
virtual void load(const string &path);
protected:
virtual int getDatasetsNum();
virtual int getDatasetLength(int id);
virtual bool initDataset(int id);
virtual bool getNextFrame(Mat &frame);
virtual vector <Point2d> getGT();
void loadDataset(const string &path);
string numberToString(int number);
};
void TRACK_votImpl::load(const string &path)
{
loadDataset(path);
}
string TRACK_votImpl::numberToString(int number)
{
string out;
char numberStr[9];
sprintf(numberStr, "%u", number);
for (unsigned int i = 0; i < 8 - strlen(numberStr); ++i)
{
out += "0";
}
out += numberStr;
return out;
}
inline bool fileExists(const std::string& name)
{
struct stat buffer;
return (stat(name.c_str(), &buffer) == 0);
}
void TRACK_votImpl::loadDataset(const string &rootPath)
{
string nameListPath = rootPath + "/list.txt";
ifstream namesList(nameListPath.c_str());
vector <int> datasetsLengths;
string datasetName;
if (namesList.is_open())
{
int currDatasetID = 0;
//All datasets/folders loop
while (getline(namesList, datasetName))
{
currDatasetID++;
vector <Ptr<TRACK_votObj> > objects;
//All frames/images loop
Ptr<TRACK_votObj> currDataset(new TRACK_votObj);
//Open dataset's ground truth file
string gtListPath = rootPath + "/" + datasetName + "/groundtruth.txt";
ifstream gtList(gtListPath.c_str());
if (!gtList.is_open())
printf("Error to open groundtruth.txt!!!");
//Make a list of datasets lengths
int currFrameID = 1;
if (currDatasetID == 0)
printf("VOT 2015 Dataset Initialization...\n");
bool trFLG = true;
do
{
currFrameID++;
string fullPath = rootPath + "/" + datasetName + "/" + numberToString(currFrameID) + ".jpg";
if (!fileExists(fullPath))
break;
//Make VOT Object
Ptr<TRACK_votObj> currObj(new TRACK_votObj);
currObj->imagePath = fullPath;
currObj->id = currFrameID;
//Get Ground Truth data
double x1 = 0, y1 = 0,
x2 = 0, y2 = 0,
x3 = 0, y3 = 0,
x4 = 0, y4 = 0;
string tmp;
getline(gtList, tmp);
sscanf(tmp.c_str(), "%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf", &x1, &y1, &x2, &y2, &x3, &y3, &x4, &y4);
currObj->gtbb.push_back(Point2d(x1, y1));
currObj->gtbb.push_back(Point2d(x2, y2));
currObj->gtbb.push_back(Point2d(x3, y3));
currObj->gtbb.push_back(Point2d(x4, y4));
//Add object to storage
objects.push_back(currObj);
} while (trFLG);
datasetsLengths.push_back(currFrameID - 1);
data.push_back(objects);
}
}
else
{
printf("Couldn't find a *list.txt* in VOT 2015 folder!!!");
}
namesList.close();
return;
}
int TRACK_votImpl::getDatasetsNum()
{
return (int)(data.size());
}
int TRACK_votImpl::getDatasetLength(int id)
{
if (id > 0 && id <= (int)data.size())
return (int)(data[id - 1].size());
else
{
printf("Dataset ID is out of range...\nAllowed IDs are: 1~%d\n", (int)data.size());
return -1;
}
}
bool TRACK_votImpl::initDataset(int id)
{
if (id > 0 && id <= (int)data.size())
{
activeDatasetID = id;
return true;
}
else
{
printf("Dataset ID is out of range...\nAllowed IDs are: 1~%d\n", (int)data.size());
return false;
}
}
bool TRACK_votImpl::getNextFrame(Mat &frame)
{
if (frameCounter >= (int)data[activeDatasetID - 1].size())
return false;
string imgPath = data[activeDatasetID - 1][frameCounter]->imagePath;
frame = imread(imgPath);
frameCounter++;
return !frame.empty();
}
Ptr<TRACK_vot> TRACK_vot::create()
{
return Ptr<TRACK_votImpl>(new TRACK_votImpl);
}
vector <Point2d> TRACK_votImpl::getGT()
{
Ptr <TRACK_votObj> currObj = data[activeDatasetID - 1][frameCounter - 1];
return currObj->gtbb;
}
}
}
set(the_description "Tracking API") set(the_description "Tracking API")
ocv_define_module(tracking opencv_imgproc opencv_core opencv_video opencv_highgui) ocv_define_module(tracking opencv_imgproc opencv_core opencv_video opencv_highgui opencv_datasets)
...@@ -48,7 +48,7 @@ namespace cv ...@@ -48,7 +48,7 @@ namespace cv
{ {
namespace tld namespace tld
{ {
CV_EXPORTS cv::Rect2d tld_InitDataset(int datasetInd, const char* rootPath = "TLD_dataset"); CV_EXPORTS cv::Rect2d tld_InitDataset(int videoInd, const char* rootPath = "TLD_dataset", int datasetInd = 0);
CV_EXPORTS cv::Mat tld_getNextDatasetFrame(); CV_EXPORTS cv::Mat tld_getNextDatasetFrame();
} }
} }
......
...@@ -49,6 +49,7 @@ ...@@ -49,6 +49,7 @@
#include "onlineBoosting.hpp" #include "onlineBoosting.hpp"
#include <iostream> #include <iostream>
#define BOILERPLATE_CODE(name,classname) \ #define BOILERPLATE_CODE(name,classname) \
static Ptr<classname> createTracker(const classname::Params &parameters=classname::Params());\ static Ptr<classname> createTracker(const classname::Params &parameters=classname::Params());\
virtual ~classname(){}; virtual ~classname(){};
...@@ -564,6 +565,11 @@ class CV_EXPORTS_W Tracker : public virtual Algorithm ...@@ -564,6 +565,11 @@ class CV_EXPORTS_W Tracker : public virtual Algorithm
virtual void read( const FileNode& fn )=0; virtual void read( const FileNode& fn )=0;
virtual void write( FileStorage& fs ) const=0; virtual void write( FileStorage& fs ) const=0;
Ptr<TrackerModel> getModel()
{
return model;
}
protected: protected:
virtual bool initImpl( const Mat& image, const Rect2d& boundingBox ) = 0; virtual bool initImpl( const Mat& image, const Rect2d& boundingBox ) = 0;
...@@ -576,6 +582,7 @@ class CV_EXPORTS_W Tracker : public virtual Algorithm ...@@ -576,6 +582,7 @@ class CV_EXPORTS_W Tracker : public virtual Algorithm
Ptr<TrackerModel> model; Ptr<TrackerModel> model;
}; };
/************************************ Specific TrackerStateEstimator Classes ************************************/ /************************************ Specific TrackerStateEstimator Classes ************************************/
/** @brief TrackerStateEstimator based on Boosting /** @brief TrackerStateEstimator based on Boosting
...@@ -1197,7 +1204,7 @@ class CV_EXPORTS_W TrackerTLD : public Tracker ...@@ -1197,7 +1204,7 @@ class CV_EXPORTS_W TrackerTLD : public Tracker
*/ */
class CV_EXPORTS_W TrackerKCF : public Tracker class CV_EXPORTS_W TrackerKCF : public Tracker
{ {
public: public:
/** /**
* \brief Feature type to be used in the tracking grayscale, colornames, compressed color-names * \brief Feature type to be used in the tracking grayscale, colornames, compressed color-names
* The modes available now: * The modes available now:
...@@ -1207,7 +1214,7 @@ class CV_EXPORTS_W TrackerKCF : public Tracker ...@@ -1207,7 +1214,7 @@ class CV_EXPORTS_W TrackerKCF : public Tracker
enum MODE { enum MODE {
GRAY = (1u << 0), GRAY = (1u << 0),
CN = (1u << 1), CN = (1u << 1),
CUSTOM = (1u<<2) CUSTOM = (1u << 2)
}; };
struct CV_EXPORTS Params struct CV_EXPORTS Params
...@@ -1220,12 +1227,12 @@ class CV_EXPORTS_W TrackerKCF : public Tracker ...@@ -1220,12 +1227,12 @@ class CV_EXPORTS_W TrackerKCF : public Tracker
/** /**
* \brief Read parameters from file, currently unused * \brief Read parameters from file, currently unused
*/ */
void read( const FileNode& /*fn*/ ); void read(const FileNode& /*fn*/);
/** /**
* \brief Read parameters from file, currently unused * \brief Read parameters from file, currently unused
*/ */
void write( FileStorage& /*fs*/ ) const; void write(FileStorage& /*fs*/) const;
double sigma; //!< gaussian kernel bandwidth double sigma; //!< gaussian kernel bandwidth
double lambda; //!< regularization double lambda; //!< regularization
...@@ -1242,29 +1249,29 @@ class CV_EXPORTS_W TrackerKCF : public Tracker ...@@ -1242,29 +1249,29 @@ class CV_EXPORTS_W TrackerKCF : public Tracker
unsigned int desc_npca; //!< non-compressed descriptors of TrackerKCF::MODE unsigned int desc_npca; //!< non-compressed descriptors of TrackerKCF::MODE
}; };
virtual void setFeatureExtractor(void (*)(const Mat, const Rect, Mat&), bool pca_func = false); virtual void setFeatureExtractor(void(*)(const Mat, const Rect, Mat&), bool pca_func = false);
/** @brief Constructor /** @brief Constructor
@param parameters KCF parameters TrackerKCF::Params @param parameters KCF parameters TrackerKCF::Params
*/ */
BOILERPLATE_CODE("KCF",TrackerKCF); BOILERPLATE_CODE("KCF", TrackerKCF);
}; };
/************************************ MultiTracker Class ************************************/ /************************************ MultiTracker Class ---By Laksono Kurnianggoro---) ************************************/
/** @brief This class is used to track multiple objects using the specified tracker algorithm. /** @brief This class is used to track multiple objects using the specified tracker algorithm.
* The MultiTracker is naive implementation of multiple object tracking. * The MultiTracker is naive implementation of multiple object tracking.
* It process the tracked objects independently without any optimization accross the tracked objects. * It process the tracked objects independently without any optimization accross the tracked objects.
*/ */
class CV_EXPORTS_W MultiTracker class CV_EXPORTS_W MultiTracker
{ {
public: public:
/** /**
* \brief Constructor. * \brief Constructor.
* In the case of trackerType is given, it will be set as the default algorithm for all trackers. * In the case of trackerType is given, it will be set as the default algorithm for all trackers.
* @param trackerType the name of the tracker algorithm to be used * @param trackerType the name of the tracker algorithm to be used
*/ */
MultiTracker(const String& trackerType = "" ); MultiTracker(const String& trackerType = "");
/** /**
* \brief Destructor * \brief Destructor
...@@ -1277,7 +1284,7 @@ class CV_EXPORTS_W MultiTracker ...@@ -1277,7 +1284,7 @@ class CV_EXPORTS_W MultiTracker
* @param image input image * @param image input image
* @param boundingBox a rectangle represents ROI of the tracked object * @param boundingBox a rectangle represents ROI of the tracked object
*/ */
bool add( const Mat& image, const Rect2d& boundingBox ); bool add(const Mat& image, const Rect2d& boundingBox);
/** /**
* \brief Add a new object to be tracked. * \brief Add a new object to be tracked.
...@@ -1285,7 +1292,7 @@ class CV_EXPORTS_W MultiTracker ...@@ -1285,7 +1292,7 @@ class CV_EXPORTS_W MultiTracker
* @param image input image * @param image input image
* @param boundingBox a rectangle represents ROI of the tracked object * @param boundingBox a rectangle represents ROI of the tracked object
*/ */
bool add( const String& trackerType, const Mat& image, const Rect2d& boundingBox ); bool add(const String& trackerType, const Mat& image, const Rect2d& boundingBox);
/** /**
* \brief Add a set of objects to be tracked. * \brief Add a set of objects to be tracked.
...@@ -1307,7 +1314,7 @@ class CV_EXPORTS_W MultiTracker ...@@ -1307,7 +1314,7 @@ class CV_EXPORTS_W MultiTracker
* The result will be saved in the internal storage. * The result will be saved in the internal storage.
* @param image input image * @param image input image
*/ */
bool update( const Mat& image); bool update(const Mat& image);
//!< storage for the tracked objects, each object corresponds to one tracker algorithm. //!< storage for the tracked objects, each object corresponds to one tracker algorithm.
std::vector<Rect2d> objects; std::vector<Rect2d> objects;
...@@ -1317,9 +1324,9 @@ class CV_EXPORTS_W MultiTracker ...@@ -1317,9 +1324,9 @@ class CV_EXPORTS_W MultiTracker
* @param image input image * @param image input image
* @param boundingBox the tracking result, represent a list of ROIs of the tracked objects. * @param boundingBox the tracking result, represent a list of ROIs of the tracked objects.
*/ */
bool update( const Mat& image, std::vector<Rect2d> & boundingBox ); bool update(const Mat& image, std::vector<Rect2d> & boundingBox);
protected: protected:
//!< storage for the tracker algorithms. //!< storage for the tracker algorithms.
std::vector< Ptr<Tracker> > trackerList; std::vector< Ptr<Tracker> > trackerList;
...@@ -1344,7 +1351,7 @@ public: ...@@ -1344,7 +1351,7 @@ public:
Point2f center; Point2f center;
// initializer list // initializer list
handlerT(): isDrawing(false), drawFromCenter(true) {}; handlerT() : isDrawing(false), drawFromCenter(true) {};
}selectorParams; }selectorParams;
// to store the tracked objects // to store the tracked objects
...@@ -1352,7 +1359,7 @@ public: ...@@ -1352,7 +1359,7 @@ public:
private: private:
static void mouseHandler(int event, int x, int y, int flags, void *param); static void mouseHandler(int event, int x, int y, int flags, void *param);
void opencv_mouse_callback( int event, int x, int y, int , void *param ); void opencv_mouse_callback(int event, int x, int y, int, void *param);
// save the keypressed characted // save the keypressed characted
int key; int key;
...@@ -1362,8 +1369,88 @@ Rect2d CV_EXPORTS_W selectROI(Mat img, bool fromCenter = true); ...@@ -1362,8 +1369,88 @@ Rect2d CV_EXPORTS_W selectROI(Mat img, bool fromCenter = true);
Rect2d CV_EXPORTS_W selectROI(const std::string& windowName, Mat img, bool showCrossair = true, bool fromCenter = true); Rect2d CV_EXPORTS_W selectROI(const std::string& windowName, Mat img, bool showCrossair = true, bool fromCenter = true);
void CV_EXPORTS_W selectROI(const std::string& windowName, Mat img, std::vector<Rect2d> & boundingBox, bool fromCenter = true); void CV_EXPORTS_W selectROI(const std::string& windowName, Mat img, std::vector<Rect2d> & boundingBox, bool fromCenter = true);
} /* namespace cv */
/************************************ Multi-Tracker Classes ---By Tyan Vladimir---************************************/
/** @brief Base abstract class for the long-term Multi Object Trackers:
@sa Tracker, MultiTrackerTLD
*/
class CV_EXPORTS_W MultiTracker_Alt
{
public:
/** @brief Constructor for Multitracker
*/
MultiTracker_Alt()
{
targetNum = 0;
}
/** @brief Add a new target to a tracking-list and initialize the tracker with a know bounding box that surrounding the target
@param image The initial frame
@param boundingBox The initial boundig box of target
@param tracker_algorithm_name Multi-tracker algorithm name
@return True if new target initialization went succesfully, false otherwise
*/
bool addTarget(const Mat& image, const Rect2d& boundingBox, String tracker_algorithm_name);
/** @brief Update all trackers from the tracking-list, find a new most likely bounding boxes for the targets
@param image The current frame
@return True means that all targets were located and false means that tracker couldn't locate one of the targets in
current frame. Note, that latter *does not* imply that tracker has failed, maybe target is indeed
missing from the frame (say, out of sight)
*/
bool update(const Mat& image);
/** @brief Current number of targets in tracking-list
*/
int targetNum;
/** @brief Trackers list for Multi-Object-Tracker
*/
std::vector <Ptr<Tracker> > trackers;
/** @brief Bounding Boxes list for Multi-Object-Tracker
*/
std::vector <Rect2d> boundingBoxes;
/** @brief List of randomly generated colors for bounding boxes display
*/
std::vector<Scalar> colors;
};
/** @brief Multi Object Tracker for TLD. TLD is a novel tracking framework that explicitly decomposes
the long-term tracking task into tracking, learning and detection.
The tracker follows the object from frame to frame. The detector localizes all appearances that
have been observed so far and corrects the tracker if necessary. The learning estimates detector’s
errors and updates it to avoid these errors in the future. The implementation is based on @cite TLD .
The Median Flow algorithm (see cv::TrackerMedianFlow) was chosen as a tracking component in this
implementation, following authors. Tracker is supposed to be able to handle rapid motions, partial
occlusions, object absence etc.
@sa Tracker, MultiTracker, TrackerTLD
*/
class CV_EXPORTS_W MultiTrackerTLD : public MultiTracker_Alt
{
public:
/** @brief Update all trackers from the tracking-list, find a new most likely bounding boxes for the targets by
optimized update method using some techniques to speedup calculations specifically for MO TLD. The only limitation
is that all target bounding boxes should have approximately same aspect ratios. Speed boost is around 20%
@param image The current frame.
@return True means that all targets were located and false means that tracker couldn't locate one of the targets in
current frame. Note, that latter *does not* imply that tracker has failed, maybe target is indeed
missing from the frame (say, out of sight)
*/
bool update_opt(const Mat& image);
};
//! @} //! @}
} /* namespace cv */
#endif #endif
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "opencv2/datasets/track_vot.hpp"
#include <opencv2/core/utility.hpp>
#include <opencv2/tracking.hpp>
#include <opencv2/videoio.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>
using namespace std;
using namespace cv;
using namespace cv::datasets;
#define NUM_TEST_FRAMES 1000
static Mat image;
static bool paused;
static bool selectObjects = false;
static bool startSelection = false;
vector<Rect2d> boundingBoxes;
int targetsCnt = 0;
int targetsNum = 0;
Rect2d boundingBox;
static const char* keys =
{ "{@tracker_algorithm | | Tracker algorithm }"
"{@target_num |1| Number of targets }"
"{@dataset_path |true| Dataset path }"
"{@dataset_id |1| Dataset ID }"
};
static void onMouse(int event, int x, int y, int, void*)
{
if (!selectObjects)
{
switch (event)
{
case EVENT_LBUTTONDOWN:
//set origin of the bounding box
startSelection = true;
boundingBox.x = x;
boundingBox.y = y;
boundingBox.width = boundingBox.height = 0;
break;
case EVENT_LBUTTONUP:
//sei with and height of the bounding box
boundingBox.width = std::abs(x - boundingBox.x);
boundingBox.height = std::abs(y - boundingBox.y);
boundingBoxes.push_back(boundingBox);
targetsCnt++;
if (targetsCnt == targetsNum)
{
paused = false;
selectObjects = true;
}
startSelection = false;
break;
case EVENT_MOUSEMOVE:
if (startSelection && !selectObjects)
{
//draw the bounding box
Mat currentFrame;
image.copyTo(currentFrame);
for (int i = 0; i < (int)boundingBoxes.size(); i++)
rectangle(currentFrame, boundingBoxes[i], Scalar(255, 0, 0), 2, 1);
rectangle(currentFrame, Point((int)boundingBox.x, (int)boundingBox.y), Point(x, y), Scalar(255, 0, 0), 2, 1);
imshow("Tracking API", currentFrame);
}
break;
}
}
}
static void help()
{
cout << "\nThis example shows the functionality of \"Long-term optical tracking API\""
"TLD dataset ID: 1~10, VOT2015 dataset ID: 1~60\n"
"-- pause video [p] and draw a bounding boxes around the targets to start the tracker\n"
"Example:\n"
"./example_tracking_multiTracker_dataset<tracker_algorithm> <number_of_targets> <dataset_path> <dataset_id>\n"
<< endl;
cout << "\n\nHot keys: \n"
"\tq - quit the program\n"
"\tp - pause video\n";
}
int main(int argc, char *argv[])
{
CommandLineParser parser(argc, argv, keys);
string tracker_algorithm = parser.get<string>(0);
targetsNum = parser.get<int>(1);
string datasetRootPath = parser.get<string>(2);
int datasetID = parser.get<int>(3);
if (tracker_algorithm.empty() || datasetRootPath.empty() || targetsNum < 1)
{
help();
return -1;
}
Mat frame;
paused = false;
namedWindow("Tracking API", 0);
setMouseCallback("Tracking API", onMouse, 0);
MultiTrackerTLD mt;
//Init Dataset
Ptr<TRACK_vot> dataset = TRACK_vot::create();
dataset->load(datasetRootPath);
dataset->initDataset(datasetID);
//Read first frame
dataset->getNextFrame(frame);
frame.copyTo(image);
for (int i = 0; i < (int)boundingBoxes.size(); i++)
rectangle(image, boundingBoxes[i], Scalar(255, 0, 0), 2, 1);
imshow("Tracking API", image);
bool initialized = false;
paused = true;
int frameCounter = 0;
//Time measurment
int64 e3 = getTickCount();
for (;;)
{
if (!paused)
{
//Time measurment
int64 e1 = getTickCount();
if (initialized){
if (!dataset->getNextFrame(frame))
break;
frame.copyTo(image);
}
if (!initialized && selectObjects)
{
//Initialize the tracker and add targets
for (int i = 0; i < (int)boundingBoxes.size(); i++)
{
if (!mt.addTarget(frame, boundingBoxes[i], tracker_algorithm))
{
cout << "Trackers Init Error!!!";
return 0;
}
rectangle(frame, boundingBoxes[i], mt.colors[0], 2, 1);
}
initialized = true;
}
else if (initialized)
{
//Update all targets
if (mt.update(frame))
{
for (int i = 0; i < mt.targetNum; i++)
{
rectangle(frame, mt.boundingBoxes[i], mt.colors[i], 2, 1);
}
}
}
imshow("Tracking API", frame);
frameCounter++;
//Time measurment
int64 e2 = getTickCount();
double t1 = (e2 - e1) / getTickFrequency();
cout << frameCounter << "\tframe : " << t1 * 1000.0 << "ms" << endl;
}
char c = (char)waitKey(2);
if (c == 'q')
break;
if (c == 'p')
paused = !paused;
//waitKey(0);
}
//Time measurment
int64 e4 = getTickCount();
double t2 = (e4 - e3) / getTickFrequency();
cout << "Average Time for Frame: " << t2 * 1000.0 / frameCounter << "ms" << endl;
cout << "Average FPS: " << 1.0 / t2*frameCounter << endl;
waitKey(0);
return 0;
}
\ No newline at end of file
...@@ -39,17 +39,21 @@ ...@@ -39,17 +39,21 @@
// //
//M*/ //M*/
#include "opencv2/datasets/track_vot.hpp"
#include <opencv2/core/utility.hpp> #include <opencv2/core/utility.hpp>
#include <opencv2/tracking.hpp> #include <opencv2/tracking.hpp>
#include <opencv2/videoio.hpp> #include <opencv2/videoio.hpp>
#include <opencv2/highgui.hpp> #include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <iostream> #include <iostream>
using namespace std; using namespace std;
using namespace cv; using namespace cv;
using namespace cv::datasets;
#define NUM_TEST_FRAMES 100 #define NUM_TEST_FRAMES 300
#define TEST_VIDEO_INDEX 7 //TLD Dataset Video Index from 1-10 #define TEST_VIDEO_INDEX 1 //TLD Dataset Video Index from 1-10
//#define RECORD_VIDEO_FLG //#define RECORD_VIDEO_FLG
static Mat image; static Mat image;
...@@ -58,6 +62,12 @@ static bool paused; ...@@ -58,6 +62,12 @@ static bool paused;
static bool selectObject = false; static bool selectObject = false;
static bool startSelection = false; static bool startSelection = false;
static const char* keys =
{ "{@tracker_algorithm | | Tracker algorithm }"
"{@dataset_path |true| Dataset path }"
"{@dataset_id |1| Dataset ID }"
};
static void onMouse(int event, int x, int y, int, void*) static void onMouse(int event, int x, int y, int, void*)
{ {
if (!selectObject) if (!selectObject)
...@@ -93,19 +103,39 @@ static void onMouse(int event, int x, int y, int, void*) ...@@ -93,19 +103,39 @@ static void onMouse(int event, int x, int y, int, void*)
} }
} }
int main() static void help()
{
cout << "\nThis example shows the functionality of \"Long-term optical tracking API\""
"TLD dataset ID: 1~10, VOT2015 dataset ID: 1~60\n"
"-- pause video [p] and draw a bounding box around the target to start the tracker\n"
"Example:\n"
"./example_tracking_tracker_dataset <tracker_algorithm> <dataset_path> <dataset_id>\n"
<< endl;
cout << "\n\nHot keys: \n"
"\tq - quit the program\n"
"\tp - pause video\n";
}
int main(int argc, char *argv[])
{ {
// CommandLineParser parser(argc, argv, keys);
// "MIL", "BOOSTING", "MEDIANFLOW", "TLD" string tracker_algorithm = parser.get<string>(0);
// string datasetRootPath = parser.get<string>(1);
string tracker_algorithm_name = "TLD"; int datasetID = parser.get<int>(2);
if (tracker_algorithm.empty() || datasetRootPath.empty())
{
help();
return -1;
}
Mat frame; Mat frame;
paused = false; paused = false;
namedWindow("Tracking API", 0); namedWindow("Tracking API", 0);
setMouseCallback("Tracking API", onMouse, 0); setMouseCallback("Tracking API", onMouse, 0);
Ptr<Tracker> tracker = Tracker::create(tracker_algorithm_name); //Create Tracker
Ptr<Tracker> tracker = Tracker::create(tracker_algorithm);
if (tracker == NULL) if (tracker == NULL)
{ {
cout << "***Error in the instantiation of the tracker...***\n"; cout << "***Error in the instantiation of the tracker...***\n";
...@@ -113,85 +143,48 @@ int main() ...@@ -113,85 +143,48 @@ int main()
return 0; return 0;
} }
//Get the first frame //Init Dataset
////Open the capture Ptr<TRACK_vot> dataset = TRACK_vot::create();
// VideoCapture cap(0); dataset->load(datasetRootPath);
// if( !cap.isOpened() ) dataset->initDataset(datasetID);
// {
// cout << "Video stream error";
// return;
// }
//cap >> frame;
//From TLD dataset
selectObject = true;
boundingBox = tld::tld_InitDataset(TEST_VIDEO_INDEX, "D:/opencv/TLD_dataset");
frame = tld::tld_getNextDatasetFrame(); //Read first frame
dataset->getNextFrame(frame);
frame.copyTo(image); frame.copyTo(image);
// Setup output video
#ifdef RECORD_VIDEO_FLG
String outputFilename = "test.avi";
VideoWriter outputVideo;
outputVideo.open(outputFilename, -1, 30, Size(image.cols, image.rows));
if (!outputVideo.isOpened())
{
std::cout << "!!! Output video could not be opened" << std::endl;
getchar();
return;
}
#endif
rectangle(image, boundingBox, Scalar(255, 0, 0), 2, 1); rectangle(image, boundingBox, Scalar(255, 0, 0), 2, 1);
imshow("Tracking API", image); imshow("Tracking API", image);
bool initialized = false; bool initialized = false;
paused = true;
int frameCounter = 0; int frameCounter = 0;
//Time measurment //Time measurment
int64 e3 = getTickCount(); int64 e3 = getTickCount();
for (;;) for (;;)
{ {
//Time measurment
int64 e1 = getTickCount();
//Frame num
frameCounter++;
if (frameCounter == NUM_TEST_FRAMES) break;
char c = (char)waitKey(2);
if (c == 'q' || c == 27)
break;
if (c == 'p')
paused = !paused;
if (!paused) if (!paused)
{ {
//cap >> frame; //Time measurment
frame = tld::tld_getNextDatasetFrame(); int64 e1 = getTickCount();
if (frame.empty()) if (initialized){
{ if (!dataset->getNextFrame(frame))
break; break;
}
frame.copyTo(image); frame.copyTo(image);
}
if (selectObject) if (!initialized && selectObject)
{
if (!initialized)
{ {
//initializes the tracker //initializes the tracker
if (!tracker->init(frame, boundingBox)) if (!tracker->init(frame, boundingBox))
{ {
cout << "***Could not initialize tracker...***\n"; cout << "***Could not initialize tracker...***\n";
return 0; return -1;
} }
initialized = true; initialized = true;
rectangle(image, boundingBox, Scalar(255, 0, 0), 2, 1);
} }
else else if (initialized)
{ {
//updates the tracker //updates the tracker
if (tracker->update(frame, boundingBox)) if (tracker->update(frame, boundingBox))
...@@ -199,22 +192,24 @@ int main() ...@@ -199,22 +192,24 @@ int main()
rectangle(image, boundingBox, Scalar(255, 0, 0), 2, 1); rectangle(image, boundingBox, Scalar(255, 0, 0), 2, 1);
} }
} }
}
imshow("Tracking API", image); imshow("Tracking API", image);
frameCounter++;
#ifdef RECORD_VIDEO_FLG
outputVideo << image;
#endif
//Time measurment //Time measurment
int64 e2 = getTickCount(); int64 e2 = getTickCount();
double t1 = (e2 - e1) / getTickFrequency(); double t1 = (e2 - e1) / getTickFrequency();
cout << frameCounter << "\tframe : " << t1 * 1000.0 << "ms" << endl; cout << frameCounter << "\tframe : " << t1 * 1000.0 << "ms" << endl;
}
char c = (char)waitKey(2);
if (c == 'q')
break;
if (c == 'p')
paused = !paused;
//waitKey(0); //waitKey(0);
} }
}
//Time measurment //Time measurment
int64 e4 = getTickCount(); int64 e4 = getTickCount();
......
/*M/////////////////////////////////////////////////////////////////////////////////////// /*M///////////////////////////////////////////////////////////////////////////////////////
// //
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
// //
// By downloading, copying, installing or using the software you agree to this license. // By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install, // If you do not agree to this license, do not download, install,
// copy or use the software. // copy or use the software.
// //
// //
// License Agreement // License Agreement
// For Open Source Computer Vision Library // For Open Source Computer Vision Library
// //
// Copyright (C) 2013, OpenCV Foundation, all rights reserved. // Copyright (C) 2013, OpenCV Foundation, all rights reserved.
// Third party copyrights are property of their respective owners. // Third party copyrights are property of their respective owners.
// //
// Redistribution and use in source and binary forms, with or without modification, // Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met: // are permitted provided that the following conditions are met:
// //
// * Redistribution's of source code must retain the above copyright notice, // * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer. // this list of conditions and the following disclaimer.
// //
// * Redistribution's in binary form must reproduce the above copyright notice, // * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation // this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution. // and/or other materials provided with the distribution.
// //
// * The name of the copyright holders may not be used to endorse or promote products // * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission. // derived from this software without specific prior written permission.
// //
// This software is provided by the copyright holders and contributors "as is" and // This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied // any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed. // warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct, // In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages // indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services; // (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused // loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability, // and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of // or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage. // the use of this software, even if advised of the possibility of such damage.
// //
//M*/ //M*/
#include "multiTracker.hpp"
namespace cv
{
//Multitracker
bool MultiTracker_Alt::addTarget(const Mat& image, const Rect2d& boundingBox, String tracker_algorithm_name)
{
Ptr<Tracker> tracker = Tracker::create(tracker_algorithm_name);
if (tracker == NULL)
return false;
if (!tracker->init(image, boundingBox))
return false;
//Add BB of target
boundingBoxes.push_back(boundingBox);
#include "precomp.hpp" //Add Tracker to stack
trackers.push_back(tracker);
namespace cv { //Assign a random color to target
if (targetNum == 1)
colors.push_back(Scalar(0, 0, 255));
else
colors.push_back(Scalar(rand() % 256, rand() % 256, rand() % 256));
// constructor
MultiTracker::MultiTracker(const String& trackerType):defaultAlgorithm(trackerType){};
// destructor
MultiTracker::~MultiTracker(){};
// add an object to be tracked, defaultAlgorithm is used //Target counter
bool MultiTracker::add(const Mat& image, const Rect2d& boundingBox){ targetNum++;
// quit if defaultAlgorithm has not been configured
if(defaultAlgorithm==""){ return true;
printf("Default algorithm was not defined!\n"); }
bool MultiTracker_Alt::update(const Mat& image)
{
for (int i = 0; i < (int)trackers.size(); i++)
if (!trackers[i]->update(image, boundingBoxes[i]))
return false; return false;
return true;
} }
// add a new tracked object //Multitracker TLD
return add(defaultAlgorithm.c_str(), image, boundingBox); /*Optimized update method for TLD Multitracker */
}; bool MultiTrackerTLD::update_opt(const Mat& image)
{
//Get parameters from first object
//TLD Tracker data extraction
Tracker* trackerPtr = trackers[0];
tld::TrackerTLDImpl* tracker = static_cast<tld::TrackerTLDImpl*>(trackerPtr);
//TLD Model Extraction
tld::TrackerTLDModel* tldModel = ((tld::TrackerTLDModel*)static_cast<TrackerModel*>(tracker->getModel()));
Ptr<tld::Data> data = tracker->data;
double scale = data->getScale();
Mat image_gray, image_blurred, imageForDetector;
cvtColor(image, image_gray, COLOR_BGR2GRAY);
if (scale > 1.0)
resize(image_gray, imageForDetector, Size(cvRound(image.cols*scale), cvRound(image.rows*scale)), 0, 0, tld::DOWNSCALE_MODE);
else
imageForDetector = image_gray;
GaussianBlur(imageForDetector, image_blurred, tld::GaussBlurKernelSize, 0.0);
// add a new tracked object //best overlap around 92%
bool MultiTracker::add( const String& trackerType, const Mat& image, const Rect2d& boundingBox ){ Mat_<uchar> standardPatch(tld::STANDARD_PATCH_SIZE, tld::STANDARD_PATCH_SIZE);
// declare a new tracker
Ptr<Tracker> newTracker = Tracker::create( trackerType );
// add the created tracker algorithm to the trackers list std::vector<std::vector<tld::TLDDetector::LabeledPatch> > detectorResults(targetNum);
trackerList.push_back(newTracker); std::vector<std::vector<Rect2d> > candidates(targetNum);
std::vector<std::vector<double> > candidatesRes(targetNum);
std::vector<Rect2d> tmpCandidates(targetNum);
std::vector<bool> detect_flgs(targetNum);
std::vector<bool> trackerNeedsReInit(targetNum);
// add the ROI to the bounding box list bool DETECT_FLG = false;
objects.push_back(boundingBox);
// initialize the created tracker //Detect all
return trackerList.back()->init(image, boundingBox); for (int k = 0; k < targetNum; k++)
}; tmpCandidates[k] = boundingBoxes[k];
if (ocl::haveOpenCL())
ocl_detect_all(imageForDetector, image_blurred, tmpCandidates, detectorResults, detect_flgs, trackers);
else
detect_all(imageForDetector, image_blurred, tmpCandidates, detectorResults, detect_flgs, trackers);
// add a set of objects to be tracked for (int k = 0; k < targetNum; k++)
bool MultiTracker::add(const String& trackerType, const Mat& image, std::vector<Rect2d> boundingBox){ {
// status of the tracker addition //TLD Tracker data extraction
bool stat=false; trackerPtr = trackers[k];
tracker = static_cast<tld::TrackerTLDImpl*>(trackerPtr);
//TLD Model Extraction
tldModel = ((tld::TrackerTLDModel*)static_cast<TrackerModel*>(tracker->getModel()));
data = tracker->data;
// add tracker for all input objects data->frameNum++;
for(unsigned i =0;i<boundingBox.size();i++){
stat=add(trackerType,image,boundingBox[i]); for (int i = 0; i < 2; i++)
if(!stat)break; {
Rect2d tmpCandid = boundingBoxes[k];
//if (i == 1)
{
DETECT_FLG = detect_flgs[k];
tmpCandid = tmpCandidates[k];
}
if (((i == 0) && !data->failedLastTime && tracker->trackerProxy->update(image, tmpCandid)) || (DETECT_FLG))
{
candidates[k].push_back(tmpCandid);
if (i == 0)
tld::resample(image_gray, tmpCandid, standardPatch);
else
tld::resample(imageForDetector, tmpCandid, standardPatch);
candidatesRes[k].push_back(tldModel->detector->Sc(standardPatch));
} }
else
{
if (i == 0)
trackerNeedsReInit[k] = true;
else
trackerNeedsReInit[k] = false;
}
}
std::vector<double>::iterator it = std::max_element(candidatesRes[k].begin(), candidatesRes[k].end());
// return the status if (it == candidatesRes[k].end())
return stat; {
};
// add a set of object to be tracked, defaultAlgorithm is used. data->confident = false;
bool MultiTracker::add(const Mat& image, std::vector<Rect2d> boundingBox){ data->failedLastTime = true;
// quit if defaultAlgorithm has not been configured
if(defaultAlgorithm==""){
printf("Default algorithm was not defined!\n");
return false; return false;
} }
else
{
boundingBoxes[k] = candidates[k][it - candidatesRes[k].begin()];
data->failedLastTime = false;
if (trackerNeedsReInit[k] || it != candidatesRes[k].begin())
tracker->trackerProxy->init(image, boundingBoxes[k]);
}
#if 1
if (it != candidatesRes[k].end())
tld::resample(imageForDetector, candidates[k][it - candidatesRes[k].begin()], standardPatch);
#endif
if (*it > tld::CORE_THRESHOLD)
data->confident = true;
if (data->confident)
{
tld::TrackerTLDImpl::Pexpert pExpert(imageForDetector, image_blurred, boundingBoxes[k], tldModel->detector, tracker->params, data->getMinSize());
tld::TrackerTLDImpl::Nexpert nExpert(imageForDetector, boundingBoxes[k], tldModel->detector, tracker->params);
std::vector<Mat_<uchar> > examplesForModel, examplesForEnsemble;
examplesForModel.reserve(100); examplesForEnsemble.reserve(100);
int negRelabeled = 0;
for (int i = 0; i < (int)detectorResults[k].size(); i++)
{
bool expertResult;
if (detectorResults[k][i].isObject)
{
expertResult = nExpert(detectorResults[k][i].rect);
if (expertResult != detectorResults[k][i].isObject)
negRelabeled++;
}
else
{
expertResult = pExpert(detectorResults[k][i].rect);
}
detectorResults[k][i].shouldBeIntegrated = detectorResults[k][i].shouldBeIntegrated || (detectorResults[k][i].isObject != expertResult);
detectorResults[k][i].isObject = expertResult;
}
tldModel->integrateRelabeled(imageForDetector, image_blurred, detectorResults[k]);
pExpert.additionalExamples(examplesForModel, examplesForEnsemble);
if (ocl::haveOpenCL())
tldModel->ocl_integrateAdditional(examplesForModel, examplesForEnsemble, true);
else
tldModel->integrateAdditional(examplesForModel, examplesForEnsemble, true);
examplesForModel.clear(); examplesForEnsemble.clear();
nExpert.additionalExamples(examplesForModel, examplesForEnsemble);
if (ocl::haveOpenCL())
tldModel->ocl_integrateAdditional(examplesForModel, examplesForEnsemble, false);
else
tldModel->integrateAdditional(examplesForModel, examplesForEnsemble, false);
}
else
{
#ifdef CLOSED_LOOP
tldModel->integrateRelabeled(imageForDetector, image_blurred, detectorResults);
#endif
}
return add(defaultAlgorithm.c_str(), image, boundingBox);
};
// update position of the tracked objects, the result is stored in internal storage
bool MultiTracker::update( const Mat& image){
for(unsigned i=0;i< trackerList.size(); i++){
trackerList[i]->update(image, objects[i]);
} }
return true;
};
// update position of the tracked objects, the result is copied to external variable
bool MultiTracker::update( const Mat& image, std::vector<Rect2d> & boundingBox ){
update(image);
boundingBox=objects;
return true; return true;
}; }
void detect_all(const Mat& img, const Mat& imgBlurred, std::vector<Rect2d>& res, std::vector < std::vector < tld::TLDDetector::LabeledPatch > > &patches, std::vector<bool> &detect_flgs,
std::vector<Ptr<Tracker> > &trackers)
{
//TLD Tracker data extraction
Tracker* trackerPtr = trackers[0];
cv::tld::TrackerTLDImpl* tracker = static_cast<tld::TrackerTLDImpl*>(trackerPtr);
//TLD Model Extraction
tld::TrackerTLDModel* tldModel = ((tld::TrackerTLDModel*)static_cast<TrackerModel*>(tracker->getModel()));
Size initSize = tldModel->getMinSize();
for (int k = 0; k < (int)trackers.size(); k++)
patches[k].clear();
Mat_<uchar> standardPatch(tld::STANDARD_PATCH_SIZE, tld::STANDARD_PATCH_SIZE);
Mat tmp;
int dx = initSize.width / 10, dy = initSize.height / 10;
Size2d size = img.size();
double scale = 1.0;
int npos = 0, nneg = 0;
double maxSc = -5.0;
Rect2d maxScRect;
int scaleID;
std::vector <Mat> resized_imgs, blurred_imgs;
std::vector <std::vector <Point> > varBuffer(trackers.size()), ensBuffer(trackers.size());
std::vector <std::vector <int> > varScaleIDs(trackers.size()), ensScaleIDs(trackers.size());
std::vector <Point> tmpP;
std::vector <int> tmpI;
//Detection part
//Generate windows and filter by variance
scaleID = 0;
resized_imgs.push_back(img);
blurred_imgs.push_back(imgBlurred);
do
{
Mat_<double> intImgP, intImgP2;
tld::TLDDetector::computeIntegralImages(resized_imgs[scaleID], intImgP, intImgP2);
for (int i = 0, imax = cvFloor((0.0 + resized_imgs[scaleID].cols - initSize.width) / dx); i < imax; i++)
{
for (int j = 0, jmax = cvFloor((0.0 + resized_imgs[scaleID].rows - initSize.height) / dy); j < jmax; j++)
{
//Optimized variance calculation
int x = dx * i,
y = dy * j,
width = initSize.width,
height = initSize.height;
double p = 0, p2 = 0;
double A, B, C, D;
A = intImgP(y, x);
B = intImgP(y, x + width);
C = intImgP(y + height, x);
D = intImgP(y + height, x + width);
p = (A + D - B - C) / (width * height);
A = intImgP2(y, x);
B = intImgP2(y, x + width);
C = intImgP2(y + height, x);
D = intImgP2(y + height, x + width);
p2 = (A + D - B - C) / (width * height);
double windowVar = p2 - p * p;
//Loop for on all objects
for (int k = 0; k < (int)trackers.size(); k++)
{
//TLD Tracker data extraction
trackerPtr = trackers[k];
tracker = static_cast<tld::TrackerTLDImpl*>(trackerPtr);
//TLD Model Extraction
tldModel = ((tld::TrackerTLDModel*)static_cast<TrackerModel*>(tracker->getModel()));
//Optimized variance calculation
bool varPass = (windowVar > tld::VARIANCE_THRESHOLD * *tldModel->detector->originalVariancePtr);
if (!varPass)
continue;
varBuffer[k].push_back(Point(dx * i, dy * j));
varScaleIDs[k].push_back(scaleID);
}
}
}
scaleID++;
size.width /= tld::SCALE_STEP;
size.height /= tld::SCALE_STEP;
scale *= tld::SCALE_STEP;
resize(img, tmp, size, 0, 0, tld::DOWNSCALE_MODE);
resized_imgs.push_back(tmp);
GaussianBlur(resized_imgs[scaleID], tmp, tld::GaussBlurKernelSize, 0.0f);
blurred_imgs.push_back(tmp);
} while (size.width >= initSize.width && size.height >= initSize.height);
//Encsemble classification
for (int k = 0; k < (int)trackers.size(); k++)
{
//TLD Tracker data extraction
trackerPtr = trackers[k];
tracker = static_cast<tld::TrackerTLDImpl*>(trackerPtr);
//TLD Model Extraction
tldModel = ((tld::TrackerTLDModel*)static_cast<TrackerModel*>(tracker->getModel()));
for (int i = 0; i < (int)varBuffer[k].size(); i++)
{
tldModel->detector->prepareClassifiers(static_cast<int> (blurred_imgs[varScaleIDs[k][i]].step[0]));
double ensRes = 0;
uchar* data = &blurred_imgs[varScaleIDs[k][i]].at<uchar>(varBuffer[k][i].y, varBuffer[k][i].x);
for (int x = 0; x < (int)tldModel->detector->classifiers.size(); x++)
{
int position = 0;
for (int n = 0; n < (int)tldModel->detector->classifiers[x].measurements.size(); n++)
{
position = position << 1;
if (data[tldModel->detector->classifiers[x].offset[n].x] < data[tldModel->detector->classifiers[x].offset[n].y])
position++;
}
double posNum = (double)tldModel->detector->classifiers[x].posAndNeg[position].x;
double negNum = (double)tldModel->detector->classifiers[x].posAndNeg[position].y;
if (posNum == 0.0 && negNum == 0.0)
continue;
else
ensRes += posNum / (posNum + negNum);
}
ensRes /= tldModel->detector->classifiers.size();
ensRes = tldModel->detector->ensembleClassifierNum(&blurred_imgs[varScaleIDs[k][i]].at<uchar>(varBuffer[k][i].y, varBuffer[k][i].x));
if ( ensRes <= tld::ENSEMBLE_THRESHOLD)
continue;
ensBuffer[k].push_back(varBuffer[k][i]);
ensScaleIDs[k].push_back(varScaleIDs[k][i]);
}
}
//NN classification
for (int k = 0; k < (int)trackers.size(); k++)
{
//TLD Tracker data extraction
trackerPtr = trackers[k];
tracker = static_cast<tld::TrackerTLDImpl*>(trackerPtr);
//TLD Model Extraction
tldModel = ((tld::TrackerTLDModel*)static_cast<TrackerModel*>(tracker->getModel()));
npos = 0;
nneg = 0;
maxSc = -5.0;
for (int i = 0; i < (int)ensBuffer[k].size(); i++)
{
tld::TLDDetector::LabeledPatch labPatch;
double curScale = pow(tld::SCALE_STEP, ensScaleIDs[k][i]);
labPatch.rect = Rect2d(ensBuffer[k][i].x*curScale, ensBuffer[k][i].y*curScale, initSize.width * curScale, initSize.height * curScale);
tld::resample(resized_imgs[ensScaleIDs[k][i]], Rect2d(ensBuffer[k][i], initSize), standardPatch);
double srValue, scValue;
srValue = tldModel->detector->Sr(standardPatch);
////To fix: Check the paper, probably this cause wrong learning
//
labPatch.isObject = srValue > tld::THETA_NN;
labPatch.shouldBeIntegrated = abs(srValue - tld::THETA_NN) < 0.1;
patches[k].push_back(labPatch);
//
if (!labPatch.isObject)
{
nneg++;
continue;
}
else
{
npos++;
}
scValue = tldModel->detector->Sc(standardPatch);
if (scValue > maxSc)
{
maxSc = scValue;
maxScRect = labPatch.rect;
}
}
if (maxSc < 0)
detect_flgs[k] = false;
else
{
res[k] = maxScRect;
detect_flgs[k] = true;
}
}
}
void ocl_detect_all(const Mat& img, const Mat& imgBlurred, std::vector<Rect2d>& res, std::vector < std::vector < tld::TLDDetector::LabeledPatch > > &patches, std::vector<bool> &detect_flgs,
std::vector<Ptr<Tracker> > &trackers)
{
//TLD Tracker data extraction
Tracker* trackerPtr = trackers[0];
cv::tld::TrackerTLDImpl* tracker = static_cast<tld::TrackerTLDImpl*>(trackerPtr);
//TLD Model Extraction
tld::TrackerTLDModel* tldModel = ((tld::TrackerTLDModel*)static_cast<TrackerModel*>(tracker->getModel()));
Size initSize = tldModel->getMinSize();
for (int k = 0; k < (int)trackers.size(); k++)
patches[k].clear();
Mat_<uchar> standardPatch(tld::STANDARD_PATCH_SIZE, tld::STANDARD_PATCH_SIZE);
Mat tmp;
int dx = initSize.width / 10, dy = initSize.height / 10;
Size2d size = img.size();
double scale = 1.0;
int npos = 0, nneg = 0;
double maxSc = -5.0;
Rect2d maxScRect;
int scaleID;
std::vector <Mat> resized_imgs, blurred_imgs;
std::vector <std::vector <Point> > varBuffer(trackers.size()), ensBuffer(trackers.size());
std::vector <std::vector <int> > varScaleIDs(trackers.size()), ensScaleIDs(trackers.size());
std::vector <Point> tmpP;
std::vector <int> tmpI;
//Detection part
//Generate windows and filter by variance
scaleID = 0;
resized_imgs.push_back(img);
blurred_imgs.push_back(imgBlurred);
do
{
Mat_<double> intImgP, intImgP2;
tld::TLDDetector::computeIntegralImages(resized_imgs[scaleID], intImgP, intImgP2);
for (int i = 0, imax = cvFloor((0.0 + resized_imgs[scaleID].cols - initSize.width) / dx); i < imax; i++)
{
for (int j = 0, jmax = cvFloor((0.0 + resized_imgs[scaleID].rows - initSize.height) / dy); j < jmax; j++)
{
//Optimized variance calculation
int x = dx * i,
y = dy * j,
width = initSize.width,
height = initSize.height;
double p = 0, p2 = 0;
double A, B, C, D;
A = intImgP(y, x);
B = intImgP(y, x + width);
C = intImgP(y + height, x);
D = intImgP(y + height, x + width);
p = (A + D - B - C) / (width * height);
A = intImgP2(y, x);
B = intImgP2(y, x + width);
C = intImgP2(y + height, x);
D = intImgP2(y + height, x + width);
p2 = (A + D - B - C) / (width * height);
double windowVar = p2 - p * p;
//Loop for on all objects
for (int k = 0; k < (int)trackers.size(); k++)
{
//TLD Tracker data extraction
trackerPtr = trackers[k];
tracker = static_cast<tld::TrackerTLDImpl*>(trackerPtr);
//TLD Model Extraction
tldModel = ((tld::TrackerTLDModel*)static_cast<TrackerModel*>(tracker->getModel()));
//Optimized variance calculation
bool varPass = (windowVar > tld::VARIANCE_THRESHOLD * *tldModel->detector->originalVariancePtr);
if (!varPass)
continue;
varBuffer[k].push_back(Point(dx * i, dy * j));
varScaleIDs[k].push_back(scaleID);
}
}
}
scaleID++;
size.width /= tld::SCALE_STEP;
size.height /= tld::SCALE_STEP;
scale *= tld::SCALE_STEP;
resize(img, tmp, size, 0, 0, tld::DOWNSCALE_MODE);
resized_imgs.push_back(tmp);
GaussianBlur(resized_imgs[scaleID], tmp, tld::GaussBlurKernelSize, 0.0f);
blurred_imgs.push_back(tmp);
} while (size.width >= initSize.width && size.height >= initSize.height);
//Encsemble classification
for (int k = 0; k < (int)trackers.size(); k++)
{
//TLD Tracker data extraction
trackerPtr = trackers[k];
tracker = static_cast<tld::TrackerTLDImpl*>(trackerPtr);
//TLD Model Extraction
tldModel = ((tld::TrackerTLDModel*)static_cast<TrackerModel*>(tracker->getModel()));
for (int i = 0; i < (int)varBuffer[k].size(); i++)
{
tldModel->detector->prepareClassifiers(static_cast<int> (blurred_imgs[varScaleIDs[k][i]].step[0]));
double ensRes = 0;
uchar* data = &blurred_imgs[varScaleIDs[k][i]].at<uchar>(varBuffer[k][i].y, varBuffer[k][i].x);
for (int x = 0; x < (int)tldModel->detector->classifiers.size(); x++)
{
int position = 0;
for (int n = 0; n < (int)tldModel->detector->classifiers[x].measurements.size(); n++)
{
position = position << 1;
if (data[tldModel->detector->classifiers[x].offset[n].x] < data[tldModel->detector->classifiers[x].offset[n].y])
position++;
}
double posNum = (double)tldModel->detector->classifiers[x].posAndNeg[position].x;
double negNum = (double)tldModel->detector->classifiers[x].posAndNeg[position].y;
if (posNum == 0.0 && negNum == 0.0)
continue;
else
ensRes += posNum / (posNum + negNum);
}
ensRes /= tldModel->detector->classifiers.size();
ensRes = tldModel->detector->ensembleClassifierNum(&blurred_imgs[varScaleIDs[k][i]].at<uchar>(varBuffer[k][i].y, varBuffer[k][i].x));
if (ensRes <= tld::ENSEMBLE_THRESHOLD)
continue;
ensBuffer[k].push_back(varBuffer[k][i]);
ensScaleIDs[k].push_back(varScaleIDs[k][i]);
}
}
//NN classification
for (int k = 0; k < (int)trackers.size(); k++)
{
//TLD Tracker data extraction
trackerPtr = trackers[k];
tracker = static_cast<tld::TrackerTLDImpl*>(trackerPtr);
//TLD Model Extraction
tldModel = ((tld::TrackerTLDModel*)static_cast<TrackerModel*>(tracker->getModel()));
npos = 0;
nneg = 0;
maxSc = -5.0;
//Prepare batch of patches
int numOfPatches = (int)ensBuffer[k].size();
Mat_<uchar> stdPatches(numOfPatches, 225);
double *resultSr = new double[numOfPatches];
double *resultSc = new double[numOfPatches];
uchar *patchesData = stdPatches.data;
for (int i = 0; i < (int)ensBuffer.size(); i++)
{
tld::resample(resized_imgs[ensScaleIDs[k][i]], Rect2d(ensBuffer[k][i], initSize), standardPatch);
uchar *stdPatchData = standardPatch.data;
for (int j = 0; j < 225; j++)
patchesData[225 * i + j] = stdPatchData[j];
}
//Calculate Sr and Sc batches
tldModel->detector->ocl_batchSrSc(stdPatches, resultSr, resultSc, numOfPatches);
for (int i = 0; i < (int)ensBuffer[k].size(); i++)
{
tld::TLDDetector::LabeledPatch labPatch;
standardPatch.data = &stdPatches.data[225 * i];
double curScale = pow(tld::SCALE_STEP, ensScaleIDs[k][i]);
labPatch.rect = Rect2d(ensBuffer[k][i].x*curScale, ensBuffer[k][i].y*curScale, initSize.width * curScale, initSize.height * curScale);
tld::resample(resized_imgs[ensScaleIDs[k][i]], Rect2d(ensBuffer[k][i], initSize), standardPatch);
double srValue, scValue;
srValue = resultSr[i];
////To fix: Check the paper, probably this cause wrong learning
//
labPatch.isObject = srValue > tld::THETA_NN;
labPatch.shouldBeIntegrated = abs(srValue - tld::THETA_NN) < 0.1;
patches[k].push_back(labPatch);
//
if (!labPatch.isObject)
{
nneg++;
continue;
}
else
{
npos++;
}
scValue = resultSc[i];
if (scValue > maxSc)
{
maxSc = scValue;
maxScRect = labPatch.rect;
}
}
if (maxSc < 0)
detect_flgs[k] = false;
else
{
res[k] = maxScRect;
detect_flgs[k] = true;
}
}
}
} /* namespace cv */ }
\ No newline at end of file
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#ifndef OPENCV_MULTITRACKER
#define OPENCV_MULTITRACKER
#include "precomp.hpp"
#include "tldTracker.hpp"
#include "tldUtils.hpp"
#include <math.h>
namespace cv
{
void detect_all(const Mat& img, const Mat& imgBlurred, std::vector<Rect2d>& res, std::vector < std::vector < tld::TLDDetector::LabeledPatch > > &patches,
std::vector<bool>& detect_flgs, std::vector<Ptr<Tracker> >& trackers);
void ocl_detect_all(const Mat& img, const Mat& imgBlurred, std::vector<Rect2d>& res, std::vector < std::vector < tld::TLDDetector::LabeledPatch > > &patches,
std::vector<bool>& detect_flgs, std::vector<Ptr<Tracker> >& trackers);
}
#endif
\ No newline at end of file
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "precomp.hpp"
namespace cv {
// constructor
MultiTracker::MultiTracker(const String& trackerType):defaultAlgorithm(trackerType){};
// destructor
MultiTracker::~MultiTracker(){};
// add an object to be tracked, defaultAlgorithm is used
bool MultiTracker::add(const Mat& image, const Rect2d& boundingBox){
// quit if defaultAlgorithm has not been configured
if(defaultAlgorithm==""){
printf("Default algorithm was not defined!\n");
return false;
}
// add a new tracked object
return add(defaultAlgorithm.c_str(), image, boundingBox);
};
// add a new tracked object
bool MultiTracker::add( const String& trackerType, const Mat& image, const Rect2d& boundingBox ){
// declare a new tracker
Ptr<Tracker> newTracker = Tracker::create( trackerType );
// add the created tracker algorithm to the trackers list
trackerList.push_back(newTracker);
// add the ROI to the bounding box list
objects.push_back(boundingBox);
// initialize the created tracker
return trackerList.back()->init(image, boundingBox);
};
// add a set of objects to be tracked
bool MultiTracker::add(const String& trackerType, const Mat& image, std::vector<Rect2d> boundingBox){
// status of the tracker addition
bool stat=false;
// add tracker for all input objects
for(unsigned i =0;i<boundingBox.size();i++){
stat=add(trackerType,image,boundingBox[i]);
if(!stat)break;
}
// return the status
return stat;
};
// add a set of object to be tracked, defaultAlgorithm is used.
bool MultiTracker::add(const Mat& image, std::vector<Rect2d> boundingBox){
// quit if defaultAlgorithm has not been configured
if(defaultAlgorithm==""){
printf("Default algorithm was not defined!\n");
return false;
}
return add(defaultAlgorithm.c_str(), image, boundingBox);
};
// update position of the tracked objects, the result is stored in internal storage
bool MultiTracker::update( const Mat& image){
for(unsigned i=0;i< trackerList.size(); i++){
trackerList[i]->update(image, objects[i]);
}
return true;
};
// update position of the tracked objects, the result is copied to external variable
bool MultiTracker::update( const Mat& image, std::vector<Rect2d> & boundingBox ){
update(image);
boundingBox=objects;
return true;
};
} /* namespace cv */
\ No newline at end of file
...@@ -48,69 +48,107 @@ namespace cv ...@@ -48,69 +48,107 @@ namespace cv
char tldRootPath[100]; char tldRootPath[100];
int frameNum = 0; int frameNum = 0;
bool flagPNG = false; bool flagPNG = false;
bool flagVOT = false;
cv::Rect2d tld_InitDataset(int datasetInd,const char* rootPath) //TLD Dataset Parameters
const char* tldFolderName[10] = {
"01_david",
"02_jumping",
"03_pedestrian1",
"04_pedestrian2",
"05_pedestrian3",
"06_car",
"07_motocross",
"08_volkswagen",
"09_carchase",
"10_panda"
};
const char* votFolderName[60] = {
"bag", "ball1", "ball2", "basketball", "birds1", "birds2", "blanket", "bmx", "bolt1", "bolt2",
"book", "butterfly", "car1", "car2", "crossing", "dinosaur", "fernando", "fish1", "fish2", "fish3",
"fish4", "girl", "glove", "godfather", "graduate", "gymnastics1", "gymnastics2 ", "gymnastics3", "gymnastics4", "hand",
"handball1", "handball2", "helicopter", "iceskater1", "iceskater2", "leaves", "marching", "matrix", "motocross1", "motocross2",
"nature", "octopus", "pedestrian1", "pedestrian2", "rabbit", "racing", "road", "shaking", "sheep", "singer1",
"singer2", "singer3", "soccer1", "soccer2", "soldier", "sphere", "tiger", "traffic", "tunnel", "wiper"
};
const Rect2d tldInitBB[10] = {
Rect2d(165, 93, 51, 54), Rect2d(147, 110, 33, 32), Rect2d(47, 51, 21, 36), Rect2d(130, 134, 21, 53), Rect2d(154, 102, 24, 52),
Rect2d(142, 125, 90, 39), Rect2d(290, 43, 23, 40), Rect2d(273, 77, 27, 25), Rect2d(337, 219, 54, 37), Rect2d(58, 100, 27, 22)
};
const Rect2d votInitBB[60] = {
Rect2d(142, 125, 90, 39), Rect2d(490, 400, 40, 40), Rect2d(273, 77, 27, 25), Rect2d(145, 84, 54, 37), Rect2d(58, 100, 27, 22),
Rect2d(450, 380, 60, 60), Rect2d(290, 43, 23, 40), Rect2d(273, 77, 27, 25), Rect2d(225, 175, 50, 50), Rect2d(58, 100, 27, 22),
Rect2d(142, 125, 90, 39), Rect2d(290, 43, 23, 40), Rect2d(273, 77, 27, 25), Rect2d(145, 84, 54, 37), Rect2d(560, 460, 50, 120),
Rect2d(142, 125, 90, 39), Rect2d(290, 43, 23, 40), Rect2d(273, 77, 27, 25), Rect2d(145, 84, 54, 37), Rect2d(58, 100, 27, 22),
Rect2d(142, 125, 90, 39), Rect2d(290, 43, 23, 40), Rect2d(273, 77, 27, 25), Rect2d(145, 84, 54, 37), Rect2d(58, 100, 27, 22),
Rect2d(142, 125, 90, 39), Rect2d(290, 43, 23, 40), Rect2d(273, 77, 27, 25), Rect2d(145, 84, 54, 37), Rect2d(58, 100, 27, 22),
Rect2d(142, 125, 90, 39), Rect2d(290, 43, 23, 40), Rect2d(273, 77, 27, 25), Rect2d(145, 84, 54, 37), Rect2d(58, 100, 27, 22),
Rect2d(142, 125, 90, 39), Rect2d(290, 43, 23, 40), Rect2d(273, 77, 27, 25), Rect2d(145, 84, 54, 37), Rect2d(58, 100, 27, 22),
Rect2d(142, 125, 90, 39), Rect2d(290, 43, 23, 40), Rect2d(273, 77, 27, 25), Rect2d(145, 84, 54, 37), Rect2d(58, 100, 27, 22),
Rect2d(142, 125, 90, 39), Rect2d(290, 43, 23, 40), Rect2d(273, 77, 27, 25), Rect2d(145, 84, 54, 37), Rect2d(58, 100, 27, 22),
Rect2d(142, 125, 90, 39), Rect2d(290, 43, 23, 40), Rect2d(273, 77, 27, 25), Rect2d(145, 84, 54, 37), Rect2d(58, 100, 27, 22),
Rect2d(142, 125, 90, 39), Rect2d(290, 43, 23, 40), Rect2d(273, 77, 27, 25), Rect2d(145, 84, 54, 37), Rect2d(58, 100, 27, 22),
};
int tldFrameOffset[10] = { 100, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
int votFrameOffset[60] = {
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1
};
bool tldFlagPNG[10] = { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 };
bool votFlagPNG[60] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
cv::Rect2d tld_InitDataset(int videoInd, const char* rootPath, int datasetInd)
{ {
char* folderName = (char *)""; char* folderName = (char *)"";
int x = 0; double x = 0,
int y = 0; y = 0,
int w = 0; w = 0,
int h = 0; h = 0;
flagPNG = false;
//Index range
frameNum = 1; // 1-10 TLD Dataset
// 1-60 VOT 2015 Dataset
if (datasetInd == 1) { int id = videoInd - 1;
folderName = (char *)"01_david";
x = 165, y = 83; if (datasetInd == 0)
w = 51; h = 54; {
frameNum = 100; folderName = (char*)tldFolderName[id];
} x = tldInitBB[id].x;
if (datasetInd == 2) { y = tldInitBB[id].y;
folderName = (char *)"02_jumping"; w = tldInitBB[id].width;
x = 147, y = 110; h = tldInitBB[id].height;
w = 33; h = 32; frameNum = tldFrameOffset[id];
} flagPNG = tldFlagPNG[id];
if (datasetInd == 3) { flagVOT = false;
folderName = (char *)"03_pedestrian1";
x = 47, y = 51;
w = 21; h = 36;
}
if (datasetInd == 4) {
folderName = (char *)"04_pedestrian2";
x = 130, y = 134;
w = 21; h = 53;
}
if (datasetInd == 5) {
folderName = (char *)"05_pedestrian3";
x = 154, y = 102;
w = 24; h = 52;
}
if (datasetInd == 6) {
folderName = (char *)"06_car";
x = 142, y = 125;
w = 90; h = 39;
}
if (datasetInd == 7) {
folderName = (char *)"07_motocross";
x = 290, y = 43;
w = 23; h = 40;
flagPNG = true;
}
if (datasetInd == 8) {
folderName = (char *)"08_volkswagen";
x = 273, y = 77;
w = 27; h = 25;
}
if (datasetInd == 9) {
folderName = (char *)"09_carchase";
x = 145, y = 84;
w = 54; h = 37;
} }
if (datasetInd == 10){ if (datasetInd == 1)
folderName = (char *)"10_panda"; {
x = 58, y = 100; folderName = (char*)votFolderName[id];
w = 27; h = 22; x = votInitBB[id].x;
y = votInitBB[id].y;
w = votInitBB[id].width;
h = votInitBB[id].height;
frameNum = votFrameOffset[id];
flagPNG = votFlagPNG[id];
flagVOT = true;
} }
strcpy(tldRootPath, rootPath); strcpy(tldRootPath, rootPath);
...@@ -127,6 +165,8 @@ namespace cv ...@@ -127,6 +165,8 @@ namespace cv
char numStr[10]; char numStr[10];
strcpy(fullPath, tldRootPath); strcpy(fullPath, tldRootPath);
strcat(fullPath, "\\"); strcat(fullPath, "\\");
if (flagVOT)
strcat(fullPath, "000");
if (frameNum < 10) strcat(fullPath, "0000"); if (frameNum < 10) strcat(fullPath, "0000");
else if (frameNum < 100) strcat(fullPath, "000"); else if (frameNum < 100) strcat(fullPath, "000");
else if (frameNum < 1000) strcat(fullPath, "00"); else if (frameNum < 1000) strcat(fullPath, "00");
......
...@@ -65,25 +65,6 @@ namespace cv ...@@ -65,25 +65,6 @@ namespace cv
// Calculate Relative similarity of the patch (NN-Model) // Calculate Relative similarity of the patch (NN-Model)
double TLDDetector::Sr(const Mat_<uchar>& patch) double TLDDetector::Sr(const Mat_<uchar>& patch)
{ {
/*
int64 e1, e2;
float t;
e1 = getTickCount();
double splus = 0.0, sminus = 0.0;
for (int i = 0; i < (int)(*positiveExamples).size(); i++)
splus = std::max(splus, 0.5 * (NCC((*positiveExamples)[i], patch) + 1.0));
for (int i = 0; i < (int)(*negativeExamples).size(); i++)
sminus = std::max(sminus, 0.5 * (NCC((*negativeExamples)[i], patch) + 1.0));
e2 = getTickCount();
t = (e2 - e1) / getTickFrequency()*1000.0;
printf("Sr: %f\n", t);
if (splus + sminus == 0.0)
return 0.0;
return splus / (sminus + splus);
*/
//int64 e1, e2;
//float t;
//e1 = getTickCount();
double splus = 0.0, sminus = 0.0; double splus = 0.0, sminus = 0.0;
Mat_<uchar> modelSample(STANDARD_PATCH_SIZE, STANDARD_PATCH_SIZE); Mat_<uchar> modelSample(STANDARD_PATCH_SIZE, STANDARD_PATCH_SIZE);
for (int i = 0; i < *posNum; i++) for (int i = 0; i < *posNum; i++)
...@@ -96,9 +77,7 @@ namespace cv ...@@ -96,9 +77,7 @@ namespace cv
modelSample.data = &(negExp->data[i * 225]); modelSample.data = &(negExp->data[i * 225]);
sminus = std::max(sminus, 0.5 * (NCC(modelSample, patch) + 1.0)); sminus = std::max(sminus, 0.5 * (NCC(modelSample, patch) + 1.0));
} }
//e2 = getTickCount();
//t = (e2 - e1) / getTickFrequency()*1000.0;
//printf("Sr CPU: %f\n", t);
if (splus + sminus == 0.0) if (splus + sminus == 0.0)
return 0.0; return 0.0;
return splus / (sminus + splus); return splus / (sminus + splus);
...@@ -106,10 +85,6 @@ namespace cv ...@@ -106,10 +85,6 @@ namespace cv
double TLDDetector::ocl_Sr(const Mat_<uchar>& patch) double TLDDetector::ocl_Sr(const Mat_<uchar>& patch)
{ {
//int64 e1, e2, e3, e4;
//double t;
//e1 = getTickCount();
//e3 = getTickCount();
double splus = 0.0, sminus = 0.0; double splus = 0.0, sminus = 0.0;
...@@ -131,41 +106,15 @@ namespace cv ...@@ -131,41 +106,15 @@ namespace cv
ocl::KernelArg::PtrReadOnly(devPositiveSamples), ocl::KernelArg::PtrReadOnly(devPositiveSamples),
ocl::KernelArg::PtrReadOnly(devNegativeSamples), ocl::KernelArg::PtrReadOnly(devNegativeSamples),
ocl::KernelArg::PtrWriteOnly(devNCC), ocl::KernelArg::PtrWriteOnly(devNCC),
posNum, *posNum,
negNum); *negNum);
//e4 = getTickCount();
//t = (e4 - e3) / getTickFrequency()*1000.0;
//printf("Mem Cpy GPU: %f\n", t);
size_t globSize = 1000; size_t globSize = 1000;
//e3 = getTickCount();
if (!k.run(1, &globSize, NULL, false)) if (!k.run(1, &globSize, NULL, false))
printf("Kernel Run Error!!!"); printf("Kernel Run Error!!!");
//e4 = getTickCount();
//t = (e4 - e3) / getTickFrequency()*1000.0;
//printf("Kernel Run GPU: %f\n", t);
//e3 = getTickCount();
Mat resNCC = devNCC.getMat(ACCESS_READ); Mat resNCC = devNCC.getMat(ACCESS_READ);
//e4 = getTickCount();
//t = (e4 - e3) / getTickFrequency()*1000.0;
//printf("Read Mem GPU: %f\n", t);
////Compare
//Mat_<uchar> modelSample(STANDARD_PATCH_SIZE, STANDARD_PATCH_SIZE);
//for (int i = 0; i < 200; i+=17)
//{
// modelSample.data = &(posExp->data[i * 225]);
// printf("%f\t%f\n\n", resNCC.at<float>(i), NCC(modelSample, patch));
//}
//for (int i = 0; i < 200; i+=23)
//{
// modelSample.data = &(negExp->data[i * 225]);
// printf("%f\t%f\n", resNCC.at<float>(500+i), NCC(modelSample, patch));
//}
for (int i = 0; i < *posNum; i++) for (int i = 0; i < *posNum; i++)
splus = std::max(splus, 0.5 * (resNCC.at<float>(i) + 1.0)); splus = std::max(splus, 0.5 * (resNCC.at<float>(i) + 1.0));
...@@ -173,10 +122,6 @@ namespace cv ...@@ -173,10 +122,6 @@ namespace cv
for (int i = 0; i < *negNum; i++) for (int i = 0; i < *negNum; i++)
sminus = std::max(sminus, 0.5 * (resNCC.at<float>(i+500) +1.0)); sminus = std::max(sminus, 0.5 * (resNCC.at<float>(i+500) +1.0));
//e2 = getTickCount();
//t = (e2 - e1) / getTickFrequency()*1000.0;
//printf("Sr GPU: %f\n\n", t);
if (splus + sminus == 0.0) if (splus + sminus == 0.0)
return 0.0; return 0.0;
return splus / (sminus + splus); return splus / (sminus + splus);
...@@ -184,11 +129,6 @@ namespace cv ...@@ -184,11 +129,6 @@ namespace cv
void TLDDetector::ocl_batchSrSc(const Mat_<uchar>& patches, double *resultSr, double *resultSc, int numOfPatches) void TLDDetector::ocl_batchSrSc(const Mat_<uchar>& patches, double *resultSr, double *resultSc, int numOfPatches)
{ {
//int64 e1, e2, e3, e4;
//double t;
//e1 = getTickCount();
//e3 = getTickCount();
UMat devPatches = patches.getUMat(ACCESS_READ, USAGE_ALLOCATE_DEVICE_MEMORY); UMat devPatches = patches.getUMat(ACCESS_READ, USAGE_ALLOCATE_DEVICE_MEMORY);
UMat devPositiveSamples = posExp->getUMat(ACCESS_READ, USAGE_ALLOCATE_DEVICE_MEMORY); UMat devPositiveSamples = posExp->getUMat(ACCESS_READ, USAGE_ALLOCATE_DEVICE_MEMORY);
UMat devNegativeSamples = negExp->getUMat(ACCESS_READ, USAGE_ALLOCATE_DEVICE_MEMORY); UMat devNegativeSamples = negExp->getUMat(ACCESS_READ, USAGE_ALLOCATE_DEVICE_MEMORY);
...@@ -208,29 +148,17 @@ namespace cv ...@@ -208,29 +148,17 @@ namespace cv
ocl::KernelArg::PtrReadOnly(devNegativeSamples), ocl::KernelArg::PtrReadOnly(devNegativeSamples),
ocl::KernelArg::PtrWriteOnly(devPosNCC), ocl::KernelArg::PtrWriteOnly(devPosNCC),
ocl::KernelArg::PtrWriteOnly(devNegNCC), ocl::KernelArg::PtrWriteOnly(devNegNCC),
posNum, *posNum,
negNum, *negNum,
numOfPatches); numOfPatches);
//e4 = getTickCount();
//t = (e4 - e3) / getTickFrequency()*1000.0;
//printf("Mem Cpy GPU: %f\n", t);
// 2 -> Pos&Neg
size_t globSize = 2 * numOfPatches*MAX_EXAMPLES_IN_MODEL; size_t globSize = 2 * numOfPatches*MAX_EXAMPLES_IN_MODEL;
//e3 = getTickCount();
if (!k.run(1, &globSize, NULL, false)) if (!k.run(1, &globSize, NULL, true))
printf("Kernel Run Error!!!"); printf("Kernel Run Error!!!");
//e4 = getTickCount();
//t = (e4 - e3) / getTickFrequency()*1000.0;
//printf("Kernel Run GPU: %f\n", t);
//e3 = getTickCount();
Mat posNCC = devPosNCC.getMat(ACCESS_READ); Mat posNCC = devPosNCC.getMat(ACCESS_READ);
Mat negNCC = devNegNCC.getMat(ACCESS_READ); Mat negNCC = devNegNCC.getMat(ACCESS_READ);
//e4 = getTickCount();
//t = (e4 - e3) / getTickFrequency()*1000.0;
//printf("Read Mem GPU: %f\n", t);
//Calculate Srs //Calculate Srs
for (int id = 0; id < numOfPatches; id++) for (int id = 0; id < numOfPatches; id++)
...@@ -256,62 +184,11 @@ namespace cv ...@@ -256,62 +184,11 @@ namespace cv
else else
resultSc[id] = spc / (smc + spc); resultSc[id] = spc / (smc + spc);
} }
////Compare positive NCCs
/*Mat_<uchar> modelSample(STANDARD_PATCH_SIZE, STANDARD_PATCH_SIZE);
Mat_<uchar> patch(STANDARD_PATCH_SIZE, STANDARD_PATCH_SIZE);
for (int j = 0; j < numOfPatches; j++)
{
for (int i = 0; i < 1; i++)
{
modelSample.data = &(posExp->data[i * 225]);
patch.data = &(patches.data[j * 225]);
printf("%f\t%f\n", resultSr[j], Sr(patch));
printf("%f\t%f\n", resultSc[j], Sc(patch));
}
}*/
//for (int i = 0; i < 200; i+=23)
//{
// modelSample.data = &(negExp->data[i * 225]);
// printf("%f\t%f\n", resNCC.at<float>(500+i), NCC(modelSample, patch));
//}
//e2 = getTickCount();
//t = (e2 - e1) / getTickFrequency()*1000.0;
//printf("Sr GPU: %f\n\n", t);
} }
// Calculate Conservative similarity of the patch (NN-Model) // Calculate Conservative similarity of the patch (NN-Model)
double TLDDetector::Sc(const Mat_<uchar>& patch) double TLDDetector::Sc(const Mat_<uchar>& patch)
{ {
/*
int64 e1, e2;
float t;
e1 = getTickCount();
double splus = 0.0, sminus = 0.0;
int med = getMedian((*timeStampsPositive));
for (int i = 0; i < (int)(*positiveExamples).size(); i++)
{
if ((int)(*timeStampsPositive)[i] <= med)
splus = std::max(splus, 0.5 * (NCC((*positiveExamples)[i], patch) + 1.0));
}
for (int i = 0; i < (int)(*negativeExamples).size(); i++)
sminus = std::max(sminus, 0.5 * (NCC((*negativeExamples)[i], patch) + 1.0));
e2 = getTickCount();
t = (e2 - e1) / getTickFrequency()*1000.0;
printf("Sc: %f\n", t);
if (splus + sminus == 0.0)
return 0.0;
return splus / (sminus + splus);
*/
//int64 e1, e2;
//double t;
//e1 = getTickCount();
double splus = 0.0, sminus = 0.0; double splus = 0.0, sminus = 0.0;
Mat_<uchar> modelSample(STANDARD_PATCH_SIZE, STANDARD_PATCH_SIZE); Mat_<uchar> modelSample(STANDARD_PATCH_SIZE, STANDARD_PATCH_SIZE);
int med = getMedian((*timeStampsPositive)); int med = getMedian((*timeStampsPositive));
...@@ -328,9 +205,7 @@ namespace cv ...@@ -328,9 +205,7 @@ namespace cv
modelSample.data = &(negExp->data[i * 225]); modelSample.data = &(negExp->data[i * 225]);
sminus = std::max(sminus, 0.5 * (NCC(modelSample, patch) + 1.0)); sminus = std::max(sminus, 0.5 * (NCC(modelSample, patch) + 1.0));
} }
//e2 = getTickCount();
//t = (e2 - e1) / getTickFrequency()*1000.0;
//printf("Sc: %f\n", t);
if (splus + sminus == 0.0) if (splus + sminus == 0.0)
return 0.0; return 0.0;
...@@ -339,13 +214,8 @@ namespace cv ...@@ -339,13 +214,8 @@ namespace cv
double TLDDetector::ocl_Sc(const Mat_<uchar>& patch) double TLDDetector::ocl_Sc(const Mat_<uchar>& patch)
{ {
//int64 e1, e2, e3, e4;
//float t;
//e1 = getTickCount();
double splus = 0.0, sminus = 0.0; double splus = 0.0, sminus = 0.0;
//e3 = getTickCount();
UMat devPatch = patch.getUMat(ACCESS_READ, USAGE_ALLOCATE_DEVICE_MEMORY); UMat devPatch = patch.getUMat(ACCESS_READ, USAGE_ALLOCATE_DEVICE_MEMORY);
UMat devPositiveSamples = posExp->getUMat(ACCESS_READ, USAGE_ALLOCATE_DEVICE_MEMORY); UMat devPositiveSamples = posExp->getUMat(ACCESS_READ, USAGE_ALLOCATE_DEVICE_MEMORY);
UMat devNegativeSamples = negExp->getUMat(ACCESS_READ, USAGE_ALLOCATE_DEVICE_MEMORY); UMat devNegativeSamples = negExp->getUMat(ACCESS_READ, USAGE_ALLOCATE_DEVICE_MEMORY);
...@@ -364,40 +234,15 @@ namespace cv ...@@ -364,40 +234,15 @@ namespace cv
ocl::KernelArg::PtrReadOnly(devPositiveSamples), ocl::KernelArg::PtrReadOnly(devPositiveSamples),
ocl::KernelArg::PtrReadOnly(devNegativeSamples), ocl::KernelArg::PtrReadOnly(devNegativeSamples),
ocl::KernelArg::PtrWriteOnly(devNCC), ocl::KernelArg::PtrWriteOnly(devNCC),
posNum, *posNum,
negNum); *negNum);
//e4 = getTickCount();
//t = (e4 - e3) / getTickFrequency()*1000.0;
//printf("Mem Cpy GPU: %f\n", t);
size_t globSize = 1000; size_t globSize = 1000;
//e3 = getTickCount();
if (!k.run(1, &globSize, NULL, false)) if (!k.run(1, &globSize, NULL, false))
printf("Kernel Run Error!!!"); printf("Kernel Run Error!!!");
//e4 = getTickCount();
//t = (e4 - e3) / getTickFrequency()*1000.0;
//printf("Kernel Run GPU: %f\n", t);
//e3 = getTickCount();
Mat resNCC = devNCC.getMat(ACCESS_READ); Mat resNCC = devNCC.getMat(ACCESS_READ);
//e4 = getTickCount();
//t = (e4 - e3) / getTickFrequency()*1000.0;
//printf("Read Mem GPU: %f\n", t);
////Compare
//Mat_<uchar> modelSample(STANDARD_PATCH_SIZE, STANDARD_PATCH_SIZE);
//for (int i = 0; i < 200; i+=17)
//{
// modelSample.data = &(posExp->data[i * 225]);
// printf("%f\t%f\n\n", resNCC.at<float>(i), NCC(modelSample, patch));
//}
//for (int i = 0; i < 200; i+=23)
//{
// modelSample.data = &(negExp->data[i * 225]);
// printf("%f\t%f\n", resNCC.at<float>(500+i), NCC(modelSample, patch));
//}
int med = getMedian((*timeStampsPositive)); int med = getMedian((*timeStampsPositive));
for (int i = 0; i < *posNum; i++) for (int i = 0; i < *posNum; i++)
...@@ -407,10 +252,6 @@ namespace cv ...@@ -407,10 +252,6 @@ namespace cv
for (int i = 0; i < *negNum; i++) for (int i = 0; i < *negNum; i++)
sminus = std::max(sminus, 0.5 * (resNCC.at<float>(i + 500) + 1.0)); sminus = std::max(sminus, 0.5 * (resNCC.at<float>(i + 500) + 1.0));
//e2 = getTickCount();
//t = (e2 - e1) / getTickFrequency()*1000.0;
//printf("Sc GPU: %f\n\n", t);
if (splus + sminus == 0.0) if (splus + sminus == 0.0)
return 0.0; return 0.0;
return splus / (sminus + splus); return splus / (sminus + splus);
...@@ -449,7 +290,6 @@ namespace cv ...@@ -449,7 +290,6 @@ namespace cv
break; break;
} }
} }
//dprintf(("%d rects in res\n", (int)res.size()));
} }
//Detection - returns most probable new target location (Max Sc) //Detection - returns most probable new target location (Max Sc)
...@@ -469,10 +309,6 @@ namespace cv ...@@ -469,10 +309,6 @@ namespace cv
std::vector <Mat> resized_imgs, blurred_imgs; std::vector <Mat> resized_imgs, blurred_imgs;
std::vector <Point> varBuffer, ensBuffer; std::vector <Point> varBuffer, ensBuffer;
std::vector <int> varScaleIDs, ensScaleIDs; std::vector <int> varScaleIDs, ensScaleIDs;
//int64 e1, e2;
//double t;
//e1 = getTickCount();
//Detection part //Detection part
//Generate windows and filter by variance //Generate windows and filter by variance
...@@ -502,12 +338,8 @@ namespace cv ...@@ -502,12 +338,8 @@ namespace cv
GaussianBlur(resized_imgs[scaleID], tmp, GaussBlurKernelSize, 0.0f); GaussianBlur(resized_imgs[scaleID], tmp, GaussBlurKernelSize, 0.0f);
blurred_imgs.push_back(tmp); blurred_imgs.push_back(tmp);
} while (size.width >= initSize.width && size.height >= initSize.height); } while (size.width >= initSize.width && size.height >= initSize.height);
//e2 = getTickCount();
//t = (e2 - e1) / getTickFrequency()*1000.0;
//printf("Variance: %d\t%f\n", varBuffer.size(), t);
//Encsemble classification //Encsemble classification
//e1 = getTickCount();
for (int i = 0; i < (int)varBuffer.size(); i++) for (int i = 0; i < (int)varBuffer.size(); i++)
{ {
prepareClassifiers(static_cast<int> (blurred_imgs[varScaleIDs[i]].step[0])); prepareClassifiers(static_cast<int> (blurred_imgs[varScaleIDs[i]].step[0]));
...@@ -516,12 +348,8 @@ namespace cv ...@@ -516,12 +348,8 @@ namespace cv
ensBuffer.push_back(varBuffer[i]); ensBuffer.push_back(varBuffer[i]);
ensScaleIDs.push_back(varScaleIDs[i]); ensScaleIDs.push_back(varScaleIDs[i]);
} }
//e2 = getTickCount();
//t = (e2 - e1) / getTickFrequency()*1000.0;
//printf("Ensemble: %d\t%f\n", ensBuffer.size(), t);
//NN classification //NN classification
//e1 = getTickCount();
for (int i = 0; i < (int)ensBuffer.size(); i++) for (int i = 0; i < (int)ensBuffer.size(); i++)
{ {
LabeledPatch labPatch; LabeledPatch labPatch;
...@@ -555,15 +383,15 @@ namespace cv ...@@ -555,15 +383,15 @@ namespace cv
maxScRect = labPatch.rect; maxScRect = labPatch.rect;
} }
} }
//e2 = getTickCount();
//t = (e2 - e1) / getTickFrequency()*1000.0;
//printf("NN: %d\t%f\n", patches.size(), t);
if (maxSc < 0) if (maxSc < 0)
return false; return false;
else
{
res = maxScRect; res = maxScRect;
return true; return true;
} }
}
bool TLDDetector::ocl_detect(const Mat& img, const Mat& imgBlurred, Rect2d& res, std::vector<LabeledPatch>& patches, Size initSize) bool TLDDetector::ocl_detect(const Mat& img, const Mat& imgBlurred, Rect2d& res, std::vector<LabeledPatch>& patches, Size initSize)
{ {
...@@ -580,10 +408,7 @@ namespace cv ...@@ -580,10 +408,7 @@ namespace cv
std::vector <Mat> resized_imgs, blurred_imgs; std::vector <Mat> resized_imgs, blurred_imgs;
std::vector <Point> varBuffer, ensBuffer; std::vector <Point> varBuffer, ensBuffer;
std::vector <int> varScaleIDs, ensScaleIDs; std::vector <int> varScaleIDs, ensScaleIDs;
//int64 e1, e2;
//double t;
//e1 = getTickCount();
//Detection part //Detection part
//Generate windows and filter by variance //Generate windows and filter by variance
scaleID = 0; scaleID = 0;
...@@ -612,12 +437,8 @@ namespace cv ...@@ -612,12 +437,8 @@ namespace cv
GaussianBlur(resized_imgs[scaleID], tmp, GaussBlurKernelSize, 0.0f); GaussianBlur(resized_imgs[scaleID], tmp, GaussBlurKernelSize, 0.0f);
blurred_imgs.push_back(tmp); blurred_imgs.push_back(tmp);
} while (size.width >= initSize.width && size.height >= initSize.height); } while (size.width >= initSize.width && size.height >= initSize.height);
//e2 = getTickCount();
//t = (e2 - e1) / getTickFrequency()*1000.0;
//printf("Variance: %d\t%f\n", varBuffer.size(), t);
//Encsemble classification //Encsemble classification
//e1 = getTickCount();
for (int i = 0; i < (int)varBuffer.size(); i++) for (int i = 0; i < (int)varBuffer.size(); i++)
{ {
prepareClassifiers((int)blurred_imgs[varScaleIDs[i]].step[0]); prepareClassifiers((int)blurred_imgs[varScaleIDs[i]].step[0]);
...@@ -626,12 +447,8 @@ namespace cv ...@@ -626,12 +447,8 @@ namespace cv
ensBuffer.push_back(varBuffer[i]); ensBuffer.push_back(varBuffer[i]);
ensScaleIDs.push_back(varScaleIDs[i]); ensScaleIDs.push_back(varScaleIDs[i]);
} }
//e2 = getTickCount();
//t = (e2 - e1) / getTickFrequency()*1000.0;
//printf("Ensemble: %d\t%f\n", ensBuffer.size(), t);
//NN classification //NN classification
//e1 = getTickCount();
//Prepare batch of patches //Prepare batch of patches
int numOfPatches = (int)ensBuffer.size(); int numOfPatches = (int)ensBuffer.size();
Mat_<uchar> stdPatches(numOfPatches, 225); Mat_<uchar> stdPatches(numOfPatches, 225);
...@@ -661,9 +478,6 @@ namespace cv ...@@ -661,9 +478,6 @@ namespace cv
srValue = resultSr[i]; srValue = resultSr[i];
//srValue = Sr(standardPatch);
//printf("%f\t%f\t\n", srValue, resultSr[i]);
////To fix: Check the paper, probably this cause wrong learning ////To fix: Check the paper, probably this cause wrong learning
// //
labPatch.isObject = srValue > THETA_NN; labPatch.isObject = srValue > THETA_NN;
...@@ -687,9 +501,6 @@ namespace cv ...@@ -687,9 +501,6 @@ namespace cv
maxScRect = labPatch.rect; maxScRect = labPatch.rect;
} }
} }
//e2 = getTickCount();
//t = (e2 - e1) / getTickFrequency()*1000.0;
//printf("NN: %d\t%f\n", patches.size(), t);
if (maxSc < 0) if (maxSc < 0)
return false; return false;
......
...@@ -66,13 +66,15 @@ namespace cv ...@@ -66,13 +66,15 @@ namespace cv
static const cv::Size GaussBlurKernelSize(3, 3); static const cv::Size GaussBlurKernelSize(3, 3);
class TLDDetector class TLDDetector
{ {
public: public:
TLDDetector(){} TLDDetector(){}
~TLDDetector(){} ~TLDDetector(){}
inline double ensembleClassifierNum(const uchar* data); double ensembleClassifierNum(const uchar* data);
inline void prepareClassifiers(int rowstep); void prepareClassifiers(int rowstep);
double Sr(const Mat_<uchar>& patch); double Sr(const Mat_<uchar>& patch);
double ocl_Sr(const Mat_<uchar>& patch); double ocl_Sr(const Mat_<uchar>& patch);
double Sc(const Mat_<uchar>& patch); double Sc(const Mat_<uchar>& patch);
...@@ -94,14 +96,13 @@ namespace cv ...@@ -94,14 +96,13 @@ namespace cv
}; };
bool detect(const Mat& img, const Mat& imgBlurred, Rect2d& res, std::vector<LabeledPatch>& patches, Size initSize); bool detect(const Mat& img, const Mat& imgBlurred, Rect2d& res, std::vector<LabeledPatch>& patches, Size initSize);
bool ocl_detect(const Mat& img, const Mat& imgBlurred, Rect2d& res, std::vector<LabeledPatch>& patches, Size initSize); bool ocl_detect(const Mat& img, const Mat& imgBlurred, Rect2d& res, std::vector<LabeledPatch>& patches, Size initSize);
protected:
friend class MyMouseCallbackDEBUG; friend class MyMouseCallbackDEBUG;
void computeIntegralImages(const Mat& img, Mat_<double>& intImgP, Mat_<double>& intImgP2){ integral(img, intImgP, intImgP2, CV_64F); } static void computeIntegralImages(const Mat& img, Mat_<double>& intImgP, Mat_<double>& intImgP2){ integral(img, intImgP, intImgP2, CV_64F); }
inline bool patchVariance(Mat_<double>& intImgP, Mat_<double>& intImgP2, double *originalVariance, Point pt, Size size); static inline bool patchVariance(Mat_<double>& intImgP, Mat_<double>& intImgP2, double *originalVariance, Point pt, Size size);
}; };
} }
} }
......
...@@ -54,7 +54,7 @@ namespace cv ...@@ -54,7 +54,7 @@ namespace cv
double posteriorProbability(const uchar* data, int rowstep) const; double posteriorProbability(const uchar* data, int rowstep) const;
double posteriorProbabilityFast(const uchar* data) const; double posteriorProbabilityFast(const uchar* data) const;
void prepareClassifier(int rowstep); void prepareClassifier(int rowstep);
private:
TLDEnsembleClassifier(const std::vector<Vec4b>& meas, int beg, int end); TLDEnsembleClassifier(const std::vector<Vec4b>& meas, int beg, int end);
static void stepPrefSuff(std::vector<Vec4b> & arr, int pos, int len, int gridSize); static void stepPrefSuff(std::vector<Vec4b> & arr, int pos, int len, int gridSize);
int code(const uchar* data, int rowstep) const; int code(const uchar* data, int rowstep) const;
......
...@@ -140,7 +140,6 @@ namespace cv ...@@ -140,7 +140,6 @@ namespace cv
detector->classifiers[k].integrate(blurredPatch, false); detector->classifiers[k].integrate(blurredPatch, false);
} }
} }
//dprintf(("positive patches: %d\nnegative patches: %d\n", (int)positiveExamples.size(), (int)negativeExamples.size()));
} }
...@@ -180,16 +179,6 @@ namespace cv ...@@ -180,16 +179,6 @@ namespace cv
detector->classifiers[i].integrate(blurredPatch, patches[k].isObject); detector->classifiers[i].integrate(blurredPatch, patches[k].isObject);
} }
} }
/*
if( negativeIntoModel > 0 )
dfprintf((stdout, "negativeIntoModel = %d ", negativeIntoModel));
if( positiveIntoModel > 0)
dfprintf((stdout, "positiveIntoModel = %d ", positiveIntoModel));
if( negativeIntoEnsemble > 0 )
dfprintf((stdout, "negativeIntoEnsemble = %d ", negativeIntoEnsemble));
if( positiveIntoEnsemble > 0 )
dfprintf((stdout, "positiveIntoEnsemble = %d ", positiveIntoEnsemble));
dfprintf((stdout, "\n"));*/
} }
...@@ -198,9 +187,6 @@ namespace cv ...@@ -198,9 +187,6 @@ namespace cv
int positiveIntoModel = 0, negativeIntoModel = 0, positiveIntoEnsemble = 0, negativeIntoEnsemble = 0; int positiveIntoModel = 0, negativeIntoModel = 0, positiveIntoEnsemble = 0, negativeIntoEnsemble = 0;
if ((int)eForModel.size() == 0) return; if ((int)eForModel.size() == 0) return;
//int64 e1, e2;
//double t;
//e1 = getTickCount();
for (int k = 0; k < (int)eForModel.size(); k++) for (int k = 0; k < (int)eForModel.size(); k++)
{ {
double sr = detector->Sr(eForModel[k]); double sr = detector->Sr(eForModel[k]);
...@@ -231,19 +217,6 @@ namespace cv ...@@ -231,19 +217,6 @@ namespace cv
detector->classifiers[i].integrate(eForEnsemble[k], isPositive); detector->classifiers[i].integrate(eForEnsemble[k], isPositive);
} }
} }
//e2 = getTickCount();
//t = (e2 - e1) / getTickFrequency() * 1000;
//printf("Integrate Additional: %fms\n", t);
/*
if( negativeIntoModel > 0 )
dfprintf((stdout, "negativeIntoModel = %d ", negativeIntoModel));
if( positiveIntoModel > 0 )
dfprintf((stdout, "positiveIntoModel = %d ", positiveIntoModel));
if( negativeIntoEnsemble > 0 )
dfprintf((stdout, "negativeIntoEnsemble = %d ", negativeIntoEnsemble));
if( positiveIntoEnsemble > 0 )
dfprintf((stdout, "positiveIntoEnsemble = %d ", positiveIntoEnsemble));
dfprintf((stdout, "\n"));*/
} }
void TrackerTLDModel::ocl_integrateAdditional(const std::vector<Mat_<uchar> >& eForModel, const std::vector<Mat_<uchar> >& eForEnsemble, bool isPositive) void TrackerTLDModel::ocl_integrateAdditional(const std::vector<Mat_<uchar> >& eForModel, const std::vector<Mat_<uchar> >& eForEnsemble, bool isPositive)
...@@ -251,10 +224,6 @@ namespace cv ...@@ -251,10 +224,6 @@ namespace cv
int positiveIntoModel = 0, negativeIntoModel = 0, positiveIntoEnsemble = 0, negativeIntoEnsemble = 0; int positiveIntoModel = 0, negativeIntoModel = 0, positiveIntoEnsemble = 0, negativeIntoEnsemble = 0;
if ((int)eForModel.size() == 0) return; if ((int)eForModel.size() == 0) return;
//int64 e1, e2;
//double t;
//e1 = getTickCount();
//Prepare batch of patches //Prepare batch of patches
int numOfPatches = (int)eForModel.size(); int numOfPatches = (int)eForModel.size();
Mat_<uchar> stdPatches(numOfPatches, 225); Mat_<uchar> stdPatches(numOfPatches, 225);
...@@ -301,19 +270,6 @@ namespace cv ...@@ -301,19 +270,6 @@ namespace cv
detector->classifiers[i].integrate(eForEnsemble[k], isPositive); detector->classifiers[i].integrate(eForEnsemble[k], isPositive);
} }
} }
//e2 = getTickCount();
//t = (e2 - e1) / getTickFrequency() * 1000;
//printf("Integrate Additional OCL: %fms\n", t);
/*
if( negativeIntoModel > 0 )
dfprintf((stdout, "negativeIntoModel = %d ", negativeIntoModel));
if( positiveIntoModel > 0 )
dfprintf((stdout, "positiveIntoModel = %d ", positiveIntoModel));
if( negativeIntoEnsemble > 0 )
dfprintf((stdout, "negativeIntoEnsemble = %d ", negativeIntoEnsemble));
if( positiveIntoEnsemble > 0 )
dfprintf((stdout, "positiveIntoEnsemble = %d ", positiveIntoEnsemble));
dfprintf((stdout, "\n"));*/
} }
//Push the patch to the model //Push the patch to the model
......
...@@ -45,6 +45,13 @@ ...@@ -45,6 +45,13 @@
namespace cv namespace cv
{ {
TrackerTLD::Params::Params(){}
void TrackerTLD::Params::read(const cv::FileNode& /*fn*/){}
void TrackerTLD::Params::write(cv::FileStorage& /*fs*/) const {}
Ptr<TrackerTLD> TrackerTLD::createTracker(const TrackerTLD::Params &parameters) Ptr<TrackerTLD> TrackerTLD::createTracker(const TrackerTLD::Params &parameters)
{ {
return Ptr<tld::TrackerTLDImpl>(new tld::TrackerTLDImpl(parameters)); return Ptr<tld::TrackerTLDImpl>(new tld::TrackerTLDImpl(parameters));
...@@ -112,7 +119,6 @@ bool TrackerTLDImpl::updateImpl(const Mat& image, Rect2d& boundingBox) ...@@ -112,7 +119,6 @@ bool TrackerTLDImpl::updateImpl(const Mat& image, Rect2d& boundingBox)
Mat_<uchar> standardPatch(STANDARD_PATCH_SIZE, STANDARD_PATCH_SIZE); Mat_<uchar> standardPatch(STANDARD_PATCH_SIZE, STANDARD_PATCH_SIZE);
std::vector<TLDDetector::LabeledPatch> detectorResults; std::vector<TLDDetector::LabeledPatch> detectorResults;
//best overlap around 92% //best overlap around 92%
std::vector<Rect2d> candidates; std::vector<Rect2d> candidates;
std::vector<double> candidatesRes; std::vector<double> candidatesRes;
bool trackerNeedsReInit = false; bool trackerNeedsReInit = false;
...@@ -128,7 +134,6 @@ bool TrackerTLDImpl::updateImpl(const Mat& image, Rect2d& boundingBox) ...@@ -128,7 +134,6 @@ bool TrackerTLDImpl::updateImpl(const Mat& image, Rect2d& boundingBox)
else else
DETECT_FLG = tldModel->detector->detect(imageForDetector, image_blurred, tmpCandid, detectorResults, tldModel->getMinSize()); DETECT_FLG = tldModel->detector->detect(imageForDetector, image_blurred, tmpCandid, detectorResults, tldModel->getMinSize());
} }
if( ( (i == 0) && !data->failedLastTime && trackerProxy->update(image, tmpCandid) ) || ( DETECT_FLG)) if( ( (i == 0) && !data->failedLastTime && trackerProxy->update(image, tmpCandid) ) || ( DETECT_FLG))
{ {
candidates.push_back(tmpCandid); candidates.push_back(tmpCandid);
...@@ -144,15 +149,8 @@ bool TrackerTLDImpl::updateImpl(const Mat& image, Rect2d& boundingBox) ...@@ -144,15 +149,8 @@ bool TrackerTLDImpl::updateImpl(const Mat& image, Rect2d& boundingBox)
trackerNeedsReInit = true; trackerNeedsReInit = true;
} }
} }
std::vector<double>::iterator it = std::max_element(candidatesRes.begin(), candidatesRes.end()); std::vector<double>::iterator it = std::max_element(candidatesRes.begin(), candidatesRes.end());
//dfprintf((stdout, "scale = %f\n", log(1.0 * boundingBox.width / (data->getMinSize()).width) / log(SCALE_STEP)));
//for( int i = 0; i < (int)candidatesRes.size(); i++ )
//dprintf(("\tcandidatesRes[%d] = %f\n", i, candidatesRes[i]));
//data->printme();
//tldModel->printme(stdout);
if( it == candidatesRes.end() ) if( it == candidatesRes.end() )
{ {
data->confident = false; data->confident = false;
...@@ -169,16 +167,7 @@ bool TrackerTLDImpl::updateImpl(const Mat& image, Rect2d& boundingBox) ...@@ -169,16 +167,7 @@ bool TrackerTLDImpl::updateImpl(const Mat& image, Rect2d& boundingBox)
#if 1 #if 1
if( it != candidatesRes.end() ) if( it != candidatesRes.end() )
{
resample(imageForDetector, candidates[it - candidatesRes.begin()], standardPatch); resample(imageForDetector, candidates[it - candidatesRes.begin()], standardPatch);
//dfprintf((stderr, "%d %f %f\n", data->frameNum, tldModel->Sc(standardPatch), tldModel->Sr(standardPatch)));
//if( candidatesRes.size() == 2 && it == (candidatesRes.begin() + 1) )
//dfprintf((stderr, "detector WON\n"));
}
else
{
//dfprintf((stderr, "%d x x\n", data->frameNum));
}
#endif #endif
if( *it > CORE_THRESHOLD ) if( *it > CORE_THRESHOLD )
...@@ -209,7 +198,6 @@ bool TrackerTLDImpl::updateImpl(const Mat& image, Rect2d& boundingBox) ...@@ -209,7 +198,6 @@ bool TrackerTLDImpl::updateImpl(const Mat& image, Rect2d& boundingBox)
detectorResults[i].isObject = expertResult; detectorResults[i].isObject = expertResult;
} }
tldModel->integrateRelabeled(imageForDetector, image_blurred, detectorResults); tldModel->integrateRelabeled(imageForDetector, image_blurred, detectorResults);
//dprintf(("%d relabeled by nExpert\n", negRelabeled));
pExpert.additionalExamples(examplesForModel, examplesForEnsemble); pExpert.additionalExamples(examplesForModel, examplesForEnsemble);
if (ocl::haveOpenCL()) if (ocl::haveOpenCL())
tldModel->ocl_integrateAdditional(examplesForModel, examplesForEnsemble, true); tldModel->ocl_integrateAdditional(examplesForModel, examplesForEnsemble, true);
...@@ -296,7 +284,6 @@ Data::Data(Rect2d initBox) ...@@ -296,7 +284,6 @@ Data::Data(Rect2d initBox)
minSize.width = (int)(initBox.width * 20.0 / minDim); minSize.width = (int)(initBox.width * 20.0 / minDim);
minSize.height = (int)(initBox.height * 20.0 / minDim); minSize.height = (int)(initBox.height * 20.0 / minDim);
frameNum = 0; frameNum = 0;
//dprintf(("minSize = %dx%d\n", minSize.width, minSize.height));
} }
void Data::printme(FILE* port) void Data::printme(FILE* port)
......
...@@ -52,12 +52,6 @@ ...@@ -52,12 +52,6 @@
namespace cv namespace cv
{ {
TrackerTLD::Params::Params(){}
void TrackerTLD::Params::read(const cv::FileNode& /*fn*/){}
void TrackerTLD::Params::write(cv::FileStorage& /*fs*/) const {}
namespace tld namespace tld
{ {
class TrackerProxy class TrackerProxy
...@@ -128,7 +122,6 @@ public: ...@@ -128,7 +122,6 @@ public:
void read(const FileNode& fn); void read(const FileNode& fn);
void write(FileStorage& fs) const; void write(FileStorage& fs) const;
protected:
class Pexpert class Pexpert
{ {
public: public:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment