From 118c1b4ace2641e55d2b537c9f8515b72165dc73 Mon Sep 17 00:00:00 2001 From: E Sommerlade Date: Tue, 25 Oct 2016 20:18:41 +0100 Subject: [PATCH] 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; }