latest version v1.9 - last update 10 Apr 2010 |
00001 /* 00002 * Copyright (C) 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 .......: ltiLoweGradientFeature.h 00027 * authors ....: Frederik Lange, Pablo Alvarado 00028 * organization: LTI, RWTH Aachen 00029 * creation ...: 30.11.2003 00030 * revisions ..: $Id: ltiLoweGradientFeature.h,v 1.5 2006/02/08 11:25:54 ltilib Exp $ 00031 */ 00032 00033 #ifndef _LTI_LOWE_GRADIENT_FEATURE_H_ 00034 #define _LTI_LOWE_GRADIENT_FEATURE_H_ 00035 00036 00037 #include "ltiVector.h" 00038 #include "ltiLocation.h" 00039 #include "ltiScaleSpacePyramid.h" 00040 #include "ltiFeatureExtractor.h" 00041 #include "ltiColorContrastGradient.h" 00042 #include "ltiBilinearInterpolator.h" 00043 #include <list> 00044 00045 namespace lti { 00046 /** 00047 * Local feature based on the gradient distribution at the level of the 00048 * location. 00049 * 00050 * This local descriptor based was developed by David Lowe (see his 00051 * paper "Distinctive Image Features from Scale-Invariant 00052 * Keypoints", 2003). 00053 * 00054 * Lowe proposed also proposed 1999 a similar local descriptor called 00055 * "SIFT", but he changed it in his later work to used the information of 00056 * one resolution only. 00057 * 00058 * It computes histograms of the gradient orientation for several 00059 * parts of the region delimited by a location, where the weights of 00060 * each sample are determined by the magnitude of the gradient and the 00061 * distance to the center of the location. 00062 * 00063 * The location is divided in each axis by a given integer number \e h 00064 * (parameters::numHistograms). This results in a total of \e h x \e h 00065 * histograms and each one of them will have \e n x \e n samples, where 00066 * \e n represents parameters::sampleRegionSize. 00067 * 00068 * It can compute features for monochrome images and for color images, where 00069 * the color feature is just the concatenation of the three monochromatic 00070 * RGB ones. 00071 */ 00072 class loweGradientFeature : public featureExtractor { 00073 public: 00074 /** 00075 * The parameters for the class loweGradientFeature 00076 */ 00077 class parameters : public featureExtractor::parameters { 00078 public: 00079 /** 00080 * Default constructor 00081 */ 00082 parameters(); 00083 00084 /** 00085 * Copy constructor 00086 * @param other the parameters object to be copied 00087 */ 00088 parameters(const parameters& other); 00089 00090 /** 00091 * Destructor 00092 */ 00093 ~parameters(); 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 * Read the parameters from 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 /** 00163 * Sigma factor. 00164 * 00165 * The samples at the center of the location will a stronger 00166 * weighting than the ones farther from that center. The weight is 00167 * computed as exp(-x^2/(2*sigma^2)), where x is the distance to the 00168 * location center. 00169 * 00170 * Default value: 3.5 00171 */ 00172 float sigma; 00173 00174 /** 00175 * Location partition. 00176 * 00177 * Each dimension of the location will be split in the given number of 00178 * parts. The total number of histograms computed will be 00179 * the square of the given value. 00180 * 00181 * Default value: 4 (i.e. a total of 16 histograms will be computed). 00182 */ 00183 int locationPartition; 00184 00185 /** 00186 * Histogram Partition 00187 * 00188 * Each histogram computed will use a number of samples equal to the 00189 * square of this value. 00190 * 00191 * Default value: 4 (i.e. a total of 16 samples will be used to compute 00192 * the histogram). 00193 */ 00194 int histogramPartition; 00195 00196 /** 00197 * Number of Bins in the orientation histogram. 00198 * 00199 * Default value: 8 (i.e. only 45 degree steps will be considered) 00200 */ 00201 int orientationBins; 00202 00203 /** 00204 * Parameters for gradient computation. 00205 * 00206 * Please ensure that the mode is "Polar" (the default). Otherwise the 00207 * results will make no sense. 00208 * 00209 * Default value: colorContrastGradient::parameters() 00210 */ 00211 colorContrastGradient::parameters gradientParam; 00212 00213 /** 00214 * Total number of levels in the pyramid. 00215 * 00216 * This should be the same value used for the location extraction stage. 00217 * 00218 * Default value: 15 00219 */ 00220 int pyramidLevels; 00221 00222 /** 00223 * Parameters used to construct the pyramid. 00224 * 00225 * For better results please ensure that this parameter set corresponds 00226 * to the ones used in the location extraction. 00227 * 00228 * Default value: scaleSpacePyramid::parameters() 00229 */ 00230 scaleSpacePyramid<channel>::parameters pyramidParam; 00231 00232 /** 00233 * Location relative radius. 00234 * 00235 * This parameter is necessary to gain the information which 00236 * location belongs to which level. 00237 * 00238 * You should use here exactly the same value given to the 00239 * location selector functor. Since the real radius of a 00240 * pixel at level zero is 0.5, you must ensure that the 00241 * used radius for a location at level zero divide by the factor given 00242 * here results in 0.5. 00243 * 00244 * Default value: 7 00245 */ 00246 float locationRelativeRadius; 00247 00248 /** 00249 * Normalize histogram. 00250 * 00251 * If set to true, each histogram will be normalized, representing a 00252 * probability distribution. 00253 * 00254 * Default value: true 00255 */ 00256 bool normalize; 00257 00258 /** 00259 * Cut threshold. 00260 * 00261 * If \a normalize is set to true, then all histogram values greater 00262 * to this value will be clipped also to this value. This is supposed 00263 * to help compensating illumination changes. If you don't want to clip, 00264 * just set this value to 1.0f. 00265 * 00266 * After all values greater than cutThreshold have been clipped, the 00267 * resulting vector will be normalized again. 00268 * 00269 * Default value: 0.2f 00270 */ 00271 float cutThreshold; 00272 00273 }; 00274 00275 /** 00276 * Default constructor 00277 */ 00278 loweGradientFeature(); 00279 00280 /** 00281 * Construct a functor using the given parameters 00282 */ 00283 loweGradientFeature(const parameters& par); 00284 00285 /** 00286 * Copy constructor 00287 * @param other the object to be copied 00288 */ 00289 loweGradientFeature(const loweGradientFeature& other); 00290 00291 /** 00292 * Destructor 00293 */ 00294 virtual ~loweGradientFeature(); 00295 00296 /** 00297 * Returns the name of this type ("loweGradientFeature") 00298 */ 00299 virtual const char* getTypeName() const; 00300 00301 /** 00302 * Copy data of "other" functor. 00303 * @param other the functor to be copied 00304 * @return a reference to this functor object 00305 */ 00306 loweGradientFeature& copy(const loweGradientFeature& other); 00307 00308 /** 00309 * Alias for copy member 00310 * @param other the functor to be copied 00311 * @return a reference to this functor object 00312 */ 00313 loweGradientFeature& operator=(const loweGradientFeature& other); 00314 00315 /** 00316 * Returns a pointer to a clone of this functor. 00317 */ 00318 virtual functor* clone() const; 00319 00320 /** 00321 * Returns used parameters 00322 */ 00323 const parameters& getParameters() const; 00324 00325 /** 00326 * Update parameters 00327 */ 00328 virtual bool updateParameters(); 00329 00330 // -------------------- 00331 00332 /** 00333 * Extracts gradient features at the locations for a gray-valued 00334 * input channel. 00335 */ 00336 bool apply(const channel &src, 00337 const std::list<location> &locs, 00338 std::list<dvector> &vcts); 00339 00340 /** 00341 * Extracts the color features at the loctions 00342 */ 00343 bool apply(const image &src, 00344 const std::list<location> &locs, 00345 std::list<dvector> &vcts); 00346 00347 /** 00348 * Extract features based on a previously generated pyramid set. 00349 * 00350 * The decision if you want color or gray features is taken at the time 00351 * of the pyramid generation. 00352 * 00353 * @see generate() 00354 */ 00355 bool apply(const std::list<location> &locs, 00356 std::list<dvector> &vcts); 00357 00358 00359 /** 00360 * Compute the gradient feature for the given location. 00361 * 00362 * You must call first the method generate() to indicate which image 00363 * needs to be analyzed. (Otherwise it would take too much time if you 00364 * need to extract several features from the same image, and the pyramid 00365 * would have to be generated each time!) 00366 * 00367 * @param locs location that need to be analyzed. 00368 * @param dest feature vector. 00369 * @return true if successful, or false otherwise. 00370 */ 00371 bool apply(const location& locs, 00372 dvector& dest); 00373 00374 /** 00375 * Generate and internal pyramidal representation for the given color 00376 * image, which can be later analyzed with the respective apply method. 00377 */ 00378 bool generate(const image &src); 00379 00380 /** 00381 * Generate and internal pyramidal representation for the given gray valued 00382 * channel, which can be later analyzed with the respective apply method. 00383 */ 00384 bool generate(const channel &src); 00385 00386 /** 00387 * @name Debug methods. 00388 */ 00389 //@{ 00390 /** 00391 * Return read-only reference to the histogram mask 00392 */ 00393 const imatrix& getHistogramMask() const; 00394 00395 /** 00396 * Return the weight mask 00397 */ 00398 const matrix<float>& getWeightMask() const; 00399 00400 /** 00401 * Return the gradient magnitude pyramid 00402 */ 00403 const scaleSpacePyramid<channel>& getMagnitudePyramid() const; 00404 00405 /** 00406 * Return the gradient orientation pyramid 00407 */ 00408 const scaleSpacePyramid<channel>& getAnglePyramid() const; 00409 00410 //@} 00411 00412 00413 protected: 00414 00415 /** 00416 * the pyramids 00417 */ 00418 scaleSpacePyramid<channel> pyrMag, pyrArg; 00419 00420 /** 00421 * Compute the histogram for a given location 00422 */ 00423 bool computeHistograms(const int level, 00424 const tpoint<float>& pos, 00425 const float angle, 00426 matrix<double>& hists) const; 00427 00428 /** 00429 * @name LUT and Masks 00430 */ 00431 00432 //@{ 00433 00434 /** 00435 * Initialize LUT and masks used to accelerate feature computation 00436 */ 00437 bool initMasks(); 00438 00439 /** 00440 * Mask contains the index of the corresponding histogram for 00441 * each entry. 00442 */ 00443 matrix<int> hmask; 00444 00445 /** 00446 * Mask contains the weight for each entry in the histogram. 00447 */ 00448 matrix<float> weight; 00449 00450 /** 00451 * Position of the location center in the mask 00452 */ 00453 tpoint<float> maskCenter; 00454 00455 /** 00456 * Total number of histograms computer per location. 00457 */ 00458 int numHistograms; 00459 00460 /** 00461 * Input/output points. 00462 * 00463 * The size of this "matrix" will always be the 2 x number of rows of the 00464 * mask, but indexed also with negative values. 00465 * 00466 * The row 0 contains the in points and the row 1 the out points. 00467 */ 00468 matrix<int> ioPts; 00469 00470 //@} 00471 00472 }; 00473 } 00474 00475 #endif