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-Lib: Image Processing and Computer Vision Library 00026 * file .......: ltiAxOGDFeature.h 00027 * authors ....: Pablo Alvarado 00028 * organization: LTI, RWTH Aachen 00029 * creation ...: 21.5.2001 00030 * revisions ..: $Id: ltiAxOGDFeature.h,v 1.9 2006/02/07 18:28:46 ltilib Exp $ 00031 */ 00032 00033 #ifndef _LTI_AX_O_G_D_FEATURE_H_ 00034 #define _LTI_AX_O_G_D_FEATURE_H_ 00035 00036 #include "ltiImage.h" 00037 #include "ltiVector.h" 00038 #include "ltiOgdKernels.h" 00039 #include "ltiOgdFilter.h" 00040 #include "ltiLocation.h" 00041 #include <list> 00042 #include <map> 00043 #include <vector> 00044 00045 #include "ltiLocalFeatureExtractor.h" 00046 #include "ltiGlobalFeatureExtractor.h" 00047 00048 namespace lti { 00049 /** 00050 * OGD based texture feature. 00051 * 00052 * Functor for texture feature extraction that uses the steerability 00053 * property of the oriented gaussian derivatives (OGD) to generate rotation 00054 * invariant feature vectors. 00055 * 00056 * The description of this feature can be found on Alvarado, P., 00057 * Doerfler, P. and Wickel, J. "Axon2 - A visual object recognition 00058 * system for non-rigid objects" SPPRA July, 2001 00059 * (http://www.techinfo.rwth-aachen.de/Veroeffentlichungen/V003_2001.pdf) 00060 * 00061 * The basic idea is to compute the "energy" of a region (a location for 00062 * local features or the whole image for global features) as a steerable 00063 * function. 00064 * 00065 * This energy is computed for different "power" channels, which are the 00066 * result of convolving the images with OGD filters of a specific order. 00067 * 00068 * In some sense, the first order OGD compute some "edge" energy, while 00069 * second order OGD compute some "line" energy. 00070 */ 00071 class axOGDFeature : public localFeatureExtractor, 00072 public globalFeatureExtractor { 00073 public: 00074 /** 00075 * The parameters for the class axOGDFeature 00076 */ 00077 class parameters : public localFeatureExtractor::parameters, 00078 public globalFeatureExtractor::parameters { 00079 public: 00080 /** 00081 * Default constructor 00082 */ 00083 parameters(); 00084 00085 /** 00086 * Copy constructor 00087 * @param other the parameters object to be copied 00088 */ 00089 parameters(const parameters& other); 00090 00091 /** 00092 * Destructor 00093 */ 00094 ~parameters(); 00095 00096 /** 00097 * Returns name of this type 00098 */ 00099 const char* getTypeName() const; 00100 00101 /** 00102 * Copy the contents of a parameters object 00103 * @param other the parameters object to be copied 00104 * @return a reference to this parameters object 00105 */ 00106 parameters& copy(const parameters& other); 00107 00108 /** 00109 * Copy the contents of a parameters object 00110 * @param other the parameters object to be copied 00111 * @return a reference to this parameters object 00112 */ 00113 parameters& operator=(const parameters& other); 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 /** 00163 * Use Gaussian kernel. 00164 * 00165 * If gaussian is true, for the local features a gaussian kernel 00166 * is used, with the given size (windowSize) and variance. If 00167 * false, a square kernel is used, with the given windowSize. 00168 * Default: true 00169 */ 00170 bool gaussian; 00171 00172 /** 00173 * Window size for the extraction of local features. 00174 * 00175 * This is the size of the gaussian kernel is "gaussian" is true, or the 00176 * size of the square window, if a faster square kernel is chosen. 00177 * Default : 13 (13x13 window) 00178 */ 00179 int windowSize; 00180 00181 /** 00182 * If "gaussian" is true, this value gives the variance to be used. 00183 * Default: -1 (i.e. use default variance for the given windowSize 00184 */ 00185 double windowVariance; 00186 00187 /** 00188 * Variance of the base gaussian used in the OGDs 00189 * Default: 2.0 00190 */ 00191 double ogdVariance; 00192 00193 /** 00194 * Specify if a second set of levels should be generated, using a 00195 * standard deviation equal to the one of the original set multiplied 00196 * with a factor sqrt(2). This allows a better resolution of the 00197 * "resolution"-axis. 00198 * Default: true 00199 */ 00200 bool voices; 00201 00202 /** 00203 * Size of the ODG filter kernels used. 00204 * Default: 13 00205 */ 00206 int ogdSize; 00207 00208 /** 00209 * Order of the derivative being used. 00210 * The valid range by now is 1 or 2. 00211 * Default: 2 00212 */ 00213 int ogdOrder; 00214 00215 /** 00216 * Number of levels used. 00217 * Default 4 00218 */ 00219 int levels; 00220 00221 /** 00222 * If true, the feature vector will contain also phase information 00223 * which is NOT rotation invariant. 00224 * Default: false 00225 */ 00226 bool considerPhase; 00227 00228 /** 00229 * If true, the angles in the thetaX channels will be fixed to 00230 * be perpendicular to the edges. If false, these angles will be keeped 00231 * to represent the phase of the energy components as described in the 00232 * original paper. 00233 * 00234 * Note that this parameter only changes the content of the 00235 * channels thetaX returned by apply(const channel&,channel&,channel&) 00236 * and apply(const channel&,channel&,channel&,channel&,channel&) methods. 00237 * 00238 * Default value: true 00239 */ 00240 bool computeEdgeOrientation; 00241 }; 00242 00243 /** 00244 * Default constructor 00245 */ 00246 axOGDFeature(); 00247 00248 /** 00249 * Copy constructor 00250 * @param other the object to be copied 00251 */ 00252 axOGDFeature(const axOGDFeature& other); 00253 00254 /** 00255 * Destructor 00256 */ 00257 virtual ~axOGDFeature(); 00258 00259 /** 00260 * Returns the name of this type ("axOGDFeature") 00261 */ 00262 virtual const char* getTypeName() const; 00263 00264 /** 00265 * Indicates which channel to use in the local feature extraction. 00266 * Some precalculation will be done, and using the 00267 * apply(const point&, dvector&) member, the feature vector of a specific 00268 * position can be computed in a faster way. 00269 * 00270 * After calling this method the corresponding monochromatic features will 00271 * be extracted. 00272 */ 00273 virtual bool use(const channel& src); 00274 00275 /** 00276 * Indicates which channels to use in the local feature extraction. 00277 * Some precalculation will be done, and using the 00278 * apply(const point&, dvector&) member, the feature vector of a specific 00279 * position can be computed in a faster way. 00280 * 00281 * After calling this method the corresponding opponent-color features will 00282 * be extracted. 00283 */ 00284 virtual bool use(const channel& center,const channel& surround); 00285 00286 /** 00287 * Extract the local feature at the position pos and leave the result 00288 * in the given vector. It depends on the last used "use" member, if 00289 * the feature vector is an "opponent-color" feature or a 00290 * monochromatic feature. 00291 * 00292 * @param pos the position at the given image. 00293 * @param dest the feature vector. 00294 * @return true if sucessful, false otherwise 00295 */ 00296 virtual bool apply(const point& pos,dvector& dest) const; 00297 00298 /** 00299 * Extracts the OGD rotation invariant feature from the given gray 00300 * valued image (a channel) 00301 * @param src channel with the source data. 00302 * @param dest the feature vector 00303 * @return true if apply successful or false otherwise. 00304 */ 00305 bool apply(const channel& src,dvector& dest) const; 00306 00307 /** 00308 * Extract the OGD features from the red, green and blue components of 00309 * the given image and concatenate the results. 00310 * @param src image with the source data. 00311 * @param dest the feature vector 00312 * @return true if apply successful or false otherwise. 00313 */ 00314 bool apply(const image& src,dvector& dest) const; 00315 00316 /** 00317 * Extracts the first order OGD coefficients for the given window 00318 * size and variance (if gaussian). The "levels" parameter will be 00319 * ignored, and only the first level will be calculated. This method 00320 * is used by other feature extractors. 00321 * 00322 * To obtain the angle othogonal to the edges, you need to divide 00323 * <code>theta1</code> by 2. This can automatically be done if you 00324 * specify it in the parameters. You can use a1 and theta1/2 for the 00325 * lti::orientationFeature. 00326 */ 00327 bool apply(const channel& src, 00328 channel& a0,channel& a1,channel& theta1) const; 00329 00330 /** 00331 * Extracts the second order OGD coefficients for the given windows 00332 * size and variance (if gaussian). The "levels" parameter will be 00333 * ignored, and only the first level will be calculated. This method 00334 * is used by other feature extractors 00335 * 00336 * To obtain the angle othogonal to the edges, you need to divide 00337 * <code>theta1</code> by 2. You can use a1 and theta1/2 for the 00338 * lti::orientationFeature. 00339 */ 00340 bool apply(const channel& src, 00341 channel& a0,channel& a1,channel& a2, 00342 channel& theta1,channel& theta2) const; 00343 00344 /** 00345 * Extracts the OGD rotation invariant opponent color feature from the 00346 * given color channels. Center and Surround must have the same sizes. 00347 * @param center the center channel. 00348 * @param sround the surround channel. 00349 * @param dest the feature vector 00350 * @return true if apply successful or false otherwise. 00351 */ 00352 bool apply(const channel& center, 00353 const channel& sround, 00354 dvector& dest) const; 00355 00356 00357 /** 00358 * Extracts the OGD features for each given location. The radius 00359 * of each location is used to determine which scale should be used 00360 * in the generation of each feature vector. 00361 * @param src original channel to be analyzed. 00362 * @param locs the locations that need to be analyzed. 00363 * @param dest the list of feature vectors. This list will have the same 00364 * size as locs. The feature vector at position p will 00365 * correspond to the location at position p. 00366 * @return true if successful, of false otherwise. 00367 */ 00368 bool apply(const channel& src, 00369 const std::list<location>& locs, 00370 std::list<dvector>& dest); 00371 00372 /** 00373 * Extracts the OGD features for each given location. The image will 00374 * be splitted in its red, green and blue components, and the feature 00375 * vectors will be concatenated. 00376 * The radius of each location is used to determine which scale 00377 * should be used in the generation of each feature vector. 00378 * @param src original channel to be analyzed. 00379 * @param locs the locations that need to be analyzed. 00380 * @param dest the list of feature vectors. This list will have the same 00381 * size as locs. The feature vector at position p will 00382 * correspond to the location at position p. 00383 * @return true if successful, of false otherwise. 00384 */ 00385 bool apply(const image& src, 00386 const std::list<location>& locs, 00387 std::list<dvector>& dest); 00388 00389 00390 /** 00391 * Extracts the opponent color OGD features for each given 00392 * location. The radius of each location is used to determine 00393 * which scale should be used in the generation of each feature 00394 * vector. 00395 * 00396 * @param center original channel considered as "center" 00397 * @param surround channel considered as surround. This must have 00398 * the same size as center. 00399 * @param locs the locations that need to be analyzed. 00400 * @param dest the list of feature vectors. This list will have the same 00401 * size as locs. The feature vector at position p will 00402 * correspond to the location at position p. 00403 * @return true if successful, of false otherwise. */ 00404 bool apply(const channel& center, 00405 const channel& surround, 00406 const std::list<location>& locs, 00407 std::list<dvector>& dest); 00408 00409 /** 00410 * Copy data of "other" functor. 00411 * @param other the functor to be copied 00412 * @return a reference to this functor object 00413 */ 00414 axOGDFeature& copy(const axOGDFeature& other); 00415 00416 /** 00417 * Returns a pointer to a clone of this functor. 00418 */ 00419 virtual functor* clone() const; 00420 00421 /** 00422 * Returns used parameters 00423 */ 00424 const parameters& getParameters() const; 00425 00426 private: 00427 /** 00428 * Extracts the first order OGD coefficients for the given windows 00429 * size and variance (if gaussian). The "levels" parameter will be 00430 * ignored, and only the first level will be calculated. This method 00431 * is used by other feature extractors. 00432 * 00433 * To obtain the angle othogonal to the edges, you need to divide 00434 * <code>theta1</code> by 2. You can use a1 and theta1/2 for the 00435 * lti::orientationFeature. 00436 */ 00437 bool apply(const channel& src, 00438 const bool& voices, 00439 const int& level, 00440 channel& a0,channel& a1,channel& theta1) const; 00441 00442 /** 00443 * Extracts the second order OGD coefficients for the given windows 00444 * size and variance (if gaussian). The "levels" parameter will be 00445 * ignored, and only the first level will be calculated. This method 00446 * is used by other feature extractors 00447 * 00448 * To obtain the angle othogonal to the edges, you need to divide 00449 * <code>theta1</code> by 2. You can use a1 and theta1/2 for the 00450 * lti::orientationFeature. 00451 */ 00452 bool apply(const channel& src, 00453 const bool& voices, 00454 const int& level, 00455 channel& a0,channel& a1,channel& a2, 00456 channel& theta1,channel& theta2) const; 00457 00458 00459 /** 00460 * Generate the basis power channels. 00461 * If voice is true, the power correspond to a "voice" channel, and 00462 * the filter parameters must be adjusted. 00463 */ 00464 void generatePowerBasisOgd1(const channel& chnl, 00465 const bool voice, 00466 channel& p11, 00467 channel& p12, 00468 channel& p22) const; 00469 00470 /** 00471 * Generate the basis power channels for the opponent color feature, 00472 * where the first given channel corresponds to the center and the second 00473 * to the surround. 00474 */ 00475 void generatePowerBasisOgd1(const channel& center, 00476 const channel& sround, 00477 const bool voice, 00478 channel& pc1, 00479 channel& pc2, 00480 channel& ps1, 00481 channel& ps2) const; 00482 00483 /** 00484 * Generate the basis power channels of a gray-valued image using 00485 * second order OGD. 00486 */ 00487 void generatePowerBasisOgd2(const channel& chnl, 00488 const bool voice, 00489 channel& p11, 00490 channel& p12, 00491 channel& p13, 00492 channel& p22, 00493 channel& p23, 00494 channel& p33) const; 00495 00496 /** 00497 * Calculate the global descriptors using the first order ogd basis 00498 * power channels 00499 */ 00500 void globalOgd1(const channel& p11, 00501 const channel& p12, 00502 const channel& p22, 00503 double& a0, 00504 double& a1, 00505 double& theta1) const; 00506 00507 /** 00508 * Calculate the local descriptors using the first order ogd basis 00509 * power channels 00510 */ 00511 void localOgd1(const point& pos, 00512 const imatrix& ioPts, 00513 const channel& p11, 00514 const channel& p12, 00515 const channel& p22, 00516 double& a0, 00517 double& a1, 00518 double& theta1) const; 00519 00520 /** 00521 * Calculate the global descriptors using the first order ogd basis 00522 * power channels for the opponent color feature 00523 */ 00524 void globalOgd1(const channel& center, 00525 const channel& sround, 00526 const bool voice, 00527 double& ac0, 00528 double& ac1, 00529 double& thetac1, 00530 double& as0, 00531 double& as1, 00532 double& thetas1, 00533 double& ao0, 00534 double& ao1, 00535 double& thetao1) const; 00536 00537 00538 /** 00539 * Calculate the global descriptors using the first order ogd basis 00540 * power channels for the opponent color feature 00541 */ 00542 void localOgd1(const point& pos, 00543 const imatrix& ioPts, 00544 const channel& pc1, 00545 const channel& pc2, 00546 const channel& ps1, 00547 const channel& ps2, 00548 double& ac0, 00549 double& ac1, 00550 double& thetac1, 00551 double& as0, 00552 double& as1, 00553 double& thetas1, 00554 double& ao0, 00555 double& ao1, 00556 double& thetao1) const; 00557 00558 /** 00559 * Calculate the global descriptors using the second order ogd basis 00560 * power channels 00561 */ 00562 void globalOgd2(const channel& p11, 00563 const channel& p12, 00564 const channel& p13, 00565 const channel& p22, 00566 const channel& p23, 00567 const channel& p33, 00568 double& a0, 00569 double& a1, 00570 double& a2, 00571 double& theta1, 00572 double& theta2) const; 00573 00574 /** 00575 * Calculate the global descriptors using the second order ogd basis 00576 * power channels 00577 */ 00578 void localOgd2(const point& pos, 00579 const imatrix& ioPts, 00580 const channel& p11, 00581 const channel& p12, 00582 const channel& p13, 00583 const channel& p22, 00584 const channel& p23, 00585 const channel& p33, 00586 double& a0, 00587 double& a1, 00588 double& a2, 00589 double& theta1, 00590 double& theta2) const; 00591 00592 /** 00593 * Check the location list for used radii, and initialize 00594 * the region io-points required. 00595 * 00596 */ 00597 int analyzeLocations(const std::list<location>& locs, 00598 std::map<float,int>& radToIdx, 00599 std::map<float,int>& radToScale, 00600 std::vector<imatrix>& ioPts); 00601 00602 /** 00603 * Get the io points for the radial location of the given radius. 00604 * This is used by the apply methods which analyse only given 00605 * locations, to take only the necessary data into consideration. 00606 */ 00607 void getRadialIoPoints(const double& radius, 00608 imatrix& ioPts); 00609 00610 00611 protected: 00612 /** 00613 * This channels contain the term a0-a2 and theta2 00614 */ 00615 std::vector<channel> theChannels; 00616 00617 /** 00618 * The degree of the OGD used to extract the channels 00619 */ 00620 int ogdOrder; 00621 00622 /** 00623 * The number of levels included in theChannels 00624 */ 00625 int numLevels; 00626 00627 }; 00628 } 00629 00630 #endif