latest version v1.9 - last update 10 Apr 2010 |
00001 /* 00002 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 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 .......: ltiLocationSearchEvaluation.h 00027 * authors ....: Pablo Alvarado 00028 * organization: LTI, RWTH Aachen 00029 * creation ...: 25.11.2003 00030 * revisions ..: $Id: ltiLocationSearchEvaluation.h,v 1.2 2007/04/09 12:15:44 alvarado Exp $ 00031 */ 00032 00033 #ifndef _LTI_LOCATION_SEARCH_EVALUATION_TESTER_H_ 00034 #define _LTI_LOCATION_SEARCH_EVALUATION_TESTER_H_ 00035 00036 #include "ltiKdTree.h" 00037 #include "ltiParetoFront.h" 00038 #include "ltiPyramidLocationSearch.h" 00039 00040 namespace lti { 00041 00042 /** 00043 * Pareto evaluation of the lti::pyramidLocationSearch functor. 00044 * 00045 * This class tests the parameterization of the lti::pyramidLocationSearch 00046 * functor by searching the Pareto front of some fittness measures, using 00047 * the genetic search framework provided by the paretoFront class. 00048 * 00049 * The fitness criteria used here are: 00050 * - number of locations 00051 * - reciprocal of location number (1/number of locations) 00052 * - number of occupied levels in the pyramid 00053 * - reciprocal of the time taken to extract all locations 00054 * - scale repeatability, i.e. considering scale changes only 00055 * - rotation repeatability, i.e. considering rotations only 00056 * - rotation scale repeatability, i.e. considering scale and rotation 00057 * - scale stable locations, i.e. considering scale changes only 00058 * - rotation stable locations, i.e. considering rotations only 00059 * - rotation scale stable locations, i.e. considering scale and rotation 00060 * 00061 * For the evaluation of a parameterization the algorithm takes all 00062 * images stored in the file specified in parameters::images. For 00063 * each one of them a set of rotations and scalings are applied, to 00064 * the image and the locations estracted from it. Since the geometric 00065 * transformation is known, we have a "should-be" set of locations, obtained 00066 * transforming the original image locations. This set is compared with 00067 * the locations extracted from the transformed image. The correspondences 00068 * are counted and they constitute in percentage the fitness measure. 00069 * 00070 * The "repeatability" measures equal the "stable locations" normalized 00071 * by the total number of locations. 00072 */ 00073 class locationSearchEvaluation : public paretoFront { 00074 public: 00075 00076 /** 00077 * The parameters for the class locationSearchEvaluation 00078 */ 00079 class parameters : public paretoFront::parameters { 00080 public: 00081 /** 00082 * Default constructor 00083 */ 00084 parameters(); 00085 00086 /** 00087 * Copy constructor 00088 * @param other the parameters object to be copied 00089 */ 00090 parameters(const parameters& other); 00091 00092 /** 00093 * Destructor 00094 */ 00095 ~parameters(); 00096 00097 /** 00098 * Returns name of this type 00099 */ 00100 const char* getTypeName() const; 00101 00102 /** 00103 * Copy the contents of a parameters object 00104 * @param other the parameters object to be copied 00105 * @return a reference to this parameters object 00106 */ 00107 parameters& copy(const parameters& other); 00108 00109 /** 00110 * Copy the contents of a parameters object 00111 * @param other the parameters object to be copied 00112 * @return a reference to this parameters object 00113 */ 00114 parameters& operator=(const parameters& other); 00115 00116 00117 /** 00118 * Returns a pointer to a clone of the parameters 00119 */ 00120 virtual functor::parameters* clone() const; 00121 00122 /** 00123 * Write the parameters in the given ioHandler 00124 * @param handler the ioHandler to be used 00125 * @param complete if true (the default) the enclosing begin/end will 00126 * be also written, otherwise only the data block will be written. 00127 * @return true if write was successful 00128 */ 00129 virtual bool write(ioHandler& handler,const bool& complete=true) const; 00130 00131 /** 00132 * Read the parameters from the given ioHandler 00133 * @param handler the ioHandler to be used 00134 * @param complete if true (the default) the enclosing begin/end will 00135 * be also written, otherwise only the data block will be written. 00136 * @return true if write was successful 00137 */ 00138 virtual bool read(ioHandler& handler,const bool& complete=true); 00139 00140 # ifdef _LTI_MSC_6 00141 /** 00142 * This function is required by MSVC only, as a workaround for a 00143 * very awful bug, which exists since MSVC V.4.0, and still by 00144 * V.6.0 with all bugfixes (so called "service packs") remains 00145 * there... This method is also public due to another bug, so please 00146 * NEVER EVER call this method directly: use read() instead 00147 */ 00148 bool readMS(ioHandler& handler,const bool& complete=true); 00149 00150 /** 00151 * This function is required by MSVC only, as a workaround for a 00152 * very awful bug, which exists since MSVC V.4.0, and still by 00153 * V.6.0 with all bugfixes (so called "service packs") remains 00154 * there... This method is also public due to another bug, so please 00155 * NEVER EVER call this method directly: use write() instead 00156 */ 00157 bool writeMS(ioHandler& handler,const bool& complete=true) const; 00158 # endif 00159 00160 // ------------------------------------------------ 00161 // the parameters 00162 // ------------------------------------------------ 00163 00164 /** 00165 * @name Fitness measures 00166 * 00167 * Value containing the 1D fitness measures to be computed. 00168 * The constants defined here are: 00169 * - numberOfLocations 00170 * - locationsReciprocal (1/number of locations) 00171 * - occupiedLevels 00172 * - time 00173 * - scaleRepeatability 00174 * - rotationRepeatability 00175 * - rotationScaleRepeatability 00176 * - scaleStable 00177 * - rotationStable 00178 * - rotationScaleStable 00179 * 00180 * This sequence is important, since it determines the positions of 00181 * the single measures in the fitness output vector. 00182 * 00183 * If more fitness measures are selected than the inherited parameter 00184 * fitnessSpaceDimensionality, then the first ones in this sequence 00185 * will be selected. 00186 * 00187 * If less fitness measure are selected than the inherited parameter 00188 * fitnessSpaceDimensionality, then the rest of the vector will be 00189 * filled with zeros. 00190 * 00191 * The difference between the "*Repeatibility" and the "*Stable" measures 00192 * is that the first ones are the number of stable locations normalized 00193 * to the total number of locations, i.e. their maximal value will be 00194 * always 1.0. The "*Stable" unnormalized fitness measures may be 00195 * important to optimize in those applications that require many 00196 * stable locations to work, and not only the major part of them. 00197 */ 00198 //@{ 00199 /** 00200 * Total number of locations detected per image. 00201 * 00202 * Default value: false 00203 */ 00204 bool numberOfLocations; 00205 00206 /** 00207 * Locations' reciprocal 00208 * 00209 * This is the inverse of the number of location (1/number of locations). 00210 * It is often better to search of parameterizations that produce a 00211 * low number of locations. The used value will be 1/(1+\#locs) to avoid 00212 * divisions by zero. 00213 * 00214 * Default value: false 00215 */ 00216 bool locationsReciprocal; 00217 00218 /** 00219 * Percentage of generated levels with locations. Useful to detect how 00220 * many levels are really necessary. 00221 * 00222 * Default value: false 00223 */ 00224 bool occupiedLevels; 00225 00226 /** 00227 * Mean time required to extract the locations 00228 * 00229 * Default value: true 00230 */ 00231 bool time; 00232 00233 /** 00234 * Repeatability considering only image scaling 00235 * 00236 * Default value: false 00237 */ 00238 bool scaleRepeatability; 00239 00240 /** 00241 * Repeatability considering only image rotation 00242 * 00243 * Default value: false 00244 */ 00245 bool rotationRepeatability; 00246 00247 /** 00248 * Repeatability considering both rotation and scaling 00249 * 00250 * Default value: true 00251 */ 00252 bool rotationScaleRepeatability; 00253 00254 /** 00255 * Absolute number of stable locations considering only image scaling 00256 * 00257 * Default value: false 00258 */ 00259 bool scaleStable; 00260 00261 /** 00262 * Absolute number of stable locations considering only image rotation 00263 * 00264 * Default value: false 00265 */ 00266 bool rotationStable; 00267 00268 /** 00269 * Absolute number of stable locations considering both rotation and 00270 * scaling 00271 * 00272 * Default value: true 00273 */ 00274 bool rotationScaleStable; 00275 00276 //@} 00277 00278 /** 00279 * Name of a file containing all images to be analyzed. 00280 * 00281 * Default value: "images.txt" 00282 */ 00283 std::string images; 00284 00285 /** 00286 * Mask posfix 00287 * 00288 * For each image file in \a images, a manual segmented mask can 00289 * be used to ignore those locations outside the objects of interest. 00290 * 00291 * The filename of the masks will be assumed to be the same 00292 * image name with the given postfix. For example, if a image is 00293 * called "test.png" and the postfix is "-preseg", then the 00294 * mask will be assumed to be "test-preseg.png". 00295 * 00296 * Default value: "_premask" 00297 */ 00298 std::string postfix; 00299 00300 /** 00301 * Values for all parameters of the pyramidLocationSearch functor 00302 * that will be used as minima. 00303 * 00304 * Default value: 00305 * numLevels 4 00306 * upsampleFirstLevel 0 00307 * pyramidParameters::factor 0.5 00308 * pyramidParameters::gaussian false 00309 * pyramidParameters::interpolatorType BilinearInterpolator 00310 * interpolateMaxima false 00311 * smoothingGaussianVariance 0 00312 * spatialMaximumNeighborhoodSize 3 00313 * peakSelectionMode GradientMagnitude 00314 * doGLevelDistance 1 00315 * doGKernelVariance 1 00316 * saliencyThreshold 0 00317 * edgenessThreshold 2 00318 * orientationWindowRadius = 2 00319 */ 00320 pyramidLocationSearch::parameters minValues; 00321 00322 /** 00323 * Values for all parameters of the pyramidLocationSearch functor 00324 * that will be used as minima. 00325 * 00326 * Default value: 00327 * numLevels 30 00328 * upsampleFirstLevel 3 00329 * pyramidParameters::factor pow(0.5,1.0/8.0) 00330 * pyramidParameters::gaussian true 00331 * pyramidParameters::interpolatorType BiquadraticInterpolator 00332 * interpolateMaxima true 00333 * smoothingGaussianVariance 5 00334 * spatialMaximumNeighborhoodSize 7 00335 * peakSelectionMode DoG 00336 * doGLevelDistance 4 00337 * doGKernelVariance 4 00338 * saliencyThreshold 0.99 00339 * edgenessThreshold 10 00340 * orientationWindowRadius = 5 00341 */ 00342 pyramidLocationSearch::parameters maxValues; 00343 00344 /** 00345 * Additive angle change. 00346 * 00347 * The interval from firstAngle to lastAngle will be divided in 00348 * subintervals with a width stepAngle. 00349 * 00350 * This must be given in radians, but if you give a value greater than 00351 * 2*Pi, it will be assumed to be in degrees. 00352 * 00353 * Default value: lti::degToRad(10), i.e. 10 degrees in radians. 00354 */ 00355 float stepAngle; 00356 00357 /** 00358 * Multiplicative scaling change. 00359 * 00360 * The scaling interval will begin with firstScaling, which will be 00361 * multiplied each type by stepScaling until last scaling is reached. 00362 * 00363 * This value must be greater than 1. 00364 * 00365 * Default value: sqrt(2) 00366 */ 00367 float stepScaling; 00368 00369 /** 00370 * First scaling of the image will downsample it by a factor of 4 00371 * 00372 * Default value: 0.25 00373 */ 00374 float firstScaling; 00375 00376 /** 00377 * Last scaling of the image will be an upsampling by a factor of 2 00378 * 00379 * Default value: 2 00380 */ 00381 float lastScaling; 00382 00383 /** 00384 * First angle 00385 * 00386 * This must be given in radians, but if you give a value greater than 00387 * 2*Pi, it will be assumed to be in degrees. 00388 * 00389 * Default value 0 00390 */ 00391 float firstAngle; 00392 00393 /** 00394 * Last rotation angle 00395 * 00396 * This must be given in radians, but if you give a value greater than 00397 * 2*Pi, it will be assumed to be in degrees. 00398 * 00399 * Default value: 2*Pi 00400 */ 00401 float lastAngle; 00402 00403 /** 00404 * If true, a location will be considered to match only if position AND 00405 * rotation lie within the tolerance levels. If false, only the position 00406 * will be considered while analyzing the repeatability 00407 * 00408 * Default value: true 00409 */ 00410 bool considerAngle; 00411 00412 /** 00413 * Tolerance for scale deviation. 00414 * 00415 * Between two candidate matching locations, the match will be accepted 00416 * only if the ratio between scale of both locations does not goes 00417 * beneath the given tolerance value, which must be always smaller than 00418 * one. 00419 * 00420 * Default value: 1/sqrt(2) 00421 */ 00422 float scaleTolerance; 00423 00424 /** 00425 * Tolerance for position deviation. 00426 * 00427 * Between two candidate matching locations, the match will be accepted 00428 * only if the distance between both locations does not exceed the given 00429 * tolerance value, which must be always positive. 00430 * 00431 * Default value: 1.5f 00432 */ 00433 float positionTolerance; 00434 00435 /** 00436 * Angular tolerance. 00437 * 00438 * Two locations, which coincide in position and scale, match together 00439 * if the angular difference is smaller than the given angle. 00440 * 00441 * This must be given in radians, but if you give a value greater than 00442 * 2*Pi, it will be assumed to be in degrees. 00443 * 00444 * Default value: lti::degToRad(10), i.e. 10 degrees in radians. 00445 */ 00446 float angleTolerance; 00447 }; 00448 00449 /** 00450 * Default constructor 00451 */ 00452 locationSearchEvaluation(); 00453 00454 /** 00455 * Construct a functor using the given parameters 00456 */ 00457 locationSearchEvaluation(const parameters& par); 00458 00459 /** 00460 * Copy constructor 00461 * @param other the object to be copied 00462 */ 00463 locationSearchEvaluation(const locationSearchEvaluation& other); 00464 00465 /** 00466 * Destructor 00467 */ 00468 virtual ~locationSearchEvaluation(); 00469 00470 /** 00471 * Returns the name of this type ("locationSearchEvaluation") 00472 */ 00473 virtual const char* getTypeName() const; 00474 00475 /** 00476 * Returns a pointer to a clone of this functor. 00477 */ 00478 virtual functor* clone() const; 00479 00480 /** 00481 * Returns used parameters 00482 */ 00483 const parameters& getParameters() const; 00484 00485 /** 00486 * Set parameters 00487 */ 00488 bool setParameters(const functor::parameters& par); 00489 00490 /** 00491 * @name Public methods to be reimplemented 00492 */ 00493 //@{ 00494 00495 /** 00496 * Convert a binary-chain representation of a chromosome to a valid 00497 * parameter object. 00498 */ 00499 virtual bool chromosomeToPhenotype(const chromosome& genotype, 00500 functor::parameters& phenotype) const; 00501 00502 /** 00503 * Return a fresh allocated parameters for the evaluated functor, which is 00504 * equivalent to the given genotype. 00505 */ 00506 virtual functor::parameters* 00507 chromosomeToPhenotype(const chromosome& genotype) const; 00508 00509 /** 00510 * Convert a valid parameters object (phenotype) into binary-chain 00511 * representation of a chromosome. 00512 */ 00513 virtual bool phenotypeToChromosome(const functor::parameters& phenotype, 00514 chromosome& genotype) const; 00515 00516 /** 00517 * Return the length in bits for a chromosome. 00518 * 00519 * This method needs to be reimplemented, in order to get some 00520 * default implementations to work. 00521 */ 00522 virtual int getChromosomeSize() const; 00523 00524 /** 00525 * Evaluate Chromosome 00526 * 00527 * This method is one of the most important ones for the pareto evaluation. 00528 * Its task is to produce a multidimensional fitness measure for a given 00529 * chromosome. 00530 * 00531 * It returns true if the evaluation was successful, of false if the 00532 * phenotype represents some invalid parameterization. It is highly 00533 * recomended that the mutation and crossover methods are reimplemented to 00534 * avoid invalid parameterizations. 00535 */ 00536 virtual bool evaluateChromosome(const chromosome& individual, 00537 dvector& fitness); 00538 00539 //@} 00540 00541 /** 00542 * @name Evaluation Functions 00543 * 00544 * The real evaluation is provided here in order to compute measures 00545 * independently of the Pareto Front. 00546 */ 00547 //@{ 00548 /** 00549 * Index names for the complete multidimensional fitness measure 00550 */ 00551 enum { 00552 IdxTime, /**< Well, this is not really time, because that 00553 * would be "cost" instead of "fitness", in 00554 * reality, * this dimension contains 1.0/time in 00555 * s^-1, meaning the number of complete 00556 * location extractions per second. 00557 */ 00558 IdxNumberOfLocations, /**< Mean number of extracted locations 00559 */ 00560 IdxLocationsRecip, /**< Location reciprocal. 00561 * 00562 * Inverse of the number of locations detected. 00563 */ 00564 IdxOccupiedLevels, /**< Mean number of occupied levels. 00565 */ 00566 IdxScalePosRep, /**< Scale repeatability defined as total 00567 * number of stable locations divided by 00568 * the total number of locations for 00569 * changes of scaling only. 00570 */ 00571 IdxRotationPosRep, /**< Rotation repeatability defined as 00572 * total number of stable locations 00573 * divided by the total number of 00574 * locations for changes in the rotation 00575 * only. 00576 */ 00577 IdxRSPosRep, /**< Rotation repeatability defined as 00578 * total number of stable locations 00579 * divided by the total number of 00580 * locations for changes in the rotation 00581 * and scale. This will only be computed 00582 * if the RSRepeatability bit in the parameters 00583 * is enabled (it costs too much time!). 00584 */ 00585 IdxScaleARep, /**< Scale angular repeatability defined as 00586 * total number of angular stable 00587 * locations divided by the total number 00588 * of locations for changes of scaling 00589 * only. 00590 */ 00591 IdxRotationARep, /**< Rotation angular repeatability defined 00592 * as total number of angular stable 00593 * locations divided by the total number 00594 * of locations for changes in the 00595 * rotation only. 00596 */ 00597 IdxRSARep, /**< Angular repeatability defined as total 00598 * number of angular stable locations 00599 * divided by the total number of 00600 * locations for changes in the rotation 00601 * and scale. This will only be computed 00602 * if the RSRepeatability bit in the parameters 00603 * is enabled (it costs too much time!). 00604 */ 00605 IdxScalePosStable, /**< Scale stability defined as total 00606 * number of stable locations divided by 00607 * the total number of locations for 00608 * changes of scaling only. 00609 */ 00610 IdxRotationPosStable, /**< Rotation stability defined as 00611 * total number of stable locations 00612 * divided by the total number of 00613 * locations for changes in the rotation 00614 * only. 00615 */ 00616 IdxRSPosStable, /**< Rotation stability defined as 00617 * total number of stable locations 00618 * divided by the total number of 00619 * locations for changes in the rotation 00620 * and scale. This will only be computed 00621 * if the RSStability bit in the parameters 00622 * is enabled (it costs too much time!). 00623 */ 00624 IdxScaleAStable, /**< Scale angular stability defined as 00625 * total number of angular stable 00626 * locations divided by the total number 00627 * of locations for changes of scaling 00628 * only. 00629 */ 00630 IdxRotationAStable, /**< Rotation angular stability defined 00631 * as total number of angular stable 00632 * locations divided by the total number 00633 * of locations for changes in the 00634 * rotation only. 00635 */ 00636 IdxRSAStable, /**< Angular stability defined as total 00637 * number of angular stable locations 00638 * divided by the total number of 00639 * locations for changes in the rotation 00640 * and scale. This will only be computed 00641 * if the RSStability bit in the parameters 00642 * is enabled (it costs too much time!). 00643 */ 00644 }; 00645 00646 00647 00648 /** 00649 * Evaluate the set of images (in the parameters) using the 00650 * given parameterization. 00651 * 00652 * @param param parameters of the location selector to be used in 00653 * the evaluation. 00654 * @param fitness multidimensional fitness measures for each image in 00655 * one row. 00656 * @param onlyMeanAndVariance if true, the mean and variance of all 00657 * results will be computed. Otherwise all fitness measures 00658 * for all images will be provided. 00659 */ 00660 bool evaluate(const pyramidLocationSearch::parameters& param, 00661 dmatrix& fitness,const bool onlyMeanAndVariance = false); 00662 00663 /** 00664 * Evaluation of the location search with the given channel using 00665 * the given parameterization. 00666 */ 00667 bool evaluate(const channel& chnl, 00668 const pyramidLocationSearch::parameters& param, 00669 dvector& fitness); 00670 00671 //@} 00672 00673 protected: 00674 /** 00675 * Total number of fitness measures that will be computed 00676 * 00677 */ 00678 static const int totalFitnessDimensionality; 00679 00680 /** 00681 * Evaluation of the location search with the given channel 00682 * using the given parameterization. 00683 */ 00684 bool evaluate(const channel& chnl, 00685 const channel8& mask, 00686 dvector& fitness); 00687 00688 /** 00689 * Compare both location sets. 00690 * 00691 * @param olocs original image location set. 00692 * @param blocs back-transformed location set from the location extracted 00693 * from the transformed image. 00694 * @param posStable number of locations stable respect their position 00695 * @param rotStable number of locations also stable in detected 00696 * rotation angle (rotStable <= posStable). 00697 * @return true if successful, false otherwise. 00698 */ 00699 bool compare(const kdTree<tpoint<float>,int>& olocs, 00700 const std::vector<location>& olocs, 00701 const std::vector<location>& blocs, 00702 int& posStable, 00703 int& rotStable) const; 00704 00705 private: 00706 /** 00707 * Structure containing a single enum with the number of bits required 00708 * for each parameter. 00709 */ 00710 struct bits; 00711 00712 /** 00713 * Functor used for the location search need only one setup for one 00714 * parameter set 00715 */ 00716 pyramidLocationSearch locationSearcher; 00717 00718 /** 00719 * Get the image name 00720 */ 00721 std::string getMaskName(const std::string& imgName, 00722 const std::string& postfix) const; 00723 00724 /** 00725 * All channels read. 00726 * 00727 * Since the tests take a very long time, usually just a few images 00728 * are used here. It is much better to read them once here. 00729 */ 00730 std::vector<channel> imageData; 00731 00732 /** 00733 * All mask for channels read. 00734 * 00735 * Since the tests take a very long time, usually just a few images 00736 * are used here. It is much better to read them once and cache them here. 00737 * 00738 * The maskData contains the segmentation mask of the imageData, used to 00739 * optimize the selection of mask in the imporant regions. If a 00740 * channel is empty, all locations will be valid. 00741 */ 00742 std::vector<channel8> maskData; 00743 00744 }; 00745 } 00746 00747 #endif 00748