/*M/////////////////////////////////////////////////////////////////////////////////////// // // 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 "trackerMILModel.hpp" namespace cv { class TrackerMILImpl : public TrackerMIL { public: TrackerMILImpl( const TrackerMIL::Params ¶meters = TrackerMIL::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 ); void compute_integral( const Mat & img, Mat & ii_img ); TrackerMIL::Params params; }; /* * TrackerMIL */ /* * Parameters */ TrackerMIL::Params::Params() { samplerInitInRadius = 3; samplerSearchWinSize = 25; samplerInitMaxNegNum = 65; samplerTrackInRadius = 4; samplerTrackMaxPosNum = 100000; samplerTrackMaxNegNum = 65; featureSetNumFeatures = 250; } void TrackerMIL::Params::read( const cv::FileNode& fn ) { samplerInitInRadius = fn["samplerInitInRadius"]; samplerSearchWinSize = fn["samplerSearchWinSize"]; samplerInitMaxNegNum = fn["samplerInitMaxNegNum"]; samplerTrackInRadius = fn["samplerTrackInRadius"]; samplerTrackMaxPosNum = fn["samplerTrackMaxPosNum"]; samplerTrackMaxNegNum = fn["samplerTrackMaxNegNum"]; featureSetNumFeatures = fn["featureSetNumFeatures"]; } void TrackerMIL::Params::write( cv::FileStorage& fs ) const { fs << "samplerInitInRadius" << samplerInitInRadius; fs << "samplerSearchWinSize" << samplerSearchWinSize; fs << "samplerInitMaxNegNum" << samplerInitMaxNegNum; fs << "samplerTrackInRadius" << samplerTrackInRadius; fs << "samplerTrackMaxPosNum" << samplerTrackMaxPosNum; fs << "samplerTrackMaxNegNum" << samplerTrackMaxNegNum; fs << "featureSetNumFeatures" << featureSetNumFeatures; } /* * Constructor */ Ptr<TrackerMIL> TrackerMIL::createTracker(const TrackerMIL::Params ¶meters){ return Ptr<TrackerMILImpl>(new TrackerMILImpl(parameters)); } TrackerMILImpl::TrackerMILImpl( const TrackerMIL::Params ¶meters ) : params( parameters ) { isInit = false; } void TrackerMILImpl::read( const cv::FileNode& fn ) { params.read( fn ); } void TrackerMILImpl::write( cv::FileStorage& fs ) const { params.write( fs ); } void TrackerMILImpl::compute_integral( const Mat & img, Mat & ii_img ) { Mat ii; std::vector<Mat> ii_imgs; integral( img, ii, CV_32F ); split( ii, ii_imgs ); ii_img = ii_imgs[0]; } bool TrackerMILImpl::initImpl( const Mat& image, const Rect2d& boundingBox ) { srand (1); Mat intImage; compute_integral( image, intImage ); TrackerSamplerCSC::Params CSCparameters; CSCparameters.initInRad = params.samplerInitInRadius; CSCparameters.searchWinSize = params.samplerSearchWinSize; CSCparameters.initMaxNegNum = params.samplerInitMaxNegNum; CSCparameters.trackInPosRad = params.samplerTrackInRadius; CSCparameters.trackMaxPosNum = params.samplerTrackMaxPosNum; CSCparameters.trackMaxNegNum = params.samplerTrackMaxNegNum; Ptr<TrackerSamplerAlgorithm> CSCSampler = Ptr<TrackerSamplerCSC>( new TrackerSamplerCSC( CSCparameters ) ); if( !sampler->addTrackerSamplerAlgorithm( CSCSampler ) ) return false; //or add CSC sampler with default parameters //sampler->addTrackerSamplerAlgorithm( "CSC" ); //Positive sampling CSCSampler.staticCast<TrackerSamplerCSC>()->setMode( TrackerSamplerCSC::MODE_INIT_POS ); sampler->sampling( intImage, boundingBox ); std::vector<Mat> posSamples = sampler->getSamples(); //Negative sampling CSCSampler.staticCast<TrackerSamplerCSC>()->setMode( TrackerSamplerCSC::MODE_INIT_NEG ); sampler->sampling( intImage, boundingBox ); std::vector<Mat> negSamples = sampler->getSamples(); if( posSamples.empty() || negSamples.empty() ) return false; //compute HAAR features TrackerFeatureHAAR::Params HAARparameters; HAARparameters.numFeatures = params.featureSetNumFeatures; HAARparameters.rectSize = Size( (int)boundingBox.width, (int)boundingBox.height ); HAARparameters.isIntegral = true; Ptr<TrackerFeature> trackerFeature = Ptr<TrackerFeatureHAAR>( new TrackerFeatureHAAR( HAARparameters ) ); featureSet->addTrackerFeature( trackerFeature ); featureSet->extraction( posSamples ); const std::vector<Mat> posResponse = featureSet->getResponses(); featureSet->extraction( negSamples ); const std::vector<Mat> negResponse = featureSet->getResponses(); model = Ptr<TrackerMILModel>( new TrackerMILModel( boundingBox ) ); Ptr<TrackerStateEstimatorMILBoosting> stateEstimator = Ptr<TrackerStateEstimatorMILBoosting>( new TrackerStateEstimatorMILBoosting( params.featureSetNumFeatures ) ); model->setTrackerStateEstimator( stateEstimator ); //Run model estimation and update model.staticCast<TrackerMILModel>()->setMode( TrackerMILModel::MODE_POSITIVE, posSamples ); model->modelEstimation( posResponse ); model.staticCast<TrackerMILModel>()->setMode( TrackerMILModel::MODE_NEGATIVE, negSamples ); model->modelEstimation( negResponse ); model->modelUpdate(); return true; } bool TrackerMILImpl::updateImpl( const Mat& image, Rect2d& boundingBox ) { Mat intImage; compute_integral( image, intImage ); //get the last location [AAM] X(k-1) Ptr<TrackerTargetState> lastLocation = model->getLastTargetState(); Rect lastBoundingBox( (int)lastLocation->getTargetPosition().x, (int)lastLocation->getTargetPosition().y, lastLocation->getTargetWidth(), lastLocation->getTargetHeight() ); //sampling new frame based on last location ( sampler->getSamplers().at( 0 ).second ).staticCast<TrackerSamplerCSC>()->setMode( TrackerSamplerCSC::MODE_DETECT ); sampler->sampling( intImage, lastBoundingBox ); std::vector<Mat> detectSamples = sampler->getSamples(); if( detectSamples.empty() ) return false; /*//TODO debug samples Mat f; image.copyTo(f); for( size_t i = 0; i < detectSamples.size(); i=i+10 ) { Size sz; Point off; detectSamples.at(i).locateROI(sz, off); rectangle(f, Rect(off.x,off.y,detectSamples.at(i).cols,detectSamples.at(i).rows), Scalar(255,0,0), 1); }*/ //extract features from new samples featureSet->extraction( detectSamples ); std::vector<Mat> response = featureSet->getResponses(); //predict new location ConfidenceMap cmap; model.staticCast<TrackerMILModel>()->setMode( TrackerMILModel::MODE_ESTIMATON, detectSamples ); model.staticCast<TrackerMILModel>()->responseToConfidenceMap( response, cmap ); model->getTrackerStateEstimator().staticCast<TrackerStateEstimatorMILBoosting>()->setCurrentConfidenceMap( cmap ); if( !model->runStateEstimator() ) { return false; } Ptr<TrackerTargetState> currentState = model->getLastTargetState(); boundingBox = Rect( (int)currentState->getTargetPosition().x, (int)currentState->getTargetPosition().y, currentState->getTargetWidth(), currentState->getTargetHeight() ); /*//TODO debug rectangle(f, lastBoundingBox, Scalar(0,255,0), 1); rectangle(f, boundingBox, Scalar(0,0,255), 1); imshow("f", f); //waitKey( 0 );*/ //sampling new frame based on new location //Positive sampling ( sampler->getSamplers().at( 0 ).second ).staticCast<TrackerSamplerCSC>()->setMode( TrackerSamplerCSC::MODE_INIT_POS ); sampler->sampling( intImage, boundingBox ); std::vector<Mat> posSamples = sampler->getSamples(); //Negative sampling ( sampler->getSamplers().at( 0 ).second ).staticCast<TrackerSamplerCSC>()->setMode( TrackerSamplerCSC::MODE_INIT_NEG ); sampler->sampling( intImage, boundingBox ); std::vector<Mat> negSamples = sampler->getSamples(); if( posSamples.empty() || negSamples.empty() ) return false; //extract features featureSet->extraction( posSamples ); std::vector<Mat> posResponse = featureSet->getResponses(); featureSet->extraction( negSamples ); std::vector<Mat> negResponse = featureSet->getResponses(); //model estimate model.staticCast<TrackerMILModel>()->setMode( TrackerMILModel::MODE_POSITIVE, posSamples ); model->modelEstimation( posResponse ); model.staticCast<TrackerMILModel>()->setMode( TrackerMILModel::MODE_NEGATIVE, negSamples ); model->modelEstimation( negResponse ); //model update model->modelUpdate(); return true; } } /* namespace cv */