@ -40,6 +40,7 @@ static inline cv::Point2f centerRect(const cv::Rect& r)
{
return cv : : Point2f ( r . x + ( ( float ) r . width ) / 2 , r . y + ( ( float ) r . height ) / 2 ) ;
} ;
static inline cv : : Rect scale_rect ( const cv : : Rect & r , float scale )
{
cv : : Point2f m = centerRect ( r ) ;
@ -51,11 +52,15 @@ static inline cv::Rect scale_rect(const cv::Rect& r, float scale)
return cv : : Rect ( x , y , cvRound ( width ) , cvRound ( height ) ) ;
} ;
void * workcycleObjectDetectorFunction ( void * p ) ;
class DetectionBasedTracker : : SeparateDetectionWork
namespace cv
{
void * workcycleObjectDetectorFunction ( void * p ) ;
}
class cv : : DetectionBasedTracker : : SeparateDetectionWork
{
public :
SeparateDetectionWork ( DetectionBasedTracker & _detectionBasedTracker , const std : : string & cascadeFilename ) ;
SeparateDetectionWork ( cv : : DetectionBasedTracker & _detectionBasedTracker , cv : : Ptr < DetectionBasedTracker : : IDetector > _detector ) ;
virtual ~ SeparateDetectionWork ( ) ;
bool communicateWithDetectingThread ( const Mat & imageGray , vector < Rect > & rectsWhereRegions ) ;
bool run ( ) ;
@ -77,7 +82,7 @@ class DetectionBasedTracker::SeparateDetectionWork
protected :
DetectionBasedTracker & detectionBasedTracker ;
cv : : CascadeClassifier cascadeInThread ;
cv : : Ptr < DetectionBasedTracker : : IDetector > cascadeInThread ;
pthread_t second_workthread ;
pthread_mutex_t mutex ;
@ -105,7 +110,7 @@ class DetectionBasedTracker::SeparateDetectionWork
long long timeWhenDetectingThreadStartedWork ;
} ;
DetectionBasedTracker : : SeparateDetectionWork : : SeparateDetectionWork ( DetectionBasedTracker & _detectionBasedTracker , const std : : string & cascadeFilename )
cv : : DetectionBasedTracker : : SeparateDetectionWork : : SeparateDetectionWork ( DetectionBasedTracker & _detectionBasedTracker , cv : : Ptr < DetectionBasedTracker : : IDetector > _detector )
: detectionBasedTracker ( _detectionBasedTracker ) ,
cascadeInThread ( ) ,
isObjectDetectingReady ( false ) ,
@ -113,9 +118,10 @@ DetectionBasedTracker::SeparateDetectionWork::SeparateDetectionWork(DetectionBas
stateThread ( STATE_THREAD_STOPPED ) ,
timeWhenDetectingThreadStartedWork ( - 1 )
{
if ( ! cascadeInThread . load ( cascadeFilename ) ) {
CV_Error ( CV_StsBadArg , " DetectionBasedTracker::SeparateDetectionWork::SeparateDetectionWork: Cannot load a cascade from the file ' " + cascadeFilename + " ' " ) ;
}
CV_Assert ( ! _detector . empty ( ) ) ;
cascadeInThread = _detector ;
int res = 0 ;
res = pthread_mutex_init ( & mutex , NULL ) ; //TODO: should be attributes?
if ( res ) {
@ -137,7 +143,7 @@ DetectionBasedTracker::SeparateDetectionWork::SeparateDetectionWork(DetectionBas
}
}
DetectionBasedTracker : : SeparateDetectionWork : : ~ SeparateDetectionWork ( )
cv : : DetectionBasedTracker : : SeparateDetectionWork : : ~ SeparateDetectionWork ( )
{
if ( stateThread ! = STATE_THREAD_STOPPED ) {
LOGE ( " \n \n \n ATTENTION!!! dangerous algorithm error: destructor DetectionBasedTracker::DetectionBasedTracker::~SeparateDetectionWork is called before stopping the workthread " ) ;
@ -147,7 +153,7 @@ DetectionBasedTracker::SeparateDetectionWork::~SeparateDetectionWork()
pthread_cond_destroy ( & objectDetectorRun ) ;
pthread_mutex_destroy ( & mutex ) ;
}
bool DetectionBasedTracker : : SeparateDetectionWork : : run ( )
bool cv : : DetectionBasedTracker : : SeparateDetectionWork : : run ( )
{
LOGD ( " DetectionBasedTracker::SeparateDetectionWork::run() --- start " ) ;
pthread_mutex_lock ( & mutex ) ;
@ -196,18 +202,18 @@ do {
} while ( 0 )
# endif
void * workcycleObjectDetectorFunction ( void * p )
void * cv : : workcycleObjectDetectorFunction ( void * p )
{
CATCH_ALL_AND_LOG ( { ( ( DetectionBasedTracker : : SeparateDetectionWork * ) p ) - > workcycleObjectDetector ( ) ; } ) ;
CATCH_ALL_AND_LOG ( { ( ( cv : : DetectionBasedTracker : : SeparateDetectionWork * ) p ) - > workcycleObjectDetector ( ) ; } ) ;
try {
( ( DetectionBasedTracker : : SeparateDetectionWork * ) p ) - > stateThread = DetectionBasedTracker : : SeparateDetectionWork : : STATE_THREAD_STOPPED ;
( ( cv : : DetectionBasedTracker : : SeparateDetectionWork * ) p ) - > stateThread = cv : : DetectionBasedTracker : : SeparateDetectionWork : : STATE_THREAD_STOPPED ;
} catch ( . . . ) {
LOGE0 ( " DetectionBasedTracker: workcycleObjectDetectorFunction: ERROR concerning pointer, received as the function parameter " ) ;
}
return NULL ;
}
void DetectionBasedTracker : : SeparateDetectionWork : : workcycleObjectDetector ( )
void cv : : DetectionBasedTracker : : SeparateDetectionWork : : workcycleObjectDetector ( )
{
static double freq = getTickFrequency ( ) ;
LOGD0 ( " DetectionBasedTracker::SeparateDetectionWork::workcycleObjectDetector() --- start " ) ;
@ -274,20 +280,17 @@ void DetectionBasedTracker::SeparateDetectionWork::workcycleObjectDetector()
int64 t1_detect = getTickCount ( ) ;
int minObjectSize = detectionBasedTracker . parameters . minObjectSize ;
Size min_objectSize = Size ( minObjectSize , minObjectSize ) ;
int maxObjectSize = detectionBasedTracker . parameters . maxObjectSize ;
Size max_objectSize ( maxObjectSize , maxObjectSize ) ;
cascadeInThread - > detect ( imageSeparateDetecting , objects ) ;
cascadeInThread . detectMultiScale ( imageSeparateDetecting , objects ,
/*cascadeInThread.detectMultiScale( imageSeparateDetecting, objects,
detectionBasedTracker . parameters . scaleFactor , detectionBasedTracker . parameters . minNeighbors , 0
| CV_HAAR_SCALE_IMAGE
,
min_objectSize ,
max_objectSize
) ;
*/
LOGD ( " DetectionBasedTracker::SeparateDetectionWork::workcycleObjectDetector() --- end handling imageSeparateDetecting " ) ;
if ( ! isWorking ( ) ) {
@ -333,7 +336,7 @@ void DetectionBasedTracker::SeparateDetectionWork::workcycleObjectDetector()
LOGI ( " DetectionBasedTracker::SeparateDetectionWork::workcycleObjectDetector: Returning " ) ;
}
void DetectionBasedTracker : : SeparateDetectionWork : : stop ( )
void cv : : DetectionBasedTracker : : SeparateDetectionWork : : stop ( )
{
//FIXME: TODO: should add quickStop functionality
pthread_mutex_lock ( & mutex ) ;
@ -350,7 +353,7 @@ void DetectionBasedTracker::SeparateDetectionWork::stop()
pthread_mutex_unlock ( & mutex ) ;
}
void DetectionBasedTracker : : SeparateDetectionWork : : resetTracking ( )
void cv : : DetectionBasedTracker : : SeparateDetectionWork : : resetTracking ( )
{
LOGD ( " DetectionBasedTracker::SeparateDetectionWork::resetTracking " ) ;
pthread_mutex_lock ( & mutex ) ;
@ -371,7 +374,7 @@ void DetectionBasedTracker::SeparateDetectionWork::resetTracking()
}
bool DetectionBasedTracker : : SeparateDetectionWork : : communicateWithDetectingThread ( const Mat & imageGray , vector < Rect > & rectsWhereRegions )
bool cv : : DetectionBasedTracker : : SeparateDetectionWork : : communicateWithDetectingThread ( const Mat & imageGray , vector < Rect > & rectsWhereRegions )
{
static double freq = getTickFrequency ( ) ;
@ -420,19 +423,13 @@ bool DetectionBasedTracker::SeparateDetectionWork::communicateWithDetectingThrea
return shouldHandleResult ;
}
DetectionBasedTracker : : Parameters : : Parameters ( )
cv : : DetectionBasedTracker : : Parameters : : Parameters ( )
{
minObjectSize = 96 ;
maxObjectSize = INT_MAX ;
scaleFactor = 1.1 ;
maxTrackLifetime = 5 ;
minNeighbors = 2 ;
minDetectionPeriod = 0 ;
}
DetectionBasedTracker : : InnerParameters : : InnerParameters ( )
cv : : DetectionBasedTracker : : InnerParameters : : InnerParameters ( )
{
numLastPositionsToTrack = 4 ;
numStepsToWaitBeforeFirstShow = 6 ;
@ -444,39 +441,32 @@ DetectionBasedTracker::InnerParameters::InnerParameters()
coeffObjectSpeedUsingInPrediction = 0.8 ;
}
DetectionBasedTracker : : DetectionBasedTracker ( const std : : string & cascadeFilename , const Parameters & params )
cv : : DetectionBasedTracker : : DetectionBasedTracker ( cv : : Ptr < IDetector > MainDetector , cv : : Ptr < IDetector > TrackingDetector , const Parameters & params )
: separateDetectionWork ( ) ,
parameters ( params ) ,
innerParameters ( ) ,
numTrackedSteps ( 0 )
numTrackedSteps ( 0 ) ,
cascadeForTracking ( TrackingDetector )
{
CV_Assert ( ( params . minObjectSize > 0 )
& & ( params . maxObjectSize > = 0 )
& & ( params . scaleFactor > 1.0 )
& & ( params . maxTrackLifetime > = 0 ) ) ;
if ( ! cascadeForTracking . load ( cascadeFilename ) ) {
CV_Error ( CV_StsBadArg , " DetectionBasedTracker::DetectionBasedTracker: Cannot load a cascade from the file ' " + cascadeFilename + " ' " ) ;
}
CV_Assert ( ( params . maxTrackLifetime > = 0 )
& & ( ! MainDetector . empty ( ) )
& & ( ! TrackingDetector . empty ( ) ) ) ;
parameters = params ;
separateDetectionWork = new SeparateDetectionWork ( * this , cascadeFilename ) ;
separateDetectionWork = new SeparateDetectionWork ( * this , MainDetector ) ;
weightsPositionsSmoothing . push_back ( 1 ) ;
weightsSizesSmoothing . push_back ( 0.5 ) ;
weightsSizesSmoothing . push_back ( 0.3 ) ;
weightsSizesSmoothing . push_back ( 0.2 ) ;
}
DetectionBasedTracker : : ~ DetectionBasedTracker ( )
cv : : DetectionBasedTracker : : ~ DetectionBasedTracker ( )
{
}
void DetectionBasedTracker : : process ( const Mat & imageGray )
{
CV_Assert ( imageGray . type ( ) = = CV_8UC1 ) ;
if ( ! separateDetectionWork - > isWorking ( ) ) {
@ -494,15 +484,9 @@ void DetectionBasedTracker::process(const Mat& imageGray)
Mat imageDetect = imageGray ;
int D = parameters . minObjectSize ;
if ( D < 1 )
D = 1 ;
vector < Rect > rectsWhereRegions ;
bool shouldHandleResult = separateDetectionWork - > communicateWithDetectingThread ( imageGray , rectsWhereRegions ) ;
if ( shouldHandleResult ) {
LOGD ( " DetectionBasedTracker::process: get _rectsWhereRegions were got from resultDetect " ) ;
} else {
@ -517,7 +501,6 @@ void DetectionBasedTracker::process(const Mat& imageGray)
continue ;
}
//correction by speed of rectangle
if ( n > 1 ) {
Point2f center = centerRect ( r ) ;
@ -547,7 +530,7 @@ void DetectionBasedTracker::process(const Mat& imageGray)
updateTrackedObjects ( detectedObjectsInRegions ) ;
}
void DetectionBasedTracker : : getObjects ( std : : vector < cv : : Rect > & result ) const
void cv : : DetectionBasedTracker : : getObjects ( std : : vector < cv : : Rect > & result ) const
{
result . clear ( ) ;
@ -560,7 +543,8 @@ void DetectionBasedTracker::getObjects(std::vector<cv::Rect>& result) const
LOGD ( " DetectionBasedTracker::process: found a object with SIZE %d x %d, rect={%d, %d, %d x %d} " , r . width , r . height , r . x , r . y , r . width , r . height ) ;
}
}
void DetectionBasedTracker : : getObjects ( std : : vector < Object > & result ) const
void cv : : DetectionBasedTracker : : getObjects ( std : : vector < Object > & result ) const
{
result . clear ( ) ;
@ -574,25 +558,23 @@ void DetectionBasedTracker::getObjects(std::vector<Object>& result) const
}
}
bool DetectionBasedTracker : : run ( )
bool cv : : DetectionBasedTracker : : run ( )
{
return separateDetectionWork - > run ( ) ;
}
void DetectionBasedTracker : : stop ( )
void cv : : DetectionBasedTracker : : stop ( )
{
separateDetectionWork - > stop ( ) ;
}
void DetectionBasedTracker : : resetTracking ( )
void cv : : DetectionBasedTracker : : resetTracking ( )
{
separateDetectionWork - > resetTracking ( ) ;
trackedObjects . clear ( ) ;
}
void DetectionBasedTracker : : updateTrackedObjects ( const vector < Rect > & detectedObjects )
void cv : : DetectionBasedTracker : : updateTrackedObjects ( const vector < Rect > & detectedObjects )
{
enum {
NEW_RECTANGLE = - 1 ,
@ -711,7 +693,8 @@ void DetectionBasedTracker::updateTrackedObjects(const vector<Rect>& detectedObj
}
}
}
Rect DetectionBasedTracker : : calcTrackedObjectPositionToShow ( int i ) const
Rect cv : : DetectionBasedTracker : : calcTrackedObjectPositionToShow ( int i ) const
{
if ( ( i < 0 ) | | ( i > = ( int ) trackedObjects . size ( ) ) ) {
LOGE ( " DetectionBasedTracker::calcTrackedObjectPositionToShow: ERROR: wrong i=%d " , i ) ;
@ -743,8 +726,8 @@ Rect DetectionBasedTracker::calcTrackedObjectPositionToShow(int i) const
double sum = 0 ;
for ( int j = 0 ; j < Nsize ; j + + ) {
int k = N - j - 1 ;
w + = lastPositions [ k ] . width * weightsSizesSmoothing [ j ] ;
h + = lastPositions [ k ] . height * weightsSizesSmoothing [ j ] ;
w + = lastPositions [ k ] . width * weightsSizesSmoothing [ j ] ;
h + = lastPositions [ k ] . height * weightsSizesSmoothing [ j ] ;
sum + = weightsSizesSmoothing [ j ] ;
}
w / = sum ;
@ -762,7 +745,7 @@ Rect DetectionBasedTracker::calcTrackedObjectPositionToShow(int i) const
Point br ( lastPositions [ k ] . br ( ) ) ;
Point2f c1 ;
c1 = tl ;
c1 = c1 * 0.5f ;
c1 = c1 * 0.5f ;
Point2f c2 ;
c2 = br ;
c2 = c2 * 0.5f ;
@ -792,7 +775,7 @@ Rect DetectionBasedTracker::calcTrackedObjectPositionToShow(int i) const
return res ;
}
void DetectionBasedTracker : : detectInRegion ( const Mat & img , const Rect & r , vector < Rect > & detectedObjectsInRegions )
void cv : : DetectionBasedTracker : : detectInRegion ( const Mat & img , const Rect & r , vector < Rect > & detectedObjectsInRegions )
{
Rect r0 ( Point ( ) , img . size ( ) ) ;
Rect r1 = scale_rect ( r , innerParameters . coeffTrackingWindowSize ) ;
@ -802,8 +785,7 @@ void DetectionBasedTracker::detectInRegion(const Mat& img, const Rect& r, vector
return ;
}
int d = std : : min ( r . width , r . height ) ;
d = cvRound ( d * innerParameters . coeffObjectSizeToTrack ) ;
int d = cvRound ( std : : min ( r . width , r . height ) * innerParameters . coeffObjectSizeToTrack ) ;
vector < Rect > tmpobjects ;
@ -811,17 +793,17 @@ void DetectionBasedTracker::detectInRegion(const Mat& img, const Rect& r, vector
LOGD ( " DetectionBasedTracker::detectInRegion: img1.size()=%d x %d, d=%d " ,
img1 . size ( ) . width , img1 . size ( ) . height , d ) ;
int maxObjectSize = parameters . maxObjectSize ;
Size max_objectSize ( maxObjectSize , maxObjectSize ) ;
cascadeForTracking . detectMultiScale ( img1 , tmpobjects ,
cascadeForTracking - > setMinObjectSize ( Size ( d , d ) ) ;
cascadeForTracking - > detect ( img1 , tmpobjects ) ;
/*
detectMultiScale ( img1 , tmpobjects ,
parameters . scaleFactor , parameters . minNeighbors , 0
| CV_HAAR_FIND_BIGGEST_OBJECT
| CV_HAAR_SCALE_IMAGE
,
Size ( d , d ) ,
max_objectSize
) ;
) ; */
for ( size_t i = 0 ; i < tmpobjects . size ( ) ; i + + ) {
Rect curres ( tmpobjects [ i ] . tl ( ) + r1 . tl ( ) , tmpobjects [ i ] . size ( ) ) ;
@ -829,12 +811,9 @@ void DetectionBasedTracker::detectInRegion(const Mat& img, const Rect& r, vector
}
}
bool DetectionBasedTracker : : setParameters ( const Parameters & params )
bool cv : : DetectionBasedTracker : : setParameters ( const Parameters & params )
{
if ( ( params . minObjectSize < = 0 )
| | ( params . maxObjectSize < 0 )
| | ( params . scaleFactor < = 1.0 )
| | ( params . maxTrackLifetime < 0 ) )
if ( params . maxTrackLifetime < 0 )
{
LOGE ( " DetectionBasedTracker::setParameters: ERROR: wrong parameters value " ) ;
return false ;
@ -846,7 +825,7 @@ bool DetectionBasedTracker::setParameters(const Parameters& params)
return true ;
}
const DetectionBasedTracker : : Parameters & DetectionBasedTracker : : getParameters ( )
const cv : : DetectionBasedTracker : : Parameters & DetectionBasedTracker : : getParameters ( )
{
return parameters ;
}