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 .......: ltiPyramidLocationSearch.h 00027 * authors ....: Frederik Lange, Pablo Alvarado 00028 * organization: LTI, RWTH Aachen 00029 * creation ...: 18.03.2003 00030 * revisions ..: $Id: ltiPyramidLocationSearch.h,v 1.4 2006/02/08 11:41:08 ltilib Exp $ 00031 */ 00032 00033 #ifndef _LTI_PYRAMID_LOCATION_SEARCH_H_ 00034 #define _LTI_PYRAMID_LOCATION_SEARCH_H_ 00035 00036 #include "ltiImage.h" 00037 #include "ltiMath.h" 00038 #include "ltiTransform.h" 00039 #include "ltiLocation.h" 00040 #include "ltiScaleSpacePyramid.h" 00041 #include "ltiGradientFunctor.h" 00042 00043 #include <list> 00044 #include <vector> 00045 #include <map> 00046 00047 using std::list; 00048 using std::vector; 00049 00050 namespace lti { 00051 /** 00052 * Search for salient locations in the scale space of a channel. 00053 * 00054 * The detected locations can be used to extract local features. 00055 * 00056 * For more information see: 00057 * David G. Lowe "Distinctive Image Features from Scale-Invariant Keypoints" 00058 * June, 2003 00059 * 00060 * This functor is more robust but also computationally more expensive than 00061 * its predecessor lti::axLocalRegions. 00062 * 00063 * The method is not 100% any of the variants published by Lowe, but it 00064 * got his name since the general principle is the one explain in the 00065 * previously mentioned paper. 00066 * 00067 * One of the major differences with Lowe's approach is the use of a 00068 * scale-space pyramid where all levels has their own scale. Lowe uses 00069 * the same size for all level within an octave. The Gaussian smoothing is 00070 * done here only for the first level, and thereafter only the one required 00071 * to keep the downsampling valid. 00072 * 00073 * @see lti::axLocalRegions, lti::locationSelector, 00074 * lti::localColorFeature, lti::axOGDFeature 00075 */ 00076 class pyramidLocationSearch : public transform { 00077 public: 00078 /** 00079 * The parameters for the class pyramidLocationSearch 00080 */ 00081 class parameters : public transform::parameters { 00082 public: 00083 /** 00084 * Default constructor 00085 */ 00086 parameters(); 00087 00088 /** 00089 * Copy constructor 00090 * @param other the parameters object to be copied 00091 */ 00092 parameters(const parameters& other); 00093 00094 /** 00095 * Destructor 00096 */ 00097 ~parameters(); 00098 00099 /** 00100 * Returns name of this type 00101 */ 00102 const char* getTypeName() const; 00103 00104 /** 00105 * Copy the contents of a parameters object 00106 * @param other the parameters object to be copied 00107 * @return a reference to this parameters object 00108 */ 00109 parameters& copy(const parameters& other); 00110 00111 /** 00112 * Copy the contents of a parameters object 00113 * @param other the parameters object to be copied 00114 * @return a reference to this parameters object 00115 */ 00116 parameters& operator=(const parameters& other); 00117 00118 00119 /** 00120 * Returns a pointer to a clone of the parameters 00121 */ 00122 virtual functor::parameters* clone() const; 00123 00124 /** 00125 * Write the parameters in the given ioHandler 00126 * @param handler the ioHandler to be used 00127 * @param complete if true (the default) the enclosing begin/end will 00128 * be also written, otherwise only the data block will be written. 00129 * @return true if write was successful 00130 */ 00131 virtual bool write(ioHandler& handler,const bool complete=true) const; 00132 00133 /** 00134 * Read the parameters from the given ioHandler 00135 * @param handler the ioHandler to be used 00136 * @param complete if true (the default) the enclosing begin/end will 00137 * be also written, otherwise only the data block will be written. 00138 * @return true if write was successful 00139 */ 00140 virtual bool read(ioHandler& handler,const bool complete=true); 00141 00142 # ifdef _LTI_MSC_6 00143 /** 00144 * This function is required by MSVC only, as a workaround for a 00145 * very awful bug, which exists since MSVC V.4.0, and still by 00146 * V.6.0 with all bugfixes (so called "service packs") remains 00147 * there... This method is also public due to another bug, so please 00148 * NEVER EVER call this method directly: use read() instead 00149 */ 00150 bool readMS(ioHandler& handler,const bool complete=true); 00151 00152 /** 00153 * This function is required by MSVC only, as a workaround for a 00154 * very awful bug, which exists since MSVC V.4.0, and still by 00155 * V.6.0 with all bugfixes (so called "service packs") remains 00156 * there... This method is also public due to another bug, so please 00157 * NEVER EVER call this method directly: use write() instead 00158 */ 00159 bool writeMS(ioHandler& handler,const bool complete=true) const; 00160 # endif 00161 00162 // ------------------------------------------------ 00163 // the parameters 00164 // ------------------------------------------------ 00165 00166 /** 00167 * @name Scale-space pyramid options 00168 */ 00169 //@{ 00170 /** 00171 * Number of levels in the pyramid 00172 * 00173 * Default value: 15 (five octaves with the default levelScaleFactor) 00174 */ 00175 int numLevels; 00176 00177 /** 00178 * Lowe suggests to upsample the first level by a factor of two using 00179 * bilinear interpolation. 00180 * 00181 * Here you can given the number of upsampled levels you want to 00182 * have in your pyramid. Using the default levelScaleFactor you need 00183 * to set here 3 in order to get a first level upsampled a scaling 00184 * factor of exaclty 2. 00185 * 00186 * In general, the size of the first level will be the reciprocal of 00187 * levelScaleFactor to the power of upsampleFirstLevel, multiplied by 00188 * the size of the original channel. 00189 * 00190 * If you want to use the original channel as the highest 00191 * resolution level or the pyramid, set this parameter to \a 0. 00192 * 00193 * This value must be 0 or positive. 00194 * 00195 * Usually, the locations returned by the apply methods contain 00196 * coordinates in the original image. By setting the parameter 00197 * locationsAtLevelZero to \a true the location coordinates 00198 * relate to the channel at level \a 0 in the channel pyramid 00199 * (see getChannelPyramid()). This can be useful when the 00200 * location search is part of a feature extraction. The level \a 00201 * 0 channel is either the original image or the upsampled image 00202 * depending on the value or upsampleFirstLevel. 00203 * 00204 * Default value: 1 00205 */ 00206 int upsampleFirstLevel; 00207 00208 /** 00209 * Parameters used in the pyramid. 00210 * 00211 * Lowe suggests to use scaling factors of the form 2^(-1/n), 00212 * meaning that one octave will be divided by an integer number n of 00213 * level. His experiments suggest that the optimal value for n is 3. 00214 * The default value for this factor is 2^(-1/3) = 0.793700526. 00215 * 00216 * The scaling factor (factor) is set to 00217 */ 00218 scaleSpacePyramid<channel>::parameters pyramidParameters; 00219 00220 /** 00221 * Set to \a true to enable subpixel interpolation in the determination 00222 * of scale space maxima. 00223 * 00224 * Default value: true 00225 */ 00226 bool interpolateMaxima; 00227 00228 /** 00229 * Set to true if only locations have to be accepted which have a 00230 * saliency bigger than its upper and lower levels. 00231 * 00232 * Default value: false 00233 */ 00234 bool checkInterLevelMaxima; 00235 00236 /** 00237 * Value used for the smoothing kernel of only the first level. 00238 * 00239 * This corresponds to the variance of the kernel, and not to the 00240 * standard deviation. 00241 * 00242 * If you don't want any smoothing, set this value to zero. The size 00243 * of the kernel will be computed automatically to have at the first 00244 * and last tabs values less than 5 percent of the middle tab. 00245 * 00246 * Default value: Lowe suggestion of 1.6^2 = 2.56 (kernel size 5) 00247 */ 00248 float smoothingGaussianVariance; 00249 00250 /** 00251 * Usually, the locations returned by the apply methods contain 00252 * coordinates in the original image. By setting the parameter 00253 * locationsAtLevelZero to \a true the location coordinates 00254 * relate to the channel at level \a 0 in the channel pyramid 00255 * (see getChannelPyramid()) instead. This can be useful when the 00256 * location search is part of a feature extraction. The level \a 00257 * 0 channel is either the original image or the upsampled image 00258 * depending on the value or upsampleFirstLevel. 00259 * 00260 * Default \a false 00261 * 00262 * \b NOTE: Usually, you will not want this option to be 00263 * activated. Be sure to fully understand the consequences 00264 * before you do. 00265 */ 00266 bool locationsAtLevelZero; 00267 //@} 00268 00269 /** 00270 * @name Maxima detection 00271 */ 00272 //@{ 00273 /** 00274 * The size of the neighborhood to search for maxima in one level. 00275 * 00276 * The accepted values are 3,5 or 7 (meaning 3x3, 5x5 or 7x7 00277 * neighborhoods). 00278 * 00279 * Default value: 3 00280 */ 00281 int spatialMaximumNeighborhoodSize; 00282 00283 /** 00284 * Modes available for the peak detection 00285 */ 00286 enum ePeakSelectionMode { 00287 GradientMagnitude, /**< Magnitude of the gradient */ 00288 Laplacian, /**< Laplacian, using an lti::laplacianKernel */ 00289 Harris, /**< Harris corner detector */ 00290 DoG /**< Difference of Gaussians. See doGLevelDistance 00291 for more information.*/ 00292 }; 00293 00294 /** 00295 * Method for peak selection: 00296 * - GradientMagnitude 00297 * - Laplacian 00298 * - Harris 00299 * - DoG (Default and best) 00300 * 00301 * Default value: DoG 00302 */ 00303 ePeakSelectionMode peakSelectionMode; 00304 00305 /** 00306 * Scale distance for the difference of Gaussians. 00307 * 00308 * The Difference of Gaussians (DoG) peak detection mode needs to know 00309 * which levels it has to compare. The default implementation compares 00310 * two adjacent levels, but this is not mandatory. You can specify here 00311 * any integer greater or equal 1. 00312 * 00313 * The computation is done convolving each level with a precomputed 00314 * kernel, that considers this value and the doGVariance, so that the 00315 * computation times will be proportionally increasing with greater 00316 * values here and in doGVariance. 00317 * 00318 * The kernel \e K used will be: 00319 * 00320 * \f[ K(x,y) = G(x,y,k\sigma) - G(x,y,\sigma) \f] 00321 * 00322 * where \e G is a Gaussian function and \e k represents this 00323 * doGLevelDistance parameter. 00324 * 00325 * Default value: 1 00326 */ 00327 int doGLevelDistance; 00328 00329 /** 00330 * Variance for the Gaussian of the current level when using 00331 * the DoG peak detection mode. 00332 * 00333 * The size of the final kernel used can be indicated explicitely or 00334 * computed automatically depending on the value of doGKernelSize. 00335 * 00336 * Default value: 1.6*1.6 00337 */ 00338 float doGKernelVariance; 00339 00340 /** 00341 * Size of the kernel used to compute the DoG. 00342 * 00343 * If you set here a negative value, a kernel will be computed with a 00344 * size such that the taps of a Gaussian kernel with 00345 * variance doGLevelDistance*doGKernelVariance will be no greater than 00346 * 5\% of the the kernel tap at the position zero. 00347 * 00348 * If you don't want automatic computation of the kernel size, you 00349 * should set and odd value greater or equal 3. 00350 * 00351 * Default value: -1 (e.g. automatic size computation) 00352 */ 00353 int doGKernelSize; 00354 00355 /** 00356 * Minimum relative value for the allowed for a location to be salient. 00357 * 00358 * If the Laplacian pyramid (or its equivalent in other 00359 * peakDetectionMode) contains a value less than saliencyThreshold 00360 * times the maximum value at the corresponding pyramid level, then 00361 * that value will be ignored. 00362 * 00363 * If the number of levels in the pyramid is greater than the size 00364 * of these vector, to all "additional" levels, the last valid value 00365 * of the vector will be used. This means, if the given vector is 00366 * of size one, then for all levels the same threshold will be used. 00367 * 00368 * Default value: vector<float>(1,0.1f), i.e. all levels will use 0.1f 00369 */ 00370 vector<float> saliencyThreshold; 00371 00372 /** 00373 * Edgeness Threshold. 00374 * 00375 * The edgeness is defined here as the ratio between the largest and the 00376 * smallest eigenvalues of the Hessian matrix. This means, the smallest 00377 * possible edgeness value is one, when both eigenvalues are equal, 00378 * denoting a point with no definite edge direction, being a good 00379 * candidate for a stable salient point. The larger the value, the 00380 * greater the probability that the salient value is an egde made 00381 * salient by noise. 00382 * 00383 * Set the value closer to one to filter out edge point or larger to 00384 * tolerate edge induced locations. 00385 * 00386 * Default value 10; 00387 */ 00388 float edgenessThreshold; 00389 00390 /** 00391 * Density filter. 00392 * 00393 * There are many applications where a global saliency threshold for the 00394 * whole image is not appropriate. In those cases, you usually set the 00395 * saliency threshold very low, so that in dark image regions some 00396 * locations can also be detected. 00397 * 00398 * The density filter activates a "local" saliency check. First, all 00399 * locations are computed considering the saliencyThreshold only. Then, 00400 * all locations "vote" with their saliency value in a window of radius 00401 * densityKernelRadius. Voting means here, to assign all pixels in the 00402 * window the maximum value between the value they already had and the 00403 * saliency of the location. 00404 * 00405 * Only those locations will survive, which have a saliency value 00406 * greater or equal than the final "accumulated" saliency multiplied 00407 * with the corresponding level densityThreshold 00408 * 00409 * Default value: false 00410 */ 00411 bool densityFilter; 00412 00413 /** 00414 * Density Kernel Radius 00415 * 00416 * Radius of a circular region around a location for density check. The 00417 * greater the number, the more competitive the saliency of a location 00418 * must be, in order to survive. 00419 * 00420 * Default value: 3 00421 */ 00422 int densityKernelRadius; 00423 00424 /** 00425 * Minimum relative value for the allowed for a location to be salient. 00426 * 00427 * A location will be considered salient only if the value at the final 00428 * local saliency estimation map multiplied by the corresponding 00429 * densityThreshold is smaller or equal the location saliency. 00430 * 00431 * If the number of levels in the pyramid is greater than the size 00432 * of these vector, to all "additional" levels, the last valid value 00433 * of the vector will be used. This means, if the given vector is 00434 * of size one, then for all levels the same threshold will be used. 00435 * 00436 * Default value: vector<float>(1,0.75f), i.e. all levels will use 0.75f 00437 */ 00438 fvector densityThreshold; 00439 00440 //@} 00441 00442 /** 00443 * @name Orientation detection 00444 */ 00445 //@{ 00446 /** 00447 * Radius of the orientation window 00448 * 00449 * The orientation will be analyzed at the nearest level corresponding 00450 * to the radius of a location. The window used will have a size of 00451 * (1+2*orientationWindowRadius)^2. 00452 * 00453 * Default value: 3 00454 */ 00455 int orientationWindowRadius; 00456 00457 /** 00458 * Orientation sigma factor 00459 * 00460 * The values in the window are weighted with a Gaussian having as 00461 * standard deviation (sigma) the orientation window radius divided 00462 * by this factor. 00463 * 00464 * This value must always be greater than zero, or an unpredictible 00465 * behaviour must be expected. 00466 * 00467 * Default value: 2 00468 */ 00469 float orientationSigmaFactor; 00470 00471 /** 00472 * The resolution of the histogram for the determination of the 00473 * orientation of the location 00474 * 00475 * Default value: 36 00476 */ 00477 int binsInOrientationHistogram; 00478 00479 /** 00480 * Threshold used to accept multiple orientations. 00481 * 00482 * To compute the orientation of a location, a window with 00483 * orientationWindowRadius is used to compute an orientation histogram. 00484 * The greatest peak in this histogram determines the dominant 00485 * orientation. However, if there are other peaks with a value equal 00486 * the greatest peak times this factor, then locations with their 00487 * orientation will also be inserted in the location list. 00488 * 00489 * Set to 1.0 to detect only the maximum or maxima (if there are several 00490 * bins sharing the same maximal value), or greater than 1 if you want 00491 * only one maximum. A value of zero or less will include a location 00492 * for all angles detected in the image (a much as 00493 * binsInOrientationHistogram). 00494 * 00495 * Default value: 0.8 00496 */ 00497 float multiOrientationThreshold; 00498 00499 /** 00500 * Average orientation 00501 * 00502 * If this value is set to true, all entries with values greater 00503 * than multiOrientationThreshold times the maximum entry will 00504 * be used to compute one single average value for the orientation. Note 00505 * that no multi-oriented locations will be detected, but only one. 00506 * 00507 * If is set to false, the entries are used directly as orientations, as 00508 * Lowe suggested. 00509 * 00510 * Default value: false 00511 */ 00512 bool averageOrientation; 00513 00514 //@} 00515 00516 /** 00517 * @name Location properties 00518 */ 00519 //@{ 00520 /** 00521 * This value indicates the scaling factor for a location radius. 00522 * 00523 * In other words, this value will be multiplied with the corresponding 00524 * pixel radius of a scaling factor to obtain the location radius. 00525 * 00526 * Remember that the pixel radius at level 0 is 0.5; 00527 * 00528 * Default value: 7 00529 */ 00530 float locationRelativeRadius; 00531 //@} 00532 }; 00533 00534 /** 00535 * Default constructor 00536 */ 00537 pyramidLocationSearch(); 00538 00539 /** 00540 * Construct a functor using the given parameters 00541 */ 00542 pyramidLocationSearch(const parameters& par); 00543 00544 /** 00545 * Copy constructor 00546 * @param other the object to be copied 00547 */ 00548 pyramidLocationSearch(const pyramidLocationSearch& other); 00549 00550 /** 00551 * Destructor 00552 */ 00553 virtual ~pyramidLocationSearch(); 00554 00555 /** 00556 * Returns the name of this type ("pyramidLocationSearch") 00557 */ 00558 virtual const char* getTypeName() const; 00559 00560 /** 00561 * @name Apply methods 00562 */ 00563 //@{ 00564 00565 /** 00566 * Extracts the most relevant locations from the given channel, and return 00567 * them as list of lti::location objects. 00568 * 00569 * @param src channel with the source data. 00570 * @param locs list of relevant locations 00571 * @return true if apply successful or false otherwise. 00572 */ 00573 bool apply(const channel& src, 00574 std::list<location>& locs); 00575 00576 /** 00577 * Extracts the most relevant locations from the given channel, and return 00578 * them as list of lti::location objects. 00579 * 00580 * @param src channel with the source data. 00581 * @param locs list of relevant locations 00582 * @param totalLocs total number of detected locations 00583 * @return true if apply successful or false otherwise. 00584 */ 00585 bool apply(const channel& src, 00586 std::list<location>& locs, 00587 int& totalLocs); 00588 00589 /** 00590 * Extracts the most relevant locations from the given channel, 00591 * and return them as map where the key equals the level in which 00592 * the locations where found and the value is a list of 00593 * lti::location objects in that level. 00594 * 00595 * \b Note: This apply is faster than 00596 * apply(const channel&,std::list<location>&). 00597 * 00598 * @param src channel with the source data. 00599 * @param locs map of lists of relevant locations per level 00600 * @return true if apply successful or false otherwise. 00601 */ 00602 bool apply(const channel& src,std::map<int,std::list<location> >& locs); 00603 00604 /** 00605 * Extracts the most relevant locations from the given channel, 00606 * and return them as map where the key equals the level in which 00607 * the locations where found and the value is a list of 00608 * lti::location objects in that level. 00609 * 00610 * \b Note: This apply is faster than 00611 * apply(const channel&,std::list<location>&). 00612 * 00613 * @param src channel with the source data. 00614 * @param locs map of lists of relevant locations per level 00615 * @param totalLocs total number of detected locations 00616 * @return true if apply successful or false otherwise. 00617 */ 00618 bool apply(const channel& src, 00619 std::map<int,std::list<location> >& locs, 00620 int& totalLocs); 00621 00622 00623 /** 00624 * Extracts the most relevant locations from both channels, and return 00625 * them as list of lti::location objects. 00626 * 00627 * @param c1 first color or other feature component 00628 * @param c2 second color or other feature component 00629 * @param locs list of relevant locations 00630 * @return true if apply successful or false otherwise. 00631 */ 00632 bool apply(const channel& c1, 00633 const channel& c2, 00634 std::list<location>& locs); 00635 00636 /** 00637 * Extracts the most relevant locations from both channels, and return 00638 * them as list of lti::location objects. 00639 * 00640 * @param c1 first color or other feature component 00641 * @param c2 second color or other feature component 00642 * @param locs list of relevant locations 00643 * @param totalLocs total number of detected locations 00644 * @return true if apply successful or false otherwise. 00645 */ 00646 bool apply(const channel& c1, 00647 const channel& c2, 00648 std::list<location>& locs, 00649 int& totalLocs); 00650 00651 /** 00652 * Extracts the most relevant locations from both channels, 00653 * and return them as map where the key equals the level in which 00654 * the locations where found and the value is a list of 00655 * lti::location objects in that level. 00656 * 00657 * \b Note: This apply is faster than 00658 * apply(const channel&,std::list<location>&). 00659 * 00660 * @param c1 first color or other feature component 00661 * @param c2 second color or other feature component 00662 * @param locs map of lists of relevant locations per level 00663 * @return true if apply successful or false otherwise. 00664 */ 00665 bool apply(const channel& c1,const channel& c2, 00666 std::map<int,std::list<location> >& locs); 00667 00668 /** 00669 * Extracts the most relevant locations from both channels, 00670 * and return them as map where the key equals the level in which 00671 * the locations where found and the value is a list of 00672 * lti::location objects in that level. 00673 * 00674 * \b Note: This apply is faster than 00675 * apply(const channel&,std::list<location>&). 00676 * 00677 * @param c1 first color or other feature component 00678 * @param c2 second color or other feature component 00679 * @param locs map of lists of relevant locations per level 00680 * @param totalLocs total number of detected locations 00681 * @return true if apply successful or false otherwise. 00682 */ 00683 bool apply(const channel& c1,const channel& c2, 00684 std::map<int,std::list<location> >& locs, 00685 int& totalLocs); 00686 00687 /** 00688 * Extracts the most relevant locations from the given channel, and return 00689 * them as list of lti::location objects. 00690 * 00691 * @param c1 first color or other feature component 00692 * @param c2 second color or other feature component 00693 * @param c3 third color or other feature component 00694 * @param locs list of relevant locations 00695 * @return true if apply successful or false otherwise. 00696 */ 00697 bool apply(const channel& c1,const channel& c2,const channel& c3, 00698 std::list<location>& locs); 00699 00700 /** 00701 * Extracts the most relevant locations from the given channel, and return 00702 * them as list of lti::location objects. 00703 * 00704 * @param c1 first color or other feature component 00705 * @param c2 second color or other feature component 00706 * @param c3 third color or other feature component 00707 * @param locs list of relevant locations 00708 * @param totalLocs total number of detected locations 00709 * @return true if apply successful or false otherwise. 00710 */ 00711 bool apply(const channel& c1,const channel& c2,const channel& c3, 00712 std::list<location>& locs, 00713 int& totalLocs); 00714 00715 /** 00716 * Extracts the most relevant locations from the given channel, 00717 * and return them as map where the key equals the level in which 00718 * the locations where found and the value is a list of 00719 * lti::location objects in that level. 00720 * 00721 * \b Note: This apply is faster than 00722 * apply(const channel&,std::list<location>&). 00723 * 00724 * @param c1 first color or other feature component 00725 * @param c2 second color or other feature component 00726 * @param c3 third color or other feature component 00727 * @param locs map of lists of relevant locations per level 00728 * @return true if apply successful or false otherwise. 00729 */ 00730 bool apply(const channel& c1,const channel& c2,const channel& c3, 00731 std::map<int,std::list<location> >& locs); 00732 00733 /** 00734 * Extracts the most relevant locations from the given channel, 00735 * and return them as map where the key equals the level in which 00736 * the locations where found and the value is a list of 00737 * lti::location objects in that level. 00738 * 00739 * \b Note: This apply is faster than 00740 * apply(const channel&,std::list<location>&). 00741 * 00742 * @param c1 first color or other feature component 00743 * @param c2 second color or other feature component 00744 * @param c3 third color or other feature component 00745 * @param locs map of lists of relevant locations per level 00746 * @param totalLocs total number of detected locations 00747 * @return true if apply successful or false otherwise. 00748 */ 00749 bool apply(const channel& c1,const channel& c2,const channel& c3, 00750 std::map<int,std::list<location> >& locs, 00751 int& totalLocs); 00752 00753 //@} 00754 00755 #if 0 00756 /** 00757 * @name Apply masked methods. 00758 * 00759 * Some times, you know that some part of the images will contain 00760 * locations although the contrast or saliency is very low, while other 00761 * sections should be "suppressed", independently of their saliency values. 00762 * 00763 * This family of apply methods allow you to specify a mask (lti::channel) 00764 * that specify the expected maximal saliency. 00765 * 00766 * The threshold that a location's saliency value has to surpass is 00767 * the one used in the normal apply() methods multiplied by the value 00768 * in the corresponding pixel of the given mask. Thus, the pixels masked 00769 * with zero will produce all possible locations; the pixels masked with 00770 * one will behave as in the normal applies; pixels with values greater 00771 * than one will suppress locations (compared with the normal case). 00772 * 00773 * The simplest mask contains a strongly smoothed intensity channel of 00774 * the image, normalize to have as maximum value 1.0. Additionaly, if 00775 * a background segmentation is available, those values can be set to 00776 * std::numeric_limits<float>::max() in order to suppress all background 00777 * locations. 00778 * 00779 * The mask is always the last argument. Otherwise, they could not be 00780 * distinguished from the normal apply methods. 00781 */ 00782 //@{ 00783 /** 00784 * Extracts the most relevant locations from the given channel, and return 00785 * them as list of lti::location objects. 00786 * 00787 * @param src channel with the source data. 00788 * @param locs list of relevant locations 00789 * @param mask saliency suppression mask 00790 * @return true if apply successful or false otherwise. 00791 */ 00792 bool apply(const channel& src, 00793 std::list<location>& locs, 00794 const channel& mask); 00795 00796 /** 00797 * Extracts the most relevant locations from the given channel, and return 00798 * them as list of lti::location objects. 00799 * 00800 * @param src channel with the source data. 00801 * @param mask saliency suppression mask 00802 * @param locs list of relevant locations 00803 * @param totalLocs total number of detected locations 00804 * @return true if apply successful or false otherwise. 00805 */ 00806 bool apply(const channel& src, 00807 std::list<location>& locs, 00808 int& totalLocs, 00809 const channel& mask); 00810 00811 /** 00812 * Extracts the most relevant locations from the given channel, 00813 * and return them as map where the key equals the level in which 00814 * the locations where found and the value is a list of 00815 * lti::location objects in that level. 00816 * 00817 * \b Note: This apply is faster than 00818 * apply(const channel&,std::list<location>&). 00819 * 00820 * @param src channel with the source data. 00821 * @param mask saliency suppression mask 00822 * @param locs map of lists of relevant locations per level 00823 * @return true if apply successful or false otherwise. 00824 */ 00825 bool apply(const channel& src, 00826 std::map<int,std::list<location> >& locs, 00827 const channel& mask); 00828 00829 /** 00830 * Extracts the most relevant locations from the given channel, 00831 * and return them as map where the key equals the level in which 00832 * the locations where found and the value is a list of 00833 * lti::location objects in that level. 00834 * 00835 * \b Note: This apply is faster than 00836 * apply(const channel&,std::list<location>&). 00837 * 00838 * @param src channel with the source data. 00839 * @param locs map of lists of relevant locations per level 00840 * @param totalLocs total number of detected locations 00841 * @return true if apply successful or false otherwise. 00842 */ 00843 bool apply(const channel& src, 00844 std::map<int,std::list<location> >& locs, 00845 int& totalLocs, 00846 const channel& mask); 00847 00848 //@} 00849 00850 #endif 00851 00852 /** 00853 * Copy data of "other" functor. 00854 * @param other the functor to be copied 00855 * @return a reference to this functor object 00856 */ 00857 pyramidLocationSearch& copy(const pyramidLocationSearch& other); 00858 00859 /** 00860 * Alias for copy member 00861 * @param other the functor to be copied 00862 * @return a reference to this functor object 00863 */ 00864 pyramidLocationSearch& operator=(const pyramidLocationSearch& other); 00865 00866 /** 00867 * Returns a pointer to a clone of this functor. 00868 */ 00869 virtual functor* clone() const; 00870 00871 /** 00872 * Returns used parameters 00873 */ 00874 const pyramidLocationSearch::parameters& getParameters() const; 00875 00876 /** 00877 * @name Read-only access to the created pyramids in an apply method. 00878 * 00879 * This methods are used not only for debugging purposes, but also 00880 * to save some time with the computation of a channel pyramid, which 00881 * is usually employed in the computation of features. 00882 */ 00883 //@{ 00884 /** 00885 * Return the saliency pyramid of the last channel of the last apply 00886 * 00887 * Note that the multi-channel apply-methods use only one pyramid for 00888 * all channels, and therefore only the last one is kept. 00889 */ 00890 const scaleSpacePyramid<channel>& getSaliencyPyramid() const; 00891 00892 /** 00893 * Return the orientation pyramid of the last channel of the last apply 00894 * 00895 * Note that the multi-channel apply-methods use only one pyramid for 00896 * all channels, and therefore only the last one is kept. 00897 */ 00898 const scaleSpacePyramid<channel>& getOrientationPyramid() const; 00899 00900 /** 00901 * Return the input channel pyramid of the last channel of the last apply 00902 * 00903 * Note that the multi-channel apply-methods use only one pyramid for 00904 * all channels, and therefore only the last one is kept. 00905 */ 00906 const scaleSpacePyramid<channel>& getChannelPyramid() const; 00907 00908 //@} 00909 00910 00911 protected: 00912 00913 /** 00914 * @name Saliency Methods 00915 */ 00916 //@{ 00917 /** 00918 * Applies the edge and/or corner extraction to the source souce channel 00919 * based on Laplace-Operator 00920 * 00921 */ 00922 void applyLaplacian(const channel& src, channel& dest) const ; 00923 00924 /** 00925 * Extracts the magnitude and angle of the gradient for the given 00926 * for the given channel. 00927 * 00928 * @param src original channel 00929 * @param mag magnitude of the gradient 00930 * @param angle angle of the gradient. 00931 */ 00932 void applyMag(const channel& src, 00933 channel& mag, 00934 channel& angle) const; 00935 00936 /** 00937 * Applies the Harris cornerness extraction to the source souce channel 00938 * this is a measure for the curvature at a pixel 00939 */ 00940 void applyCornerness(const channel& src, channel& dest) const; 00941 00942 /** 00943 * Applies a DoG kernel to the given channel 00944 */ 00945 void applyDoG(const channel& src, channel& dest) const; 00946 //@} 00947 00948 /** 00949 * The required pyramids 00950 */ 00951 //@{ 00952 /** 00953 * Pyramid of original channel. 00954 */ 00955 scaleSpacePyramid<channel> iPyr; 00956 00957 /** 00958 * Pyramid of Laplacians, DoG, Harris cornerness, or gradient magnitude, 00959 * depending on the mode selected in the parameters. 00960 */ 00961 scaleSpacePyramid<channel> lapPyr; 00962 00963 /** 00964 * Vector containing the maxima at each level of the pyramid 00965 */ 00966 fvector lapMax; 00967 00968 /** 00969 * Pyramid containing the angles of the gradient, used to compute 00970 * the rotation of each feature. 00971 */ 00972 scaleSpacePyramid<channel> argPyr; 00973 00974 /** 00975 * Pyramid containing the magnitude of the gradient 00976 */ 00977 scaleSpacePyramid<channel> magPyr; 00978 00979 /** 00980 * Pyramid with maxima detected in the lapPyr. 00981 * 00982 * This pyramid will only be initialized if the spatial maximum 00983 * neighborhood is greater than 3. 00984 */ 00985 scaleSpacePyramid<channel> maxPyr; 00986 00987 /** 00988 * First level factor 00989 * 00990 * If the pyramid was upsampled, this is the factor with which the 00991 * first level was created. 00992 */ 00993 double firstLevelFactor; 00994 //@} 00995 00996 /** 00997 * Functor used to compute gradients 00998 */ 00999 gradientFunctor gradient; 01000 01001 /** 01002 * Compute the doGKernel as wished by the user. 01003 */ 01004 bool computeDoGKernel(); 01005 01006 /** 01007 * Kernel used to compute the DoG 01008 */ 01009 sepKernel<float> doGKernel; 01010 01011 /** 01012 * @name Apply helper methods 01013 */ 01014 //@{ 01015 /** 01016 * Compute the pyramids 01017 */ 01018 bool computePyramids(const channel& src); 01019 01020 /** 01021 * Compute the position of the locations for each level, based on 01022 * the pyramids 01023 */ 01024 bool 01025 computeLocationsPosition(std::map< int, std::list<location> >& locMap); 01026 01027 /** 01028 * Compute the orientation of each location in each level. 01029 * 01030 * The total number of locations is also computed 01031 */ 01032 bool 01033 computeLocationOrientation(std::map< int, std::list<location> >& locMap, 01034 int& totalLocs); 01035 //@} 01036 01037 /** 01038 * Compute the maximum for the given three values, assuming that the 01039 * middle value has an offset of zero and using a quadratic function 01040 * that passes through all three points. 01041 * 01042 * The returned value \a x will be between -1.0 and 1.0 if a maximum 01043 * was detected, or will remain untouched if no maximum was found. If 01044 * a maximum is found, the function returns true. 01045 */ 01046 inline bool qmaximum(const float ym1,const float y0,const float y1, 01047 float& x) const; 01048 01049 /** 01050 * Compute the angle given an index. It will use the neighbors to 01051 * compute the position of the maximum. 01052 */ 01053 float getAngle(const vector<float>& angles, 01054 const int idx) const; 01055 01056 /** 01057 * Compute the edgeness ratio. 01058 * 01059 * The value computed here corresponds to the Tr(H)^2/Det(H), with 01060 * the Hessian matrix H. 01061 * 01062 * This method expects x and y to be greater 1 and to be not larger than 01063 * 1 minus the last valid index bei each coordinate. 01064 */ 01065 float edgenessRatio(const channel& chnl, 01066 const int y, 01067 const int x) const; 01068 01069 01070 /** 01071 * Transport all data in the second map into the first one, without 01072 * copying it. 01073 * 01074 * At the end of the operation the second map will be empty. 01075 */ 01076 void concatLocsMap(std::map<int,std::list<location> >& src1dest, 01077 std::map<int,std::list<location> >& src2) const; 01078 01079 /** 01080 * Density filter 01081 * 01082 * If the saliency threshold is too low, too many locations will be 01083 * detected. The density filter chooses the most salient locations such 01084 * that in the radio of each level no more than 01085 * 01086 */ 01087 bool densityFilter(std::map<int,std::list<location> >& srcDest) const; 01088 }; 01089 } 01090 01091 #endif