diff --git a/main_demo.cpp b/main_demo.cpp index eb3434a..7171969 100644 --- a/main_demo.cpp +++ b/main_demo.cpp @@ -13,7 +13,9 @@ cv::Point g_botRight(0,0); cv::Point g_botRight_tmp(0,0); bool plot = false; bool g_trackerInitialized = false; -ColorTracker * g_tracker = NULL; +ColorTracker *g_tracker = NULL; + + static void onMouse( int event, int x, int y, int, void* param) { @@ -29,7 +31,7 @@ static void onMouse( int event, int x, int y, int, void* param) if (g_tracker != NULL) delete g_tracker; g_tracker = new ColorTracker(); - g_tracker->init(*(cv::Mat *)param, g_topLeft.x, g_topLeft.y, g_botRight.x, g_botRight.y); + g_tracker->init(*(cv::Mat *)param, Rect2d(g_topLeft.x, g_topLeft.y, g_botRight.x - g_topLeft.x, g_botRight.y - g_topLeft.y)); g_trackerInitialized = true; }else if (event == cv::EVENT_MOUSEMOVE && !g_trackerInitialized){ //plot bbox @@ -83,7 +85,10 @@ int main(int argc, char **argv) } if (g_trackerInitialized && g_tracker != NULL){ - bb = g_tracker->track(img); + if (bb == NULL) { + bb = new Rect2d(); + } + g_tracker->update(img, *bb); } if (!g_trackerInitialized && plot && g_botRight_tmp.x > 0){ diff --git a/main_vot.cpp b/main_vot.cpp index 8ce12cb..51bc11e 100644 --- a/main_vot.cpp +++ b/main_vot.cpp @@ -23,21 +23,23 @@ int main(int, char **) vot_io.getNextImage(image); //tracker initialization - tracker.init(image, init_rect.x, init_rect.y, init_rect.x + init_rect.width, init_rect.y + init_rect.height); + tracker.init(image, init_rect); //track double average_speed_ms = 0.0; double num_frames = 0.0; while (vot_io.getNextImage(image) == 1){ + Rect2d bb; double time_profile_counter = cv::getCPUTickCount(); - BBox * bb = tracker.track(image); + + bool success = tracker.update(image, bb); + time_profile_counter = cv::getCPUTickCount() - time_profile_counter; average_speed_ms += time_profile_counter/((double)cvGetTickFrequency()*1000); num_frames += 1.0; - if (bb != NULL){ - vot_io.outputBoundingBox(cv::Rect(bb->x, bb->y, bb->width, bb->height)); - delete bb; + if (success){ + vot_io.outputBoundingBox(cv::Rect(bb.x, bb.y, bb.width, bb.height)); } else { vot_io.outputBoundingBox(cv::Rect(std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN())); } diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index cc60cb9..428465b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -4,4 +4,4 @@ set(COLOR_LIB_SRC colotracker.cpp histogram.cpp region.cpp) add_library(color STATIC ${COLOR_LIB_SRC}) target_link_libraries(color ${OpenCV_LIBS}) -set_target_properties(color PROPERTIES VERSION 1.0.0 SOVERSION 1) \ No newline at end of file +set_target_properties(color PROPERTIES VERSION 1.0.0 SOVERSION 1) diff --git a/src/colotracker.cpp b/src/colotracker.cpp index 1b58d33..95e0277 100644 --- a/src/colotracker.cpp +++ b/src/colotracker.cpp @@ -2,17 +2,17 @@ #include #include -void ColorTracker::init(cv::Mat & img, int x1, int y1, int x2, int y2) +bool ColorTracker::initImpl(const cv::Mat & img, const cv::Rect2d & initial) { im1 = cv::Mat( img.rows, img.cols, CV_8UC1 ); im2 = cv::Mat( img.rows, img.cols, CV_8UC1 ); im3 = cv::Mat( img.rows, img.cols, CV_8UC1 ); //boundary checks - y1 = std::max(0, y1); - y2 = std::min(img.rows-1, y2); - x1 = std::max(0, x1); - x2 = std::min(img.cols-1, x2); + const double y1 = std::max(0.0, initial.y); + const double y2 = std::min(img.rows-1.0, initial.y + initial.height); + const double x1 = std::max(0.0, initial.x); + const double x2 = std::min(img.cols-1.0, initial.x + initial.width); preprocessImage(img); @@ -65,6 +65,9 @@ void ColorTracker::init(cv::Mat & img, int x1, int y1, int x2, int y2) bound1 = 0.05; bound2 = 0.1; + model = cv::Ptr(new ColorTrackerModel()); + + return true; } cv::Point ColorTracker::histMeanShift(double x1, double y1, double x2, double y2) @@ -379,10 +382,15 @@ cv::Point ColorTracker::histMeanShiftAnisotropicScale(double x1, double y1, doub -BBox * ColorTracker::track(cv::Mat & img, double x1, double y1, double x2, double y2) +bool ColorTracker::updateImpl(const cv::Mat & img, cv::Rect2d & boundingBox) { - double width = x2-x1; - double height = y2-y1; + + double width = lastPosition.width; + double height = lastPosition.height; + double x1 = lastPosition.x; + double y1 = lastPosition.y; + double x2 = lastPosition.x + width; + double y2 = lastPosition.y + height; im1_old = im1.clone(); im2_old = im2.clone(); @@ -424,15 +432,24 @@ BBox * ColorTracker::track(cv::Mat & img, double x1, double y1, double x2, doubl } } - BBox * retBB = new BBox(); - retBB->setBBox(modeCenter.x - width/2, modeCenter.y - height/2, width, height, 1, 1); - lastPosition.setBBox(modeCenter.x - width/2, modeCenter.y - height/2, width, height, 1, 1); + boundingBox.x = modeCenter.x - width/2; + boundingBox.y = modeCenter.y - height/2; + boundingBox.width = width; + boundingBox.height = height; + + lastPosition.x = modeCenter.x - width/2; + lastPosition.y = modeCenter.y - height/2; + lastPosition.width = width; + lastPosition.height = height; + lastPosition.accuracy = 1; + lastPosition.normCross = 1; + frame++; - return retBB; + return true; } -void ColorTracker::preprocessImage(cv::Mat &img) +void ColorTracker::preprocessImage(const cv::Mat &img) { cv::Mat ra[3] = {im1, im2, im3}; cv::split(img, ra); @@ -520,4 +537,4 @@ void ColorTracker::extractForegroundHistogram(int x1, int y1, int x2, int y2, Hi hist.clear(); hist.insertValues(data1, data2, data3, weights); -} \ No newline at end of file +} diff --git a/src/colotracker.h b/src/colotracker.h index 91a71ee..a4c14a6 100644 --- a/src/colotracker.h +++ b/src/colotracker.h @@ -2,6 +2,8 @@ #define COLOTRACKER_H #include "cv.h" +#include "opencv2/core/persistence.hpp" +#include "opencv2/tracking/tracker.hpp" #include "highgui.h" #include "region.h" #include "histogram.h" @@ -14,7 +16,14 @@ #define BIN_2 16 #define BIN_3 16 -class ColorTracker +class ColorTrackerModel: public cv::TrackerModel { + void modelEstimationImpl(const std::vector&) { } + void modelUpdateImpl() { } +}; + + + +class ColorTracker : public cv::Tracker { private: BBox lastPosition; @@ -41,7 +50,7 @@ class ColorTracker cv::Point histMeanShiftIsotropicScale(double x1, double y1, double x2, double y2, double * scale, int * msIter = NULL); cv::Point histMeanShiftAnisotropicScale(double x1, double y1, double x2, double y2, double * width, double * height); - void preprocessImage(cv::Mat & img); + void preprocessImage(const cv::Mat & img); void extractBackgroundHistogram(int x1, int y1, int x2, int y2, Histogram &hist); void extractForegroundHistogram(int x1, int y1, int x2, int y2, Histogram &hist); @@ -55,8 +64,13 @@ class ColorTracker int frame; int sumIter; + // Abstract methods for param IO in cv::Tracker + void read(const cv::FileNode&) {} + void write(cv::FileStorage&) const {} + + // Init methods - void init(cv::Mat & img, int x1, int y1, int x2, int y2); + bool initImpl(const cv::Mat & img, const cv::Rect2d & output); // Set last object position - starting position for next tracking step inline void setLastBBox(int x1, int y1, int x2, int y2) @@ -72,11 +86,7 @@ class ColorTracker } // frame-to-frame object tracking - BBox * track(cv::Mat & img, double x1, double y1, double x2, double y2); - inline BBox * track(cv::Mat & img) - { - return track(img, lastPosition.x, lastPosition.y, lastPosition.x + lastPosition.width, lastPosition.y + lastPosition.height); - } + bool updateImpl(const cv::Mat & img, cv::Rect2d & output); }; #endif // COLOTRACKER_H diff --git a/src/region.h b/src/region.h index a007bf9..e5083a2 100644 --- a/src/region.h +++ b/src/region.h @@ -9,9 +9,9 @@ #define BBOX_C3F6FA38_1DD3_4796_8FB6_62A80862095F__INCLUDED_ #include +#include "cv.h" - -class BBox +class BBox : public cv::Rect2d { public: @@ -24,10 +24,6 @@ class BBox double accuracy; double normCross; - double height; - double width; - double x; - double y; double * getTopLeftWidthHeight(); void setBBox(double _x, double _y, double _width, double _height, double _accuracy, double _normCross = 0); @@ -37,8 +33,8 @@ class BBox static std::vector clusterBBoxes(std::vector & BB); static std::vector findDiff(std::vector & A, std::vector & B); - - bool operator==(const BBox & right) const + template + bool operator==(const Other & right) const { if ( (this->x - right.x) != 0 || (this->y - right.y) != 1 || @@ -48,7 +44,8 @@ class BBox return true; } - bool operator!=(const BBox & right) const + template + bool operator!=(const Other & right) const { return !(*this == right); }