From 4ae95b6e2a233f5e5f1c8aa2542b203ab6cf730e Mon Sep 17 00:00:00 2001 From: Vladislav Sovrasov Date: Fri, 14 Apr 2017 13:22:01 +0300 Subject: [PATCH] tracking: add confidence threshold to TrackerKCF --- .../include/opencv2/tracking/tracker.hpp | 1 + modules/tracking/samples/kcf.cpp | 130 ++---------------- modules/tracking/src/trackerKCF.cpp | 9 ++ 3 files changed, 19 insertions(+), 121 deletions(-) diff --git a/modules/tracking/include/opencv2/tracking/tracker.hpp b/modules/tracking/include/opencv2/tracking/tracker.hpp index 9b12158a6f..c69ca5bcfa 100644 --- a/modules/tracking/include/opencv2/tracking/tracker.hpp +++ b/modules/tracking/include/opencv2/tracking/tracker.hpp @@ -1236,6 +1236,7 @@ class CV_EXPORTS_W TrackerKCF : public Tracker */ void write(FileStorage& /*fs*/) const; + double detect_thresh; //!< detection confidence threshold double sigma; //!< gaussian kernel bandwidth double lambda; //!< regularization double interp_factor; //!< linear interpolation factor for adaptation diff --git a/modules/tracking/samples/kcf.cpp b/modules/tracking/samples/kcf.cpp index 56c0592c5d..f40a3c5f26 100644 --- a/modules/tracking/samples/kcf.cpp +++ b/modules/tracking/samples/kcf.cpp @@ -13,29 +13,11 @@ #include #include #include +#include "samples_utility.hpp" using namespace std; using namespace cv; -class BoxExtractor { -public: - Rect2d extract(Mat img); - Rect2d extract(const std::string& windowName, Mat img, bool showCrossair = true); - - struct handlerT{ - bool isDrawing; - Rect2d box; - Mat image; - - // initializer list - handlerT(): isDrawing(false) {}; - }params; - -private: - 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 ); -}; - int main( int argc, char** argv ){ // show help if(argc<2){ @@ -48,9 +30,6 @@ int main( int argc, char** argv ){ return 0; } - // ROI selector - BoxExtractor box; - // create the tracker Ptr tracker = TrackerKCF::create(); @@ -62,7 +41,7 @@ int main( int argc, char** argv ){ // get bounding box cap >> frame; - Rect2d roi=box.extract("tracker",frame); + Rect2d roi= selectROI("tracker", frame, true, false); //quit if ROI was not selected if(roi.width==0 || roi.height==0) @@ -82,7 +61,13 @@ int main( int argc, char** argv ){ break; // update the tracking result - tracker->update(frame,roi); + bool isfound = tracker->update(frame,roi); + if(!isfound) + { + cout << "The target has been lost...\n"; + waitKey(0); + return 0; + } // draw the tracked object rectangle( frame, roi, Scalar( 255, 0, 0 ), 2, 1 ); @@ -95,100 +80,3 @@ int main( int argc, char** argv ){ } } - -void BoxExtractor::mouseHandler(int event, int x, int y, int flags, void *param){ - BoxExtractor *self =static_cast(param); - self->opencv_mouse_callback(event,x,y,flags,param); -} - -void BoxExtractor::opencv_mouse_callback( int event, int x, int y, int , void *param ){ - handlerT * data = (handlerT*)param; - switch( event ){ - // update the selected bounding box - case EVENT_MOUSEMOVE: - if( data->isDrawing ){ - data->box.width = x-data->box.x; - data->box.height = y-data->box.y; - } - break; - - // start to select the bounding box - case EVENT_LBUTTONDOWN: - data->isDrawing = true; - data->box = cvRect( x, y, 0, 0 ); - break; - - // cleaning up the selected bounding box - case EVENT_LBUTTONUP: - data->isDrawing = false; - if( data->box.width < 0 ){ - data->box.x += data->box.width; - data->box.width *= -1; - } - if( data->box.height < 0 ){ - data->box.y += data->box.height; - data->box.height *= -1; - } - break; - } -} - -Rect2d BoxExtractor::extract(Mat img){ - return extract("Bounding Box Extractor", img); -} - -Rect2d BoxExtractor::extract(const std::string& windowName, Mat img, bool showCrossair){ - - int key=0; - - // show the image and give feedback to user - imshow(windowName,img); - printf("Select an object to track and then press SPACE/BACKSPACE/ENTER button!\n"); - - // copy the data, rectangle should be drawn in the fresh image - params.image=img.clone(); - - // select the object - setMouseCallback( windowName, mouseHandler, (void *)¶ms ); - - // end selection process on SPACE (32) BACKSPACE (27) or ENTER (13) - while(!(key==32 || key==27 || key==13)){ - // draw the selected object - rectangle( - params.image, - params.box, - Scalar(255,0,0),2,1 - ); - - // draw cross air in the middle of bounding box - if(showCrossair){ - // horizontal line - line( - params.image, - Point((int)params.box.x,(int)(params.box.y+params.box.height/2)), - Point((int)(params.box.x+params.box.width),(int)(params.box.y+params.box.height/2)), - Scalar(255,0,0),2,1 - ); - - // vertical line - line( - params.image, - Point((int)(params.box.x+params.box.width/2),(int)params.box.y), - Point((int)(params.box.x+params.box.width/2),(int)(params.box.y+params.box.height)), - Scalar(255,0,0),2,1 - ); - } - - // show the image bouding box - imshow(windowName,params.image); - - // reset the image - params.image=img.clone(); - - //get keyboard event - key=waitKey(1); - } - - - return params.box; -} diff --git a/modules/tracking/src/trackerKCF.cpp b/modules/tracking/src/trackerKCF.cpp index fb0f43d415..c90245c3d6 100644 --- a/modules/tracking/src/trackerKCF.cpp +++ b/modules/tracking/src/trackerKCF.cpp @@ -341,6 +341,10 @@ namespace cv{ // extract the maximum response minMaxLoc( response, &minVal, &maxVal, &minLoc, &maxLoc ); + if (maxVal < params.detect_thresh) + { + return false; + } roi.x+=(maxLoc.x-roi.width/2+1); roi.y+=(maxLoc.y-roi.height/2+1); } @@ -821,6 +825,7 @@ namespace cv{ * Parameters */ TrackerKCF::Params::Params(){ + detect_thresh = 0.5; sigma=0.2; lambda=0.01; interp_factor=0.075; @@ -841,6 +846,9 @@ namespace cv{ void TrackerKCF::Params::read( const cv::FileNode& fn ){ *this = TrackerKCF::Params(); + if (!fn["detect_thresh"].empty()) + fn["detect_thresh"] >> detect_thresh; + if (!fn["sigma"].empty()) fn["sigma"] >> sigma; @@ -883,6 +891,7 @@ namespace cv{ } void TrackerKCF::Params::write( cv::FileStorage& fs ) const{ + fs << "detect_thresh" << detect_thresh; fs << "sigma" << sigma; fs << "lambda" << lambda; fs << "interp_factor" << interp_factor;