latest version v1.9 - last update 10 Apr 2010 |
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 .......: ltiCamshiftTracker.h 00027 * authors ....: Suat Akyol 00028 * organization: LTI, RWTH Aachen 00029 * creation ...: 8.6.2001 00030 * revisions ..: $Id: ltiCamshiftTracker.h,v 1.8 2006/02/07 18:34:17 ltilib Exp $ 00031 */ 00032 00033 #ifndef _LTI_CAMSHIFT_TRACKER_H_ 00034 #define _LTI_CAMSHIFT_TRACKER_H_ 00035 00036 // include files which are needed in this header!! 00037 #include "ltiException.h" 00038 #include "ltiGaussKernels.h" 00039 #include "ltiMath.h" 00040 00041 // include to parent class: 00042 #include "ltiModifier.h" 00043 00044 namespace lti { 00045 /** 00046 * This is the implementation of the CAMSHIFT (Continuously Adaptive 00047 * Mean Shift) Tracking algorithm as described in: G.Bradski, 00048 * "Computer Vision Face Tracking For Use in a Perceptual User 00049 * Interface", IEEE Workshop on Applic.Comp.Vis.,1998. 00050 * 00051 * It tracks a rectangular search window in a channel/channel8, 00052 * which must contain probability information of relevant image 00053 * content (e.g. a skinProbabilityMap). It uses an iterative 00054 * gradient ascent algorithm, that finds the peak, which is the 00055 * closest to the specified window. 00056 * 00057 * Use this by calling an apply on subsequent images and thereby 00058 * passing the last result. Nevertheless, it is possible to control 00059 * rectangle size and position manually. 00060 * 00061 * After an apply you can get Information about the distribution inside the 00062 * search window (e.g. orientation). Use the getXXX() methods to do so. 00063 */ 00064 class camshiftTracker : public modifier { 00065 public: 00066 /** 00067 * the parameters for the class camshiftTracker 00068 */ 00069 class parameters : public modifier::parameters { 00070 public: 00071 /** 00072 * default constructor 00073 */ 00074 parameters(); 00075 00076 /** 00077 * copy constructor 00078 * @param other the parameters object to be copied 00079 */ 00080 parameters(const parameters& other); 00081 00082 /** 00083 * destructor 00084 */ 00085 ~parameters(); 00086 00087 /** 00088 * Kernel Type. 00089 */ 00090 enum eKernelType { 00091 Constant, /**< All data gets equal weight (default)*/ 00092 Gaussian /**< Data in the center of search window gets more weight */ 00093 }; 00094 00095 /** 00096 * returns name of this type 00097 */ 00098 const char* getTypeName() const; 00099 00100 /** 00101 * copy the contents of a parameters object 00102 * @param other the parameters object to be copied 00103 * @return a reference to this parameters object 00104 */ 00105 parameters& copy(const parameters& other); 00106 00107 /** 00108 * copy the contents of a parameters object 00109 * @param other the parameters object to be copied 00110 * @return a reference to this parameters object 00111 */ 00112 parameters& operator=(const parameters& other); 00113 00114 00115 /** 00116 * returns a pointer to a clone of the parameters 00117 */ 00118 virtual functor::parameters* clone() const; 00119 00120 /** 00121 * write the parameters in the given ioHandler 00122 * @param handler the ioHandler to be used 00123 * @param complete if true (the default) the enclosing begin/end will 00124 * be also written, otherwise only the data block will be written. 00125 * @return true if write was successful 00126 */ 00127 virtual bool write(ioHandler& handler,const bool complete=true) const; 00128 00129 /** 00130 * write the parameters in the given ioHandler 00131 * @param handler the ioHandler to be used 00132 * @param complete if true (the default) the enclosing begin/end will 00133 * be also written, otherwise only the data block will be written. 00134 * @return true if write was successful 00135 */ 00136 virtual bool read(ioHandler& handler,const bool complete=true); 00137 00138 # ifdef _LTI_MSC_6 00139 /** 00140 * this function is required by MSVC only, as a workaround for a 00141 * very awful bug, which exists since MSVC V.4.0, and still by 00142 * V.6.0 with all bugfixes (so called "service packs") remains 00143 * there... This method is also public due to another bug, so please 00144 * NEVER EVER call this method directly: use read() instead 00145 */ 00146 bool readMS(ioHandler& handler,const bool complete=true); 00147 00148 /** 00149 * this function is required by MSVC only, as a workaround for a 00150 * very awful bug, which exists since MSVC V.4.0, and still by 00151 * V.6.0 with all bugfixes (so called "service packs") remains 00152 * there... This method is also public due to another bug, so please 00153 * NEVER EVER call this method directly: use write() instead 00154 */ 00155 bool writeMS(ioHandler& handler,const bool complete=true) const; 00156 # endif 00157 00158 // ------------------------------------------------ 00159 // the parameters 00160 // ------------------------------------------------ 00161 00162 // If you add more parameters manually, do not forget to do following: 00163 // 1. indicate in the default constructor the default values 00164 // 2. make sure that the copy member also copy your new parameters 00165 // 3. make sure that the read and write members also read and 00166 // write your parameters 00167 00168 /** 00169 * In order to let the tracker adapt the window size, you have 00170 * to specify a ratio of height to width, that has to be kept 00171 * constant. Otherwise the window size will not be changed by 00172 * the tracker (this is the default, which means 0.0). 00173 * 00174 * height=sizeRatio*width 00175 */ 00176 double sizeRatio; 00177 00178 /** 00179 * This is meant for dealing with missing or insufficient data 00180 * within the search window. If zeroth moment within search 00181 * window doesn't exceed this quota of the maximum possible 00182 * zeroth moment, then the tracker simply doesn't react. 00183 * 00184 * Set this to a value between 0.0 and 1.0 for 0% resp. 100% 00185 * (although 100% is not a reasonable value) 00186 * 00187 * Default is 0.0 00188 */ 00189 double threshold; 00190 00191 /** 00192 * This indicates, how the Data inside the search window should 00193 * be weighted. 00194 * 00195 * Default is "Constant". 00196 * 00197 * Please see eKernelType for further information. 00198 */ 00199 eKernelType kernelType; 00200 00201 }; 00202 00203 /** 00204 * default constructor 00205 */ 00206 camshiftTracker(); 00207 00208 /** 00209 * copy constructor 00210 * @param other the object to be copied 00211 */ 00212 camshiftTracker(const camshiftTracker& other); 00213 00214 /** 00215 * destructor 00216 */ 00217 virtual ~camshiftTracker(); 00218 00219 /** 00220 * returns the name of this type ("camshiftTracker") 00221 */ 00222 virtual const char* getTypeName() const; 00223 00224 /** 00225 * Centers the given search window on the nearest probability peak. 00226 * 00227 * Tracking is realised by using this rectangle in the next call 00228 * of this function. Information about the distribution inside 00229 * the search window is stored and can be retrieved by using the 00230 * getXXXX() methods of this functor. 00231 * 00232 * @param src channel with the source data. Should represent a 00233 * probability map with values between 0.0 and 1.0 00234 * @param window the tracking window. Result will be left here. 00235 * @return true if apply successful or false otherwise. 00236 */ 00237 bool apply(const channel& src,rectangle& window); 00238 00239 /** 00240 * Centers the given search window on the nearest probability peak. 00241 * 00242 * Tracking is realised by using this rectangle in the next call 00243 * of this function. Information about the distribution inside 00244 * the search window is stored and can be retrieved by using the 00245 * getXXXX() methods of this functor. 00246 * 00247 * @param src channel8 with the source data. Should represent a 00248 * probability map (prob(0)=0.0 and prob(255)=1.0) 00249 * @param window the tracking window. Result will be left here. 00250 * @return true if apply successful or false otherwise. 00251 */ 00252 bool apply(const channel8& src,rectangle& window); 00253 00254 /** 00255 * Resets the internal state but not the parameters 00256 */ 00257 bool reset(); 00258 00259 /** 00260 * Tells, if tracker is initialized 00261 */ 00262 bool isInitialized(); 00263 00264 /** 00265 * Tells, if last tracking attempt delivered valid data 00266 */ 00267 bool isValid(); 00268 00269 /** 00270 * Returns Main orientation (-Pi/2 to +Pi/2) of current internal 00271 * distribution state 00272 */ 00273 double getOrientation(); 00274 00275 /** 00276 * Returns length of current internal distribution state 00277 */ 00278 double getLength(); 00279 00280 /** 00281 * Returns width of current internal distribution state 00282 */ 00283 double getWidth(); 00284 00285 /** 00286 * Returns center of current internal distribution state 00287 */ 00288 tpoint<float> getCenter(); 00289 00290 /** 00291 * copy data of "other" functor. 00292 * @param other the functor to be copied 00293 * @return a reference to this functor object 00294 */ 00295 camshiftTracker& copy(const camshiftTracker& other); 00296 00297 /** 00298 * returns a pointer to a clone of this functor. 00299 */ 00300 virtual functor* clone() const; 00301 00302 /** 00303 * returns used parameters 00304 */ 00305 const parameters& getParameters() const; 00306 00307 private: 00308 /** 00309 * Struct for storing the tracker data after call of any apply method 00310 */ 00311 class trackerState { 00312 public: 00313 trackerState(); 00314 ~trackerState(); 00315 00316 // methods 00317 void clear(); 00318 trackerState& copy(const trackerState& other); 00319 trackerState& operator=(const trackerState& other); 00320 00321 // Moments 00322 double M00, M10, M01, M11, M20, M02; 00323 // relative Center positions and size 00324 double xc, yc, s; 00325 // Center position in absolute coordinates 00326 tpoint<float> absCenter; 00327 }; 00328 00329 /** 00330 * shifts and clips rect to fit into given canvas 00331 */ 00332 bool correctRect(trectangle<int>& rect, const trectangle<int>& canvas) const; 00333 00334 /** 00335 * calculates moments in given src 00336 */ 00337 bool getTrackerState(const channel& src); 00338 00339 /** 00340 * stores results of last call of one apply method 00341 */ 00342 trackerState td; 00343 00344 /** 00345 * indicates if the tracker is initialized 00346 */ 00347 bool initialized; 00348 00349 /** 00350 * indicates if last tracking attempt delivered valid data 00351 */ 00352 bool valid; 00353 }; 00354 } 00355 00356 #endif