diff --git a/modules/tracking/src/tld_tracker.cpp b/modules/tracking/src/tld_tracker.cpp index 38a400288..2508e326d 100644 --- a/modules/tracking/src/tld_tracker.cpp +++ b/modules/tracking/src/tld_tracker.cpp @@ -62,7 +62,7 @@ #define DOWNSCALE_MODE INTER_LINEAR #define BLUR_AS_VADIM #undef CLOSED_LOOP -static const cv::Size GaussBlurKernelSize(3,3); +static const cv::Size GaussBlurKernelSize(3, 3); using namespace cv; using namespace tld; @@ -88,18 +88,12 @@ using namespace tld; * 11. group decls logically, order of statements * * ?10. all in one class -* todo: initializer lists -* -* format: if,while,for, , Assert -* format: methods -* --> compile -* ; , -* --> compile -* -->commit-push -->notify +* todo: initializer lists; const methods * * ?( ) * -* ?vadim: for{1command} can omit {}; if( a != (b + c) ) vs ( a != ( b + c ) ) +* ?vadim: for{1command} can omit {}; if( a != (b + c) ) vs ( a != ( b + c ) ); if{} for{} method{} oneline:spaces, omit{}; +* 1-statement for/if without {} */ /* design decisions: @@ -109,24 +103,24 @@ namespace cv { class TLDDetector; -class MyMouseCallbackDEBUG{ +class MyMouseCallbackDEBUG +{ public: - MyMouseCallbackDEBUG( Mat& img, Mat& imgBlurred,TLDDetector* detector):img_(img),imgBlurred_(imgBlurred),detector_(detector){} - static void onMouse( int event, int x, int y, int, void* obj){ - ((MyMouseCallbackDEBUG*)obj)->onMouse(event,x,y); - } - MyMouseCallbackDEBUG& operator = (const MyMouseCallbackDEBUG& /*other*/){return *this;} + MyMouseCallbackDEBUG(Mat& img, Mat& imgBlurred, TLDDetector* detector):img_(img), imgBlurred_(imgBlurred), detector_(detector){} + static void onMouse(int event, int x, int y, int, void* obj){ ((MyMouseCallbackDEBUG*)obj)->onMouse(event, x, y); } + MyMouseCallbackDEBUG& operator = (const MyMouseCallbackDEBUG& /*other*/){ return *this; } private: - void onMouse( int event, int x, int y); - Mat& img_,imgBlurred_; + void onMouse(int event, int x, int y); + Mat& img_, imgBlurred_; TLDDetector* detector_; }; -class Data { +class Data +{ public: Data(Rect2d initBox); - Size getMinSize(){return minSize;} - double getScale(){return scale;} + Size getMinSize(){ return minSize; } + double getScale(){ return scale; } bool confident; bool failedLastTime; int frameNum; @@ -136,35 +130,39 @@ private: Size minSize; }; -class TLDDetector { +class TLDDetector +{ public: - TLDDetector(const TrackerTLD::Params& params,Ptr model_in):model(model_in),params_(params){} + TLDDetector(const TrackerTLD::Params& params, Ptr model_in):model(model_in), params_(params){} ~TLDDetector(){} - static void generateScanGrid(int rows,int cols,Size initBox,std::vector& res,bool withScaling = false); - struct LabeledPatch{ + static void generateScanGrid(int rows, int cols, Size initBox, std::vector& res, bool withScaling = false); + struct LabeledPatch + { Rect2d rect; bool isObject, shouldBeIntegrated; }; - bool detect(const Mat& img,const Mat& imgBlurred,Rect2d& res,std::vector& patches); + bool detect(const Mat& img, const Mat& imgBlurred, Rect2d& res, std::vector& patches); protected: friend class MyMouseCallbackDEBUG; Ptr model; - void computeIntegralImages(const Mat& img,Mat_& intImgP,Mat_& intImgP2){integral(img,intImgP,intImgP2,CV_64F);} - inline bool patchVariance(Mat_& intImgP,Mat_& intImgP2,double originalVariance,Point pt,Size size); + void computeIntegralImages(const Mat& img, Mat_& intImgP, Mat_& intImgP2){ integral(img, intImgP, intImgP2, CV_64F); } + inline bool patchVariance(Mat_& intImgP, Mat_& intImgP2, double originalVariance, Point pt, Size size); TrackerTLD::Params params_; }; - template -class TrackerProxyImpl : public TrackerProxy{ +class TrackerProxyImpl : public TrackerProxy +{ public: TrackerProxyImpl(Tparams params = Tparams()):params_(params){} - bool init( const Mat& image, const Rect2d& boundingBox ){ + bool init(const Mat& image, const Rect2d& boundingBox) + { trackerPtr = T::createTracker(); - return trackerPtr->init(image,boundingBox); + return trackerPtr->init(image, boundingBox); } - bool update( const Mat& image,Rect2d& boundingBox){ - return trackerPtr->update(image,boundingBox); + bool update(const Mat& image, Rect2d& boundingBox) + { + return trackerPtr->update(image, boundingBox); } private: Ptr trackerPtr; @@ -172,53 +170,55 @@ private: Rect2d boundingBox_; }; -class TrackerTLDModel : public TrackerModel{ - public: - TrackerTLDModel(TrackerTLD::Params params,const Mat& image, const Rect2d& boundingBox,Size minSize); - Rect2d getBoundingBox(){return boundingBox_;} - void setBoudingBox(Rect2d boundingBox){boundingBox_ = boundingBox;} - double getOriginalVariance(){return originalVariance_;} +class TrackerTLDModel : public TrackerModel +{ +public: + TrackerTLDModel(TrackerTLD::Params params, const Mat& image, const Rect2d& boundingBox, Size minSize); + Rect2d getBoundingBox(){ return boundingBox_; } + void setBoudingBox(Rect2d boundingBox){ boundingBox_ = boundingBox; } + double getOriginalVariance(){ return originalVariance_; } inline double ensembleClassifierNum(const uchar* data); - inline void prepareClassifiers(int rowstep){for(int i = 0;i < (int)classifiers.size();i++)classifiers[i].prepareClassifier(rowstep);} + inline void prepareClassifiers(int rowstep){ for( int i = 0; i < (int)classifiers.size(); i++ ) classifiers[i].prepareClassifier(rowstep); } double Sr(const Mat_& patch); double Sc(const Mat_& patch); - void integrateRelabeled(Mat& img,Mat& imgBlurred,const std::vector& patches); - void integrateAdditional(const std::vector >& eForModel,const std::vector >& eForEnsemble,bool isPositive); - Size getMinSize(){return minSize_;} - void printme(FILE* port = stdout); + void integrateRelabeled(Mat& img, Mat& imgBlurred, const std::vector& patches); + void integrateAdditional(const std::vector >& eForModel, const std::vector >& eForEnsemble, bool isPositive); + Size getMinSize(){ return minSize_; } + void printme(FILE* port = stdout); - protected: +protected: Size minSize_; - int timeStampPositiveNext,timeStampNegativeNext; + int timeStampPositiveNext, timeStampNegativeNext; TrackerTLD::Params params_; - void pushIntoModel(const Mat_& example,bool positive); + void pushIntoModel(const Mat_& example, bool positive); void modelEstimationImpl( const std::vector& /*responses*/ ){} void modelUpdateImpl(){} Rect2d boundingBox_; double originalVariance_; - std::vector > positiveExamples,negativeExamples; - std::vector timeStampsPositive,timeStampsNegative; + std::vector > positiveExamples, negativeExamples; + std::vector timeStampsPositive, timeStampsNegative; RNG rng; std::vector classifiers; }; class TrackerTLDImpl : public TrackerTLD { - public: - TrackerTLDImpl( const TrackerTLD::Params ¶meters = TrackerTLD::Params() ); - void read( const FileNode& fn ); - void write( FileStorage& fs ) const; +public: + TrackerTLDImpl(const TrackerTLD::Params ¶meters = TrackerTLD::Params()); + void read(const FileNode& fn); + void write(FileStorage& fs) const; - protected: - class Pexpert{ +protected: + class Pexpert + { public: - Pexpert(const Mat& img,const Mat& imgBlurred,Rect2d& resultBox,const TLDDetector* detector,TrackerTLD::Params params,Size initSize): - img_(img),imgBlurred_(imgBlurred),resultBox_(resultBox),detector_(detector),params_(params),initSize_(initSize){} - bool operator()(Rect2d /*box*/){return false;} - int additionalExamples(std::vector >& examplesForModel,std::vector >& examplesForEnsemble); + Pexpert(const Mat& img, const Mat& imgBlurred, Rect2d& resultBox, const TLDDetector* detector, TrackerTLD::Params params, Size initSize): + img_(img), imgBlurred_(imgBlurred), resultBox_(resultBox), detector_(detector), params_(params), initSize_(initSize){} + bool operator()(Rect2d /*box*/){ return false; } + int additionalExamples(std::vector >& examplesForModel, std::vector >& examplesForEnsemble); protected: Pexpert(){} - Mat img_,imgBlurred_; + Mat img_, imgBlurred_; Rect2d resultBox_; const TLDDetector* detector_; TrackerTLD::Params params_; @@ -226,17 +226,22 @@ class TrackerTLDImpl : public TrackerTLD Size initSize_; }; - class Nexpert : public Pexpert{ + class Nexpert : public Pexpert + { public: - Nexpert(const Mat& img,Rect2d& resultBox,const TLDDetector* detector,TrackerTLD::Params params){ - img_ = img; resultBox_ = resultBox; detector_ = detector; params_ = params;} + Nexpert(const Mat& img, Rect2d& resultBox, const TLDDetector* detector, TrackerTLD::Params params) + { + img_ = img; resultBox_ = resultBox; detector_ = detector; params_ = params; + } bool operator()(Rect2d box); - int additionalExamples(std::vector >& examplesForModel,std::vector >& examplesForEnsemble){ - examplesForModel.clear();examplesForEnsemble.clear();return 0;} + int additionalExamples(std::vector >& examplesForModel, std::vector >& examplesForEnsemble) + { + examplesForModel.clear(); examplesForEnsemble.clear(); return 0; + } }; - bool initImpl( const Mat& image, const Rect2d& boundingBox ); - bool updateImpl( const Mat& image, Rect2d& boundingBox ); + bool initImpl(const Mat& image, const Rect2d& boundingBox); + bool updateImpl(const Mat& image, Rect2d& boundingBox); TrackerTLD::Params params; Ptr data; @@ -244,75 +249,74 @@ class TrackerTLDImpl : public TrackerTLD Ptr detector; }; +TrackerTLD::Params::Params(){} -TrackerTLD::Params::Params(){ -} - -void TrackerTLD::Params::read( const cv::FileNode& /*fn*/ ){ -} +void TrackerTLD::Params::read(const cv::FileNode& /*fn*/){} -void TrackerTLD::Params::write( cv::FileStorage& /*fs*/ ) const{ -} +void TrackerTLD::Params::write(cv::FileStorage& /*fs*/) const {} -Ptr TrackerTLD::createTracker(const TrackerTLD::Params ¶meters){ +Ptr TrackerTLD::createTracker(const TrackerTLD::Params ¶meters) +{ return Ptr(new TrackerTLDImpl(parameters)); } TrackerTLDImpl::TrackerTLDImpl(const TrackerTLD::Params ¶meters) : - params( parameters ){ + params( parameters ) +{ isInit = false; - trackerProxy = Ptr > - (new TrackerProxyImpl()); + trackerProxy = Ptr > + (new TrackerProxyImpl()); } -void TrackerTLDImpl::read( const cv::FileNode& fn ) +void TrackerTLDImpl::read(const cv::FileNode& fn) { params.read( fn ); } -void TrackerTLDImpl::write( cv::FileStorage& fs ) const +void TrackerTLDImpl::write(cv::FileStorage& fs) const { params.write( fs ); } -bool TrackerTLDImpl::initImpl(const Mat& image, const Rect2d& boundingBox ){ +bool TrackerTLDImpl::initImpl(const Mat& image, const Rect2d& boundingBox) +{ Mat image_gray; - trackerProxy->init(image,boundingBox); + trackerProxy->init(image, boundingBox); cvtColor( image, image_gray, COLOR_BGR2GRAY ); data = Ptr(new Data(boundingBox)); double scale = data->getScale(); Rect2d myBoundingBox = boundingBox; - if(scale > 1.0) + if( scale > 1.0 ) { Mat image_proxy; - resize(image_gray,image_proxy,Size(cvRound(image.cols * scale),cvRound(image.rows * scale)),0,0,DOWNSCALE_MODE); + resize(image_gray, image_proxy, Size(cvRound(image.cols * scale), cvRound(image.rows * scale)), 0, 0, DOWNSCALE_MODE); image_proxy.copyTo(image_gray); myBoundingBox.x *= scale; myBoundingBox.y *= scale; myBoundingBox.width *= scale; myBoundingBox.height *= scale; } - model = Ptr(new TrackerTLDModel(params,image_gray,myBoundingBox,data->getMinSize())); - detector = Ptr(new TLDDetector(params,model)); + model = Ptr(new TrackerTLDModel(params, image_gray, myBoundingBox, data->getMinSize())); + detector = Ptr(new TLDDetector(params, model)); data->confident = false; data->failedLastTime = false; return true; } -bool TrackerTLDImpl::updateImpl(const Mat& image, Rect2d& boundingBox){ - Mat image_gray,image_blurred,imageForDetector; +bool TrackerTLDImpl::updateImpl(const Mat& image, Rect2d& boundingBox) +{ + Mat image_gray, image_blurred, imageForDetector; cvtColor( image, image_gray, COLOR_BGR2GRAY ); double scale = data->getScale(); - if(scale > 1.0){ - resize(image_gray,imageForDetector,Size(cvRound(image.cols*scale),cvRound(image.rows*scale)),0,0,DOWNSCALE_MODE); - }else{ + if( scale > 1.0 ) + resize(image_gray, imageForDetector, Size(cvRound(image.cols*scale), cvRound(image.rows*scale)), 0, 0, DOWNSCALE_MODE); + else imageForDetector = image_gray; - } - GaussianBlur(imageForDetector,image_blurred,GaussBlurKernelSize,0.0); + GaussianBlur(imageForDetector, image_blurred, GaussBlurKernelSize, 0.0); TrackerTLDModel* tldModel = ((TrackerTLDModel*)static_cast(model)); data->frameNum++; - Mat_ standardPatch(STANDARD_PATCH_SIZE,STANDARD_PATCH_SIZE); + Mat_ standardPatch(STANDARD_PATCH_SIZE, STANDARD_PATCH_SIZE); std::vector detectorResults; //best overlap around 92% @@ -322,169 +326,187 @@ bool TrackerTLDImpl::updateImpl(const Mat& image, Rect2d& boundingBox){ for( int i = 0; i < 2; i++ ) { Rect2d tmpCandid = boundingBox; - if(((i == 0)&& !(data->failedLastTime)&& trackerProxy->update(image,tmpCandid)) || - ((i == 1)&& (detector->detect(imageForDetector,image_blurred,tmpCandid,detectorResults)))){ + if( ( (i == 0) && !(data->failedLastTime) && trackerProxy->update(image, tmpCandid) ) || + ( (i == 1) && detector->detect(imageForDetector, image_blurred, tmpCandid, detectorResults) ) ) + { candidates.push_back(tmpCandid); - if(i == 0){ - resample(image_gray,tmpCandid,standardPatch); - }else{ - resample(imageForDetector,tmpCandid,standardPatch); - } + if( i == 0 ) + resample(image_gray, tmpCandid, standardPatch); + else + resample(imageForDetector, tmpCandid, standardPatch); candidatesRes.push_back(tldModel->Sc(standardPatch)); - }else{ - if(i == 0){ + } + else + { + if( i == 0 ) trackerNeedsReInit = true; - } } } - std::vector::iterator it = std::max_element(candidatesRes.begin(),candidatesRes.end()); + std::vector::iterator it = std::max_element(candidatesRes.begin(), candidatesRes.end()); - dfprintf((stdout,"scale = %f\n",log(1.0 * boundingBox.width / (data->getMinSize()).width) / log(SCALE_STEP))); - for(int i = 0;i < (int)candidatesRes.size();i++){ - dprintf(("\tcandidatesRes[%d] = %f\n",i,candidatesRes[i])); - } + dfprintf((stdout, "scale = %f\n", log(1.0 * boundingBox.width / (data->getMinSize()).width) / log(SCALE_STEP))); + for( int i = 0; i < (int)candidatesRes.size(); i++ ) + dprintf(("\tcandidatesRes[%d] = %f\n", i, candidatesRes[i])); data->printme(); tldModel->printme(stdout); - if(it == candidatesRes.end()){ + if( it == candidatesRes.end() ) + { data->confident = false; data->failedLastTime = true; return false; - }else{ + } + else + { boundingBox = candidates[it - candidatesRes.begin()]; data->failedLastTime = false; - if(trackerNeedsReInit || it != candidatesRes.begin()){ - trackerProxy->init(image,boundingBox); - } + if( trackerNeedsReInit || it != candidatesRes.begin() ) + trackerProxy->init(image, boundingBox); } #if 1 - if(it != candidatesRes.end()){ - resample(imageForDetector,candidates[it - candidatesRes.begin()],standardPatch); - dfprintf((stderr,"%d %f %f\n",data->frameNum,tldModel->Sc(standardPatch),tldModel->Sr(standardPatch))); - if(candidatesRes.size() == 2 && it == (candidatesRes.begin() + 1)) - dfprintf((stderr,"detector WON\n")); - }else{ - dfprintf((stderr,"%d x x\n",data->frameNum)); + if( it != candidatesRes.end() ) + { + resample(imageForDetector, candidates[it - candidatesRes.begin()], standardPatch); + dfprintf((stderr, "%d %f %f\n", data->frameNum, tldModel->Sc(standardPatch), tldModel->Sr(standardPatch))); + if( candidatesRes.size() == 2 && it == (candidatesRes.begin() + 1) ) + dfprintf((stderr, "detector WON\n")); + } + else + { + dfprintf((stderr, "%d x x\n", data->frameNum)); } #endif - if(*it > CORE_THRESHOLD){ + if( *it > CORE_THRESHOLD ) data->confident = true; - } - if(data->confident){ - Pexpert pExpert(imageForDetector,image_blurred,boundingBox,detector,params,data->getMinSize()); - Nexpert nExpert(imageForDetector,boundingBox,detector,params); - std::vector > examplesForModel,examplesForEnsemble; - examplesForModel.reserve(100);examplesForEnsemble.reserve(100); + if( data->confident ) + { + Pexpert pExpert(imageForDetector, image_blurred, boundingBox, detector, params, data->getMinSize()); + Nexpert nExpert(imageForDetector, boundingBox, detector, params); + std::vector > examplesForModel, examplesForEnsemble; + examplesForModel.reserve(100); examplesForEnsemble.reserve(100); int negRelabeled = 0; - for(int i = 0;i < (int)detectorResults.size();i++){ + for( int i = 0; i < (int)detectorResults.size(); i++ ) + { bool expertResult; - if(detectorResults[i].isObject){ + if( detectorResults[i].isObject ) + { expertResult = nExpert(detectorResults[i].rect); - if(expertResult != detectorResults[i].isObject){negRelabeled++;} - }else{ + if( expertResult != detectorResults[i].isObject ){ negRelabeled++; } + } + else + { expertResult = pExpert(detectorResults[i].rect); } detectorResults[i].shouldBeIntegrated = detectorResults[i].shouldBeIntegrated || (detectorResults[i].isObject != expertResult); detectorResults[i].isObject = expertResult; } - tldModel->integrateRelabeled(imageForDetector,image_blurred,detectorResults); - dprintf(("%d relabeled by nExpert\n",negRelabeled)); - pExpert.additionalExamples(examplesForModel,examplesForEnsemble); - tldModel->integrateAdditional(examplesForModel,examplesForEnsemble,true); - examplesForModel.clear();examplesForEnsemble.clear(); - nExpert.additionalExamples(examplesForModel,examplesForEnsemble); - tldModel->integrateAdditional(examplesForModel,examplesForEnsemble,false); - }else{ + tldModel->integrateRelabeled(imageForDetector, image_blurred, detectorResults); + dprintf(("%d relabeled by nExpert\n", negRelabeled)); + pExpert.additionalExamples(examplesForModel, examplesForEnsemble); + tldModel->integrateAdditional(examplesForModel, examplesForEnsemble, true); + examplesForModel.clear(); examplesForEnsemble.clear(); + nExpert.additionalExamples(examplesForModel, examplesForEnsemble); + tldModel->integrateAdditional(examplesForModel, examplesForEnsemble, false); + } + else + { #ifdef CLOSED_LOOP - tldModel->integrateRelabeled(imageForDetector,image_blurred,detectorResults); + tldModel->integrateRelabeled(imageForDetector, image_blurred, detectorResults); #endif } return true; } -TrackerTLDModel::TrackerTLDModel(TrackerTLD::Params params,const Mat& image, const Rect2d& boundingBox,Size minSize):minSize_(minSize), -timeStampPositiveNext(0),timeStampNegativeNext(0),params_(params),boundingBox_(boundingBox){ +TrackerTLDModel::TrackerTLDModel(TrackerTLD::Params params, const Mat& image, const Rect2d& boundingBox, Size minSize):minSize_(minSize), +timeStampPositiveNext(0), timeStampNegativeNext(0), params_(params), boundingBox_(boundingBox) +{ originalVariance_ = variance(image(boundingBox)); - std::vector closest,scanGrid; - Mat scaledImg,blurredImg,image_blurred; + std::vector closest, scanGrid; + Mat scaledImg, blurredImg, image_blurred; - double scale = scaleAndBlur(image,cvRound(log(1.0 * boundingBox.width / (minSize.width)) / log(SCALE_STEP)), - scaledImg,blurredImg,GaussBlurKernelSize,SCALE_STEP); - GaussianBlur(image,image_blurred,GaussBlurKernelSize,0.0); - TLDDetector::generateScanGrid(image.rows,image.cols,minSize,scanGrid); - getClosestN(scanGrid,Rect2d(boundingBox.x / scale,boundingBox.y / scale,boundingBox.width / scale,boundingBox.height / scale),10,closest); + double scale = scaleAndBlur(image, cvRound(log(1.0 * boundingBox.width / (minSize.width)) / log(SCALE_STEP)), + scaledImg, blurredImg, GaussBlurKernelSize, SCALE_STEP); + GaussianBlur(image, image_blurred, GaussBlurKernelSize, 0.0); + TLDDetector::generateScanGrid(image.rows, image.cols, minSize, scanGrid); + getClosestN(scanGrid, Rect2d(boundingBox.x / scale, boundingBox.y / scale, boundingBox.width / scale, boundingBox.height / scale), 10, closest); Mat_ blurredPatch(minSize); - TLDEnsembleClassifier::makeClassifiers(minSize,MEASURES_PER_CLASSIFIER,GRIDSIZE,classifiers); + TLDEnsembleClassifier::makeClassifiers(minSize, MEASURES_PER_CLASSIFIER, GRIDSIZE, classifiers); positiveExamples.reserve(200); - for(int i = 0;i < (int)closest.size();i++){ - for(int j = 0;j < 20;j++){ + for( int i = 0; i < (int)closest.size(); i++ ) + { + for( int j = 0; j < 20; j++ ) + { Point2f center; Size2f size; - Mat_ standardPatch(STANDARD_PATCH_SIZE,STANDARD_PATCH_SIZE); - center.x = (float)(closest[i].x + closest[i].width * (0.5 + rng.uniform(-0.01,0.01))); - center.y = (float)(closest[i].y + closest[i].height * (0.5 + rng.uniform(-0.01,0.01))); - size.width = (float)(closest[i].width * rng.uniform((double)0.99,(double)1.01)); - size.height = (float)(closest[i].height * rng.uniform((double)0.99,(double)1.01)); - float angle = (float)rng.uniform(-10.0,10.0); - - resample(scaledImg,RotatedRect(center,size,angle),standardPatch); + Mat_ standardPatch(STANDARD_PATCH_SIZE, STANDARD_PATCH_SIZE); + center.x = (float)(closest[i].x + closest[i].width * (0.5 + rng.uniform(-0.01, 0.01))); + center.y = (float)(closest[i].y + closest[i].height * (0.5 + rng.uniform(-0.01, 0.01))); + size.width = (float)(closest[i].width * rng.uniform((double)0.99, (double)1.01)); + size.height = (float)(closest[i].height * rng.uniform((double)0.99, (double)1.01)); + float angle = (float)rng.uniform(-10.0, 10.0); + + resample(scaledImg, RotatedRect(center, size, angle), standardPatch); - for(int y = 0;y < standardPatch.rows;y++){ - for(int x = 0;x < standardPatch.cols;x++){ - standardPatch(x,y) += (uchar)rng.gaussian(5.0); + for( int y = 0; y < standardPatch.rows; y++ ) + { + for( int x = 0; x < standardPatch.cols; x++ ) + { + standardPatch(x, y) += (uchar)rng.gaussian(5.0); } } #ifdef BLUR_AS_VADIM - GaussianBlur(standardPatch,blurredPatch,GaussBlurKernelSize,0.0); - resize(blurredPatch,blurredPatch,minSize); + GaussianBlur(standardPatch, blurredPatch, GaussBlurKernelSize, 0.0); + resize(blurredPatch, blurredPatch, minSize); #else - resample(blurredImg,RotatedRect(center,size,angle),blurredPatch); + resample(blurredImg, RotatedRect(center, size, angle), blurredPatch); #endif - pushIntoModel(standardPatch,true); - for(int k = 0;k < (int)classifiers.size();k++){ - classifiers[k].integrate(blurredPatch,true); - } + pushIntoModel(standardPatch, true); + for( int k = 0; k < (int)classifiers.size(); k++ ) + classifiers[k].integrate(blurredPatch, true); } } - TLDDetector::generateScanGrid(image.rows,image.cols,minSize,scanGrid,true); + TLDDetector::generateScanGrid(image.rows, image.cols, minSize, scanGrid, true); negativeExamples.clear(); negativeExamples.reserve(NEG_EXAMPLES_IN_INIT_MODEL); std::vector indices; indices.reserve(NEG_EXAMPLES_IN_INIT_MODEL); - while(negativeExamples.size() < NEG_EXAMPLES_IN_INIT_MODEL){ - int i = rng.uniform((int)0,(int)scanGrid.size()); - if(std::find(indices.begin(),indices.end(),i) == indices.end() && overlap(boundingBox,scanGrid[i]) < 0.2){ - Mat_ standardPatch(STANDARD_PATCH_SIZE,STANDARD_PATCH_SIZE); - resample(image,scanGrid[i],standardPatch); - pushIntoModel(standardPatch,false); - - resample(image_blurred,scanGrid[i],blurredPatch); - for(int k = 0;k < (int)classifiers.size();k++){ - classifiers[k].integrate(blurredPatch,false); - } + while( negativeExamples.size() < NEG_EXAMPLES_IN_INIT_MODEL ) + { + int i = rng.uniform((int)0, (int)scanGrid.size()); + if( std::find(indices.begin(), indices.end(), i) == indices.end() && overlap(boundingBox, scanGrid[i]) < NEXPERT_THRESHOLD ) + { + Mat_ standardPatch(STANDARD_PATCH_SIZE, STANDARD_PATCH_SIZE); + resample(image, scanGrid[i], standardPatch); + pushIntoModel(standardPatch, false); + + resample(image_blurred, scanGrid[i], blurredPatch); + for( int k = 0; k < (int)classifiers.size(); k++ ) + classifiers[k].integrate(blurredPatch, false); } } - dprintf(("positive patches: %d\nnegative patches: %d\n",(int)positiveExamples.size(),(int)negativeExamples.size())); + dprintf(("positive patches: %d\nnegative patches: %d\n", (int)positiveExamples.size(), (int)negativeExamples.size())); } -void TLDDetector::generateScanGrid(int rows,int cols,Size initBox,std::vector& res,bool withScaling){ +void TLDDetector::generateScanGrid(int rows, int cols, Size initBox, std::vector& res, bool withScaling) +{ res.clear(); //scales step: SCALE_STEP; hor step: 10% of width; verstep: 10% of height; minsize: 20pix - for(double h = initBox.height, w = initBox.width;h < cols && w < rows;){ - for( double x = 0; (x + w + 1.0) <= cols; x += (0.1 * w)) + for( double h = initBox.height, w = initBox.width; h < cols && w < rows; ) + { + for( double x = 0; (x + w + 1.0) <= cols; x += (0.1 * w) ) { - for(double y = 0; (y + h + 1.0) <= rows; y += (0.1 * h)) - res.push_back(Rect2d(x,y,w,h)); + for( double y = 0; (y + h + 1.0) <= rows; y += (0.1 * h) ) + res.push_back(Rect2d(x, y, w, h)); } if( withScaling ) { @@ -494,7 +516,7 @@ void TLDDetector::generateScanGrid(int rows,int cols,Size initBox,std::vector initBox.height || w > initBox.width); + CV_Assert( h > initBox.height || w > initBox.width); } } else @@ -507,61 +529,66 @@ void TLDDetector::generateScanGrid(int rows,int cols,Size initBox,std::vector& patches){ +bool TLDDetector::detect(const Mat& img, const Mat& imgBlurred, Rect2d& res, std::vector& patches) +{ TrackerTLDModel* tldModel = ((TrackerTLDModel*)static_cast(model)); Size initSize = tldModel->getMinSize(); patches.clear(); - Mat resized_img,blurred_img; - Mat_ standardPatch(STANDARD_PATCH_SIZE,STANDARD_PATCH_SIZE); + Mat resized_img, blurred_img; + Mat_ standardPatch(STANDARD_PATCH_SIZE, STANDARD_PATCH_SIZE); img.copyTo(resized_img); imgBlurred.copyTo(blurred_img); - double originalVariance = tldModel->getOriginalVariance();; + double originalVariance = tldModel->getOriginalVariance(); ; int dx = initSize.width / 10, dy = initSize.height / 10; Size2d size = img.size(); double scale = 1.0; - int total = 0,pass = 0; - int npos = 0,nneg = 0; - double tmp = 0,maxSc = -5.0; + int total = 0, pass = 0; + int npos = 0, nneg = 0; + double tmp = 0, maxSc = -5.0; Rect2d maxScRect; START_TICK("detector"); do { - Mat_ intImgP,intImgP2; - computeIntegralImages(resized_img,intImgP,intImgP2); + Mat_ intImgP, intImgP2; + computeIntegralImages(resized_img, intImgP, intImgP2); tldModel->prepareClassifiers((int)blurred_img.step[0]); - for(int i = 0,imax = cvFloor((0.0 + resized_img.cols - initSize.width) / dx);i < imax;i++){ - for(int j = 0,jmax = cvFloor((0.0 + resized_img.rows - initSize.height) / dy);j < jmax;j++){ + for( int i = 0, imax = cvFloor((0.0 + resized_img.cols - initSize.width) / dx); i < imax; i++ ) + { + for( int j = 0, jmax = cvFloor((0.0 + resized_img.rows - initSize.height) / dy); j < jmax; j++ ) + { LabeledPatch labPatch; total++; - if(!patchVariance(intImgP,intImgP2,originalVariance,Point(dx * i,dy * j),initSize)){ + if( !patchVariance(intImgP, intImgP2, originalVariance, Point(dx * i, dy * j), initSize) ) continue; - } - if(!(tldModel->ensembleClassifierNum(&blurred_img.at(dy * j,dx * i)) > ENSEMBLE_THRESHOLD)){ + if( tldModel->ensembleClassifierNum(&blurred_img.at(dy * j, dx * i)) <= ENSEMBLE_THRESHOLD ) continue; - } pass++; - labPatch.rect = Rect2d(dx * i * scale,dy * j * scale,initSize.width * scale,initSize.height * scale); - resample(resized_img,Rect2d(Point(dx * i,dy * j),initSize),standardPatch); + labPatch.rect = Rect2d(dx * i * scale, dy * j * scale, initSize.width * scale, initSize.height * scale); + resample(resized_img, Rect2d(Point(dx * i, dy * j), initSize), standardPatch); tmp = tldModel->Sr(standardPatch); labPatch.isObject = tmp > THETA_NN; labPatch.shouldBeIntegrated = abs(tmp - THETA_NN) < 0.1; patches.push_back(labPatch); - if(!labPatch.isObject){ + if( !labPatch.isObject ) + { nneg++; continue; - }else{ + } + else + { npos++; } tmp = tldModel->Sc(standardPatch); - if(tmp > maxSc){ + if( tmp > maxSc ) + { maxSc = tmp; maxScRect = labPatch.rect; } @@ -571,53 +598,54 @@ bool TLDDetector::detect(const Mat& img,const Mat& imgBlurred,Rect2d& res,std::v size.width /= SCALE_STEP; size.height /= SCALE_STEP; scale *= SCALE_STEP; - resize(img,resized_img,size,0,0,DOWNSCALE_MODE); - GaussianBlur(resized_img,blurred_img,GaussBlurKernelSize,0.0f); + resize(img, resized_img, size, 0, 0, DOWNSCALE_MODE); + GaussianBlur(resized_img, blurred_img, GaussBlurKernelSize, 0.0f); } while( size.width >= initSize.width && size.height >= initSize.height ); END_TICK("detector"); - dfprintf((stdout,"after NCC: nneg = %d npos = %d\n",nneg,npos)); + dfprintf((stdout, "after NCC: nneg = %d npos = %d\n", nneg, npos)); #if !0 - std::vector poss,negs; + std::vector poss, negs; - for(int i = 0;i < (int)patches.size();i++){ - if(patches[i].isObject) + for( int i = 0; i < (int)patches.size(); i++ ) + { + if( patches[i].isObject ) poss.push_back(patches[i].rect); else negs.push_back(patches[i].rect); } - dfprintf((stdout,"%d pos and %d neg\n",(int)poss.size(),(int)negs.size())); - drawWithRects(img,negs,poss,"tech"); + dfprintf((stdout, "%d pos and %d neg\n", (int)poss.size(), (int)negs.size())); + drawWithRects(img, negs, poss, "tech"); #endif - dfprintf((stdout,"%d after ensemble\n",pass)); - if(maxSc < 0){ + dfprintf((stdout, "%d after ensemble\n", pass)); + if( maxSc < 0 ) return false; - } res = maxScRect; return true; } /** Computes the variance of subimage given by box, with the help of two integral * images intImgP and intImgP2 (sum of squares), which should be also provided.*/ -bool TLDDetector::patchVariance(Mat_& intImgP,Mat_& intImgP2,double originalVariance,Point pt,Size size){ - int x = (pt.x),y = (pt.y),width = (size.width),height = (size.height); +bool TLDDetector::patchVariance(Mat_& intImgP, Mat_& intImgP2, double originalVariance, Point pt, Size size) +{ + int x = (pt.x), y = (pt.y), width = (size.width), height = (size.height); CV_Assert( 0 <= x && (x + width) < intImgP.cols && (x + width) < intImgP2.cols ); CV_Assert( 0 <= y && (y + height) < intImgP.rows && (y + height) < intImgP2.rows ); - double p = 0,p2 = 0; - double A,B,C,D; + double p = 0, p2 = 0; + double A, B, C, D; - A = intImgP(y,x); - B = intImgP(y,x + width); - C = intImgP(y + height,x); - D = intImgP(y + height,x + width); + A = intImgP(y, x); + B = intImgP(y, x + width); + C = intImgP(y + height, x); + D = intImgP(y + height, x + width); p = (A + D - B - C) / (width * height); - A = intImgP2(y,x); - B = intImgP2(y,x + width); - C = intImgP2(y + height,x); - D = intImgP2(y + height,x + width); + A = intImgP2(y, x); + B = intImgP2(y, x + width); + C = intImgP2(y + height, x); + D = intImgP2(y + height, x + width); p2 = (A + D - B - C) / (width * height); return ((p2 - p * p) > VARIANCE_THRESHOLD * originalVariance); @@ -636,9 +664,9 @@ double TrackerTLDModel::Sr(const Mat_& patch) { double splus = 0.0, sminus = 0.0; for( int i = 0; i < (int)positiveExamples.size(); i++ ) - splus = std::max(splus, 0.5 * (NCC(positiveExamples[i],patch) + 1.0)); + splus = std::max(splus, 0.5 * (NCC(positiveExamples[i], patch) + 1.0)); for( int i = 0; i < (int)negativeExamples.size(); i++ ) - sminus = std::max(sminus, 0.5 * (NCC(negativeExamples[i],patch) + 1.0)); + sminus = std::max(sminus, 0.5 * (NCC(negativeExamples[i], patch) + 1.0)); if( splus + sminus == 0.0) return 0.0; return splus / (sminus + splus); @@ -646,38 +674,38 @@ double TrackerTLDModel::Sr(const Mat_& patch) double TrackerTLDModel::Sc(const Mat_& patch) { - double splus = 0.0,sminus = 0.0; + double splus = 0.0, sminus = 0.0; int med = getMedian(timeStampsPositive); for( int i = 0; i < (int)positiveExamples.size(); i++ ) { if( (int)timeStampsPositive[i] <= med ) - splus = std::max(splus, 0.5 * (NCC(positiveExamples[i],patch) + 1.0)); + splus = std::max(splus, 0.5 * (NCC(positiveExamples[i], patch) + 1.0)); } for( int i = 0; i < (int)negativeExamples.size(); i++ ) - sminus = std::max(sminus, 0.5 * (NCC(negativeExamples[i],patch) + 1.0)); + sminus = std::max(sminus, 0.5 * (NCC(negativeExamples[i], patch) + 1.0)); if( splus + sminus == 0.0 ) return 0.0; return splus / (sminus + splus); } -void TrackerTLDModel::integrateRelabeled(Mat& img,Mat& imgBlurred,const std::vector& patches) +void TrackerTLDModel::integrateRelabeled(Mat& img, Mat& imgBlurred, const std::vector& patches) { - Mat_ standardPatch(STANDARD_PATCH_SIZE,STANDARD_PATCH_SIZE),blurredPatch(minSize_); - int positiveIntoModel = 0,negativeIntoModel = 0,positiveIntoEnsemble = 0,negativeIntoEnsemble = 0; + Mat_ standardPatch(STANDARD_PATCH_SIZE, STANDARD_PATCH_SIZE), blurredPatch(minSize_); + int positiveIntoModel = 0, negativeIntoModel = 0, positiveIntoEnsemble = 0, negativeIntoEnsemble = 0; for( int k = 0; k < (int)patches.size(); k++ ) { if( patches[k].shouldBeIntegrated ) { - resample(img,patches[k].rect,standardPatch); + resample(img, patches[k].rect, standardPatch); if( patches[k].isObject ) { positiveIntoModel++; - pushIntoModel(standardPatch,true); + pushIntoModel(standardPatch, true); } else { negativeIntoModel++; - pushIntoModel(standardPatch,false); + pushIntoModel(standardPatch, false); } } @@ -687,31 +715,29 @@ void TrackerTLDModel::integrateRelabeled(Mat& img,Mat& imgBlurred,const std::vec if( patches[k].shouldBeIntegrated ) #endif { - resample(imgBlurred,patches[k].rect,blurredPatch); + resample(imgBlurred, patches[k].rect, blurredPatch); if( patches[k].isObject ) positiveIntoEnsemble++; else negativeIntoEnsemble++; for( int i = 0; i < (int)classifiers.size(); i++ ) - { - classifiers[i].integrate(blurredPatch,patches[k].isObject); - } + classifiers[i].integrate(blurredPatch, patches[k].isObject); } } if( negativeIntoModel > 0 ) - dfprintf((stdout,"negativeIntoModel = %d ",negativeIntoModel)); + dfprintf((stdout, "negativeIntoModel = %d ", negativeIntoModel)); if( positiveIntoModel > 0) - dfprintf((stdout,"positiveIntoModel = %d ",positiveIntoModel)); + dfprintf((stdout, "positiveIntoModel = %d ", positiveIntoModel)); if( negativeIntoEnsemble > 0 ) - dfprintf((stdout,"negativeIntoEnsemble = %d ",negativeIntoEnsemble)); + dfprintf((stdout, "negativeIntoEnsemble = %d ", negativeIntoEnsemble)); if( positiveIntoEnsemble > 0 ) - dfprintf((stdout,"positiveIntoEnsemble = %d ",positiveIntoEnsemble)); - dfprintf((stdout,"\n")); + dfprintf((stdout, "positiveIntoEnsemble = %d ", positiveIntoEnsemble)); + dfprintf((stdout, "\n")); } -void TrackerTLDModel::integrateAdditional(const std::vector >& eForModel,const std::vector >& eForEnsemble,bool isPositive) +void TrackerTLDModel::integrateAdditional(const std::vector >& eForModel, const std::vector >& eForEnsemble, bool isPositive) { - int positiveIntoModel = 0,negativeIntoModel = 0,positiveIntoEnsemble = 0,negativeIntoEnsemble = 0; + int positiveIntoModel = 0, negativeIntoModel = 0, positiveIntoEnsemble = 0, negativeIntoEnsemble = 0; for( int k = 0; k < (int)eForModel.size(); k++ ) { double sr = Sr(eForModel[k]); @@ -720,17 +746,17 @@ void TrackerTLDModel::integrateAdditional(const std::vector >& eForM if( isPositive ) { positiveIntoModel++; - pushIntoModel(eForModel[k],true); + pushIntoModel(eForModel[k], true); } else { negativeIntoModel++; - pushIntoModel(eForModel[k],false); + pushIntoModel(eForModel[k], false); } } double p = 0; for( int i = 0; i < (int)classifiers.size(); i++ ) - p += classifiers[i].posteriorProbability(eForEnsemble[k].data,(int)eForEnsemble[k].step[0]); + p += classifiers[i].posteriorProbability(eForEnsemble[k].data, (int)eForEnsemble[k].step[0]); p /= classifiers.size(); if( (p > ENSEMBLE_THRESHOLD) != isPositive ) { @@ -739,32 +765,32 @@ void TrackerTLDModel::integrateAdditional(const std::vector >& eForM else negativeIntoEnsemble++; for( int i = 0; i < (int)classifiers.size(); i++ ) - classifiers[i].integrate(eForEnsemble[k],isPositive); + classifiers[i].integrate(eForEnsemble[k], isPositive); } } if( negativeIntoModel > 0 ) - dfprintf((stdout,"negativeIntoModel = %d ",negativeIntoModel)); + dfprintf((stdout, "negativeIntoModel = %d ", negativeIntoModel)); if( positiveIntoModel > 0 ) - dfprintf((stdout,"positiveIntoModel = %d ",positiveIntoModel)); + dfprintf((stdout, "positiveIntoModel = %d ", positiveIntoModel)); if( negativeIntoEnsemble > 0 ) - dfprintf((stdout,"negativeIntoEnsemble = %d ",negativeIntoEnsemble)); + dfprintf((stdout, "negativeIntoEnsemble = %d ", negativeIntoEnsemble)); if( positiveIntoEnsemble > 0 ) - dfprintf((stdout,"positiveIntoEnsemble = %d ",positiveIntoEnsemble)); - dfprintf((stdout,"\n")); + dfprintf((stdout, "positiveIntoEnsemble = %d ", positiveIntoEnsemble)); + dfprintf((stdout, "\n")); } -int TrackerTLDImpl::Pexpert::additionalExamples(std::vector >& examplesForModel,std::vector >& examplesForEnsemble) +int TrackerTLDImpl::Pexpert::additionalExamples(std::vector >& examplesForModel, std::vector >& examplesForEnsemble) { - examplesForModel.clear();examplesForEnsemble.clear(); - examplesForModel.reserve(100);examplesForEnsemble.reserve(100); + examplesForModel.clear(); examplesForEnsemble.clear(); + examplesForModel.reserve(100); examplesForEnsemble.reserve(100); - std::vector closest,scanGrid; - Mat scaledImg,blurredImg; + std::vector closest, scanGrid; + Mat scaledImg, blurredImg; - double scale = scaleAndBlur(img_,cvRound(log(1.0 * resultBox_.width / (initSize_.width)) / log(SCALE_STEP)), - scaledImg,blurredImg,GaussBlurKernelSize,SCALE_STEP); - TLDDetector::generateScanGrid(img_.rows,img_.cols,initSize_,scanGrid); - getClosestN(scanGrid,Rect2d(resultBox_.x / scale,resultBox_.y / scale,resultBox_.width / scale,resultBox_.height / scale),10,closest); + double scale = scaleAndBlur(img_, cvRound(log(1.0 * resultBox_.width / (initSize_.width)) / log(SCALE_STEP)), + scaledImg, blurredImg, GaussBlurKernelSize, SCALE_STEP); + TLDDetector::generateScanGrid(img_.rows, img_.cols, initSize_, scanGrid); + getClosestN(scanGrid, Rect2d(resultBox_.x / scale, resultBox_.y / scale, resultBox_.width / scale, resultBox_.height / scale), 10, closest); for( int i = 0; i < (int)closest.size(); i++ ) { @@ -772,27 +798,27 @@ int TrackerTLDImpl::Pexpert::additionalExamples(std::vector >& exam { Point2f center; Size2f size; - Mat_ standardPatch(STANDARD_PATCH_SIZE,STANDARD_PATCH_SIZE),blurredPatch(initSize_); - center.x = (float)(closest[i].x + closest[i].width * (0.5 + rng.uniform(-0.01,0.01))); - center.y = (float)(closest[i].y + closest[i].height * (0.5 + rng.uniform(-0.01,0.01))); - size.width = (float)(closest[i].width * rng.uniform((double)0.99,(double)1.01)); - size.height = (float)(closest[i].height * rng.uniform((double)0.99,(double)1.01)); - float angle = (float)rng.uniform(-5.0,5.0); + Mat_ standardPatch(STANDARD_PATCH_SIZE, STANDARD_PATCH_SIZE), blurredPatch(initSize_); + center.x = (float)(closest[i].x + closest[i].width * (0.5 + rng.uniform(-0.01, 0.01))); + center.y = (float)(closest[i].y + closest[i].height * (0.5 + rng.uniform(-0.01, 0.01))); + size.width = (float)(closest[i].width * rng.uniform((double)0.99, (double)1.01)); + size.height = (float)(closest[i].height * rng.uniform((double)0.99, (double)1.01)); + float angle = (float)rng.uniform(-5.0, 5.0); for( int y = 0; y < standardPatch.rows; y++ ) { for( int x = 0; x < standardPatch.cols; x++ ) { - standardPatch(x,y) += (uchar)rng.gaussian(5.0); + standardPatch(x, y) += (uchar)rng.gaussian(5.0); } } #ifdef BLUR_AS_VADIM - GaussianBlur(standardPatch,blurredPatch,GaussBlurKernelSize,0.0); - resize(blurredPatch,blurredPatch,initSize_); + GaussianBlur(standardPatch, blurredPatch, GaussBlurKernelSize, 0.0); + resize(blurredPatch, blurredPatch, initSize_); #else - resample(blurredImg,RotatedRect(center,size,angle),blurredPatch); + resample(blurredImg, RotatedRect(center, size, angle), blurredPatch); #endif - resample(scaledImg,RotatedRect(center,size,angle),standardPatch); + resample(scaledImg, RotatedRect(center, size, angle), standardPatch); examplesForModel.push_back(standardPatch); examplesForEnsemble.push_back(blurredPatch); } @@ -802,7 +828,7 @@ int TrackerTLDImpl::Pexpert::additionalExamples(std::vector >& exam bool TrackerTLDImpl::Nexpert::operator()(Rect2d box) { - if( overlap(resultBox_,box) < NEXPERT_THRESHOLD ) + if( overlap(resultBox_, box) < NEXPERT_THRESHOLD ) return false; else return true; @@ -810,31 +836,31 @@ bool TrackerTLDImpl::Nexpert::operator()(Rect2d box) Data::Data(Rect2d initBox) { - double minDim = std::min(initBox.width,initBox.height); + double minDim = std::min(initBox.width, initBox.height); scale = 20.0 / minDim; minSize.width = (int)(initBox.width * 20.0 / minDim); minSize.height = (int)(initBox.height * 20.0 / minDim); frameNum = 0; - dprintf(("minSize = %dx%d\n",minSize.width,minSize.height)); + dprintf(("minSize = %dx%d\n", minSize.width, minSize.height)); } void Data::printme(FILE* port) { - dfprintf((port,"Data:\n")); - dfprintf((port,"\tframeNum = %d\n",frameNum)); - dfprintf((port,"\tconfident = %s\n",confident?"true":"false")); - dfprintf((port,"\tfailedLastTime = %s\n",failedLastTime?"true":"false")); - dfprintf((port,"\tminSize = %dx%d\n",minSize.width,minSize.height)); + dfprintf((port, "Data:\n")); + dfprintf((port, "\tframeNum = %d\n", frameNum)); + dfprintf((port, "\tconfident = %s\n", confident?"true":"false")); + dfprintf((port, "\tfailedLastTime = %s\n", failedLastTime?"true":"false")); + dfprintf((port, "\tminSize = %dx%d\n", minSize.width, minSize.height)); } void TrackerTLDModel::printme(FILE* port) { - dfprintf((port,"TrackerTLDModel:\n")); - dfprintf((port,"\tpositiveExamples.size() = %d\n",(int)positiveExamples.size())); - dfprintf((port,"\tnegativeExamples.size() = %d\n",(int)negativeExamples.size())); + dfprintf((port, "TrackerTLDModel:\n")); + dfprintf((port, "\tpositiveExamples.size() = %d\n", (int)positiveExamples.size())); + dfprintf((port, "\tnegativeExamples.size() = %d\n", (int)negativeExamples.size())); } -void MyMouseCallbackDEBUG::onMouse( int event, int x, int y) +void MyMouseCallbackDEBUG::onMouse(int event, int x, int y) { if( event == EVENT_LBUTTONDOWN ) { @@ -842,39 +868,39 @@ void MyMouseCallbackDEBUG::onMouse( int event, int x, int y) img_.copyTo(imgCanvas); TrackerTLDModel* tldModel = ((TrackerTLDModel*)static_cast(detector_->model)); Size initSize = tldModel->getMinSize(); - Mat_ standardPatch(STANDARD_PATCH_SIZE,STANDARD_PATCH_SIZE); - double originalVariance = tldModel->getOriginalVariance();; + Mat_ standardPatch(STANDARD_PATCH_SIZE, STANDARD_PATCH_SIZE); + double originalVariance = tldModel->getOriginalVariance(); double tmp; - Mat resized_img,blurred_img; + Mat resized_img, blurred_img; double scale = SCALE_STEP; //double scale = SCALE_STEP * SCALE_STEP * SCALE_STEP * SCALE_STEP; - Size2d size(img_.cols / scale,img_.rows / scale); - resize(img_,resized_img,size); - resize(imgBlurred_,blurred_img,size); + Size2d size(img_.cols / scale, img_.rows / scale); + resize(img_, resized_img, size); + resize(imgBlurred_, blurred_img, size); - Mat_ intImgP,intImgP2; - detector_->computeIntegralImages(resized_img,intImgP,intImgP2); + Mat_ intImgP, intImgP2; + detector_->computeIntegralImages(resized_img, intImgP, intImgP2); int dx = initSize.width / 10, dy = initSize.height / 10, i = (int)(x / scale / dx), j = (int)(y / scale / dy); - dfprintf((stderr,"patchVariance = %s\n",(detector_->patchVariance(intImgP,intImgP2,originalVariance, - Point(dx * i,dy * j),initSize))?"true":"false")); + dfprintf((stderr, "patchVariance = %s\n", (detector_->patchVariance(intImgP, intImgP2, originalVariance, + Point(dx * i, dy * j), initSize))?"true":"false")); tldModel->prepareClassifiers((int)blurred_img.step[0]); - dfprintf((stderr,"p = %f\n",(tldModel->ensembleClassifierNum(&blurred_img.at(dy * j,dx * i))))); - fprintf(stderr,"ensembleClassifier = %s\n", - (!(tldModel->ensembleClassifierNum(&blurred_img.at(dy * j,dx * i)) > ENSEMBLE_THRESHOLD))?"true":"false"); + dfprintf((stderr, "p = %f\n", (tldModel->ensembleClassifierNum(&blurred_img.at(dy * j, dx * i))))); + fprintf(stderr, "ensembleClassifier = %s\n", + (!(tldModel->ensembleClassifierNum(&blurred_img.at(dy * j, dx * i)) > ENSEMBLE_THRESHOLD))?"true":"false"); - resample(resized_img,Rect2d(Point(dx * i,dy * j),initSize),standardPatch); + resample(resized_img, Rect2d(Point(dx * i, dy * j), initSize), standardPatch); tmp = tldModel->Sr(standardPatch); - dfprintf((stderr,"Sr = %f\n",tmp)); - dfprintf((stderr,"isObject = %s\n",(tmp > THETA_NN)?"true":"false")); - dfprintf((stderr,"shouldBeIntegrated = %s\n",(abs(tmp - THETA_NN) < 0.1)?"true":"false")); - dfprintf((stderr,"Sc = %f\n",tldModel->Sc(standardPatch))); + dfprintf((stderr, "Sr = %f\n", tmp)); + dfprintf((stderr, "isObject = %s\n", (tmp > THETA_NN)?"true":"false")); + dfprintf((stderr, "shouldBeIntegrated = %s\n", (abs(tmp - THETA_NN) < 0.1)?"true":"false")); + dfprintf((stderr, "Sc = %f\n", tldModel->Sc(standardPatch))); - rectangle(imgCanvas,Rect2d(Point2d(scale * dx * i,scale * dy * j),Size2d(initSize.width * scale,initSize.height * scale)), 0, 2, 1 ); - imshow("picker",imgCanvas); + rectangle(imgCanvas, Rect2d(Point2d(scale * dx * i, scale * dy * j), Size2d(initSize.width * scale, initSize.height * scale)), 0, 2, 1 ); + imshow("picker", imgCanvas); waitKey(); } } @@ -903,7 +929,7 @@ void TrackerTLDModel::pushIntoModel(const Mat_& example, bool positive) } else { - int index = rng.uniform((int)0,(int)proxyV->size()); + int index = rng.uniform((int)0, (int)proxyV->size()); (*proxyV)[index] = example; (*proxyT)[index] = (*proxyN); } diff --git a/modules/tracking/src/tld_tracker.hpp b/modules/tracking/src/tld_tracker.hpp index 7215bbb39..39f983244 100644 --- a/modules/tracking/src/tld_tracker.hpp +++ b/modules/tracking/src/tld_tracker.hpp @@ -57,60 +57,67 @@ namespace cv {namespace tld #define dfprintf(x) #define dprintf(x) #endif -#define MEASURE_TIME(a) {\ - clock_t start;float milisec = 0.0;\ - start = clock();{a} milisec = 1000.0 * (clock() - start) / CLOCKS_PER_SEC;\ - dprintf(("%-90s took %f milis\n",#a,milisec)); } -#define HERE dprintf(("line %d\n",__LINE__));fflush(stderr); -#define START_TICK(name) { clock_t start;double milisec = 0.0; start = clock(); -#define END_TICK(name) milisec = 1000.0 * (clock() - start) / CLOCKS_PER_SEC;\ - dprintf(("%s took %f milis\n",name,milisec)); } +#define MEASURE_TIME(a)\ +{\ + clock_t start; float milisec = 0.0; \ + start = clock(); {a} milisec = 1000.0 * (clock() - start) / CLOCKS_PER_SEC; \ + dprintf(("%-90s took %f milis\n", #a, milisec));\ +} +#define HERE dprintf(("line %d\n", __LINE__)); fflush(stderr); +#define START_TICK(name)\ +{ \ + clock_t start; double milisec = 0.0; start = clock(); +#define END_TICK(name) milisec = 1000.0 * (clock() - start) / CLOCKS_PER_SEC; \ + dprintf(("%s took %f milis\n", name, milisec)); \ +} extern Rect2d etalon; void myassert(const Mat& img); void printPatch(const Mat_& standardPatch); std::string type2str(const Mat& mat); -void drawWithRects(const Mat& img,std::vector& blackOnes,Rect2d whiteOne = Rect2d(-1.0,-1.0,-1.0,-1.0)); -void drawWithRects(const Mat& img,std::vector& blackOnes,std::vector& whiteOnes,String fileName = ""); +void drawWithRects(const Mat& img, std::vector& blackOnes, Rect2d whiteOne = Rect2d(-1.0, -1.0, -1.0, -1.0)); +void drawWithRects(const Mat& img, std::vector& blackOnes, std::vector& whiteOnes, String fileName = ""); //aux functions and variables -template inline T CLIP(T x,T a,T b){return std::min(std::max(x,a),b);} +template inline T CLIP(T x, T a, T b){ return std::min(std::max(x, a), b); } /** Computes overlap between the two given rectangles. Overlap is computed as ratio of rectangles' intersection to that * of their union.*/ -double overlap(const Rect2d& r1,const Rect2d& r2); +double overlap(const Rect2d& r1, const Rect2d& r2); /** Resamples the area surrounded by r2 in img so it matches the size of samples, where it is written.*/ -void resample(const Mat& img,const RotatedRect& r2,Mat_& samples); +void resample(const Mat& img, const RotatedRect& r2, Mat_& samples); /** Specialization of resample() for rectangles without retation for better performance and simplicity.*/ -void resample(const Mat& img,const Rect2d& r2,Mat_& samples); +void resample(const Mat& img, const Rect2d& r2, Mat_& samples); /** Computes the variance of single given image.*/ double variance(const Mat& img); /** Computes normalized corellation coefficient between the two patches (they should be * of the same size).*/ -double NCC(const Mat_& patch1,const Mat_& patch2); -void getClosestN(std::vector& scanGrid,Rect2d bBox,int n,std::vector& res); -double scaleAndBlur(const Mat& originalImg,int scale,Mat& scaledImg,Mat& blurredImg,Size GaussBlurKernelSize, double scaleStep); +double NCC(const Mat_& patch1, const Mat_& patch2); +void getClosestN(std::vector& scanGrid, Rect2d bBox, int n, std::vector& res); +double scaleAndBlur(const Mat& originalImg, int scale, Mat& scaledImg, Mat& blurredImg, Size GaussBlurKernelSize, double scaleStep); int getMedian(const std::vector& values, int size = -1); -class TLDEnsembleClassifier{ +class TLDEnsembleClassifier +{ public: - static int makeClassifiers(Size size,int measurePerClassifier,int gridSize,std::vector& classifiers); - void integrate(const Mat_& patch,bool isPositive); - double posteriorProbability(const uchar* data,int rowstep)const; - double posteriorProbabilityFast(const uchar* data)const; + static int makeClassifiers(Size size, int measurePerClassifier, int gridSize, std::vector& classifiers); + void integrate(const Mat_& patch, bool isPositive); + double posteriorProbability(const uchar* data, int rowstep) const; + double posteriorProbabilityFast(const uchar* data) const; void prepareClassifier(int rowstep); private: - TLDEnsembleClassifier(const std::vector& meas,int beg,int end); - static void stepPrefSuff(std::vector & arr,int pos,int len,int gridSize); - int code(const uchar* data,int rowstep)const; - int codeFast(const uchar* data)const; + TLDEnsembleClassifier(const std::vector& meas, int beg, int end); + static void stepPrefSuff(std::vector & arr, int pos, int len, int gridSize); + int code(const uchar* data, int rowstep) const; + int codeFast(const uchar* data) const; std::vector posAndNeg; std::vector measurements; std::vector offset; int lastStep_; }; -class TrackerProxy{ +class TrackerProxy +{ public: - virtual bool init( const Mat& image, const Rect2d& boundingBox) = 0; + virtual bool init(const Mat& image, const Rect2d& boundingBox) = 0; virtual bool update(const Mat& image, Rect2d& boundingBox) = 0; virtual ~TrackerProxy(){} }; diff --git a/modules/tracking/src/tld_utils.cpp b/modules/tracking/src/tld_utils.cpp index 1f9254622..c85467fdc 100644 --- a/modules/tracking/src/tld_utils.cpp +++ b/modules/tracking/src/tld_utils.cpp @@ -53,58 +53,61 @@ namespace cv {namespace tld { //debug functions and variables -Rect2d etalon(14.0,110.0,20.0,20.0); -void drawWithRects(const Mat& img,std::vector& blackOnes,Rect2d whiteOne){ +Rect2d etalon(14.0, 110.0, 20.0, 20.0); +void drawWithRects(const Mat& img, std::vector& blackOnes, Rect2d whiteOne) +{ Mat image; img.copyTo(image); - if(whiteOne.width >= 0){ - rectangle( image,whiteOne, 255, 1, 1 ); - } - for(int i = 0;i < (int)blackOnes.size();i++){ - rectangle( image,blackOnes[i], 0, 1, 1 ); - } - imshow("img",image); + if( whiteOne.width >= 0 ) + rectangle( image, whiteOne, 255, 1, 1 ); + for( int i = 0; i < (int)blackOnes.size(); i++ ) + rectangle( image, blackOnes[i], 0, 1, 1 ); + imshow("img", image); } -void drawWithRects(const Mat& img,std::vector& blackOnes,std::vector& whiteOnes,String filename){ +void drawWithRects(const Mat& img, std::vector& blackOnes, std::vector& whiteOnes, String filename) +{ Mat image; static int frameCounter = 1; img.copyTo(image); - for(int i = 0;i < (int)whiteOnes.size();i++){ - rectangle( image,whiteOnes[i], 255, 1, 1 ); - } - for(int i = 0;i < (int)blackOnes.size();i++){ - rectangle( image,blackOnes[i], 0, 1, 1 ); - } - imshow("img",image); - if(filename.length() > 0){ + for( int i = 0; i < (int)whiteOnes.size(); i++ ) + rectangle( image, whiteOnes[i], 255, 1, 1 ); + for( int i = 0; i < (int)blackOnes.size(); i++ ) + rectangle( image, blackOnes[i], 0, 1, 1 ); + imshow("img", image); + if( filename.length() > 0 ) + { char inbuf[100]; - sprintf(inbuf,"%s%d.jpg",filename.c_str(),frameCounter); - imwrite(inbuf,image); + sprintf(inbuf, "%s%d.jpg", filename.c_str(), frameCounter); + imwrite(inbuf, image); frameCounter++; } } -void myassert(const Mat& img){ +void myassert(const Mat& img) +{ int count = 0; - for(int i = 0;i < img.rows;i++){ - for(int j = 0;j < img.cols;j++){ - if(img.at(i,j) == 0){ + for( int i = 0; i < img.rows; i++ ) + { + for( int j = 0; j < img.cols; j++ ) + { + if( img.at(i, j) == 0 ) count++; - } } } - dprintf(("black: %d out of %d (%f)\n",count,img.rows * img.cols,1.0 * count / img.rows / img.cols)); + dprintf(("black: %d out of %d (%f)\n", count, img.rows * img.cols, 1.0 * count / img.rows / img.cols)); } -void printPatch(const Mat_& standardPatch){ - for(int i = 0;i < standardPatch.rows;i++){ - for(int j = 0;j < standardPatch.cols;j++){ - dprintf(("%5.2f, ",(double)standardPatch(i,j))); - } +void printPatch(const Mat_& standardPatch) +{ + for( int i = 0; i < standardPatch.rows; i++ ) + { + for( int j = 0; j < standardPatch.cols; j++ ) + dprintf(("%5.2f, ", (double)standardPatch(i, j))); dprintf(("\n")); } } -std::string type2str(const Mat& mat){ +std::string type2str(const Mat& mat) +{ int type = mat.type(); std::string r; @@ -129,59 +132,63 @@ std::string type2str(const Mat& mat){ } //generic functions -double scaleAndBlur(const Mat& originalImg,int scale,Mat& scaledImg,Mat& blurredImg,Size GaussBlurKernelSize, double scaleStep){ +double scaleAndBlur(const Mat& originalImg, int scale, Mat& scaledImg, Mat& blurredImg, Size GaussBlurKernelSize, double scaleStep) +{ double dScale = 1.0; - for(int i = 0; i < scale; i++, dScale *= scaleStep); + for( int i = 0; i < scale; i++, dScale *= scaleStep ); Size2d size = originalImg.size(); size.height /= dScale; size.width /= dScale; - resize(originalImg,scaledImg,size); - GaussianBlur(scaledImg,blurredImg,GaussBlurKernelSize,0.0); + resize(originalImg, scaledImg, size); + GaussianBlur(scaledImg, blurredImg, GaussBlurKernelSize, 0.0); return dScale; } -void getClosestN(std::vector& scanGrid,Rect2d bBox,int n,std::vector& res){ - if(n >= (int)scanGrid.size()){ - res.assign(scanGrid.begin(),scanGrid.end()); +void getClosestN(std::vector& scanGrid, Rect2d bBox, int n, std::vector& res) +{ + if( n >= (int)scanGrid.size() ) + { + res.assign(scanGrid.begin(), scanGrid.end()); return; } std::vector overlaps; - overlaps.assign(n,0.0); - res.assign(scanGrid.begin(),scanGrid.begin() + n); - for(int i = 0;i < n;i++){ - overlaps[i] = overlap(res[i],bBox); - } + overlaps.assign(n, 0.0); + res.assign(scanGrid.begin(), scanGrid.begin() + n); + for( int i = 0; i < n; i++ ) + overlaps[i] = overlap(res[i], bBox); double otmp; Rect2d rtmp; - for (int i = 1; i < n; i++){ + for (int i = 1; i < n; i++) + { int j = i; while (j > 0 && overlaps[j - 1] > overlaps[j]) { - otmp = overlaps[j];overlaps[j] = overlaps[j - 1];overlaps[j - 1] = otmp; - rtmp = res[j];res[j] = res[j - 1];res[j - 1] = rtmp; + otmp = overlaps[j]; overlaps[j] = overlaps[j - 1]; overlaps[j - 1] = otmp; + rtmp = res[j]; res[j] = res[j - 1]; res[j - 1] = rtmp; j--; } } - for(int i = n;i < (int)scanGrid.size();i++){ + for( int i = n; i < (int)scanGrid.size(); i++ ) + { double o = 0.0; - if((o = overlap(scanGrid[i],bBox)) <= overlaps[0]){ + if( (o = overlap(scanGrid[i], bBox)) <= overlaps[0] ) continue; - } int j = 0; while( j < n && overlaps[j] < o ) - { j++; - } j--; - for(int k = 0;k < j;overlaps[k] = overlaps[k + 1],res[k] = res[k + 1],k++); - overlaps[j] = o;res[j] = scanGrid[i]; + for( int k = 0; k < j; overlaps[k] = overlaps[k + 1], res[k] = res[k + 1], k++ ); + overlaps[j] = o; res[j] = scanGrid[i]; } } -double variance(const Mat& img){ - double p = 0,p2 = 0; - for(int i = 0;i < img.rows;i++){ - for(int j = 0;j < img.cols;j++){ - p += img.at(i,j); - p2 += img.at(i,j) * img.at(i,j); +double variance(const Mat& img) +{ + double p = 0, p2 = 0; + for( int i = 0; i < img.rows; i++ ) + { + for( int j = 0; j < img.cols; j++ ) + { + p += img.at(i, j); + p2 += img.at(i, j) * img.at(i, j); } } p /= (img.cols * img.rows); @@ -189,87 +196,96 @@ double variance(const Mat& img){ return p2 - p * p; } -double NCC(const Mat_& patch1,const Mat_& patch2){ - CV_Assert(patch1.rows == patch2.rows); - CV_Assert(patch1.cols == patch2.cols); +double NCC(const Mat_& patch1, const Mat_& patch2) +{ + CV_Assert( patch1.rows == patch2.rows ); + CV_Assert( patch1.cols == patch2.cols ); int N = patch1.rows * patch1.cols; - int s1 = 0,s2 = 0,n1 = 0,n2 = 0,prod = 0; - for(int i = 0;i < patch1.rows;i++){ - for(int j = 0;j < patch1.cols;j++){ - int p1 = patch1(i,j), p2 = patch2(i,j); + int s1 = 0, s2 = 0, n1 = 0, n2 = 0, prod = 0; + for( int i = 0; i < patch1.rows; i++ ) + { + for( int j = 0; j < patch1.cols; j++ ) + { + int p1 = patch1(i, j), p2 = patch2(i, j); s1 += p1; s2 += p2; n1 += (p1 * p1); n2 += (p2 * p2); prod += (p1 * p2); } } - double sq1 = sqrt(std::max(0.0,n1 - 1.0 * s1 * s1 / N)),sq2 = sqrt(std::max(0.0,n2 - 1.0 * s2 * s2 / N)); + double sq1 = sqrt(std::max(0.0, n1 - 1.0 * s1 * s1 / N)), sq2 = sqrt(std::max(0.0, n2 - 1.0 * s2 * s2 / N)); double ares = (sq2 == 0) ? sq1 / abs(sq1) : (prod - s1 * s2 / N) / sq1 / sq2; return ares; } -int getMedian(const std::vector& values, int size){ - if(size == -1){ +int getMedian(const std::vector& values, int size) +{ + if( size == -1 ) size = (int)values.size(); - } - std::vector copy(values.begin(),values.begin() + size); - std::sort(copy.begin(),copy.end()); - if(size % 2 == 0){ + std::vector copy(values.begin(), values.begin() + size); + std::sort(copy.begin(), copy.end()); + if( size % 2 == 0 ) return (copy[size / 2 - 1] + copy[size / 2]) / 2; - }else{ + else return copy[(size - 1) / 2]; - } } -double overlap(const Rect2d& r1,const Rect2d& r2){ +double overlap(const Rect2d& r1, const Rect2d& r2) +{ double a1 = r1.area(), a2 = r2.area(), a0 = (r1&r2).area(); return a0 / (a1 + a2 - a0); } -void resample(const Mat& img,const RotatedRect& r2,Mat_& samples){ - Mat_ M(2,3),R(2,2),Si(2,2),s(2,1),o(2,1); - R(0,0) = (float)cos(r2.angle * CV_PI / 180);R(0,1) = (float)(-sin(r2.angle * CV_PI / 180)); - R(1,0) = (float)sin(r2.angle * CV_PI / 180);R(1,1) = (float)cos(r2.angle * CV_PI / 180); - Si(0,0) = (float)(samples.cols / r2.size.width); Si(0,1) = 0.0f; - Si(1,0) = 0.0f; Si(1,1) = (float)(samples.rows / r2.size.height); - s(0,0) = (float)samples.cols; s(1,0) = (float)samples.rows; - o(0,0) = r2.center.x;o(1,0) = r2.center.y; - Mat_ A(2,2),b(2,1); +void resample(const Mat& img, const RotatedRect& r2, Mat_& samples) +{ + Mat_ M(2, 3), R(2, 2), Si(2, 2), s(2, 1), o(2, 1); + R(0, 0) = (float)cos(r2.angle * CV_PI / 180); R(0, 1) = (float)(-sin(r2.angle * CV_PI / 180)); + R(1, 0) = (float)sin(r2.angle * CV_PI / 180); R(1, 1) = (float)cos(r2.angle * CV_PI / 180); + Si(0, 0) = (float)(samples.cols / r2.size.width); Si(0, 1) = 0.0f; + Si(1, 0) = 0.0f; Si(1, 1) = (float)(samples.rows / r2.size.height); + s(0, 0) = (float)samples.cols; s(1, 0) = (float)samples.rows; + o(0, 0) = r2.center.x; o(1, 0) = r2.center.y; + Mat_ A(2, 2), b(2, 1); A = Si * R; b = s / 2.0 - Si * R * o; - A.copyTo(M.colRange(Range(0,2))); - b.copyTo(M.colRange(Range(2,3))); - warpAffine(img,samples,M,samples.size()); + A.copyTo(M.colRange(Range(0, 2))); + b.copyTo(M.colRange(Range(2, 3))); + warpAffine(img, samples, M, samples.size()); } -void resample(const Mat& img,const Rect2d& r2,Mat_& samples){ - Mat_ M(2,3); - M(0,0) = (float)(samples.cols / r2.width); M(0,1) = 0.0f; M(0,2) = (float)(-r2.x * samples.cols / r2.width); - M(1,0) = 0.0f; M(1,1) = (float)(samples.rows / r2.height); M(1,2) = (float)(-r2.y * samples.rows / r2.height); - warpAffine(img,samples,M,samples.size()); +void resample(const Mat& img, const Rect2d& r2, Mat_& samples) +{ + Mat_ M(2, 3); + M(0, 0) = (float)(samples.cols / r2.width); M(0, 1) = 0.0f; M(0, 2) = (float)(-r2.x * samples.cols / r2.width); + M(1, 0) = 0.0f; M(1, 1) = (float)(samples.rows / r2.height); M(1, 2) = (float)(-r2.y * samples.rows / r2.height); + warpAffine(img, samples, M, samples.size()); } //other stuff -void TLDEnsembleClassifier::stepPrefSuff(std::vector& arr,int pos,int len,int gridSize){ +void TLDEnsembleClassifier::stepPrefSuff(std::vector& arr, int pos, int len, int gridSize) +{ #if 0 int step = len / (gridSize - 1), pref = (len - step * (gridSize - 1)) / 2; - for(int i = 0;i < (int)(sizeof(x1) / sizeof(x1[0]));i++){ + for( int i = 0; i < (int)(sizeof(x1) / sizeof(x1[0])); i++ ) arr[i] = pref + arr[i] * step; - } #else int total = len - gridSize; - int quo = total / (gridSize - 1),rem = total % (gridSize - 1); - int smallStep = quo,bigStep = quo + 1; - int bigOnes = rem,smallOnes = gridSize - bigOnes - 1; + int quo = total / (gridSize - 1), rem = total % (gridSize - 1); + int smallStep = quo, bigStep = quo + 1; + int bigOnes = rem, smallOnes = gridSize - bigOnes - 1; int bigOnes_front = bigOnes / 2, bigOnes_back = bigOnes - bigOnes_front; - for(int i = 0;i < (int)arr.size();i++){ - if(arr[i].val[pos] < bigOnes_back){ + for( int i = 0; i < (int)arr.size(); i++ ) + { + if( arr[i].val[pos] < bigOnes_back ) + { arr[i].val[pos] = (uchar)(arr[i].val[pos] * bigStep + arr[i].val[pos]); continue; } - if(arr[i].val[pos] < (bigOnes_front + smallOnes)){ + if( arr[i].val[pos] < (bigOnes_front + smallOnes) ) + { arr[i].val[pos] = (uchar)(bigOnes_front * bigStep + (arr[i].val[pos] - bigOnes_front) * smallStep + arr[i].val[pos]); continue; } - if(arr[i].val[pos] < (bigOnes_front + smallOnes + bigOnes_back)){ + if( arr[i].val[pos] < (bigOnes_front + smallOnes + bigOnes_back) ) + { arr[i].val[pos] = (uchar)(bigOnes_front * bigStep + smallOnes * smallStep + (arr[i].val[pos] - (bigOnes_front + smallOnes)) * bigStep + arr[i].val[pos]); @@ -279,62 +295,69 @@ void TLDEnsembleClassifier::stepPrefSuff(std::vector& arr,int pos,int len } #endif } -void TLDEnsembleClassifier::prepareClassifier(int rowstep){ - if(lastStep_ != rowstep){ +void TLDEnsembleClassifier::prepareClassifier(int rowstep) +{ + if( lastStep_ != rowstep ) + { lastStep_ = rowstep; - for(int i = 0;i < (int)offset.size();i++){ + for( int i = 0; i < (int)offset.size(); i++ ) + { offset[i].x = rowstep * measurements[i].val[0] + measurements[i].val[1]; offset[i].y = rowstep * measurements[i].val[2] + measurements[i].val[3]; } } } -TLDEnsembleClassifier::TLDEnsembleClassifier(const std::vector& meas,int beg,int end):lastStep_(-1){ +TLDEnsembleClassifier::TLDEnsembleClassifier(const std::vector& meas, int beg, int end):lastStep_(-1) +{ int posSize = 1, mpc = end - beg; for( int i = 0; i < mpc; i++ ) posSize *= 2; - posAndNeg.assign(posSize,Point2i(0,0)); - measurements.assign(meas.begin() + beg,meas.begin() + end); - offset.assign(mpc,Point2i(0,0)); + posAndNeg.assign(posSize, Point2i(0, 0)); + measurements.assign(meas.begin() + beg, meas.begin() + end); + offset.assign(mpc, Point2i(0, 0)); } -void TLDEnsembleClassifier::integrate(const Mat_& patch,bool isPositive){ - int position = code(patch.data,(int)patch.step[0]); - if(isPositive){ +void TLDEnsembleClassifier::integrate(const Mat_& patch, bool isPositive) +{ + int position = code(patch.data, (int)patch.step[0]); + if( isPositive ) posAndNeg[position].x++; - }else{ + else posAndNeg[position].y++; - } } -double TLDEnsembleClassifier::posteriorProbability(const uchar* data,int rowstep)const{ - int position = code(data,rowstep); +double TLDEnsembleClassifier::posteriorProbability(const uchar* data, int rowstep) const +{ + int position = code(data, rowstep); double posNum = (double)posAndNeg[position].x, negNum = (double)posAndNeg[position].y; - if(posNum == 0.0 && negNum == 0.0){ + if( posNum == 0.0 && negNum == 0.0 ) return 0.0; - }else{ + else return posNum / (posNum + negNum); - } } -double TLDEnsembleClassifier::posteriorProbabilityFast(const uchar* data)const{ +double TLDEnsembleClassifier::posteriorProbabilityFast(const uchar* data) const +{ int position = codeFast(data); double posNum = (double)posAndNeg[position].x, negNum = (double)posAndNeg[position].y; - if(posNum == 0.0 && negNum == 0.0){ + if( posNum == 0.0 && negNum == 0.0 ) return 0.0; - }else{ + else return posNum / (posNum + negNum); - } } -int TLDEnsembleClassifier::codeFast(const uchar* data)const{ +int TLDEnsembleClassifier::codeFast(const uchar* data) const +{ int position = 0; - for(int i = 0;i < (int)measurements.size();i++){ + for( int i = 0; i < (int)measurements.size(); i++ ) + { position = position << 1; - if(data[offset[i].x] < data[offset[i].y]){ + if( data[offset[i].x] < data[offset[i].y] ) position++; - } } return position; } -int TLDEnsembleClassifier::code(const uchar* data,int rowstep)const{ +int TLDEnsembleClassifier::code(const uchar* data, int rowstep) const +{ int position = 0; - for(int i = 0;i < (int)measurements.size();i++){ + for( int i = 0; i < (int)measurements.size(); i++ ) + { position = position << 1; if( *(data + rowstep * measurements[i].val[0] + measurements[i].val[1]) < *(data + rowstep * measurements[i].val[2] + measurements[i].val[3]) ) @@ -344,34 +367,37 @@ int TLDEnsembleClassifier::code(const uchar* data,int rowstep)const{ } return position; } -int TLDEnsembleClassifier::makeClassifiers(Size size,int measurePerClassifier,int gridSize, - std::vector& classifiers){ +int TLDEnsembleClassifier::makeClassifiers(Size size, int measurePerClassifier, int gridSize, + std::vector& classifiers) +{ std::vector measurements; - for(int i = 0;i < gridSize;i++){ - for(int j = 0;j < gridSize;j++){ - for(int k = 0;k < j;k++){ + for( int i = 0; i < gridSize; i++ ) + { + for( int j = 0; j < gridSize; j++ ) + { + for( int k = 0; k < j; k++ ) + { Vec4b m; m.val[0] = m.val[2] = i; - m.val[1] = j;m.val[3] = k; + m.val[1] = j; m.val[3] = k; measurements.push_back(m); m.val[1] = m.val[3] = i; - m.val[0] = j;m.val[2] = k; + m.val[0] = j; m.val[2] = k; measurements.push_back(m); } } } - random_shuffle(measurements.begin(),measurements.end()); + random_shuffle(measurements.begin(), measurements.end()); - stepPrefSuff(measurements,0,size.width,gridSize); - stepPrefSuff(measurements,1,size.width,gridSize); - stepPrefSuff(measurements,2,size.height,gridSize); - stepPrefSuff(measurements,3,size.height,gridSize); + stepPrefSuff(measurements, 0, size.width, gridSize); + stepPrefSuff(measurements, 1, size.width, gridSize); + stepPrefSuff(measurements, 2, size.height, gridSize); + stepPrefSuff(measurements, 3, size.height, gridSize); - for(int i = 0,howMany = measurements.size() / measurePerClassifier;i < howMany;i++){ - classifiers.push_back(TLDEnsembleClassifier(measurements,i * measurePerClassifier, (i + 1) * measurePerClassifier)); - } + for( int i = 0, howMany = measurements.size() / measurePerClassifier; i < howMany; i++ ) + classifiers.push_back(TLDEnsembleClassifier(measurements, i * measurePerClassifier, (i + 1) * measurePerClassifier)); return (int)classifiers.size(); }