From 118c1b4ace2641e55d2b537c9f8515b72165dc73 Mon Sep 17 00:00:00 2001 From: E Sommerlade Date: Tue, 25 Oct 2016 20:18:41 +0100 Subject: [PATCH 1/5] fixed detection_based_tracker on visual studio 2013 and later --- .../objdetect/detection_based_tracker.hpp | 6 +- .../objdetect/src/detection_based_tracker.cpp | 81 ++++++++----------- samples/cpp/dbt_face_detection.cpp | 14 +++- 3 files changed, 50 insertions(+), 51 deletions(-) mode change 100644 => 100755 samples/cpp/dbt_face_detection.cpp diff --git a/modules/objdetect/include/opencv2/objdetect/detection_based_tracker.hpp b/modules/objdetect/include/opencv2/objdetect/detection_based_tracker.hpp index 080ae1b7e5..14845c47f8 100644 --- a/modules/objdetect/include/opencv2/objdetect/detection_based_tracker.hpp +++ b/modules/objdetect/include/opencv2/objdetect/detection_based_tracker.hpp @@ -64,7 +64,11 @@ class CV_EXPORTS DetectionBasedTracker int maxTrackLifetime; int minDetectionPeriod; //the minimal time between run of the big object detector (on the whole frame) in ms (1000 mean 1 sec), default=0 - Parameters(); + Parameters() + { + maxTrackLifetime=5; + minDetectionPeriod=0; + } }; class IDetector diff --git a/modules/objdetect/src/detection_based_tracker.cpp b/modules/objdetect/src/detection_based_tracker.cpp index 8c236c7594..2690f4f9d1 100644 --- a/modules/objdetect/src/detection_based_tracker.cpp +++ b/modules/objdetect/src/detection_based_tracker.cpp @@ -42,6 +42,7 @@ //M*/ #include "precomp.hpp" +#include #if (defined(__cplusplus) && __cplusplus > 199711L) || (defined(_MSC_VER) && _MSC_VER >= 1700) #define USE_STD_THREADS @@ -124,7 +125,8 @@ namespace cv class cv::DetectionBasedTracker::SeparateDetectionWork { public: - SeparateDetectionWork(cv::DetectionBasedTracker& _detectionBasedTracker, cv::Ptr _detector); + SeparateDetectionWork(cv::DetectionBasedTracker& _detectionBasedTracker, cv::Ptr _detector, + const cv::DetectionBasedTracker::Parameters& params); virtual ~SeparateDetectionWork(); bool communicateWithDetectingThread(const Mat& imageGray, std::vector& rectsWhereRegions); bool run(); @@ -135,23 +137,24 @@ class cv::DetectionBasedTracker::SeparateDetectionWork { return (stateThread==STATE_THREAD_WORKING_SLEEPING) || (stateThread==STATE_THREAD_WORKING_WITH_IMAGE); } - inline void lock() + void setParameters(const cv::DetectionBasedTracker::Parameters& params) { -#ifdef USE_STD_THREADS - mtx_lock.lock(); -#else - pthread_mutex_lock(&mutex); -#endif + std::unique_lock mtx_lock(mtx); + parameters = params; } - inline void unlock() + + inline void init() { + std::unique_lock mtx_lock(mtx); + stateThread = STATE_THREAD_STOPPED; + isObjectDetectingReady = false; + shouldObjectDetectingResultsBeForgot = false; #ifdef USE_STD_THREADS - mtx_lock.unlock(); + objectDetectorThreadStartStop.notify_one(); #else - pthread_mutex_unlock(&mutex); + pthread_cond_signal(&(objectDetectorThreadStartStop)); #endif } - protected: DetectionBasedTracker& detectionBasedTracker; @@ -159,7 +162,6 @@ class cv::DetectionBasedTracker::SeparateDetectionWork #ifdef USE_STD_THREADS std::thread second_workthread; std::mutex mtx; - std::unique_lock mtx_lock; std::condition_variable objectDetectorRun; std::condition_variable objectDetectorThreadStartStop; #else @@ -187,23 +189,23 @@ class cv::DetectionBasedTracker::SeparateDetectionWork friend void* workcycleObjectDetectorFunction(void* p); long long timeWhenDetectingThreadStartedWork; + cv::DetectionBasedTracker::Parameters parameters; }; -cv::DetectionBasedTracker::SeparateDetectionWork::SeparateDetectionWork(DetectionBasedTracker& _detectionBasedTracker, cv::Ptr _detector) +cv::DetectionBasedTracker::SeparateDetectionWork::SeparateDetectionWork(DetectionBasedTracker& _detectionBasedTracker, cv::Ptr _detector, + const cv::DetectionBasedTracker::Parameters& params) :detectionBasedTracker(_detectionBasedTracker), cascadeInThread(), isObjectDetectingReady(false), shouldObjectDetectingResultsBeForgot(false), stateThread(STATE_THREAD_STOPPED), - timeWhenDetectingThreadStartedWork(-1) + timeWhenDetectingThreadStartedWork(-1), + parameters(params) { CV_Assert(_detector); cascadeInThread = _detector; -#ifdef USE_STD_THREADS - mtx_lock = std::unique_lock(mtx); - mtx_lock.unlock(); -#else +#ifndef USE_STD_THREADS int res=0; res=pthread_mutex_init(&mutex, NULL);//TODO: should be attributes? if (res) { @@ -235,21 +237,22 @@ cv::DetectionBasedTracker::SeparateDetectionWork::~SeparateDetectionWork() pthread_cond_destroy(&objectDetectorThreadStartStop); pthread_cond_destroy(&objectDetectorRun); pthread_mutex_destroy(&mutex); +#else + second_workthread.join(); #endif } bool cv::DetectionBasedTracker::SeparateDetectionWork::run() { LOGD("DetectionBasedTracker::SeparateDetectionWork::run() --- start"); #ifdef USE_STD_THREADS - mtx_lock.lock(); + std::unique_lock mtx_lock(mtx); + // unlocked when leaving scope #else pthread_mutex_lock(&mutex); #endif if (stateThread != STATE_THREAD_STOPPED) { LOGE("DetectionBasedTracker::SeparateDetectionWork::run is called while the previous run is not stopped"); -#ifdef USE_STD_THREADS - mtx_lock.unlock(); -#else +#ifndef USE_STD_THREADS pthread_mutex_unlock(&mutex); #endif return false; @@ -258,7 +261,6 @@ bool cv::DetectionBasedTracker::SeparateDetectionWork::run() #ifdef USE_STD_THREADS second_workthread = std::thread(workcycleObjectDetectorFunction, (void*)this); //TODO: add attributes? objectDetectorThreadStartStop.wait(mtx_lock); - mtx_lock.unlock(); #else pthread_create(&second_workthread, NULL, workcycleObjectDetectorFunction, (void*)this); //TODO: add attributes? pthread_cond_wait(&objectDetectorThreadStartStop, &mutex); @@ -284,16 +286,7 @@ void* cv::workcycleObjectDetectorFunction(void* p) { CATCH_ALL_AND_LOG({ ((cv::DetectionBasedTracker::SeparateDetectionWork*)p)->workcycleObjectDetector(); }); try{ - ((cv::DetectionBasedTracker::SeparateDetectionWork*)p)->lock(); - ((cv::DetectionBasedTracker::SeparateDetectionWork*)p)->stateThread = cv::DetectionBasedTracker::SeparateDetectionWork::STATE_THREAD_STOPPED; - ((cv::DetectionBasedTracker::SeparateDetectionWork*)p)->isObjectDetectingReady=false; - ((cv::DetectionBasedTracker::SeparateDetectionWork*)p)->shouldObjectDetectingResultsBeForgot=false; -#ifdef USE_STD_THREADS - ((cv::DetectionBasedTracker::SeparateDetectionWork*)p)->objectDetectorThreadStartStop.notify_one(); -#else - pthread_cond_signal(&(((cv::DetectionBasedTracker::SeparateDetectionWork*)p)->objectDetectorThreadStartStop)); -#endif - ((cv::DetectionBasedTracker::SeparateDetectionWork*)p)->unlock(); + ((cv::DetectionBasedTracker::SeparateDetectionWork*)p)->init(); } catch(...) { LOGE0("DetectionBasedTracker: workcycleObjectDetectorFunction: ERROR concerning pointer, received as the function parameter"); } @@ -308,7 +301,7 @@ void cv::DetectionBasedTracker::SeparateDetectionWork::workcycleObjectDetector() CV_Assert(stateThread==STATE_THREAD_WORKING_SLEEPING); #ifdef USE_STD_THREADS - mtx_lock.lock(); + std::unique_lock mtx_lock(mtx); #else pthread_mutex_lock(&mutex); #endif @@ -453,7 +446,7 @@ void cv::DetectionBasedTracker::SeparateDetectionWork::stop() { //FIXME: TODO: should add quickStop functionality #ifdef USE_STD_THREADS - mtx_lock.lock(); + std::unique_lock mtx_lock(mtx); #else pthread_mutex_lock(&mutex); #endif @@ -464,6 +457,7 @@ void cv::DetectionBasedTracker::SeparateDetectionWork::stop() pthread_mutex_unlock(&mutex); #endif LOGE("SimpleHighguiDemoCore::stop is called but the SimpleHighguiDemoCore pthread is not active"); + stateThread = STATE_THREAD_STOPPING; return; } stateThread=STATE_THREAD_STOPPING; @@ -485,7 +479,7 @@ void cv::DetectionBasedTracker::SeparateDetectionWork::resetTracking() { LOGD("DetectionBasedTracker::SeparateDetectionWork::resetTracking"); #ifdef USE_STD_THREADS - mtx_lock.lock(); + std::unique_lock mtx_lock(mtx); #else pthread_mutex_lock(&mutex); #endif @@ -523,7 +517,7 @@ bool cv::DetectionBasedTracker::SeparateDetectionWork::communicateWithDetectingT bool shouldHandleResult = false; #ifdef USE_STD_THREADS - mtx_lock.lock(); + std::unique_lock mtx_lock(mtx); #else pthread_mutex_lock(&mutex); #endif @@ -572,12 +566,6 @@ bool cv::DetectionBasedTracker::SeparateDetectionWork::communicateWithDetectingT return shouldHandleResult; } -cv::DetectionBasedTracker::Parameters::Parameters() -{ - maxTrackLifetime=5; - minDetectionPeriod=0; -} - cv::DetectionBasedTracker::InnerParameters::InnerParameters() { numLastPositionsToTrack=4; @@ -603,7 +591,7 @@ cv::DetectionBasedTracker::DetectionBasedTracker(cv::Ptr mainDetector && trackingDetector ); if (mainDetector) { - separateDetectionWork.reset(new SeparateDetectionWork(*this, mainDetector)); + separateDetectionWork.reset(new SeparateDetectionWork(*this, mainDetector, params)); } weightsPositionsSmoothing.push_back(1); @@ -1016,12 +1004,9 @@ bool cv::DetectionBasedTracker::setParameters(const Parameters& params) } if (separateDetectionWork) { - separateDetectionWork->lock(); + separateDetectionWork->setParameters(params); } parameters=params; - if (separateDetectionWork) { - separateDetectionWork->unlock(); - } return true; } diff --git a/samples/cpp/dbt_face_detection.cpp b/samples/cpp/dbt_face_detection.cpp old mode 100644 new mode 100755 index 920ae001d8..355dd52a65 --- a/samples/cpp/dbt_face_detection.cpp +++ b/samples/cpp/dbt_face_detection.cpp @@ -1,4 +1,4 @@ -#if defined(__linux__) || defined(LINUX) || defined(__APPLE__) || defined(ANDROID) +#if defined(__linux__) || defined(LINUX) || defined(__APPLE__) || defined(ANDROID) || (defined(_MSC_VER) && _MSC_VER>1700) #include // Gaussian Blur #include // Basic OpenCV structures (cv::Mat, Scalar) @@ -54,9 +54,19 @@ int main(int , char** ) std::string cascadeFrontalfilename = "../../data/lbpcascades/lbpcascade_frontalface.xml"; cv::Ptr cascade = makePtr(cascadeFrontalfilename); cv::Ptr MainDetector = makePtr(cascade); + if ( cascade->empty() ) + { + printf("Error: Cannot load %s\n", cascadeFrontalfilename.c_str()); + return 2; + } cascade = makePtr(cascadeFrontalfilename); cv::Ptr TrackingDetector = makePtr(cascade); + if ( cascade->empty() ) + { + printf("Error: Cannot load %s\n", cascadeFrontalfilename.c_str()); + return 2; + } DetectionBasedTracker::Parameters params; DetectionBasedTracker Detector(MainDetector, TrackingDetector, params); @@ -98,7 +108,7 @@ int main(int , char** ) #include int main() { - printf("This sample works for UNIX or ANDROID only\n"); + printf("This sample works for UNIX or ANDROID or Visual Studio 2013+ only\n"); return 0; } From d0474a9b813cc4fca6d2f8524ce730d5b1d72891 Mon Sep 17 00:00:00 2001 From: E Sommerlade Date: Wed, 26 Oct 2016 15:37:06 +0100 Subject: [PATCH 2/5] fixed use of std::lock outside of ifdefs --- modules/objdetect/src/detection_based_tracker.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/modules/objdetect/src/detection_based_tracker.cpp b/modules/objdetect/src/detection_based_tracker.cpp index 2690f4f9d1..0b643926e8 100644 --- a/modules/objdetect/src/detection_based_tracker.cpp +++ b/modules/objdetect/src/detection_based_tracker.cpp @@ -139,13 +139,24 @@ class cv::DetectionBasedTracker::SeparateDetectionWork } void setParameters(const cv::DetectionBasedTracker::Parameters& params) { +#ifdef USE_STD_THREADS std::unique_lock mtx_lock(mtx); +#else + pthread_mutex_lock(&mutex); +#endif parameters = params; +#ifndef USE_STD_THREADS + pthread_mutex_unlock(&mutex); +#endif } inline void init() { +#ifdef USE_STD_THREADS std::unique_lock mtx_lock(mtx); +#else + pthread_mutex_lock(&mutex); +#endif stateThread = STATE_THREAD_STOPPED; isObjectDetectingReady = false; shouldObjectDetectingResultsBeForgot = false; @@ -153,6 +164,7 @@ class cv::DetectionBasedTracker::SeparateDetectionWork objectDetectorThreadStartStop.notify_one(); #else pthread_cond_signal(&(objectDetectorThreadStartStop)); + pthread_mutex_unlock(&mutex); #endif } protected: From 41c47a84fc55aa2eacc76c1ccb5288e265a493df Mon Sep 17 00:00:00 2001 From: E Sommerlade Date: Wed, 26 Oct 2016 15:59:44 +0100 Subject: [PATCH 3/5] restored Parameters() constructor to maintain ABI compatibility. Added CV_EXPORTS to nested class --- .../include/opencv2/objdetect/detection_based_tracker.hpp | 8 ++------ modules/objdetect/src/detection_based_tracker.cpp | 6 ++++++ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/modules/objdetect/include/opencv2/objdetect/detection_based_tracker.hpp b/modules/objdetect/include/opencv2/objdetect/detection_based_tracker.hpp index 14845c47f8..44213a818a 100644 --- a/modules/objdetect/include/opencv2/objdetect/detection_based_tracker.hpp +++ b/modules/objdetect/include/opencv2/objdetect/detection_based_tracker.hpp @@ -59,16 +59,12 @@ namespace cv class CV_EXPORTS DetectionBasedTracker { public: - struct Parameters + struct CV_EXPORTS Parameters { int maxTrackLifetime; int minDetectionPeriod; //the minimal time between run of the big object detector (on the whole frame) in ms (1000 mean 1 sec), default=0 - Parameters() - { - maxTrackLifetime=5; - minDetectionPeriod=0; - } + Parameters(); }; class IDetector diff --git a/modules/objdetect/src/detection_based_tracker.cpp b/modules/objdetect/src/detection_based_tracker.cpp index 0b643926e8..5bff2f9ab6 100644 --- a/modules/objdetect/src/detection_based_tracker.cpp +++ b/modules/objdetect/src/detection_based_tracker.cpp @@ -578,6 +578,12 @@ bool cv::DetectionBasedTracker::SeparateDetectionWork::communicateWithDetectingT return shouldHandleResult; } +cv::DetectionBasedTracker::Parameters::Parameters() +{ + maxTrackLifetime = 5; + minDetectionPeriod = 0; +} + cv::DetectionBasedTracker::InnerParameters::InnerParameters() { numLastPositionsToTrack=4; From c93de78ff659ed435ed430b66d55f09ad032f2e8 Mon Sep 17 00:00:00 2001 From: E Sommerlade Date: Wed, 26 Oct 2016 19:59:10 +0100 Subject: [PATCH 4/5] removed spaces at line endings, fixed warning --- modules/objdetect/src/detection_based_tracker.cpp | 6 +++--- samples/cpp/dbt_face_detection.cpp | 6 ++---- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/modules/objdetect/src/detection_based_tracker.cpp b/modules/objdetect/src/detection_based_tracker.cpp index 5bff2f9ab6..88c7923efa 100644 --- a/modules/objdetect/src/detection_based_tracker.cpp +++ b/modules/objdetect/src/detection_based_tracker.cpp @@ -125,7 +125,7 @@ namespace cv class cv::DetectionBasedTracker::SeparateDetectionWork { public: - SeparateDetectionWork(cv::DetectionBasedTracker& _detectionBasedTracker, cv::Ptr _detector, + SeparateDetectionWork(cv::DetectionBasedTracker& _detectionBasedTracker, cv::Ptr _detector, const cv::DetectionBasedTracker::Parameters& params); virtual ~SeparateDetectionWork(); bool communicateWithDetectingThread(const Mat& imageGray, std::vector& rectsWhereRegions); @@ -204,14 +204,14 @@ class cv::DetectionBasedTracker::SeparateDetectionWork cv::DetectionBasedTracker::Parameters parameters; }; -cv::DetectionBasedTracker::SeparateDetectionWork::SeparateDetectionWork(DetectionBasedTracker& _detectionBasedTracker, cv::Ptr _detector, +cv::DetectionBasedTracker::SeparateDetectionWork::SeparateDetectionWork(DetectionBasedTracker& _detectionBasedTracker, cv::Ptr _detector, const cv::DetectionBasedTracker::Parameters& params) :detectionBasedTracker(_detectionBasedTracker), cascadeInThread(), isObjectDetectingReady(false), shouldObjectDetectingResultsBeForgot(false), stateThread(STATE_THREAD_STOPPED), - timeWhenDetectingThreadStartedWork(-1), + timeWhenDetectingThreadStartedWork(-1), parameters(params) { CV_Assert(_detector); diff --git a/samples/cpp/dbt_face_detection.cpp b/samples/cpp/dbt_face_detection.cpp index 355dd52a65..0b465cdc23 100755 --- a/samples/cpp/dbt_face_detection.cpp +++ b/samples/cpp/dbt_face_detection.cpp @@ -81,7 +81,7 @@ int main(int , char** ) Mat GrayFrame; vector Faces; - while(true) + do { VideoStream >> ReferenceFrame; cvtColor(ReferenceFrame, GrayFrame, COLOR_RGB2GRAY); @@ -94,9 +94,7 @@ int main(int , char** ) } imshow(WindowName, ReferenceFrame); - - if (waitKey(30) >= 0) break; - } + } while (waitKey(30) < 0); Detector.stop(); From d00dcb1b3a8f026118df41e625221c65609afb23 Mon Sep 17 00:00:00 2001 From: E Sommerlade Date: Mon, 31 Oct 2016 09:47:44 +0000 Subject: [PATCH 5/5] reversed mysterious mode change --- samples/cpp/dbt_face_detection.cpp | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 samples/cpp/dbt_face_detection.cpp diff --git a/samples/cpp/dbt_face_detection.cpp b/samples/cpp/dbt_face_detection.cpp old mode 100755 new mode 100644