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

ltiLkTracker.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 .......: ltiLkTracker.h
00027  * authors ....: Frederik Lange
00028  * organization: LTI, RWTH Aachen
00029  * creation ...: 26.4.2001
00030  * revisions ..: $Id: ltiLkTracker.h,v 1.8 2006/02/08 11:23:21 ltilib Exp $
00031  */
00032 
00033 #ifndef _LTI_LK_TRACKER_H_
00034 #define _LTI_LK_TRACKER_H_
00035 
00036 #include "ltiImage.h"
00037 #include "ltiModifier.h"
00038 #include "ltiPointList.h"
00039 #include "ltiGaussianPyramid.h"
00040 #include "ltiCornerDetector.h"
00041 
00042 namespace lti {
00043 
00044   /**
00045    * This functor implements a hierachical Lucas Kanade optical flow.
00046    * It is used for feature tracking through a image sequence.
00047    * Therefore it uses a corner detector to find the initial features
00048    *
00049    * For more details please look at Jean-Yves Bouguet's paper "Pyramidal
00050    * Implementation of the Lucas Kanade Feature Tracker.  Description of the
00051    * algorithm"
00052    *
00053    */
00054   class lkTracker : public modifier {
00055   public:
00056 
00057     /**
00058      * constant which describes a point outOfRange.  In general, a point
00059      * with negative coordinates can be considered out of range
00060      */
00061     static const tpoint<float> outOfRange;
00062 
00063     /**
00064      * the parameters for the class lkTracker
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        * returns name of this type
00086        */
00087       const char* getTypeName() const;
00088 
00089       /**
00090        * copy the contents of a parameters object
00091        * @param other the parameters object to be copied
00092        * @return a reference to this parameters object
00093        */
00094       parameters& copy(const parameters& other);
00095 
00096       /**
00097        * copy the contents of a parameters object
00098        * @param other the parameters object to be copied
00099        * @return a reference to this parameters object
00100        */
00101       parameters& operator=(const parameters& other);
00102 
00103 
00104       /**
00105        * returns a pointer to a clone of the parameters
00106        */
00107       virtual functor::parameters* clone() const;
00108 
00109       /**
00110        * write the parameters in the given ioHandler
00111        * @param handler the ioHandler to be used
00112        * @param complete if true (the default) the enclosing begin/end will
00113        *        be also written, otherwise only the data block will be written.
00114        * @return true if write was successful
00115        */
00116       virtual bool write(ioHandler& handler,const bool complete=true) const;
00117 
00118       /**
00119        * write the parameters in the given ioHandler
00120        * @param handler the ioHandler to be used
00121        * @param complete if true (the default) the enclosing begin/end will
00122        *        be also written, otherwise only the data block will be written.
00123        * @return true if write was successful
00124        */
00125       virtual bool read(ioHandler& handler,const bool complete=true);
00126 
00127 #     ifdef _LTI_MSC_6
00128       /**
00129        * this function is required by MSVC only, as a workaround for a
00130        * very awful bug, which exists since MSVC V.4.0, and still by
00131        * V.6.0 with all bugfixes (so called "service packs") remains
00132        * there...  This method is also public due to another bug, so please
00133        * NEVER EVER call this method directly: use read() instead
00134        */
00135       bool readMS(ioHandler& handler,const bool complete=true);
00136 
00137       /**
00138        * this function is required by MSVC only, as a workaround for a
00139        * very awful bug, which exists since MSVC V.4.0, and still by
00140        * V.6.0 with all bugfixes (so called "service packs") remains
00141        * there...  This method is also public due to another bug, so please
00142        * NEVER EVER call this method directly: use write() instead
00143        */
00144       bool writeMS(ioHandler& handler,const bool complete=true) const;
00145 #     endif
00146 
00147       // ------------------------------------------------
00148       // the parameters
00149       // ------------------------------------------------
00150 
00151       /**
00152        * WindowSize gives the size of the window used for comparsion
00153        * of the features.
00154        *
00155        * Default value is 4
00156        */
00157       int windowSize;
00158 
00159       /**
00160        * NumLevels gives the number of levels in the Pyramid.
00161        *
00162        * Default value is 4
00163        */
00164       int numLevels;
00165 
00166       /**
00167        * maximal number of iteration steps per pyramid level.
00168        * Default value: 10
00169        */
00170       int maxStepsPerLevel;
00171 
00172       /**
00173        * This is the square of the computed pixel residual which must be
00174        * reached before the algorithm stops.
00175        * Default value: 0.0009f (0.03*0.03);
00176        */
00177       float eta2Threshold;
00178 
00179       /**
00180        * if the difference between both matched windows is greater
00181        * than this threshold, the point will be marked as invalid, and it
00182        * will not be tracked any more.
00183        * Default value: 0.99f
00184        */
00185       float errorThreshold;
00186 
00187       /**
00188        * @name Corner Extraction
00189        * The following parameters controls the internal corner detection
00190        * algorithms.
00191        */
00192       //@{
00193       /**
00194        * if true, a corner detector is used.
00195        *
00196        * Default is true
00197        */
00198       bool autoCorners;
00199 
00200       /**
00201        * set the corner detector to be used.  A copy of the given
00202        * functor will be made.
00203        */
00204       bool setCornerDetector(const cornerDetector& cdet);
00205 
00206       /**
00207        * get a reference to the corner detector functor being used
00208        */
00209       cornerDetector& getCornerDetector();
00210 
00211       /**
00212        * get a read only reference to the corner detector object being used
00213        */
00214       const cornerDetector& getCornerDetector() const;
00215       //@}
00216 
00217     protected:
00218       /**
00219        * cornerDetector used to generate the corners.
00220        *
00221        * Default value:
00222        */
00223       cornerDetector* cornerFinder;
00224     };
00225 
00226     /**
00227      * default constructor
00228      */
00229     lkTracker();
00230 
00231     /**
00232      * copy constructor
00233      * @param other the object to be copied
00234      */
00235     lkTracker(const lkTracker& other);
00236 
00237     /**
00238      * destructor
00239      */
00240     virtual ~lkTracker();
00241 
00242     /**
00243      * returns the name of this type ("lkTracker")
00244      */
00245     virtual const char* getTypeName() const;
00246 
00247     /**
00248      * Track the points in the src channel and return the new positions in
00249      * the given point list.
00250      * Please note that internally the pointList contains points with
00251      * <code>float</code> precision, and to return an <code>pointList</code>
00252      * they need to be casted.  Is faster if you try to use directly the
00253      * other apply member, which works directly with the float-points.
00254      *
00255      * @param src the channel with the points being tracked.
00256      *            The first presentation (or the next presentation after a
00257      *            reset() ) is used for initialization only.  The
00258      *            next ones are used to track the first given point set, and
00259      *            the results will be left in <code>featurePoints</code>.
00260      *
00261      * @param featurePoints the first time the apply is called (or after a
00262      *            reset() ), this list contain the positions of the points to
00263      *            track.  If the attribute <code>autoCorners</code> of the
00264      *            parameters is true, the content of this list will be
00265      *            discarded and the positions  of the automatic detected
00266      *            corners will be left here.  Points getting
00267      *            invalid during tracking are marked by negative values in the
00268      *            point list.
00269      *
00270      * @return true if apply successful or false otherwise.
00271      */
00272     bool apply(const channel& src, pointList& featurePoints);
00273 
00274     /**
00275      * Track the points in the src channel and return the new positions in
00276      * the given point list.
00277      * Please note that internally the pointList contains points with
00278      * <code>float</code> precision, and to return an <code>pointList</code>
00279      * they need to be casted.  Is faster if you try to use directly the
00280      * other apply member, which works directly with the float-points.
00281      *
00282      * @param src the channel with the points being tracked.
00283      *            The first presentation (or the next presentation after a
00284      *            reset() ) is used for initialization only.  The
00285      *            next ones are used to track the first given point set, and
00286      *            the results will be left in <code>featurePoints</code>.
00287      *
00288      * @param featurePoints the first time the apply is called (or after a
00289      *            reset() ), this list contain the positions of the points to
00290      *            track.  If the attribute <code>autoCorners</code> of the
00291      *            parameters is true, the content of this list will be
00292      *            discarded and the positions  of the automatic detected
00293      *            corners will be left here.  Points getting
00294      *            invalid during tracking are marked by negative values in the
00295      *            point list.
00296      * @param validPoints returns the number of valid points in the list
00297      *            feature points.
00298      * @return true if apply successful or false otherwise.
00299      */
00300     bool apply(const channel& src, pointList& featurePoints,int& validPoints);
00301 
00302     /**
00303      * Track the points in the src channel and return the new positions in
00304      * the given point list.
00305      *
00306      * @param src the channel with the points being tracked.
00307      *            The first presentation (or the next presentation after a
00308      *            reset() ) is used for initialization only.  The
00309      *            next ones are used to track the first given point set, and
00310      *            the results will be left in <code>featurePoints</code>.
00311      *
00312      * @param featurePoints the first time the apply is called (or after a
00313      *            reset() ), this list contain the positions of the points to
00314      *            track.  If the attribute <code>autoCorners</code> of the
00315      *            parameters is true, the content of this list will be
00316      *            discarded and the positions  of the automatic detected
00317      *            corners will be left here.  Points getting
00318      *            invalid during tracking are marked by negative values in the
00319      *            point list.
00320      *
00321      * @return true if apply successful or false otherwise.
00322      */
00323     bool apply(const channel& src, tpointList<float>& featurePoints);
00324 
00325     /**
00326      * Track the points in the src channel and return the new positions in
00327      * the given point list.
00328      *
00329      * @param src the channel with the points being tracked.
00330      *            The first presentation (or the next presentation after a
00331      *            reset() ) is used for initialization only.  The
00332      *            next ones are used to track the first given point set, and
00333      *            the results will be left in <code>featurePoints</code>.
00334      *
00335      * @param featurePoints the first time the apply is called (or after a
00336      *            reset() ), this list contain the positions of the points to
00337      *            track.  If the attribute <code>autoCorners</code> of the
00338      *            parameters is true, the content of this list will be
00339      *            discarded and the positions  of the automatic detected
00340      *            corners will be left here.  Points getting
00341      *            invalid during tracking are marked by negative values in the
00342      *            point list.
00343      * @param validPoints returns the number of valid points in the list
00344      *            featurePoints
00345      *
00346      * @return true if apply successful or false otherwise.
00347      */
00348     bool apply(const channel& src, tpointList<float>& featurePoints,
00349                int& validPoints);
00350 
00351     /**
00352      * Resets the internal state but not the parameters
00353      */
00354     bool reset();
00355 
00356     /**
00357      * Reset some points in the tracking list.
00358      *
00359      * Please note that this reset takes effect only if there is already
00360      * a tracking point list in the functor, i.e. if a "total" reset was
00361      * already done followed by an apply.
00362      *
00363      * @param whichPoints Only those points in the list with valid
00364      * values (coordinates > 0) will be reset: they will get this
00365      * valid value.  All invalid points in the list, i.e. with
00366      * coordinates lower than zero will be keped as they are.
00367      * Please note that point sequence in this list must correspond to
00368      * the sequence of the tracking list!
00369      */
00370     bool reset(const tpointList<float>& whichPoints);
00371 
00372     /**
00373      * Reset some points in the tracking list.
00374      *
00375      * Please note that this reset takes effect only if there is already
00376      * a tracking point list in the functor, i.e. if a "total" reset was
00377      * already done followed by an apply.
00378      *
00379      * @param whichPoints Only those points in the list with valid
00380      * values (coordinates > 0) will be reset: they will get this
00381      * valid value.  All invalid points in the list, i.e. with
00382      * coordinates lower than zero will be keped as they are.
00383      * Please note that point sequence in this list must correspond to
00384      * the sequence of the tracking list!
00385      */
00386     bool reset(const pointList& whichPoints);
00387 
00388     /**
00389      * copy data of "other" functor.
00390      * @param other the functor to be copied
00391      * @return a reference to this functor object
00392      */
00393     lkTracker& copy(const lkTracker& other);
00394 
00395     /**
00396      * returns a pointer to a clone of this functor.
00397      */
00398     virtual functor* clone() const;
00399 
00400     /**
00401      * returns used parameters
00402      */
00403     const parameters& getParameters() const;
00404 
00405   protected:
00406     /**
00407      * a position/direction vector type
00408      */
00409     class vec2d {
00410     public:
00411       /**
00412        * Default constructor.  Intialize all members with 0.0f
00413        */
00414       vec2d() : error(0.0f) {};
00415 
00416       /**
00417        * default destructor
00418        */
00419       ~vec2d(){};
00420 
00421       /**
00422        * position of the origin of the vector
00423        */
00424       tpoint<float> p;
00425 
00426       /**
00427        * direction of the vector
00428        */
00429       tpoint<float> d;
00430 
00431       /**
00432        * error term
00433        */
00434       float error;
00435     };
00436 
00437   private:
00438     /**
00439      * automatic detection of corners
00440      */
00441     void findInitialPoints(const channel& img,pointList& initialPoints);
00442 
00443     /**
00444      * exchange both pyramids and generate the new gassian pyramid for
00445      * the given channel in the pyramid B.
00446      */
00447     void buildPyramid(const channel& img);
00448 
00449     /**
00450      * generate the gradient of the given channel
00451      */
00452     void buildGradientMaps(const gaussianPyramid<channel>& src,
00453                            channel*& gradX,
00454                            channel*& gradY);
00455 
00456     /**
00457      * return the result of a bilinear interpolation for the value at(y,x)
00458      */
00459     inline float getBilinear(const float x, const float y, const channel& map);
00460 
00461     /**
00462      * indicates if the tracker is initialised
00463      */
00464     bool initialised;
00465 
00466     /**
00467      * the two pyramids for the downsampled images
00468      * These are pointers to allow efficient exchange from B to A without
00469      * copying anything.
00470      */
00471     gaussianPyramid<channel>
00472       *pyramidA,
00473       *pyramidB;
00474 
00475     /**
00476      * the flow vectors between the images
00477      */
00478     std::list<vec2d> flowVectors;
00479 
00480   };
00481 }
00482 
00483 #endif

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