diff --git a/modules/tracking/include/opencv2/tracking/tracker.hpp b/modules/tracking/include/opencv2/tracking/tracker.hpp index 3c7e480b5..c17f65133 100644 --- a/modules/tracking/include/opencv2/tracking/tracker.hpp +++ b/modules/tracking/include/opencv2/tracking/tracker.hpp @@ -49,6 +49,7 @@ #include "onlineBoosting.hpp" #include + #define BOILERPLATE_CODE(name,classname) \ static Ptr createTracker(const classname::Params ¶meters=classname::Params());\ virtual ~classname(){}; @@ -576,6 +577,7 @@ class CV_EXPORTS_W Tracker : public virtual Algorithm Ptr model; }; + /************************************ Specific TrackerStateEstimator Classes ************************************/ /** @brief TrackerStateEstimator based on Boosting @@ -1362,6 +1364,31 @@ 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); void CV_EXPORTS_W selectROI(const std::string& windowName, Mat img, std::vector & boundingBox, bool fromCenter = true); + +/************************************ Multi-Tracker Classes ************************************/ + +class CV_EXPORTS_W MultiTracker_Alt +{ +public: + + bool addTarget(const Mat& image, const Rect2d& boundingBox, char* tracker_algorithm_name); + + bool update(const Mat& image); + + int targetNum = 0; + std::vector > trackers; + std::vector boundingBoxes; + std::vector colors; +}; + +class CV_EXPORTS_W MultiTrackerTLD : public MultiTracker_Alt +{ +public: + bool update(const Mat& image); +}; + +//! @} + } /* namespace cv */ //! @} diff --git a/modules/tracking/samples/multiTracker_test.cpp b/modules/tracking/samples/multiTracker_test.cpp new file mode 100644 index 000000000..ac3c37382 --- /dev/null +++ b/modules/tracking/samples/multiTracker_test.cpp @@ -0,0 +1,227 @@ +/*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 +#include +#include +#include +#include + +using namespace std; +using namespace cv; + +#define NUM_TEST_FRAMES 100 +#define TEST_VIDEO_INDEX 7 //TLD Dataset Video Index from 1-10 +//#define RECORD_VIDEO_FLG + +static Mat image; +static bool paused; +static bool selectObject = false; +static bool startSelection = false; +Rect2d boundingBox; + +static void onMouse(int event, int x, int y, int, void*) +{ + if (!selectObject) + { + 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); + paused = false; + selectObject = true; + break; + case EVENT_MOUSEMOVE: + + if (startSelection && !selectObject) + { + //draw the bounding box + Mat currentFrame; + image.copyTo(currentFrame); + rectangle(currentFrame, Point((int)boundingBox.x, (int)boundingBox.y), Point(x, y), Scalar(255, 0, 0), 2, 1); + imshow("Tracking API", currentFrame); + } + break; + } + } +} + +int main() +{ + // + // "MIL", "BOOSTING", "MEDIANFLOW", "TLD" + // + char* tracker_algorithm_name = "TLD"; + + Mat frame; + paused = false; + namedWindow("Tracking API", 0); + setMouseCallback("Tracking API", onMouse, 0); + + MultiTrackerTLD mt; + + //Get the first frame + ////Open the capture + // VideoCapture cap(0); + // if( !cap.isOpened() ) + // { + // cout << "Video stream error"; + // return; + // } + //cap >> frame; + + //From TLD dataset + selectObject = true; + Rect2d boundingBox1 = tld::tld_InitDataset(TEST_VIDEO_INDEX, "D:/opencv/TLD_dataset"); + Rect2d boundingBox2; + boundingBox2.x = 280; + boundingBox2.y = 60; + boundingBox2.width = 40; + boundingBox2.height = 60; + + frame = tld::tld_getNextDatasetFrame(); + 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); + imshow("Tracking API", image); + + + bool initialized = false; + int frameCounter = 0; + + //Time measurment + int64 e3 = getTickCount(); + + 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) + { + //cap >> frame; + frame = tld::tld_getNextDatasetFrame(); + if (frame.empty()) + { + break; + } + frame.copyTo(image); + + if (selectObject) + { + if (!initialized) + { + //initializes the tracker + mt.addTarget(frame, boundingBox1, tracker_algorithm_name); + rectangle(image, boundingBox1, mt.colors[0], 2, 1); + + + mt.addTarget(frame, boundingBox2, tracker_algorithm_name); + rectangle(image, boundingBox2, mt.colors[1], 2, 1); + initialized = true; + } + else + { + //updates the tracker + if (mt.update(frame)) + for (int i=0; i < mt.targetNum; i++) + rectangle(image, mt.boundingBoxes[i], mt.colors[i], 2, 1); + } + } + imshow("Tracking API", image); + +#ifdef RECORD_VIDEO_FLG + outputVideo << image; +#endif + + + //Time measurment + int64 e2 = getTickCount(); + double t1 = (e2 - e1) / getTickFrequency(); + cout << frameCounter << "\tframe : " << t1 * 1000.0 << "ms" << endl; + + 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 diff --git a/modules/tracking/src/multiTracker.cpp b/modules/tracking/src/multiTracker.cpp index f21c999e2..d8c53d22f 100644 --- a/modules/tracking/src/multiTracker.cpp +++ b/modules/tracking/src/multiTracker.cpp @@ -1,120 +1,49 @@ -/*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 -#include "precomp.hpp" +namespace cv +{ + //Multitracker + bool MultiTracker::addTarget(const Mat& image, const Rect2d& boundingBox, char* tracker_algorithm_name) + { + Ptr tracker = Tracker::create(tracker_algorithm_name); + if (tracker == NULL) + return false; -namespace cv { + if (!tracker->init(image, boundingBox)) + return false; - // constructor - MultiTracker::MultiTracker(const String& trackerType):defaultAlgorithm(trackerType){}; + //Add BB of target + boundingBoxes.push_back(boundingBox); - // destructor - MultiTracker::~MultiTracker(){}; + //Add Tracker to stack + trackers.push_back(tracker); - // 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; - } + //Assign a random color to target + colors.push_back(Scalar(rand() % 256, rand() % 256, rand() % 256)); - // add a new tracked object - return add(defaultAlgorithm.c_str(), image, boundingBox); - }; + //Target counter + targetNum++; - // add a new tracked object - bool MultiTracker::add( const String& trackerType, const Mat& image, const Rect2d& boundingBox ){ - // declare a new tracker - Ptr newTracker = Tracker::create( trackerType ); + return true; + } - // add the created tracker algorithm to the trackers list - trackerList.push_back(newTracker); + bool MultiTracker::update(const Mat& image) + { + for (int i = 0; i < trackers.size(); i++) + if (!trackers[i]->update(image, boundingBoxes[i])) + return false; - // add the ROI to the bounding box list - objects.push_back(boundingBox); + return true; + } - // initialize the created tracker - return trackerList.back()->init(image, boundingBox); - }; + //Multitracker TLD + /*Optimized update method for TLD Multitracker */ + bool MultiTrackerTLD::update(const Mat& image) + { + for (int i = 0; i < trackers.size(); i++) + if (!trackers[i]->update(image, boundingBoxes[i])) + return false; - // add a set of objects to be tracked - bool MultiTracker::add(const String& trackerType, const Mat& image, std::vector boundingBox){ - // status of the tracker addition - bool stat=false; - - // add tracker for all input objects - for(unsigned i =0;i 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 & boundingBox ){ - update(image); - boundingBox=objects; - return true; - }; - -} /* namespace cv */ + return true; + } +} diff --git a/modules/tracking/src/tldDetector.cpp b/modules/tracking/src/tldDetector.cpp index cbb783ece..900761bef 100644 --- a/modules/tracking/src/tldDetector.cpp +++ b/modules/tracking/src/tldDetector.cpp @@ -219,7 +219,7 @@ namespace cv // 2 -> Pos&Neg 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!!!"); //e4 = getTickCount(); //t = (e4 - e3) / getTickFrequency()*1000.0;