/*/////////////////////////////////////////////////////////////////////////////////////// // // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. // // By downloading, copying, installing or using the software you agree to this license. // If you do not agree to this license, do not download, install, // copy or use the software. // // // License Agreement // For Open Source Computer Vision Library // // Copyright (C) 2013, OpenCV Foundation, all rights reserved. // Third party copyrights are property of their respective owners. // // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: // // * Redistribution's of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // // * Redistribution's in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // // * The name of the copyright holders may not be used to endorse or promote products // derived from this software without specific prior written permission. // // This software is provided by the copyright holders and contributors "as is" and // any express or implied warranties, including, but not limited to, the implied // warranties of merchantability and fitness for a particular purpose are disclaimed. // In no event shall the Intel Corporation or contributors be liable for any direct, // indirect, incidental, special, exemplary, or consequential damages // (including, but not limited to, procurement of substitute goods or services; // loss of use, data, or profits; or business interruption) however caused // and on any theory of liability, whether in contract, strict liability, // or tort (including negligence or otherwise) arising in any way out of // the use of this software, even if advised of the possibility of such damage. // //M*/ #include "precomp.hpp" #include "opencv2/video/tracking.hpp" #include "opencv2/imgproc.hpp" #include "time.h" #include #include #include "tld_tracker.hpp" #include "opencv2/highgui.hpp" #define THETA_NN 0.50 #define STANDARD_PATCH_SIZE 15 #define CORE_THRESHOLD 0.5 #define NEG_EXAMPLES_IN_INIT_MODEL 300 #define MAX_EXAMPLES_IN_MODEL 500 #define MEASURES_PER_CLASSIFIER 13 #define SCALE_STEP 1.2 #define DOWNSCALE_MODE INTER_LINEAR #define BLUR_AS_VADIM #undef CLOSED_LOOP static const cv::Size GaussBlurKernelSize(3,3); using namespace cv; using namespace tld; /* * FIXME(optimize): * no median * direct formula in resamples * FIXME(issues) * THETA_NN 0.5<->0.6 dramatic change vs video 6 !! * TODO(features) * benchmark: two streams of photos --> better video * (try inter_area for resize) * TODO: * fix pushbot ->pick commits -> compare_branches->all in 1->resubmit * ||video(0.5<->0.6) --> debug if box size is less than 20 * perfect PN * * vadim: * ?3. comment each function/method * 5. empty lines to separate logical... * 6. comment logical sections * ?10. all in one class * 11. group decls logically, order of statements * 12. not v=vector(n), but assign(n,0) * -->14. TLDEnsembleClassifier * 16. loops limits * 17. inner scope loops * 18. classify in TLDEnsembleClassifier * 19. var checker * 20. NCC using plain loops * 21. precompute offset * 22. vec of structs (detect and beyond) * */ /* design decisions: * blur --> resize (vs. resize-->blur) in detect(), ensembleClassifier stage * no random gauss noise, when making examples for ensembleClassifier */ namespace cv { class TLDDetector; 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;} private: void onMouse( int event, int x, int y); Mat& img_,imgBlurred_; TLDDetector* detector_; }; class Data { public: Data(Rect2d initBox); Size getMinSize(){return minSize;} double getScale(){return scale;} bool confident; bool failedLastTime; int frameNum; void printme(FILE* port=stdout); private: double scale; Size minSize; }; class TrackerTLDModel; class TLDDetector { public: TLDDetector(const TrackerTLD::Params& params,Ptrmodel_in):model(model_in),params_(params){} ~TLDDetector(){} static void generateScanGrid(int rows,int cols,Size initBox,std::vector& res,bool withScaling=false); bool detect(const Mat& img,const Mat& imgBlurred,Rect2d& res,std::vector& rect,std::vector& isObject, std::vector& shouldBeIntegrated); 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); bool ensembleClassifier(const uchar* data,int rowstep){return ensembleClassifierNum(data,rowstep)>0.5;} double ensembleClassifierNum(const uchar* data,int rowstep); TrackerTLD::Params params_; }; 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); protected: Mat img_,imgBlurred_; Rect2d resultBox_; const TLDDetector* detector_; TrackerTLD::Params params_; RNG rng; Size initSize_; }; class Nexpert{ public: 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;} protected: Mat img_; Rect2d resultBox_; const TLDDetector* detector_; TrackerTLD::Params params_; }; template class TrackerProxyImpl : public TrackerProxy{ public: TrackerProxyImpl(Tparams params=Tparams()):params_(params){} bool init( const Mat& image, const Rect2d& boundingBox ){ trackerPtr=T::createTracker(); return trackerPtr->init(image,boundingBox); } bool update( const Mat& image,Rect2d& boundingBox){ return trackerPtr->update(image,boundingBox); } private: Ptr trackerPtr; Tparams params_; 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_;} std::vector* getClassifiers(){return &classifiers;} double Sr(const Mat_& patch); double Sc(const Mat_& patch); void integrateRelabeled(Mat& img,Mat& imgBlurred,const std::vector& box,const std::vector& isPositive, const std::vector& alsoIntoModel); void integrateAdditional(const std::vector >& eForModel,const std::vector >& eForEnsemble,bool isPositive); Size getMinSize(){return minSize_;} void printme(FILE* port=stdout); protected: Size minSize_; unsigned int timeStampPositiveNext,timeStampNegativeNext; TrackerTLD::Params params_; 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; 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; protected: bool initImpl( const Mat& image, const Rect2d& boundingBox ); bool updateImpl( const Mat& image, Rect2d& boundingBox ); TrackerTLD::Params params; Ptr data; Ptr trackerProxy; Ptr detector; }; TrackerTLD::Params::Params(){ } void TrackerTLD::Params::read( const cv::FileNode& /*fn*/ ){ } void TrackerTLD::Params::write( cv::FileStorage& /*fs*/ ) const{ } Ptr TrackerTLD::createTracker(const TrackerTLD::Params ¶meters){ return Ptr(new TrackerTLDImpl(parameters)); } TrackerTLDImpl::TrackerTLDImpl( const TrackerTLD::Params ¶meters) : params( parameters ){ isInit = false; trackerProxy=Ptr >( new TrackerProxyImpl()); } void TrackerTLDImpl::read( const cv::FileNode& fn ) { params.read( fn ); } void TrackerTLDImpl::write( cv::FileStorage& fs ) const { params.write( fs ); } bool TrackerTLDImpl::initImpl(const Mat& image, const Rect2d& boundingBox ){ Mat image_gray; 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){ Mat image_proxy; 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)); data->confident=false; data->failedLastTime=false; return true; } 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{ imageForDetector=image_gray; } GaussianBlur(imageForDetector,image_blurred,GaussBlurKernelSize,0.0); TrackerTLDModel* tldModel=((TrackerTLDModel*)static_cast(model)); data->frameNum++; Mat_ standardPatch(STANDARD_PATCH_SIZE,STANDARD_PATCH_SIZE); std::vector detectorResults; std::vector isObject,shouldBeIntegrated; //best overlap around 92% Rect2d tmpCandid=boundingBox; std::vector candidates; std::vector candidatesRes; bool trackerNeedsReInit=false; for(int i=0;i<2;i++){ if(((i==0)&&!(data->failedLastTime)&&trackerProxy->update(image,tmpCandid)) || ((i==1)&&(detector->detect(imageForDetector,image_blurred,tmpCandid,detectorResults,isObject,shouldBeIntegrated)))){ candidates.push_back(tmpCandid); if(i==0){ resample(image_gray,tmpCandid,standardPatch); }else{ resample(imageForDetector,tmpCandid,standardPatch); } candidatesRes.push_back(tldModel->Sc(standardPatch)); }else{ if(i==0){ trackerNeedsReInit=true; } } } 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])); } data->printme(); tldModel->printme(stdout); if(it==candidatesRes.end()){ data->confident=false; data->failedLastTime=true; return false; }else{ boundingBox=candidates[it-candidatesRes.begin()]; data->failedLastTime=false; if(trackerNeedsReInit || it!=candidatesRes.begin()){ trackerProxy->init(image,boundingBox); } } if(!false && 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 > CORE_THRESHOLD){ data->confident=true; } if(data->confident){ Pexpert pExpert(imageForDetector,image_blurred,boundingBox,detector,params,data->getMinSize()); Nexpert nExpert(imageForDetector,boundingBox,detector,params); bool expertResult; std::vector > examplesForModel,examplesForEnsemble; examplesForModel.reserve(100);examplesForEnsemble.reserve(100); int negRelabeled=0; for(int i=0;i<(int)detectorResults.size();i++){ if(isObject[i]){ expertResult=nExpert(detectorResults[i]); if(expertResult!=isObject[i]){negRelabeled++;} }else{ expertResult=pExpert(detectorResults[i]); } shouldBeIntegrated[i]=shouldBeIntegrated[i] || (isObject[i]!=expertResult); isObject[i]=expertResult; } tldModel->integrateRelabeled(imageForDetector,image_blurred,detectorResults,isObject,shouldBeIntegrated); 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,isObject,shouldBeIntegrated); #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; originalVariance_=variance(image(boundingBox)); std::vector closest(10),scanGrid; Mat scaledImg,blurredImg,image_blurred; double scale=scaleAndBlur(image,cvRound(log(1.0*boundingBox.width/(minSize.width))/log(SCALE_STEP)),scaledImg,blurredImg,GaussBlurKernelSize); 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); for(int i=0,howMany=TLDEnsembleClassifier::getMaxOrdinal();i 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 indices; indices.reserve(NEG_EXAMPLES_IN_INIT_MODEL); while(negativeExamples.size() 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())); } 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;hinitBox.height || w>initBox.width); } }else{ h*=SCALE_STEP; w*=SCALE_STEP; } }else{ break; } } dprintf(("%d rects in res\n",(int)res.size())); } bool TLDDetector::detect(const Mat& img,const Mat& imgBlurred,Rect2d& res,std::vector& rect,std::vector& isObject, std::vector& shouldBeIntegrated){ TrackerTLDModel* tldModel=((TrackerTLDModel*)static_cast(model)); Size initSize=tldModel->getMinSize(); rect.clear(); isObject.clear(); shouldBeIntegrated.clear(); 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();; 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; Rect2d maxScRect; START_TICK("detector"); do{ Mat_ intImgP,intImgP2; computeIntegralImages(resized_img,intImgP,intImgP2); for(int i=0,imax=cvFloor((0.0+resized_img.cols-initSize.width)/dx);i(dy*j,dx*i),(int)blurred_img.step[0])){ continue; } pass++; rect.push_back(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); isObject.push_back(tmp>THETA_NN); shouldBeIntegrated.push_back(abs(tmp-THETA_NN)<0.1); if(!isObject[isObject.size()-1]){ nneg++; continue; }else{ npos++; } tmp=tldModel->Sc(standardPatch); if(tmp>maxSc){ maxSc=tmp; maxScRect=rect[rect.size()-1]; } } } 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); }while(size.width>=initSize.width && size.height>=initSize.height); END_TICK("detector"); dfprintf((stdout,"after NCC: nneg=%d npos=%d\n",nneg,npos)); #if !0 std::vector poss,negs; for(int i=0;i<(int)rect.size();i++){ if(isObject[i]) poss.push_back(rect[i]); else negs.push_back(rect[i]); } dfprintf((stdout,"%d pos and %d neg\n",(int)poss.size(),(int)negs.size())); drawWithRects(img,negs,poss); #endif dfprintf((stdout,"%d after ensemble\n",pass)); if(maxSc<0){ return false; } res=maxScRect; return true; } bool TLDDetector::patchVariance(Mat_& intImgP,Mat_& intImgP2,double originalVariance,Point pt,Size size){ return variance(intImgP,intImgP2,Rect(pt.x,pt.y,size.width,size.height)) >= 0.5*originalVariance; } double TLDDetector::ensembleClassifierNum(const uchar* data,int rowstep){ TrackerTLDModel* tldModel=((TrackerTLDModel*)static_cast(model)); std::vector* classifiers=tldModel->getClassifiers(); double p=0; for(int k=0;k<(int)classifiers->size();k++){ p+=(*classifiers)[k].posteriorProbability(data,rowstep); } p/=classifiers->size(); return p; } double TrackerTLDModel::Sr(const Mat_& patch){ double splus=0.0; for(int i=0;i<(int)positiveExamples.size();i++){ splus=std::max(splus,0.5*(NCC(positiveExamples[i],patch)+1.0)); } double sminus=0.0; for(int i=0;i<(int)negativeExamples.size();i++){ sminus=std::max(sminus,0.5*(NCC(negativeExamples[i],patch)+1.0)); } if(splus+sminus==0.0){ return 0.0; } return splus/(sminus+splus); } double TrackerTLDModel::Sc(const Mat_& patch){ double splus=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)); } } double sminus=0.0; for(int i=0;i<(int)negativeExamples.size();i++){ 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& box,const std::vector& isPositive, const std::vector& alsoIntoModel){ 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)box.size();k++){ if(alsoIntoModel[k]){ resample(img,box[k],standardPatch); if(isPositive[k]){ positiveIntoModel++; pushIntoModel(standardPatch,true); }else{ negativeIntoModel++; pushIntoModel(standardPatch,false); } } #ifdef CLOSED_LOOP if(alsoIntoModel[k] || (isPositive[k]==false)){ #else if(alsoIntoModel[k]){ #endif resample(imgBlurred,box[k],blurredPatch); if(isPositive[k]){ positiveIntoEnsemble++; }else{ negativeIntoEnsemble++; } for(int i=0;i<(int)classifiers.size();i++){ classifiers[i].integrate(blurredPatch,isPositive[k]); } } } if(negativeIntoModel>0) dfprintf((stdout,"negativeIntoModel=%d ",negativeIntoModel)); if(positiveIntoModel>0) dfprintf((stdout,"positiveIntoModel=%d ",positiveIntoModel)); if(negativeIntoEnsemble>0) dfprintf((stdout,"negativeIntoEnsemble=%d ",negativeIntoEnsemble)); if(positiveIntoEnsemble>0) dfprintf((stdout,"positiveIntoEnsemble=%d ",positiveIntoEnsemble)); dfprintf((stdout,"\n")); } void TrackerTLDModel::integrateAdditional(const std::vector >& eForModel,const std::vector >& eForEnsemble,bool isPositive){ int positiveIntoModel=0,negativeIntoModel=0,positiveIntoEnsemble=0,negativeIntoEnsemble=0; for(int k=0;k<(int)eForModel.size();k++){ double sr=Sr(eForModel[k]); if((sr>THETA_NN)!=isPositive){ if(isPositive){ positiveIntoModel++; pushIntoModel(eForModel[k],true); }else{ negativeIntoModel++; 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.size(); if((p>0.5)!=isPositive){ if(isPositive){ positiveIntoEnsemble++; }else{ negativeIntoEnsemble++; } for(int i=0;i<(int)classifiers.size();i++){ classifiers[i].integrate(eForEnsemble[k],isPositive); } } } if(negativeIntoModel>0) dfprintf((stdout,"negativeIntoModel=%d ",negativeIntoModel)); if(positiveIntoModel>0) dfprintf((stdout,"positiveIntoModel=%d ",positiveIntoModel)); if(negativeIntoEnsemble>0) dfprintf((stdout,"negativeIntoEnsemble=%d ",negativeIntoEnsemble)); if(positiveIntoEnsemble>0) dfprintf((stdout,"positiveIntoEnsemble=%d ",positiveIntoEnsemble)); dfprintf((stdout,"\n")); } int Pexpert::additionalExamples(std::vector >& examplesForModel,std::vector >& examplesForEnsemble){ examplesForModel.clear();examplesForEnsemble.clear(); examplesForModel.reserve(100);examplesForEnsemble.reserve(100); std::vector closest(10),scanGrid; Mat scaledImg,blurredImg; double scale=scaleAndBlur(img_,cvRound(log(1.0*resultBox_.width/(initSize_.width))/log(SCALE_STEP)),scaledImg,blurredImg,GaussBlurKernelSize); 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); Point2f center; Size2f size; for(int i=0;i<(int)closest.size();i++){ for(int j=0;j<10;j++){ 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(detector_->model)); Size initSize=tldModel->getMinSize(); Mat_ standardPatch(STANDARD_PATCH_SIZE,STANDARD_PATCH_SIZE); double originalVariance=tldModel->getOriginalVariance();; double tmp; 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); 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,"p=%f\n",(detector_->ensembleClassifierNum(&blurred_img.at(dy*j,dx*i),(int)blurred_img.step[0])))); fprintf(stderr,"ensembleClassifier=%s\n", (detector_->ensembleClassifier(&blurred_img.at(dy*j,dx*i),(int)blurred_img.step[0]))?"true":"false"); 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))); rectangle(imgCanvas,Rect2d(Point2d(scale*dx*i,scale*dy*j),Size2d(initSize.width*scale,initSize.height*scale)), 0, 2, 1 ); imshow("picker",imgCanvas); waitKey(); } } void TrackerTLDModel::pushIntoModel(const Mat_& example,bool positive){ std::vector >* proxyV; unsigned int* proxyN; std::vector* proxyT; if(positive){ proxyV=&positiveExamples; proxyN=&timeStampPositiveNext; proxyT=&timeStampsPositive; }else{ proxyV=&negativeExamples; proxyN=&timeStampNegativeNext; proxyT=&timeStampsNegative; } if(proxyV->size()push_back(example); proxyT->push_back(*proxyN); }else{ int index=rng.uniform((int)0,(int)proxyV->size()); (*proxyV)[index]=example; (*proxyT)[index]=(*proxyN); } (*proxyN)++; } } /* namespace cv */