mirror of
https://github.com/opencv/opencv.git
synced 2025-07-26 07:07:37 +08:00
Merge pull request #7552 from es0m:master
This commit is contained in:
commit
050731c4d2
@ -59,7 +59,7 @@ namespace cv
|
|||||||
class CV_EXPORTS DetectionBasedTracker
|
class CV_EXPORTS DetectionBasedTracker
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
struct Parameters
|
struct CV_EXPORTS Parameters
|
||||||
{
|
{
|
||||||
int maxTrackLifetime;
|
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
|
int minDetectionPeriod; //the minimal time between run of the big object detector (on the whole frame) in ms (1000 mean 1 sec), default=0
|
||||||
|
@ -42,6 +42,7 @@
|
|||||||
//M*/
|
//M*/
|
||||||
|
|
||||||
#include "precomp.hpp"
|
#include "precomp.hpp"
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
#if (defined(__cplusplus) && __cplusplus > 199711L) || (defined(_MSC_VER) && _MSC_VER >= 1700)
|
#if (defined(__cplusplus) && __cplusplus > 199711L) || (defined(_MSC_VER) && _MSC_VER >= 1700)
|
||||||
#define USE_STD_THREADS
|
#define USE_STD_THREADS
|
||||||
@ -124,7 +125,8 @@ namespace cv
|
|||||||
class cv::DetectionBasedTracker::SeparateDetectionWork
|
class cv::DetectionBasedTracker::SeparateDetectionWork
|
||||||
{
|
{
|
||||||
public:
|
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();
|
virtual ~SeparateDetectionWork();
|
||||||
bool communicateWithDetectingThread(const Mat& imageGray, std::vector<Rect>& rectsWhereRegions);
|
bool communicateWithDetectingThread(const Mat& imageGray, std::vector<Rect>& rectsWhereRegions);
|
||||||
bool run();
|
bool run();
|
||||||
@ -135,23 +137,36 @@ class cv::DetectionBasedTracker::SeparateDetectionWork
|
|||||||
{
|
{
|
||||||
return (stateThread==STATE_THREAD_WORKING_SLEEPING) || (stateThread==STATE_THREAD_WORKING_WITH_IMAGE);
|
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
|
#ifdef USE_STD_THREADS
|
||||||
mtx_lock.lock();
|
std::unique_lock<std::mutex> mtx_lock(mtx);
|
||||||
#else
|
#else
|
||||||
pthread_mutex_lock(&mutex);
|
pthread_mutex_lock(&mutex);
|
||||||
#endif
|
#endif
|
||||||
}
|
parameters = params;
|
||||||
inline void unlock()
|
#ifndef USE_STD_THREADS
|
||||||
{
|
|
||||||
#ifdef USE_STD_THREADS
|
|
||||||
mtx_lock.unlock();
|
|
||||||
#else
|
|
||||||
pthread_mutex_unlock(&mutex);
|
pthread_mutex_unlock(&mutex);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void init()
|
||||||
|
{
|
||||||
|
#ifdef USE_STD_THREADS
|
||||||
|
std::unique_lock<std::mutex> mtx_lock(mtx);
|
||||||
|
#else
|
||||||
|
pthread_mutex_lock(&mutex);
|
||||||
|
#endif
|
||||||
|
stateThread = STATE_THREAD_STOPPED;
|
||||||
|
isObjectDetectingReady = false;
|
||||||
|
shouldObjectDetectingResultsBeForgot = false;
|
||||||
|
#ifdef USE_STD_THREADS
|
||||||
|
objectDetectorThreadStartStop.notify_one();
|
||||||
|
#else
|
||||||
|
pthread_cond_signal(&(objectDetectorThreadStartStop));
|
||||||
|
pthread_mutex_unlock(&mutex);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
DetectionBasedTracker& detectionBasedTracker;
|
DetectionBasedTracker& detectionBasedTracker;
|
||||||
@ -159,7 +174,6 @@ class cv::DetectionBasedTracker::SeparateDetectionWork
|
|||||||
#ifdef USE_STD_THREADS
|
#ifdef USE_STD_THREADS
|
||||||
std::thread second_workthread;
|
std::thread second_workthread;
|
||||||
std::mutex mtx;
|
std::mutex mtx;
|
||||||
std::unique_lock<std::mutex> mtx_lock;
|
|
||||||
std::condition_variable objectDetectorRun;
|
std::condition_variable objectDetectorRun;
|
||||||
std::condition_variable objectDetectorThreadStartStop;
|
std::condition_variable objectDetectorThreadStartStop;
|
||||||
#else
|
#else
|
||||||
@ -187,23 +201,23 @@ class cv::DetectionBasedTracker::SeparateDetectionWork
|
|||||||
friend void* workcycleObjectDetectorFunction(void* p);
|
friend void* workcycleObjectDetectorFunction(void* p);
|
||||||
|
|
||||||
long long timeWhenDetectingThreadStartedWork;
|
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),
|
:detectionBasedTracker(_detectionBasedTracker),
|
||||||
cascadeInThread(),
|
cascadeInThread(),
|
||||||
isObjectDetectingReady(false),
|
isObjectDetectingReady(false),
|
||||||
shouldObjectDetectingResultsBeForgot(false),
|
shouldObjectDetectingResultsBeForgot(false),
|
||||||
stateThread(STATE_THREAD_STOPPED),
|
stateThread(STATE_THREAD_STOPPED),
|
||||||
timeWhenDetectingThreadStartedWork(-1)
|
timeWhenDetectingThreadStartedWork(-1),
|
||||||
|
parameters(params)
|
||||||
{
|
{
|
||||||
CV_Assert(_detector);
|
CV_Assert(_detector);
|
||||||
|
|
||||||
cascadeInThread = _detector;
|
cascadeInThread = _detector;
|
||||||
#ifdef USE_STD_THREADS
|
#ifndef USE_STD_THREADS
|
||||||
mtx_lock = std::unique_lock<std::mutex>(mtx);
|
|
||||||
mtx_lock.unlock();
|
|
||||||
#else
|
|
||||||
int res=0;
|
int res=0;
|
||||||
res=pthread_mutex_init(&mutex, NULL);//TODO: should be attributes?
|
res=pthread_mutex_init(&mutex, NULL);//TODO: should be attributes?
|
||||||
if (res) {
|
if (res) {
|
||||||
@ -235,21 +249,22 @@ cv::DetectionBasedTracker::SeparateDetectionWork::~SeparateDetectionWork()
|
|||||||
pthread_cond_destroy(&objectDetectorThreadStartStop);
|
pthread_cond_destroy(&objectDetectorThreadStartStop);
|
||||||
pthread_cond_destroy(&objectDetectorRun);
|
pthread_cond_destroy(&objectDetectorRun);
|
||||||
pthread_mutex_destroy(&mutex);
|
pthread_mutex_destroy(&mutex);
|
||||||
|
#else
|
||||||
|
second_workthread.join();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
bool cv::DetectionBasedTracker::SeparateDetectionWork::run()
|
bool cv::DetectionBasedTracker::SeparateDetectionWork::run()
|
||||||
{
|
{
|
||||||
LOGD("DetectionBasedTracker::SeparateDetectionWork::run() --- start");
|
LOGD("DetectionBasedTracker::SeparateDetectionWork::run() --- start");
|
||||||
#ifdef USE_STD_THREADS
|
#ifdef USE_STD_THREADS
|
||||||
mtx_lock.lock();
|
std::unique_lock<std::mutex> mtx_lock(mtx);
|
||||||
|
// unlocked when leaving scope
|
||||||
#else
|
#else
|
||||||
pthread_mutex_lock(&mutex);
|
pthread_mutex_lock(&mutex);
|
||||||
#endif
|
#endif
|
||||||
if (stateThread != STATE_THREAD_STOPPED) {
|
if (stateThread != STATE_THREAD_STOPPED) {
|
||||||
LOGE("DetectionBasedTracker::SeparateDetectionWork::run is called while the previous run is not stopped");
|
LOGE("DetectionBasedTracker::SeparateDetectionWork::run is called while the previous run is not stopped");
|
||||||
#ifdef USE_STD_THREADS
|
#ifndef USE_STD_THREADS
|
||||||
mtx_lock.unlock();
|
|
||||||
#else
|
|
||||||
pthread_mutex_unlock(&mutex);
|
pthread_mutex_unlock(&mutex);
|
||||||
#endif
|
#endif
|
||||||
return false;
|
return false;
|
||||||
@ -258,7 +273,6 @@ bool cv::DetectionBasedTracker::SeparateDetectionWork::run()
|
|||||||
#ifdef USE_STD_THREADS
|
#ifdef USE_STD_THREADS
|
||||||
second_workthread = std::thread(workcycleObjectDetectorFunction, (void*)this); //TODO: add attributes?
|
second_workthread = std::thread(workcycleObjectDetectorFunction, (void*)this); //TODO: add attributes?
|
||||||
objectDetectorThreadStartStop.wait(mtx_lock);
|
objectDetectorThreadStartStop.wait(mtx_lock);
|
||||||
mtx_lock.unlock();
|
|
||||||
#else
|
#else
|
||||||
pthread_create(&second_workthread, NULL, workcycleObjectDetectorFunction, (void*)this); //TODO: add attributes?
|
pthread_create(&second_workthread, NULL, workcycleObjectDetectorFunction, (void*)this); //TODO: add attributes?
|
||||||
pthread_cond_wait(&objectDetectorThreadStartStop, &mutex);
|
pthread_cond_wait(&objectDetectorThreadStartStop, &mutex);
|
||||||
@ -284,16 +298,7 @@ void* cv::workcycleObjectDetectorFunction(void* p)
|
|||||||
{
|
{
|
||||||
CATCH_ALL_AND_LOG({ ((cv::DetectionBasedTracker::SeparateDetectionWork*)p)->workcycleObjectDetector(); });
|
CATCH_ALL_AND_LOG({ ((cv::DetectionBasedTracker::SeparateDetectionWork*)p)->workcycleObjectDetector(); });
|
||||||
try{
|
try{
|
||||||
((cv::DetectionBasedTracker::SeparateDetectionWork*)p)->lock();
|
((cv::DetectionBasedTracker::SeparateDetectionWork*)p)->init();
|
||||||
((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();
|
|
||||||
} catch(...) {
|
} catch(...) {
|
||||||
LOGE0("DetectionBasedTracker: workcycleObjectDetectorFunction: ERROR concerning pointer, received as the function parameter");
|
LOGE0("DetectionBasedTracker: workcycleObjectDetectorFunction: ERROR concerning pointer, received as the function parameter");
|
||||||
}
|
}
|
||||||
@ -308,7 +313,7 @@ void cv::DetectionBasedTracker::SeparateDetectionWork::workcycleObjectDetector()
|
|||||||
|
|
||||||
CV_Assert(stateThread==STATE_THREAD_WORKING_SLEEPING);
|
CV_Assert(stateThread==STATE_THREAD_WORKING_SLEEPING);
|
||||||
#ifdef USE_STD_THREADS
|
#ifdef USE_STD_THREADS
|
||||||
mtx_lock.lock();
|
std::unique_lock<std::mutex> mtx_lock(mtx);
|
||||||
#else
|
#else
|
||||||
pthread_mutex_lock(&mutex);
|
pthread_mutex_lock(&mutex);
|
||||||
#endif
|
#endif
|
||||||
@ -453,7 +458,7 @@ void cv::DetectionBasedTracker::SeparateDetectionWork::stop()
|
|||||||
{
|
{
|
||||||
//FIXME: TODO: should add quickStop functionality
|
//FIXME: TODO: should add quickStop functionality
|
||||||
#ifdef USE_STD_THREADS
|
#ifdef USE_STD_THREADS
|
||||||
mtx_lock.lock();
|
std::unique_lock<std::mutex> mtx_lock(mtx);
|
||||||
#else
|
#else
|
||||||
pthread_mutex_lock(&mutex);
|
pthread_mutex_lock(&mutex);
|
||||||
#endif
|
#endif
|
||||||
@ -464,6 +469,7 @@ void cv::DetectionBasedTracker::SeparateDetectionWork::stop()
|
|||||||
pthread_mutex_unlock(&mutex);
|
pthread_mutex_unlock(&mutex);
|
||||||
#endif
|
#endif
|
||||||
LOGE("SimpleHighguiDemoCore::stop is called but the SimpleHighguiDemoCore pthread is not active");
|
LOGE("SimpleHighguiDemoCore::stop is called but the SimpleHighguiDemoCore pthread is not active");
|
||||||
|
stateThread = STATE_THREAD_STOPPING;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
stateThread=STATE_THREAD_STOPPING;
|
stateThread=STATE_THREAD_STOPPING;
|
||||||
@ -485,7 +491,7 @@ void cv::DetectionBasedTracker::SeparateDetectionWork::resetTracking()
|
|||||||
{
|
{
|
||||||
LOGD("DetectionBasedTracker::SeparateDetectionWork::resetTracking");
|
LOGD("DetectionBasedTracker::SeparateDetectionWork::resetTracking");
|
||||||
#ifdef USE_STD_THREADS
|
#ifdef USE_STD_THREADS
|
||||||
mtx_lock.lock();
|
std::unique_lock<std::mutex> mtx_lock(mtx);
|
||||||
#else
|
#else
|
||||||
pthread_mutex_lock(&mutex);
|
pthread_mutex_lock(&mutex);
|
||||||
#endif
|
#endif
|
||||||
@ -523,7 +529,7 @@ bool cv::DetectionBasedTracker::SeparateDetectionWork::communicateWithDetectingT
|
|||||||
bool shouldHandleResult = false;
|
bool shouldHandleResult = false;
|
||||||
|
|
||||||
#ifdef USE_STD_THREADS
|
#ifdef USE_STD_THREADS
|
||||||
mtx_lock.lock();
|
std::unique_lock<std::mutex> mtx_lock(mtx);
|
||||||
#else
|
#else
|
||||||
pthread_mutex_lock(&mutex);
|
pthread_mutex_lock(&mutex);
|
||||||
#endif
|
#endif
|
||||||
@ -574,8 +580,8 @@ bool cv::DetectionBasedTracker::SeparateDetectionWork::communicateWithDetectingT
|
|||||||
|
|
||||||
cv::DetectionBasedTracker::Parameters::Parameters()
|
cv::DetectionBasedTracker::Parameters::Parameters()
|
||||||
{
|
{
|
||||||
maxTrackLifetime=5;
|
maxTrackLifetime = 5;
|
||||||
minDetectionPeriod=0;
|
minDetectionPeriod = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
cv::DetectionBasedTracker::InnerParameters::InnerParameters()
|
cv::DetectionBasedTracker::InnerParameters::InnerParameters()
|
||||||
@ -603,7 +609,7 @@ cv::DetectionBasedTracker::DetectionBasedTracker(cv::Ptr<IDetector> mainDetector
|
|||||||
&& trackingDetector );
|
&& trackingDetector );
|
||||||
|
|
||||||
if (mainDetector) {
|
if (mainDetector) {
|
||||||
separateDetectionWork.reset(new SeparateDetectionWork(*this, mainDetector));
|
separateDetectionWork.reset(new SeparateDetectionWork(*this, mainDetector, params));
|
||||||
}
|
}
|
||||||
|
|
||||||
weightsPositionsSmoothing.push_back(1);
|
weightsPositionsSmoothing.push_back(1);
|
||||||
@ -1016,12 +1022,9 @@ bool cv::DetectionBasedTracker::setParameters(const Parameters& params)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (separateDetectionWork) {
|
if (separateDetectionWork) {
|
||||||
separateDetectionWork->lock();
|
separateDetectionWork->setParameters(params);
|
||||||
}
|
}
|
||||||
parameters=params;
|
parameters=params;
|
||||||
if (separateDetectionWork) {
|
|
||||||
separateDetectionWork->unlock();
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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>=1800)
|
||||||
|
|
||||||
#include <opencv2/imgproc.hpp> // Gaussian Blur
|
#include <opencv2/imgproc.hpp> // Gaussian Blur
|
||||||
#include <opencv2/core.hpp> // Basic OpenCV structures (cv::Mat, Scalar)
|
#include <opencv2/core.hpp> // Basic OpenCV structures (cv::Mat, Scalar)
|
||||||
@ -54,9 +54,19 @@ int main(int , char** )
|
|||||||
std::string cascadeFrontalfilename = "../../data/lbpcascades/lbpcascade_frontalface.xml";
|
std::string cascadeFrontalfilename = "../../data/lbpcascades/lbpcascade_frontalface.xml";
|
||||||
cv::Ptr<cv::CascadeClassifier> cascade = makePtr<cv::CascadeClassifier>(cascadeFrontalfilename);
|
cv::Ptr<cv::CascadeClassifier> cascade = makePtr<cv::CascadeClassifier>(cascadeFrontalfilename);
|
||||||
cv::Ptr<DetectionBasedTracker::IDetector> MainDetector = makePtr<CascadeDetectorAdapter>(cascade);
|
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);
|
cascade = makePtr<cv::CascadeClassifier>(cascadeFrontalfilename);
|
||||||
cv::Ptr<DetectionBasedTracker::IDetector> TrackingDetector = makePtr<CascadeDetectorAdapter>(cascade);
|
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::Parameters params;
|
||||||
DetectionBasedTracker Detector(MainDetector, TrackingDetector, params);
|
DetectionBasedTracker Detector(MainDetector, TrackingDetector, params);
|
||||||
@ -71,7 +81,7 @@ int main(int , char** )
|
|||||||
Mat GrayFrame;
|
Mat GrayFrame;
|
||||||
vector<Rect> Faces;
|
vector<Rect> Faces;
|
||||||
|
|
||||||
while(true)
|
do
|
||||||
{
|
{
|
||||||
VideoStream >> ReferenceFrame;
|
VideoStream >> ReferenceFrame;
|
||||||
cvtColor(ReferenceFrame, GrayFrame, COLOR_RGB2GRAY);
|
cvtColor(ReferenceFrame, GrayFrame, COLOR_RGB2GRAY);
|
||||||
@ -84,9 +94,7 @@ int main(int , char** )
|
|||||||
}
|
}
|
||||||
|
|
||||||
imshow(WindowName, ReferenceFrame);
|
imshow(WindowName, ReferenceFrame);
|
||||||
|
} while (waitKey(30) < 0);
|
||||||
if (waitKey(30) >= 0) break;
|
|
||||||
}
|
|
||||||
|
|
||||||
Detector.stop();
|
Detector.stop();
|
||||||
|
|
||||||
@ -98,7 +106,7 @@ int main(int , char** )
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
int main()
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user