From 59e9a9ae21c09cacd5dbdb88ac5f18b7780939da Mon Sep 17 00:00:00 2001 From: berak Date: Tue, 3 Nov 2015 16:10:31 +0100 Subject: [PATCH] add Tracker and MultiTracker python bindings --- modules/tracking/CMakeLists.txt | 2 +- .../include/opencv2/tracking/onlineMIL.hpp | 2 +- .../include/opencv2/tracking/tracker.hpp | 74 +++++++++---------- modules/tracking/samples/multitracker.py | 35 +++++++++ modules/tracking/samples/tracker.py | 30 ++++++++ modules/tracking/src/roiSelector.cpp | 8 +- 6 files changed, 108 insertions(+), 43 deletions(-) create mode 100644 modules/tracking/samples/multitracker.py create mode 100644 modules/tracking/samples/tracker.py diff --git a/modules/tracking/CMakeLists.txt b/modules/tracking/CMakeLists.txt index 69a3c9a0d..9a8717458 100644 --- a/modules/tracking/CMakeLists.txt +++ b/modules/tracking/CMakeLists.txt @@ -1,2 +1,2 @@ set(the_description "Tracking API") -ocv_define_module(tracking opencv_imgproc opencv_core opencv_video opencv_highgui opencv_datasets) +ocv_define_module(tracking opencv_imgproc opencv_core opencv_video opencv_highgui opencv_datasets WRAP python) diff --git a/modules/tracking/include/opencv2/tracking/onlineMIL.hpp b/modules/tracking/include/opencv2/tracking/onlineMIL.hpp index be03ec8eb..b6fc25b0c 100644 --- a/modules/tracking/include/opencv2/tracking/onlineMIL.hpp +++ b/modules/tracking/include/opencv2/tracking/onlineMIL.hpp @@ -58,7 +58,7 @@ namespace cv class ClfOnlineStump; -class ClfMilBoost +class CV_EXPORTS ClfMilBoost { public: struct CV_EXPORTS Params diff --git a/modules/tracking/include/opencv2/tracking/tracker.hpp b/modules/tracking/include/opencv2/tracking/tracker.hpp index 3aef75261..5fabfecdf 100644 --- a/modules/tracking/include/opencv2/tracking/tracker.hpp +++ b/modules/tracking/include/opencv2/tracking/tracker.hpp @@ -74,7 +74,7 @@ namespace cv /** @brief Abstract base class for TrackerFeature that represents the feature. */ -class CV_EXPORTS_W TrackerFeature +class CV_EXPORTS TrackerFeature { public: virtual ~TrackerFeature(); @@ -131,7 +131,7 @@ TrackerFeatureSet is an aggregation of TrackerFeature TrackerFeature */ -class CV_EXPORTS_W TrackerFeatureSet +class CV_EXPORTS TrackerFeatureSet { public: @@ -209,7 +209,7 @@ class CV_EXPORTS_W TrackerFeatureSet /** @brief Abstract base class for TrackerSamplerAlgorithm that represents the algorithm for the specific sampler. */ -class CV_EXPORTS_W TrackerSamplerAlgorithm +class CV_EXPORTS TrackerSamplerAlgorithm { public: /** @@ -261,7 +261,7 @@ TrackerSampler is an aggregation of TrackerSamplerAlgorithm @sa TrackerSamplerAlgorithm */ -class CV_EXPORTS_W TrackerSampler +class CV_EXPORTS TrackerSampler { public: @@ -334,7 +334,7 @@ See @cite AAM \f$\hat{x}^{i}_{k}\f$ all the states candidates. Inherits this class with your Target state, In own implementation you can add scale variation, width, height, orientation, etc. */ -class CV_EXPORTS_W TrackerTargetState +class CV_EXPORTS TrackerTargetState { public: virtual ~TrackerTargetState() @@ -403,7 +403,7 @@ See @cite AAM State estimator See @cite AMVOT Statistical modeling (Fig. 3), Table III (generative) - IV (discriminative) - V (hybrid) */ -class CV_EXPORTS_W TrackerStateEstimator +class CV_EXPORTS TrackerStateEstimator { public: virtual ~TrackerStateEstimator(); @@ -449,7 +449,7 @@ See @cite AAM Ak Inherits this with your TrackerModel */ -class CV_EXPORTS_W TrackerModel +class CV_EXPORTS TrackerModel { public: @@ -539,7 +539,7 @@ class CV_EXPORTS_W Tracker : public virtual Algorithm @return True if initialization went succesfully, false otherwise */ - bool init( const Mat& image, const Rect2d& boundingBox ); + CV_WRAP bool init( const Mat& image, const Rect2d& boundingBox ); /** @brief Update the tracker, find the new most likely bounding box for the target @param image The current frame @@ -550,7 +550,7 @@ class CV_EXPORTS_W Tracker : public virtual Algorithm 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, Rect2d& boundingBox ); + CV_WRAP bool update( const Mat& image, CV_OUT Rect2d& boundingBox ); /** @brief Creates a tracker by its name. @param trackerType Tracker type @@ -560,7 +560,7 @@ class CV_EXPORTS_W Tracker : public virtual Algorithm - "MIL" -- TrackerMIL - "BOOSTING" -- TrackerBoosting */ - static Ptr create( const String& trackerType ); + CV_WRAP static Ptr create( const String& trackerType ); virtual void read( const FileNode& fn )=0; virtual void write( FileStorage& fs ) const=0; @@ -587,7 +587,7 @@ class CV_EXPORTS_W Tracker : public virtual Algorithm /** @brief TrackerStateEstimator based on Boosting */ -class CV_EXPORTS_W TrackerStateEstimatorMILBoosting : public TrackerStateEstimator +class CV_EXPORTS TrackerStateEstimatorMILBoosting : public TrackerStateEstimator { public: @@ -664,7 +664,7 @@ class CV_EXPORTS_W TrackerStateEstimatorMILBoosting : public TrackerStateEstimat /** @brief TrackerStateEstimatorAdaBoosting based on ADA-Boosting */ -class CV_EXPORTS_W TrackerStateEstimatorAdaBoosting : public TrackerStateEstimator +class CV_EXPORTS TrackerStateEstimatorAdaBoosting : public TrackerStateEstimator { public: /** @brief Implementation of the target state for TrackerAdaBoostingTargetState @@ -774,7 +774,7 @@ class CV_EXPORTS_W TrackerStateEstimatorAdaBoosting : public TrackerStateEstimat /** * \brief TrackerStateEstimator based on SVM */ -class CV_EXPORTS_W TrackerStateEstimatorSVM : public TrackerStateEstimator +class CV_EXPORTS TrackerStateEstimatorSVM : public TrackerStateEstimator { public: TrackerStateEstimatorSVM(); @@ -789,7 +789,7 @@ class CV_EXPORTS_W TrackerStateEstimatorSVM : public TrackerStateEstimator /** @brief TrackerSampler based on CSC (current state centered), used by MIL algorithm TrackerMIL */ -class CV_EXPORTS_W TrackerSamplerCSC : public TrackerSamplerAlgorithm +class CV_EXPORTS TrackerSamplerCSC : public TrackerSamplerAlgorithm { public: enum @@ -847,7 +847,7 @@ class CV_EXPORTS_W TrackerSamplerCSC : public TrackerSamplerAlgorithm /** @brief TrackerSampler based on CS (current state), used by algorithm TrackerBoosting */ -class CV_EXPORTS_W TrackerSamplerCS : public TrackerSamplerAlgorithm +class CV_EXPORTS TrackerSamplerCS : public TrackerSamplerAlgorithm { public: enum @@ -914,7 +914,7 @@ It should be noted, that the definition of "similarity" between two rectangles i their histograms. As experiments show, tracker is *not* very succesfull if target is assumed to strongly change its dimensions. */ -class CV_EXPORTS_W TrackerSamplerPF : public TrackerSamplerAlgorithm +class CV_EXPORTS TrackerSamplerPF : public TrackerSamplerAlgorithm { public: /** @brief This structure contains all the parameters that can be varied during the course of sampling @@ -949,7 +949,7 @@ private: /** * \brief TrackerFeature based on Feature2D */ -class CV_EXPORTS_W TrackerFeatureFeature2d : public TrackerFeature +class CV_EXPORTS TrackerFeatureFeature2d : public TrackerFeature { public: @@ -976,7 +976,7 @@ class CV_EXPORTS_W TrackerFeatureFeature2d : public TrackerFeature /** * \brief TrackerFeature based on HOG */ -class CV_EXPORTS_W TrackerFeatureHOG : public TrackerFeature +class CV_EXPORTS TrackerFeatureHOG : public TrackerFeature { public: @@ -995,7 +995,7 @@ class CV_EXPORTS_W TrackerFeatureHOG : public TrackerFeature /** @brief TrackerFeature based on HAAR features, used by TrackerMIL and many others algorithms @note HAAR features implementation is copied from apps/traincascade and modified according to MIL */ -class CV_EXPORTS_W TrackerFeatureHAAR : public TrackerFeature +class CV_EXPORTS TrackerFeatureHAAR : public TrackerFeature { public: struct CV_EXPORTS Params @@ -1057,7 +1057,7 @@ class CV_EXPORTS_W TrackerFeatureHAAR : public TrackerFeature /** * \brief TrackerFeature based on LBP */ -class CV_EXPORTS_W TrackerFeatureLBP : public TrackerFeature +class CV_EXPORTS TrackerFeatureLBP : public TrackerFeature { public: @@ -1083,7 +1083,7 @@ based on @cite MIL . Original code can be found here */ -class CV_EXPORTS_W TrackerMIL : public Tracker +class CV_EXPORTS TrackerMIL : public Tracker { public: struct CV_EXPORTS Params @@ -1113,7 +1113,7 @@ class CV_EXPORTS_W TrackerMIL : public Tracker The classifier uses the surrounding background as negative examples in update step to avoid the drifting problem. The implementation is based on @cite OLB . */ -class CV_EXPORTS_W TrackerBoosting : public Tracker +class CV_EXPORTS TrackerBoosting : public Tracker { public: struct CV_EXPORTS Params @@ -1151,7 +1151,7 @@ by authors to outperform MIL). During the implementation period the code at , the courtesy of the author Arthur Amarra, was used for the reference purpose. */ -class CV_EXPORTS_W TrackerMedianFlow : public Tracker +class CV_EXPORTS TrackerMedianFlow : public Tracker { public: struct CV_EXPORTS Params @@ -1180,7 +1180,7 @@ The Median Flow algorithm (see cv::TrackerMedianFlow) was chosen as a tracking c implementation, following authors. Tracker is supposed to be able to handle rapid motions, partial occlusions, object absence etc. */ -class CV_EXPORTS_W TrackerTLD : public Tracker +class CV_EXPORTS TrackerTLD : public Tracker { public: struct CV_EXPORTS Params @@ -1202,7 +1202,7 @@ class CV_EXPORTS_W TrackerTLD : public Tracker * as well as the matlab implementation. For more information about KCF with color-names features, please refer to * . */ -class CV_EXPORTS_W TrackerKCF : public Tracker +class CV_EXPORTS TrackerKCF : public Tracker { public: /** @@ -1271,7 +1271,7 @@ public: * 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 */ - MultiTracker(const String& trackerType = ""); + CV_WRAP MultiTracker(const String& trackerType = ""); /** * \brief Destructor @@ -1284,7 +1284,7 @@ public: * @param image input image * @param boundingBox a rectangle represents ROI of the tracked object */ - bool add(const Mat& image, const Rect2d& boundingBox); + CV_WRAP bool add(const Mat& image, const Rect2d& boundingBox); /** * \brief Add a new object to be tracked. @@ -1292,7 +1292,7 @@ public: * @param image input image * @param boundingBox a rectangle represents ROI of the tracked object */ - bool add(const String& trackerType, const Mat& image, const Rect2d& boundingBox); + CV_WRAP bool add(const String& trackerType, const Mat& image, const Rect2d& boundingBox); /** * \brief Add a set of objects to be tracked. @@ -1300,14 +1300,14 @@ public: * @param image input image * @param boundingBox list of the tracked objects */ - bool add(const String& trackerType, const Mat& image, std::vector boundingBox); + CV_WRAP bool add(const String& trackerType, const Mat& image, std::vector boundingBox); /** * \brief Add a set of objects to be tracked using the defaultAlgorithm tracker. * @param image input image * @param boundingBox list of the tracked objects */ - bool add(const Mat& image, std::vector boundingBox); + CV_WRAP bool add(const Mat& image, std::vector boundingBox); /** * \brief Update the current tracking status. @@ -1324,7 +1324,7 @@ public: * @param image input image * @param boundingBox the tracking result, represent a list of ROIs of the tracked objects. */ - bool update(const Mat& image, std::vector & boundingBox); + CV_WRAP bool update(const Mat& image, CV_OUT std::vector & boundingBox); protected: //!< storage for the tracker algorithms. @@ -1337,8 +1337,8 @@ protected: class ROISelector { public: Rect2d select(Mat img, bool fromCenter = true); - Rect2d select(const std::string& windowName, Mat img, bool showCrossair = true, bool fromCenter = true); - void select(const std::string& windowName, Mat img, std::vector & boundingBox, bool fromCenter = true); + Rect2d select(const cv::String& windowName, Mat img, bool showCrossair = true, bool fromCenter = true); + void select(const cv::String& windowName, Mat img, std::vector & boundingBox, bool fromCenter = true); struct handlerT{ // basic parameters @@ -1366,8 +1366,8 @@ private: }; 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); +Rect2d CV_EXPORTS_W selectROI(const cv::String& windowName, Mat img, bool showCrossair = true, bool fromCenter = true); +void CV_EXPORTS_W selectROI(const cv::String& windowName, Mat img, std::vector & boundingBox, bool fromCenter = true); /************************************ Multi-Tracker Classes ---By Tyan Vladimir---************************************/ @@ -1376,7 +1376,7 @@ void CV_EXPORTS_W selectROI(const std::string& windowName, Mat img, std::vector< @sa Tracker, MultiTrackerTLD */ -class CV_EXPORTS_W MultiTracker_Alt +class CV_EXPORTS MultiTracker_Alt { public: /** @brief Constructor for Multitracker @@ -1433,7 +1433,7 @@ occlusions, object absence etc. @sa Tracker, MultiTracker, TrackerTLD */ -class CV_EXPORTS_W MultiTrackerTLD : public MultiTracker_Alt +class CV_EXPORTS MultiTrackerTLD : public MultiTracker_Alt { public: /** @brief Update all trackers from the tracking-list, find a new most likely bounding boxes for the targets by diff --git a/modules/tracking/samples/multitracker.py b/modules/tracking/samples/multitracker.py new file mode 100644 index 000000000..59b962e5d --- /dev/null +++ b/modules/tracking/samples/multitracker.py @@ -0,0 +1,35 @@ +import numpy as np +import cv2 + +cv2.namedWindow("tracking") +camera = cv2.VideoCapture("E:/code/opencv/samples/data/768x576.avi") +tracker = cv2.MultiTracker("MIL") +bbox1 = (638.0,230.0,56.0,101.0) +bbox2 = (240.0,210.0,60.0,104.0) +bbox3 = (486.0,149.0,54.0,83.0) +init_once = False + +while camera.isOpened(): + ok, image=camera.read() + if not ok: + print 'no image read' + break + + if not init_once: + # add a list of boxes: + ok = tracker.add(image, (bbox1,bbox2)) + # or add single box: + ok = tracker.add(image, bbox3) + init_once = True + + ok, boxes = tracker.update(image) + print ok, boxes + + for newbox in boxes: + p1 = (int(newbox[0]), int(newbox[1])) + p2 = (int(newbox[0] + newbox[2]), int(newbox[1] + newbox[3])) + cv2.rectangle(image, p1, p2, (200,0,0)) + + cv2.imshow("tracking", image) + k = cv2.waitKey(1) & 0xff + if k == 27 : break # esc pressed diff --git a/modules/tracking/samples/tracker.py b/modules/tracking/samples/tracker.py new file mode 100644 index 000000000..eb86fe68f --- /dev/null +++ b/modules/tracking/samples/tracker.py @@ -0,0 +1,30 @@ +import numpy as np +import cv2 + +cv2.namedWindow("tracking") +camera = cv2.VideoCapture("E:/code/opencv/samples/data/768x576.avi") +bbox = (638.0,230.0,56.0,101.0) +tracker = cv2.Tracker_create("MIL") +init_once = False + +while camera.isOpened(): + ok, image=camera.read() + if not ok: + print 'no image read' + break + + if not init_once: + ok = tracker.init(image, bbox) + init_once = True + + ok, newbox = tracker.update(image) + print ok, newbox + + if ok: + p1 = (int(newbox[0]), int(newbox[1])) + p2 = (int(newbox[0] + newbox[2]), int(newbox[1] + newbox[3])) + cv2.rectangle(image, p1, p2, (200,0,0)) + + cv2.imshow("tracking", image) + k = cv2.waitKey(1) & 0xff + if k == 27 : break # esc pressed \ No newline at end of file diff --git a/modules/tracking/src/roiSelector.cpp b/modules/tracking/src/roiSelector.cpp index 1bfcc661d..051129fc0 100644 --- a/modules/tracking/src/roiSelector.cpp +++ b/modules/tracking/src/roiSelector.cpp @@ -91,7 +91,7 @@ namespace cv { return select("ROI selector", img, fromCenter); } - Rect2d ROISelector::select(const std::string& windowName, Mat img, bool showCrossair, bool fromCenter){ + Rect2d ROISelector::select(const cv::String& windowName, Mat img, bool showCrossair, bool fromCenter){ key=0; @@ -149,7 +149,7 @@ namespace cv { return selectorParams.box; } - void ROISelector::select(const std::string& windowName, Mat img, std::vector & boundingBox, bool fromCenter){ + void ROISelector::select(const cv::String& windowName, Mat img, std::vector & boundingBox, bool fromCenter){ std::vector box; Rect2d temp; key=0; @@ -172,12 +172,12 @@ namespace cv { return _selector.select("ROI selector", img, true, fromCenter); }; - Rect2d selectROI(const std::string& windowName, Mat img, bool showCrossair, bool fromCenter){ + Rect2d selectROI(const cv::String& windowName, Mat img, bool showCrossair, bool fromCenter){ printf("Select an object to track and then press SPACE or ENTER button!\n" ); return _selector.select(windowName,img, showCrossair, fromCenter); }; - void selectROI(const std::string& windowName, Mat img, std::vector & boundingBox, bool fromCenter){ + void selectROI(const cv::String& windowName, Mat img, std::vector & boundingBox, bool fromCenter){ return _selector.select(windowName, img, boundingBox, fromCenter); }