LTI-Lib latest version v1.9 - last update 10 Apr 2010

ltiMeanshiftTracker.h

00001 /*
00002  * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006
00003  * Lehrstuhl fuer Technische Informatik, RWTH-Aachen, Germany
00004  *
00005  * This file is part of the LTI-Computer Vision Library (LTI-Lib)
00006  *
00007  * The LTI-Lib is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public License (LGPL)
00009  * as published by the Free Software Foundation; either version 2.1 of
00010  * the License, or (at your option) any later version.
00011  *
00012  * The LTI-Lib is distributed in the hope that it will be
00013  * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
00014  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with the LTI-Lib; see the file LICENSE.  If
00019  * not, write to the Free Software Foundation, Inc., 59 Temple Place -
00020  * Suite 330, Boston, MA 02111-1307, USA.
00021  */
00022 
00023 
00024 /*----------------------------------------------------------------
00025  * project ....: LTI Digital Image/Signal Processing Library
00026  * file .......: ltiMeanshiftTracker.h
00027  * authors ....: Torsten Kämper
00028  * organization: LTI, RWTH Aachen
00029  * creation ...: 24.9.2001
00030  * revisions ..: $Id: ltiMeanshiftTracker.h,v 1.8 2006/02/08 11:27:18 ltilib Exp $
00031  */
00032 
00033 #ifndef _LTI_MEANSHIFT_TRACKER_H_
00034 #define _LTI_MEANSHIFT_TRACKER_H_
00035 
00036 // include files which are needed in this header
00037 #include "ltiHistogram.h"
00038 
00039 // include parent class:
00040 
00041 #include "ltiModifier.h"
00042 namespace lti {
00043   /**
00044    * This is the implementation of the MEANSHIFT
00045    * Tracking algorithm as described in:
00046    * Comaniciu, Ramesh and Meer, "Real-Time Tracking of
00047    * Non-Rigid Objects using the Mean Shift", IEEE Workshop
00048    * on Applic.Comp.Vis.,2000.
00049    *
00050    * It tracks a rectangular search window (the target)
00051    * in an image by its color distribution. Therefore
00052    * it uses an iterative gradient ascent algorithm, known as
00053    * mean shift, that finds a similarity peak between target
00054    * and candidate positions. The similarity is measured with
00055    * a distance metric, which can be obtained after each apply().
00056    *
00057    * Use this by calling an apply on subsequent images and thereby
00058    * passing the last returned search rectangle. Initialization is
00059    * done with first use or after a call of the reset() method.
00060    */
00061   class meanshiftTracker : public modifier {
00062   public:
00063     /**
00064      * the parameters for the class meanshiftTracker
00065      */
00066     class parameters : public modifier::parameters {
00067     public:
00068       /**
00069        * default constructor
00070        */
00071       parameters();
00072 
00073       /**
00074        * copy constructor
00075        * @param other the parameters object to be copied
00076        */
00077       parameters(const parameters& other);
00078 
00079       /**
00080        * destructor
00081        */
00082       ~parameters();
00083 
00084 
00085       /**
00086        * Kernel Type.
00087        */
00088       enum eKernelType {
00089         Normal,           /**< Normal Kernel (default)*/
00090         Epanechnikov      /**< Epanechnikov Kernel */
00091       };
00092 
00093 
00094       /**
00095        * returns name of this type
00096        */
00097       const char* getTypeName() const;
00098 
00099       /**
00100        * copy the contents of a parameters object
00101        * @param other the parameters object to be copied
00102        * @return a reference to this parameters object
00103        */
00104       parameters& copy(const parameters& other);
00105 
00106       /**
00107        * copy the contents of a parameters object
00108        * @param other the parameters object to be copied
00109        * @return a reference to this parameters object
00110        */
00111       parameters& operator=(const parameters& other);
00112 
00113 
00114       /**
00115        * returns a pointer to a clone of the parameters
00116        */
00117       virtual functor::parameters* clone() const;
00118 
00119       /**
00120        * write the parameters in the given ioHandler
00121        * @param handler the ioHandler to be used
00122        * @param complete if true (the default) the enclosing begin/end will
00123        *        be also written, otherwise only the data block will be written.
00124        * @return true if write was successful
00125        */
00126       virtual bool write(ioHandler& handler,const bool complete=true) const;
00127 
00128       /**
00129        * read the parameters from the given ioHandler
00130        * @param handler the ioHandler to be used
00131        * @param complete if true (the default) the enclosing begin/end will
00132        *        be also written, otherwise only the data block will be written.
00133        * @return true if write was successful
00134        */
00135       virtual bool read(ioHandler& handler,const bool complete=true);
00136 
00137 #     ifdef _LTI_MSC_6
00138       /**
00139        * this function is required by MSVC only, as a workaround for a
00140        * very awful bug, which exists since MSVC V.4.0, and still by
00141        * V.6.0 with all bugfixes (so called "service packs") remains
00142        * there...  This method is also public due to another bug, so please
00143        * NEVER EVER call this method directly: use read() instead
00144        */
00145       bool readMS(ioHandler& handler,const bool complete=true);
00146 
00147       /**
00148        * this function is required by MSVC only, as a workaround for a
00149        * very awful bug, which exists since MSVC V.4.0, and still by
00150        * V.6.0 with all bugfixes (so called "service packs") remains
00151        * there...  This method is also public due to another bug, so please
00152        * NEVER EVER call this method directly: use write() instead
00153        */
00154       bool writeMS(ioHandler& handler,const bool complete=true) const;
00155 #     endif
00156 
00157       // ------------------------------------------------
00158       // the parameters
00159       // ------------------------------------------------
00160 
00161       // If you add more parameters manually, do not forget to do following:
00162       // 1. indicate in the default constructor the default values
00163       // 2. make sure that the copy member also copy your new parameters
00164       // 3. make sure that the read and write members also read and
00165       //    write your parameters
00166 
00167       /**
00168        * precision for iterations:
00169        * 0.1 for deep iteration , 10.0 for fast runtime
00170        * default is 2. allowed range is [0.1 ... ]
00171        */
00172       float precision;
00173 
00174       /**
00175        * Threshold for tracker validity. Range is from 0.0 to 1.0.
00176        * If color distribution distance after apply is below this
00177        * threshold, then the tracker simply doesn't react. Default is 0.8
00178        */
00179       float threshold;
00180 
00181       /**
00182        * Kerneltypes are Normal or Epanechnikov-Kernel
00183        * Default is Normal
00184        */
00185       eKernelType kernelType;
00186 
00187       /**
00188        * The size adaption ratio tells how strong the size adaptation
00189        * may be with one call of an apply() method.
00190        * Range is 0.0 to 1.0 (reasonable values lie between 0.0 and 0.5).
00191        * Default is 0.1
00192        */
00193       float sizeAdaptRatio;
00194     };
00195 
00196     /**
00197      * default constructor
00198      */
00199     meanshiftTracker();
00200 
00201     /**
00202      * copy constructor
00203      * @param other the object to be copied
00204      */
00205     meanshiftTracker(const meanshiftTracker& other);
00206 
00207     /**
00208      * destructor
00209      */
00210     virtual ~meanshiftTracker();
00211 
00212     /**
00213      * returns the name of this type ("meanshiftTracker")
00214      */
00215     virtual const char* getTypeName() const;
00216 
00217     /**
00218      * Tracks a target color distribution. The initial target is
00219      * specified by "window" on first usage or after a reset()
00220      * (i.e. tracker is not initialized).
00221      * Subsequent calls of this method perform tracking by translating
00222      * and scaling the "window" to optimally fit the target color
00223      * distribution.
00224      */
00225     bool apply(const image& src,trectangle<int>& window);
00226 
00227     /**
00228      * Tells, if the tracker has already been initialized with a
00229      * target color distribution.
00230      */
00231     bool isInitialized() const;
00232 
00233     /**
00234      * Explicitly initialize tracker with given region in image.
00235      * This is called automatically when an apply is used while
00236      * tracker is not initialised. I.e. calling initialize() is
00237      * the same as subsequently calling reset() and apply().
00238      */
00239     void initialize(const image& src,trectangle<int>& window);
00240 
00241     /**
00242      * Explicitly initialize tracker with given region in image.
00243      * Additionally weight all pixels with the value in mask.
00244      * You must call this explicitly, if you want to initialize
00245      * with a weighting mask.
00246      */
00247     void initialize(const image& src,trectangle<int>& window, const channel8& mask);
00248 
00249     /**
00250      * Explicitly initialize tracker with given region in image.
00251      * Additionally weight all pixels with the value in mask.
00252      * You must call this explicitly, if you want to initialize
00253      * with a weighting mask.
00254      */
00255     void initialize(const image& src,trectangle<int>& window, const channel& mask);
00256 
00257     /**
00258      * Resets the tracker. Next call of apply initializes it again.
00259      */
00260     void reset();
00261 
00262     /**
00263      * Tells if returned window is valid. This depends on the threshold
00264      * parameter. If the color distribution distance between target and
00265      * candidate window is above threshold, then this method returns
00266      * false.
00267      */
00268     bool isValid() const;
00269 
00270     /**
00271      * returns the distance between the color distribution of the
00272      * initial target and the last returned window.
00273      */
00274     float getDistance() const;
00275 
00276     /**
00277      * returns the center of the tracked candidate distribution.
00278      * In general, this is the returned search windows center,
00279      * except that the winwod is at the fringe of the image.
00280      */
00281     tpoint<float> getCenter() const;
00282 
00283     /**
00284      * returns a const reference to the histogram of the target.
00285      * The histogram only changes on initialization.
00286      */
00287     const thistogram<float>& getTargetHist() const;
00288 
00289     /**
00290      * returns a const reference to the histogram of the tracked candidate.
00291      * The histogram changes after each call of an apply method.
00292      */
00293     const thistogram<float>& getCandidateHist() const;
00294 
00295     /**
00296      * copy data of "other" functor.
00297      * @param other the functor to be copied
00298      * @return a reference to this functor object
00299      */
00300     meanshiftTracker& copy(const meanshiftTracker& other);
00301 
00302     /**
00303      * alias for copy member
00304      * @param other the functor to be copied
00305      * @return a reference to this functor object
00306      */
00307     meanshiftTracker& operator=(const meanshiftTracker& other);
00308 
00309     /**
00310      * returns a pointer to a clone of this functor.
00311      */
00312     virtual functor* clone() const;
00313 
00314     /**
00315      * returns used parameters
00316      */
00317     const parameters& getParameters() const;
00318 
00319     // If you add more attributes manually, do not forget to do following:
00320     // 1. indicate in the default constructor the default values
00321     // 2. make sure that the copy member also copy your new attributes, or
00322     //    to ensure there, that these attributes are properly initialized.
00323 
00324    private:
00325     /**
00326      * Struct for storing the tracker data after call of any apply method
00327      */
00328     class trackerState {
00329       public:
00330         trackerState();
00331         ~trackerState();
00332 
00333         // methods
00334         void clear();
00335         trackerState& copy(const trackerState& other);
00336         trackerState& operator=(const trackerState& other);
00337 
00338         // final center position y1 (after iterations)
00339         tpoint<float> y1;
00340         // final Bhattacharyya coefficient for position y1
00341         float bhat1;
00342         // target color probability
00343         thistogram<float> targetProb;
00344         // candidate color probability for pos y1
00345         thistogram<float> candProb;
00346         // distance and height to width ratio of tracking box
00347         float distance, hwRatio;
00348     };
00349 
00350     /**
00351      * calculates the bhattacharyya metric for measuring
00352      * similarity of two color distributions
00353      */
00354     float calcBhatCoef(const thistogram<float>& targetProb,
00355                        const thistogram<float>& candProb) const;
00356 
00357     /**
00358      * fills the histogram "prob" with the colors inside the
00359      * rectangle "canvas" in the image. Each color is weighted
00360      * with a kernel function. Note: the histogramm is not
00361      * normalized to 1, thus use prob.getProbability() to obtain
00362      * probabilities.
00363      */
00364     void calcProb(thistogram<float>& prob,
00365                   const trectangle<int>& canvas,
00366                   const image& src) const;
00367 
00368     /**
00369      * fills the histogram "prob" with the colors inside the
00370      * rectangle "canvas" in the image. Each color is weighted
00371      * with a kernel function AND the weight given in mask.
00372      * Note: the histogramm is not normalized to 1, thus use
00373      * prob.getProbability() to obtain probabilities.
00374      */
00375     void calcProb(thistogram<float>& prob,
00376                   const trectangle<int>& canvas,
00377                   const image& src,
00378                   const channel8& mask) const;
00379 
00380      /**
00381      * fills the histogram "prob" with the colors inside the
00382      * rectangle "canvas" in the image. Each color is weighted
00383      * with a kernel function AND the weight given in mask.
00384      * Note: the histogramm is not normalized to 1, thus use
00385      * prob.getProbability() to obtain probabilities.
00386      */
00387     void calcProb(thistogram<float>& prob,
00388                   const trectangle<int>& canvas,
00389                   const image& src,
00390                   const channel& mask) const;
00391 
00392 
00393     /**
00394      * returns the Normal or Epanechikov kernel for the given position
00395      */
00396     float kernel(const tpoint<int>& cen,
00397                  const tpoint<int>& pos,
00398                  const tpoint<int>& h) const;
00399 
00400     /**
00401      * calculates the color distribution distance between two histogramms
00402      */
00403     float calcDistance(const thistogram<float>& targetProb,
00404                        const thistogram<float>& candProb) const;
00405 
00406     /**
00407      * shifts and clips rect to fit into given canvas
00408      */
00409     void correctRect(trectangle<int>& rect,
00410                      const trectangle<int>& canvas) const;
00411 
00412     /**
00413      * returns the derivate of the Epanechikov kernel
00414      */
00415     float derivateKernel(const tpoint<int>& cen,
00416                          const tpoint<int>& pos,
00417                          const tpoint<int>& h) const;
00418 
00419     /**
00420      * stores results of last call of one apply method (the state of the tracker)
00421      */
00422     trackerState td;
00423 
00424     /**
00425      * indicates if the tracker is initialized
00426      */
00427     bool initialized;
00428 
00429     /**
00430      * indicates if the last apply was a valid tracking step
00431      */
00432     bool valid;
00433 
00434   };
00435 }
00436 
00437 #endif

Generated on Sat Apr 10 15:25:51 2010 for LTI-Lib by Doxygen 1.6.1