//M*/
#include "precomp.hpp"
+#include <cassert>
#if (defined(__cplusplus) && __cplusplus > 199711L) || (defined(_MSC_VER) && _MSC_VER >= 1700)
#define USE_STD_THREADS
class cv::DetectionBasedTracker::SeparateDetectionWork
{
public:
- SeparateDetectionWork(cv::DetectionBasedTracker& _detectionBasedTracker, cv::Ptr<DetectionBasedTracker::IDetector> _detector);
+ SeparateDetectionWork(cv::DetectionBasedTracker& _detectionBasedTracker, cv::Ptr<DetectionBasedTracker::IDetector> _detector,
+ const cv::DetectionBasedTracker::Parameters& params);
virtual ~SeparateDetectionWork();
bool communicateWithDetectingThread(const Mat& imageGray, std::vector<Rect>& rectsWhereRegions);
bool run();
{
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<std::mutex> mtx_lock(mtx);
+ parameters = params;
}
- inline void unlock()
+
+ inline void init()
{
+ std::unique_lock<std::mutex> 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;
#ifdef USE_STD_THREADS
std::thread second_workthread;
std::mutex mtx;
- std::unique_lock<std::mutex> mtx_lock;
std::condition_variable objectDetectorRun;
std::condition_variable objectDetectorThreadStartStop;
#else
friend void* workcycleObjectDetectorFunction(void* p);
long long timeWhenDetectingThreadStartedWork;
+ cv::DetectionBasedTracker::Parameters parameters;
};
-cv::DetectionBasedTracker::SeparateDetectionWork::SeparateDetectionWork(DetectionBasedTracker& _detectionBasedTracker, cv::Ptr<DetectionBasedTracker::IDetector> _detector)
+cv::DetectionBasedTracker::SeparateDetectionWork::SeparateDetectionWork(DetectionBasedTracker& _detectionBasedTracker, cv::Ptr<DetectionBasedTracker::IDetector> _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<std::mutex>(mtx);
- mtx_lock.unlock();
-#else
+#ifndef USE_STD_THREADS
int res=0;
res=pthread_mutex_init(&mutex, NULL);//TODO: should be attributes?
if (res) {
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<std::mutex> 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;
#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);
{
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");
}
CV_Assert(stateThread==STATE_THREAD_WORKING_SLEEPING);
#ifdef USE_STD_THREADS
- mtx_lock.lock();
+ std::unique_lock<std::mutex> mtx_lock(mtx);
#else
pthread_mutex_lock(&mutex);
#endif
{
//FIXME: TODO: should add quickStop functionality
#ifdef USE_STD_THREADS
- mtx_lock.lock();
+ std::unique_lock<std::mutex> mtx_lock(mtx);
#else
pthread_mutex_lock(&mutex);
#endif
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;
{
LOGD("DetectionBasedTracker::SeparateDetectionWork::resetTracking");
#ifdef USE_STD_THREADS
- mtx_lock.lock();
+ std::unique_lock<std::mutex> mtx_lock(mtx);
#else
pthread_mutex_lock(&mutex);
#endif
bool shouldHandleResult = false;
#ifdef USE_STD_THREADS
- mtx_lock.lock();
+ std::unique_lock<std::mutex> mtx_lock(mtx);
#else
pthread_mutex_lock(&mutex);
#endif
return shouldHandleResult;
}
-cv::DetectionBasedTracker::Parameters::Parameters()
-{
- maxTrackLifetime=5;
- minDetectionPeriod=0;
-}
-
cv::DetectionBasedTracker::InnerParameters::InnerParameters()
{
numLastPositionsToTrack=4;
&& trackingDetector );
if (mainDetector) {
- separateDetectionWork.reset(new SeparateDetectionWork(*this, mainDetector));
+ separateDetectionWork.reset(new SeparateDetectionWork(*this, mainDetector, params));
}
weightsPositionsSmoothing.push_back(1);
}
if (separateDetectionWork) {
- separateDetectionWork->lock();
+ separateDetectionWork->setParameters(params);
}
parameters=params;
- if (separateDetectionWork) {
- separateDetectionWork->unlock();
- }
return true;
}
-#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 <opencv2/imgproc.hpp> // Gaussian Blur
#include <opencv2/core.hpp> // Basic OpenCV structures (cv::Mat, Scalar)
std::string cascadeFrontalfilename = "../../data/lbpcascades/lbpcascade_frontalface.xml";
cv::Ptr<cv::CascadeClassifier> cascade = makePtr<cv::CascadeClassifier>(cascadeFrontalfilename);
cv::Ptr<DetectionBasedTracker::IDetector> MainDetector = makePtr<CascadeDetectorAdapter>(cascade);
+ if ( cascade->empty() )
+ {
+ printf("Error: Cannot load %s\n", cascadeFrontalfilename.c_str());
+ return 2;
+ }
cascade = makePtr<cv::CascadeClassifier>(cascadeFrontalfilename);
cv::Ptr<DetectionBasedTracker::IDetector> TrackingDetector = makePtr<CascadeDetectorAdapter>(cascade);
+ if ( cascade->empty() )
+ {
+ printf("Error: Cannot load %s\n", cascadeFrontalfilename.c_str());
+ return 2;
+ }
DetectionBasedTracker::Parameters params;
DetectionBasedTracker Detector(MainDetector, TrackingDetector, params);
#include <stdio.h>
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;
}