latest version v1.9 - last update 10 Apr 2010 |
00001 /* 00002 * Copyright (C) 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-Lib: Image Processing and Computer Vision Library 00026 * file .......: ltiAxLocalRegions.h 00027 * authors ....: Pablo Alvarado 00028 * organization: LTI, RWTH Aachen 00029 * creation ...: 7.1.2002 00030 * revisions ..: $Id: ltiAxLocalRegions.h,v 1.7 2006/02/07 18:28:26 ltilib Exp $ 00031 */ 00032 00033 #ifndef _LTI_AX_LOCAL_REGIONS_H_ 00034 #define _LTI_AX_LOCAL_REGIONS_H_ 00035 00036 #include "ltiImage.h" 00037 #include "ltiMath.h" 00038 #include "ltiTransform.h" 00039 #include "ltiLocation.h" 00040 #include "ltiGaussianPyramid.h" 00041 #include <list> 00042 #include <map> 00043 00044 namespace lti { 00045 /** 00046 * This functor is based on concepts described in 00047 * Lowe, D.G. "Object Recognition from Local Scale-Invariant Features", 00048 * Proc. of the International Conference on Computer Vision, Corfu, Greece 00049 * Sept. 1999. pp. 1150-1157. This paper can be found at 00050 * 00051 * http://www.cs.ubc.ca/spider/lowe/papers/iccv99.pdf 00052 * 00053 * It uses the DoG to detect relevant locations, and depending on the 00054 * scale at which the location was found, a corresponding radius will be 00055 * assigned. The orientation of the location will be computed using a small 00056 * orientation histogram on the gradient of the image. 00057 * 00058 * The location detection is done somehow different as in Lowe's 00059 * paper, in order to get a result much faster (but maybe with more 00060 * locations as necessary): 00061 * 00062 * -# For the given channel, a gaussian pyramid is build, where the 00063 * differences between the std. deviation of the gaussians for the 00064 * different levels are sqrt(2) instead of 2. 00065 * -# The DoG (differences of gaussians) between the levels of the pyramid 00066 * are computed. 00067 * -# Compute the local maxima of each level. If their values are greater 00068 * than the given threshold multiplied by the maximum value in the image, 00069 * then consider that region as a valid interesting location and insert 00070 * it in the locations list. 00071 * -# For each location in the list, compute its orientation using 00072 * the maximal value in a orientation histogram computed for a window 00073 * of the size given in the parameters. 00074 */ 00075 class axLocalRegions : public transform { 00076 public: 00077 /** 00078 * the parameters for the class axLocalRegions 00079 */ 00080 class parameters : public transform::parameters { 00081 public: 00082 /** 00083 * default constructor 00084 */ 00085 parameters(); 00086 00087 /** 00088 * copy constructor 00089 * @param other the parameters object to be copied 00090 */ 00091 parameters(const parameters& other); 00092 00093 /** 00094 * destructor 00095 */ 00096 ~parameters(); 00097 00098 /** 00099 * returns name of this type 00100 */ 00101 const char* getTypeName() const; 00102 00103 /** 00104 * copy the contents of a parameters object 00105 * @param other the parameters object to be copied 00106 * @return a reference to this parameters object 00107 */ 00108 parameters& copy(const parameters& other); 00109 00110 /** 00111 * copy the contents of a parameters object 00112 * @param other the parameters object to be copied 00113 * @return a reference to this parameters object 00114 */ 00115 parameters& operator=(const parameters& other); 00116 00117 00118 /** 00119 * returns a pointer to a clone of the parameters 00120 */ 00121 virtual functor::parameters* clone() const; 00122 00123 /** 00124 * write the parameters in the given ioHandler 00125 * @param handler the ioHandler to be used 00126 * @param complete if true (the default) the enclosing begin/end will 00127 * be also written, otherwise only the data block will be written. 00128 * @return true if write was successful 00129 */ 00130 virtual bool write(ioHandler& handler,const bool complete=true) const; 00131 00132 /** 00133 * read the parameters from the given ioHandler 00134 * @param handler the ioHandler to be used 00135 * @param complete if true (the default) the enclosing begin/end will 00136 * be also written, otherwise only the data block will be written. 00137 * @return true if write was successful 00138 */ 00139 virtual bool read(ioHandler& handler,const bool complete=true); 00140 00141 # ifdef _LTI_MSC_6 00142 /** 00143 * this function is required by MSVC only, as a workaround for a 00144 * very awful bug, which exists since MSVC V.4.0, and still by 00145 * V.6.0 with all bugfixes (so called "service packs") remains 00146 * there... This method is also public due to another bug, so please 00147 * NEVER EVER call this method directly: use read() instead 00148 */ 00149 bool readMS(ioHandler& handler,const bool complete=true); 00150 00151 /** 00152 * this function is required by MSVC only, as a workaround for a 00153 * very awful bug, which exists since MSVC V.4.0, and still by 00154 * V.6.0 with all bugfixes (so called "service packs") remains 00155 * there... This method is also public due to another bug, so please 00156 * NEVER EVER call this method directly: use write() instead 00157 */ 00158 bool writeMS(ioHandler& handler,const bool complete=true) const; 00159 # endif 00160 00161 // ------------------------------------------------ 00162 // the parameters 00163 // ------------------------------------------------ 00164 00165 /** 00166 * The gaussian used as window for the orientation histograms will 00167 * have a std. deviation equal to this factor multiplied with the 00168 * std. deviation of the location scale. 00169 * 00170 * Default value: 3 00171 */ 00172 double orientationWindowFactor; 00173 00174 /** 00175 * Number of bins used in the orientation histogram. 00176 * 00177 * Default value 32 00178 */ 00179 int binsInOrientationHistogram; 00180 00181 /** 00182 * first level to consider. Must be greater 0 and smaller or equal than 00183 * lastLevel. 00184 * 00185 * Default: 2 00186 */ 00187 int firstLevel; 00188 00189 /** 00190 * last level to consider. Must be greater or equal than 00191 * firstLevel 00192 * 00193 * Default: 6 00194 */ 00195 int lastLevel; 00196 00197 /** 00198 * Saliency threshold values per level. The elements of the 00199 * vector should be between 0 and 1. The element of the vector 00200 * with the same index as a any given level of the internally 00201 * computed pyramid will be multiplied with the maximum value in 00202 * that level. Only those locations which surpass this value 00203 * are then considered as relevant and inserted in the locations 00204 * list. The size of the vector should be at least lastLevel+1. 00205 * Otherwise, the last value will be taken for all the remaining 00206 * levels. 00207 * 00208 * Default value: vector of size 1 with the value 0.1, 00209 * 00210 */ 00211 vector<float> saliencyThreshold; 00212 00213 /** 00214 * To detect the local maxima, a lti::maximumFilter is used. The size 00215 * of the kernel used for the firstLevel is the one given here. It 00216 * should be an odd number. 00217 * 00218 * Default value: 5 00219 */ 00220 int firstMaximumFilterSize; 00221 00222 /** 00223 * The size of the used kernel can be reduced for each higher level 00224 * in the pyramid. This value should be less or equal 1.0. Internally, 00225 * the kernel value used will be always rounded to an odd integer number 00226 * greater or equal 3. 00227 * 00228 * Default value: 1.0, i.e. do not change the filter size. 00229 */ 00230 float maximumFilterAdaption; 00231 }; 00232 00233 /** 00234 * default constructor 00235 */ 00236 axLocalRegions(); 00237 00238 /** 00239 * copy constructor 00240 * @param other the object to be copied 00241 */ 00242 axLocalRegions(const axLocalRegions& other); 00243 00244 /** 00245 * destructor 00246 */ 00247 virtual ~axLocalRegions(); 00248 00249 /** 00250 * returns the name of this type ("axLocalRegions") 00251 */ 00252 virtual const char* getTypeName() const; 00253 00254 /** 00255 * extracts the most relevant locations from the given channel, and return 00256 * them as list of lti::location objects 00257 * @param src channel with the source data. 00258 * @param locs list of relevant locations 00259 * @return true if apply successful or false otherwise. 00260 */ 00261 bool apply(const channel& src,std::list<location>& locs) const; 00262 00263 /** 00264 * extracts the most relevant locations from the given channel, and return 00265 * them in a map of lists of lti::location objects, the map first key 00266 * is the radius of the locations. 00267 * 00268 * You can iterate in the lists of locations with the same radius as 00269 * follows: 00270 * 00271 * \code 00272 * std::map<float,std::list<location> > locs; // map of lists of locations 00273 * channel chnl; // channel to be analyzed 00274 * draw<float> drawer; // draw on channel 00275 * drawer.use(chnl); // using chnl as canvas 00276 * 00277 * // ... load or create the channel to be analyzed 00278 * 00279 * axLocalRegions localizer; // our local regions functor 00280 * localizer.apply(chnl,locs); // get the local regions 00281 * 00282 * std::map<float,std::list<location> >::const_iterator locsIt; 00283 * std::list<location>::const_iterator it; 00284 * 00285 * for (locsIt=locs.begin();locsIt!=locs.end();++locsIt) { 00286 * cout << "Locations for radius " << (*locsIt).first << endl; 00287 * 00288 * // do something with each location at this level: 00289 * for (it=(*locsIt).second.begin(); 00290 * it!=(*locsIt).second.end(); 00291 * ++it) { 00292 * // for example, draw the location: 00293 * drawer.set(*it); 00294 * } 00295 * } 00296 * 00297 * \endcode 00298 * 00299 * @param src channel with the source data. 00300 * @param locs map of relevant locations 00301 * @return true if apply successful or false otherwise. 00302 */ 00303 bool apply(const channel& src, 00304 std::map<float,std::list<location> >& locs) const; 00305 00306 /** 00307 * copy data of "other" functor. 00308 * @param other the functor to be copied 00309 * @return a reference to this functor object 00310 */ 00311 axLocalRegions& copy(const axLocalRegions& other); 00312 00313 /** 00314 * alias for copy member 00315 * @param other the functor to be copied 00316 * @return a reference to this functor object 00317 */ 00318 axLocalRegions& operator=(const axLocalRegions& other); 00319 00320 /** 00321 * returns a pointer to a clone of this functor. 00322 */ 00323 virtual functor* clone() const; 00324 00325 /** 00326 * returns used parameters 00327 */ 00328 const parameters& getParameters() const; 00329 00330 protected: 00331 /** 00332 * with the final DoG pyramid, compute the location list 00333 */ 00334 bool pyramidToLocs(const channel& src, 00335 const pyramid<channel>& pyr, 00336 std::list<location>& locs) const; 00337 00338 private: 00339 /** 00340 * returns true if i is an even number 00341 */ 00342 inline bool even(const int i) const; 00343 00344 /** 00345 * return the gaussian with sigma = 2 00346 */ 00347 inline double gaussian(const float dy, 00348 const float dx, 00349 const double& s2) const; 00350 00351 }; 00352 } 00353 00354 #endif