last update 20 Sep 2009 |
00001 /* 00002 * Copyright (C) 2007 00003 * Pablo Alvarado 00004 * 00005 * This file is part of the Computer Vision and Robot Library (CVR-Lib) 00006 * 00007 * The CVR-Lib is free software; you can redistribute it and/or 00008 * modify it under the terms of the BSD License. 00009 * 00010 * All rights reserved. 00011 * 00012 * Redistribution and use in source and binary forms, with or without 00013 * modification, are permitted provided that the following conditions are met: 00014 * 00015 * 1. Redistributions of source code must retain the above copyright notice, 00016 * this list of conditions and the following disclaimer. 00017 * 00018 * 2. Redistributions in binary form must reproduce the above copyright notice, 00019 * this list of conditions and the following disclaimer in the documentation 00020 * and/or other materials provided with the distribution. 00021 * 00022 * 3. Neither the name of the authors nor the names of its contributors may be 00023 * used to endorse or promote products derived from this software without 00024 * specific prior written permission. 00025 * 00026 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00027 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00028 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00029 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 00030 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00031 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00032 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00033 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00034 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00035 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00036 * POSSIBILITY OF SUCH DAMAGE. 00037 */ 00038 00039 /** 00040 * \file cvrFastHessianDetection.h 00041 * Contains the class cvr::fastHessianDetection, 00042 * which is the location detector used by the SURF concept. 00043 * 00044 * \author Pablo Alvarado 00045 * \date 23.10.2007 00046 * 00047 * revisions ..: $Id: cvrFastHessianDetection.h,v 1.8 2007/12/19 02:57:25 alvarado Exp $ 00048 */ 00049 00050 #ifndef _CVR_FAST_HESSIAN_DETECTION_H_ 00051 #define _CVR_FAST_HESSIAN_DETECTION_H_ 00052 00053 #include "cvrLocation.h" 00054 #include "cvrChannel8.h" 00055 #include "cvrChannel.h" 00056 #include "cvrLocationDetection.h" 00057 #include "cvrList.h" 00058 #include "cvrBoundaryType.h" 00059 #include "cvrLattice2D.h" 00060 00061 namespace cvr { 00062 00063 class integralImage; 00064 00065 00066 /** 00067 * Class fastHessianDetection 00068 * 00069 * The class cvr::fastHessianDetection is one of the available location 00070 * detectors in the CVR-Lib , i.e. is a class used to detect interesing 00071 * points in an image, considering also the "scale" at which the interesting 00072 * information resides. 00073 * 00074 * This particular method is part of the SURF approach for robust feature 00075 * detection, as explained in detail in the paper: 00076 * 00077 * Herbert Bay, Tinne Tuytelaars, and Luc Van Gool. SURF: Speeded Up Robust 00078 * Features. In Proceedings of the 9th European Conference on Computer 00079 * Vision, May 2006. Available at 00080 * http://www.vision.ee.ethz.ch/~surf/papers.html 00081 * 00082 * The implementation here provides some configuration possibilities, but is 00083 * limited to provide the authors concept as reliable as the paper allowed. 00084 * 00085 * @see fastHessianDetection::parameters. 00086 * @see surfLocalDescriptor 00087 * 00088 * @ingroup gFeatureExtr 00089 */ 00090 class fastHessianDetection : public locationDetection { 00091 public: 00092 /** 00093 * Types for locations to be found 00094 */ 00095 enum eExtremaType { 00096 Minima, /**< Only detect minima of the determinant image */ 00097 Maxima, /**< Only detect maxima of the determinant image */ 00098 Both /**< Detect both maxima and minima */ 00099 }; 00100 00101 /** 00102 * Types of level selection in the multiresolutional representation 00103 */ 00104 enum eLevelSelectionMethod { 00105 Blocks, /**< Original method suggested in the SURF paper, which 00106 * uses blocks of levels separated by the same scale step, 00107 * After a block has been computed, the next one duplicates 00108 * the step. 00109 */ 00110 Exponential /**< The exponential level selection method uses for the 00111 * scales the equation \f$\alpha^n\sigma_B\f$ 00112 */ 00113 }; 00114 00115 /** 00116 * Modes available for the selection of conspicuous locations 00117 * 00118 * These modes affect the way in which the threshold value is interpreted. 00119 */ 00120 enum eLocationSelectionMode { 00121 All, /**< Ignore the threshold, and compute all locations 00122 */ 00123 Absolute, /**< The determinant of the hessian matrix has to be greater 00124 * than the threshold value (or less than -threshold) to be 00125 * considered. 00126 */ 00127 Relative, /**< The determinant of the hessian matrix has to be greater 00128 * than a threshold value computed as a percentage of the 00129 * greatest value found at each level. 00130 */ 00131 Conspicuous, /**< The determinant of the hessian matrix has to be greater 00132 * than a threshold value computed as the mean of all 00133 * values plus a number of times the standard deviation 00134 */ 00135 Number /**< At most the given number of (strongest) locations will be 00136 * returned. 00137 */ 00138 00139 }; 00140 00141 /** 00142 * The parameters for the class fastHessianDetection 00143 */ 00144 class parameters : public locationDetection::parameters { 00145 public: 00146 /** 00147 * Default constructor 00148 */ 00149 parameters(); 00150 00151 /** 00152 * Copy constructor 00153 * @param other the parameters object to be copied 00154 */ 00155 parameters(const parameters& other); 00156 00157 /** 00158 * Destructor 00159 */ 00160 ~parameters(); 00161 00162 /** 00163 * Copy the contents of a parameters object 00164 * @param other the parameters object to be copied 00165 * @return a reference to this parameters object 00166 */ 00167 parameters& copy(const parameters& other); 00168 00169 /** 00170 * Copy the contents of a parameters object 00171 * @param other the parameters object to be copied 00172 * @return a reference to this parameters object 00173 */ 00174 parameters& operator=(const parameters& other); 00175 00176 /** 00177 * Returns the complete name of the parameters class. 00178 */ 00179 virtual const std::string& name() const; 00180 00181 /** 00182 * Returns a pointer to a clone of the parameters. 00183 */ 00184 virtual parameters* clone() const; 00185 00186 /** 00187 * Returns a pointer to a new instance of the parameters. 00188 */ 00189 virtual parameters* newInstance() const; 00190 00191 /** 00192 * Write the parameters in the given ioHandler 00193 * @param handler the ioHandler to be used 00194 * @param complete if true (the default) the enclosing begin/end will 00195 * be also written, otherwise only the data block will be written. 00196 * @return true if write was successful 00197 */ 00198 virtual bool write(ioHandler& handler,const bool complete=true) const; 00199 00200 /** 00201 * Read the parameters from the given ioHandler 00202 * @param handler the ioHandler to be used 00203 * @param complete if true (the default) the enclosing begin/end will 00204 * be also written, otherwise only the data block will be written. 00205 * @return true if write was successful 00206 */ 00207 virtual bool read(ioHandler& handler,const bool complete=true); 00208 00209 // ------------------------------------------------ 00210 // the parameters 00211 // ------------------------------------------------ 00212 00213 /** 00214 * @name Parameters for the "scale-space" levels 00215 */ 00216 //@{ 00217 /** 00218 * Number of levels of the multi-scale representation used to detect 00219 * interest points. 00220 * 00221 * You need at least 3 levels. 00222 * 00223 * See parameters::initialKernelStep for an example. 00224 * 00225 * Default value: 12 00226 */ 00227 int numberOfLevels; 00228 00229 /** 00230 * Kernel size for the highest spatian resolution 00231 * 00232 * This is the kernel side size, which means that, if you provide 9, then 00233 * a kernel 9x9 will be built. 00234 * 00235 * The kernel size is intrinsically tied to the sigma (standard 00236 * deviation) of the kernel. A 9x9 kernel will always use a sigma=1.2 in 00237 * accordance to the SURF paper. Any other kernel size will ajust the 00238 * sigma linearly. A kernel of 27x27 will use a sigma of 3x1.2=3.6, 00239 * since 27=3x9. 00240 * 00241 * The size value has to be divisible by 3 and odd. 00242 * 00243 * See parameters::initialKernelStep for an example. 00244 * 00245 * 00246 * Default value: 9 00247 */ 00248 int initialKernelSize; 00249 00250 /** 00251 * Level selection method. 00252 * 00253 * You can choose between two methods for the level selection: 00254 * - The \c Blocks method resembles the one proposed in the SURF paper 00255 * selecting blocks of levels separated by a fixed amount of "scale". 00256 * - The \c Exponential method increases the scale exponentially, as 00257 * is usual in scale-space pyramids. However, since the kernel sizes 00258 * must be odd and divisible by three, the lower resolution will 00259 * not exactly grow at exponential rates. 00260 * 00261 * Default value: Blocks 00262 */ 00263 eLevelSelectionMethod levelSelectionMethod; 00264 00265 /** 00266 * Kernel step size change between levels. 00267 * 00268 * This parameters is used only if you select the levelSelectionMethod as 00269 * \c Blocks. 00270 * 00271 * The multiresolutional representation of a channel contains several 00272 * levels, each one computed with a kernel size to which this step value 00273 * is iteratively added. Once the \c levelGroupSize has been reached, 00274 * the kernel step is duplicated. 00275 * 00276 * For example, with 00277 * - \c initialKernelSize=9, 00278 * - \c initialKernelStep=6, 00279 * - \c levelGroupSize=4, and 00280 * - \c numberOfLevels=12, 00281 * 00282 * then the used kernel sizes will be 00283 * -# 9x9, 15x15, 21x21, 27x27, 00284 * -# 39x39, 51x51, 63x63, 75x75, 00285 * -# 99x99, 123x123,147x147,171x171 00286 * 00287 * The step value has to be even and divisible by three (and hence, 00288 * divisible by 6). If not, then the closest number divisible by 6 will 00289 * be used. 00290 * 00291 * Default value: 6 00292 */ 00293 int initialKernelStep; 00294 00295 /** 00296 * Number of levels in a group or octave 00297 * 00298 * If levelSelectionMethod is set to \c Blocks, a group of levels is the 00299 * number of levels generated using the same kernel step. The "next" 00300 * group will double the kernel size step. 00301 * 00302 * See parameters::initialKernelStep for an example. 00303 * 00304 * If levelSelectionMethod is set to \c Exponential, then this is the 00305 * number of levels tried to be present in an octave. However, since 00306 * the kernel sizes have to be divisible by three and have to be odd, 00307 * then this might become true only for the higher levels. 00308 * 00309 * Default value: 4 00310 */ 00311 int levelGroupSize; 00312 00313 /** 00314 * Norm power. 00315 * 00316 * Theoretically this value has to be 4.0f in order to keep the same 00317 * information weight of all levels. You can modify this value to 00318 * slightly smaller values (e.g. 3.9f) if you want to give more weight to 00319 * larger locations, or larger values (4.1f) if you need to obtain 00320 * locations of small details. 00321 * 00322 * The outputs of the filters approximating the second order derivatives 00323 * have to be normalized by the filter mask sizes (and hence, the norm 00324 * will be proportional to the square of the scale). Additionally, the 00325 * determinant of the hessian matrix is computed by products of two 00326 * filter outputs, and hence, the total norm is proportional to the scale 00327 * to the power of four. 00328 * 00329 * Default value: 4 00330 */ 00331 float normPower; 00332 //@} 00333 00334 /** 00335 * @name Parameters for the location selection 00336 */ 00337 //@{ 00338 /** 00339 * Types of extrema to search for. 00340 * 00341 * The locations are placed on local extrema of the scale-space 00342 * representation of the image. Here you can indicate if they should be 00343 * placed on \c Maxima, on \c Minima or on \c Both. 00344 * 00345 * Default value: Both 00346 */ 00347 eExtremaType extrema; 00348 00349 /** 00350 * Mode for location selection. 00351 * 00352 * You can select among different modes for selecting the locations 00353 * according to their strength in the value of the hessian determinant. 00354 * 00355 * This will affect the way in which the threshold value is interpreted. 00356 * See parameters::threshold for more information. 00357 * 00358 * Default value: Absolute 00359 */ 00360 eLocationSelectionMode locationSelectionMode; 00361 00362 /** 00363 * Threshold value. 00364 * 00365 * The meaning of this threshold value depends on the settings of the 00366 * locationSelectionMode. 00367 * 00368 * - If \c locationSelectionMode is set to \b All, then this value is 00369 * ignored and all detected locations will be returned. 00370 * - If \c locationSelectionMode is set to \b Absolute, then this value 00371 * means the weakest strength a location can exhibit in order to be 00372 * returned in the results. 00373 * - If \c locationSelectionMode is set to \b Relative, then this value 00374 * means the fraction of the maximal location strengh that will be 00375 * allowed. This value has to be between 0 and 1. 00376 * - If \c locationSelectionMode is set to \b Conspicuous, then this 00377 * value means the number of times the standard deviation will be 00378 * multiplied with when added to the strengths mean value to compute 00379 * the threshold. 00380 00381 * - If \c locationSelectionMode is set to \b Number, then this value 00382 * means the maximal number of locations that will be returned, where 00383 * only the strongest locations will be returned. This is the slowest 00384 * method of all, since it requires to sort the values. 00385 * 00386 * Default value: 0.1f 00387 */ 00388 float threshold; 00389 00390 /** 00391 * Subsample levels 00392 * 00393 * The search for conspicuous locations can be made using all pixels in 00394 * all levels (value set to \c false) or just some selected samples 00395 * depending on the scale of a level (value set to \c true). 00396 * 00397 * Default value: true 00398 */ 00399 bool subsampleLevels; 00400 00401 /** 00402 * Initial sampling step 00403 * 00404 * If subsampleLevels is set to \c true, this is the initial sampling 00405 * step. If subsampleLevels is set to \c false then all levels use this 00406 * value. 00407 * 00408 * This value must be 1 or greater. 00409 * 00410 * Default value: 2 00411 */ 00412 int initialSamplingStep; 00413 //@} 00414 00415 /** 00416 * @name Parameters for the estimation of the location orientation. 00417 * 00418 * The algorithm in the SURF paper states that on a circular window 00419 * around the detected location a set of samples is chosen for which some 00420 * gradient related values (computed through Haar filters) are computed 00421 * and used in a "weighted voting" approach. Each sample votes in an 00422 * orientation window (or windows) that covers the angle of the 00423 * "gradient" and with a weight given by its magnitude. At the end, an 00424 * orientation value is selected of the window with the largest 00425 * accumulated magnitude and with the angle of the accumulated values. 00426 */ 00427 //@{ 00428 /** 00429 * Selection flag used to deactivate orientation computation. 00430 * 00431 * In order to compute the so-called U-SURF descriptors, which lack of 00432 * orientation, we can save some time by deactivating the orientation 00433 * computation. 00434 * 00435 * To deactivate the computation of the orientation just set this 00436 * parameter to \c false. 00437 * 00438 * Default value: \c true 00439 */ 00440 bool computeOrientation; 00441 00442 /** 00443 * Factor used to compute radius of the circular neighborhood employed to 00444 * compute the orientation of a location. 00445 * 00446 * The real neighborhood radius will be computed multiplying the scale on 00447 * which a location was found by this factor. 00448 * 00449 * Default value: 6 00450 */ 00451 float orientationNeighborhoodFactor; 00452 00453 /** 00454 * Factor used to compute the samples within the orientation neighborhood 00455 * considered. 00456 * 00457 * The real sampling step is computed multiplying this factor with 00458 * the scale on which a location has been found. 00459 * 00460 * The value \c orientationNeighborhoodFactor has to be divisible by 00461 * this number. 00462 * 00463 * Default value: 1 00464 */ 00465 float orientationSamplingStepFactor; 00466 00467 /** 00468 * Factor to compute the Haar wavelet side. 00469 * 00470 * The real wavelet size is computed multiplying this factor with 00471 * the scale on which the location has been found (always rounded to 00472 * the next odd size, to be centered on the location) 00473 * 00474 * Default value: 4 00475 */ 00476 float orientationWaveletSizeFactor; 00477 00478 /** 00479 * Gaussian weights for the orientation 00480 * 00481 * The wavelet responses on the samples in the neighborhood used to 00482 * compute the orientation are weighted with a gaussian that has an 00483 * standard deviation of this factor multiplied by the scale on which the 00484 * location has been found. 00485 * 00486 * Default value: 2.5 00487 */ 00488 float orientationGaussianFactor; 00489 00490 /** 00491 * Angular width for the orientation window. 00492 * 00493 * This is used as follows. When a sample produces an angular value to 00494 * vote for, over that angular value a slice is placed with an angular 00495 * span of the value given here. All windows that fall beneath that 00496 * slice will count the vote. This means, a value of zero forces just 00497 * one window to be taken into consideration, as the original SURF paper 00498 * states. 00499 * 00500 * If this angular value is less than 2*Pi, then it is assumed to be 00501 * given in radians. Otherwise is interpreted in degrees. 00502 * 00503 * The value must be positive or zero. 00504 * 00505 * In the original paper a value of zero is used, however, a value of 60 00506 * has proven (with orientationNumberOfWindows=6) to be much more 00507 * reliable. 00508 * 00509 * Default value: 60 00510 */ 00511 float orientationWindowWidth; 00512 00513 /** 00514 * Number of angular windows. 00515 * 00516 * Each window will contain angles in an interval of 00517 * orientationWindowWidth distributed homogeneously on the 2*Pi radians. 00518 * 00519 * Default value: 6 00520 */ 00521 int orientationNumberOfWindows; 00522 //@} 00523 }; 00524 00525 /** 00526 * Default constructor 00527 */ 00528 fastHessianDetection(); 00529 00530 /** 00531 * Construct a functor using the given parameters 00532 */ 00533 fastHessianDetection(const parameters& par); 00534 00535 /** 00536 * Copy constructor 00537 * @param other the object to be copied 00538 */ 00539 fastHessianDetection(const fastHessianDetection& other); 00540 00541 /** 00542 * Destructor 00543 */ 00544 virtual ~fastHessianDetection(); 00545 00546 /** 00547 * Compute the locations based on the determinant of the "fast Hessian" 00548 * matrix. 00549 * 00550 * @param src channel8 with the source image. 00551 * @param locs lists of detected locations. 00552 * 00553 * @return true if apply successful or false otherwise. 00554 */ 00555 virtual bool apply(const channel8& src, 00556 list<location>& locs) const; 00557 00558 /** 00559 * Compute the locations based on the determinant of the "fast Hessian" 00560 * matrix. 00561 * 00562 * @param src channel8 with the source image. 00563 * @param locs lists of detected locations. 00564 * @param strength the determinant value of the hessian matrix at 00565 * the center of the location. 00566 * 00567 * @return true if apply successful or false otherwise. 00568 */ 00569 bool apply(const channel8& src, 00570 list<location>& locs, 00571 list<float>& strength) const; 00572 00573 /** 00574 * Compute the locations based on the determinant of the "fast Hessian" 00575 * matrix. 00576 * 00577 * @param src channel8 with the source image. 00578 * @param locs lists of detected locations. 00579 * @param strength the determinant value of the hessian matrix at 00580 * the center of the location. 00581 * @param numLocs number of location in \a locs and \a strength 00582 * 00583 * @return true if apply successful or false otherwise. 00584 */ 00585 bool apply(const channel8& src, 00586 list<location>& locs, 00587 list<float>& strength, 00588 int& numLocs) const; 00589 00590 /** 00591 * Compute the locations based on the determinant of the "fast Hessian" 00592 * matrix. 00593 * 00594 * This method provides numLocs = locs.size() directly. The reason is 00595 * simple: speed. The size() method needs to count the elements, and 00596 * this is usually done in the process. 00597 * 00598 * @param src channel8 with the source image. 00599 * @param locs lists of detected locations. 00600 * @param numLocs number of locations detected. 00601 * 00602 * @return true if apply successful or false otherwise. 00603 */ 00604 virtual bool apply(const channel8& src, 00605 list<location>& locs, 00606 int& numLocs) const; 00607 00608 /** 00609 * Compute the locations based on the determinant of the "fast Hessian" 00610 * matrix. 00611 * 00612 * @param src channel8 with the source image. 00613 * @param locs lists of detected locations. 00614 * 00615 * @return true if apply successful or false otherwise. 00616 */ 00617 virtual bool apply(const channel& src, 00618 list<location>& locs) const; 00619 00620 /** 00621 * Compute the locations based on the determinant of the "fast Hessian" 00622 * matrix. 00623 * 00624 * @param src channel8 with the source image. 00625 * @param locs lists of detected locations. 00626 * @param strength the determinant value of the hessian matrix at 00627 * the center of the location. 00628 * 00629 * @return true if apply successful or false otherwise. 00630 */ 00631 bool apply(const channel& src, 00632 list<location>& locs, 00633 list<float>& strength) const; 00634 00635 /** 00636 * Compute the locations based on the determinant of the "fast Hessian" 00637 * matrix. 00638 * 00639 * @param src channel8 with the source image. 00640 * @param locs lists of detected locations. 00641 * @param strength the determinant value of the hessian matrix at 00642 * the center of the location. 00643 * @param numLocs number of location in \a locs and \a strength 00644 * 00645 * @return true if apply successful or false otherwise. 00646 */ 00647 bool apply(const channel& src, 00648 list<location>& locs, 00649 list<float>& strength, 00650 int& numLocs) const; 00651 00652 00653 /** 00654 * Compute the locations based on the determinant of the "fast Hessian" 00655 * matrix. 00656 * 00657 * This method provides numLocs = locs.size() directly. The reason is 00658 * simple: speed. The size() method needs to count the elements, and 00659 * this is usually done in the process. 00660 * 00661 * @param src channel8 with the source image. 00662 * @param locs lists of detected locations. 00663 * @param numLocs number of locations detected. 00664 * 00665 * @return true if apply successful or false otherwise. 00666 */ 00667 virtual bool apply(const channel& src, 00668 list<location>& locs, 00669 int& numLocs) const; 00670 00671 /** 00672 * Sort the locations according to their strength, in descending 00673 * order: the strongest locations are always first. 00674 * 00675 * This is useful to take a fixed number of the strongest locations. 00676 * 00677 * The behaviour is influenced by the parameter settings of 00678 * parameters::extrema. If it is set to Maxima, then the values are sorted 00679 * as given, in descending order; if set to Minima, then the values are 00680 * sorted in ascending order; if set to Both, then the absolute value of 00681 * the strength is sorted in descending order. 00682 * 00683 * @param locs the unsorted locations as provided by the apply method. 00684 * @param strength the corresponding strengths for the locations, as 00685 * provided by the apply method. It has to have exactly 00686 * the same size as the locs list. 00687 * @param sortedLocs the sorted locations as vector, to have access to 00688 * the rank of the location 00689 * @param sortedStrength the sorted strength. 00690 * 00691 * @return \c true if successful or \c false otherwise. 00692 */ 00693 bool sort(const list<location>& locs, 00694 const list<float>& strength, 00695 std::vector<location>& sortedLocs, 00696 fvector& sortedStrength) const; 00697 00698 /** 00699 * Operates on a copy of the given arguments. 00700 * 00701 * @param src channel with the source image. 00702 * @param locs lists of detected locations. 00703 * 00704 * @return true if apply successful or false otherwise. 00705 */ 00706 //bool apply(const channel& src, channel& dest) const; 00707 00708 /** 00709 * Copy data of "other" functor. 00710 * @param other the functor to be copied 00711 * @return a reference to this functor object 00712 */ 00713 fastHessianDetection& copy(const fastHessianDetection& other); 00714 00715 /** 00716 * Alias for copy member 00717 * @param other the functor to be copied 00718 * @return a reference to this functor object 00719 */ 00720 fastHessianDetection& operator=(const fastHessianDetection& other); 00721 00722 /** 00723 * Returns the complete name of the functor class 00724 */ 00725 virtual const std::string& name() const; 00726 00727 /** 00728 * Returns a pointer to a clone of this functor. 00729 */ 00730 virtual fastHessianDetection* clone() const; 00731 00732 /** 00733 * Returns a pointer to a new instance of this functor. 00734 */ 00735 virtual fastHessianDetection* newInstance() const; 00736 00737 /** 00738 * Returns used parameters 00739 */ 00740 const parameters& getParameters() const; 00741 00742 /** 00743 * Update parameters 00744 */ 00745 bool updateParameters(); 00746 00747 private: 00748 /** 00749 * Compute the determinant of the approximated Hessian matrix. 00750 * 00751 * The template type T is usually int32 or float, which are the 00752 * result types of the integralImage functor. 00753 * 00754 * @param kernelSize size of the kernel used. The associated variance 00755 * can be computed as 1.2*kernelSize/9 00756 * @param intImg the integral image of the input image 00757 */ 00758 template<typename T> 00759 bool computeDeterminant(const int kernelSize, 00760 const matrix<T>& intImg, 00761 const integralImage& integrator, 00762 const int sampleStep, 00763 matrix<float>& det) const; 00764 00765 /** 00766 * Compute the "pseudo-pyramid". 00767 * 00768 * The template type T is usually ubyte or float, which are the 00769 * possible channel types. 00770 * 00771 * @param chnl the original input channel 00772 * @param intImg integral image for the input channel 00773 * @param levels all the determinant channels for different scales. 00774 * @param kernelSizes sizes of kernels used for each level. If you 00775 * need the scale \e s, it can be computed as 00776 * \f$1,2 K_s / 9 = s \f$, Where K_s is the kernel 00777 * size. 00778 */ 00779 template<typename T> 00780 bool computeLevels(const matrix<T>& chnl, 00781 matrix<typename typeInfo<T>::accumulation_type>& intImg, 00782 std::vector<fmatrix>& levels, 00783 ivector& kernelSizes, 00784 ivector& sampleSteps) const; 00785 00786 /** 00787 * This method searches for local extrema (minima and maxima) and tries 00788 * to improve the locations placement with interpolation. 00789 * 00790 * @param scale value of scale associated with the central level 00791 * @param prevLevel "previous" level, with a higher level of detail (lower 00792 * index in the pseudo-pyramid 00793 * @param level current level, corresponding to the given scale 00794 * @param nextLevel "next" level, with a lower degree of detail (higher 00795 * index in the pseudo-pyramid 00796 * @param locs list of detected locations. 00797 * @param strength determinant of the hessian matrix for the given location 00798 * Since this should not take much time, the value stored 00799 * is the one at the center of the 3x3x3 neighborhood, and 00800 * \e not the interpolated value for the maximum. 00801 */ 00802 bool searchLevelExtremes(const float scalePrev, 00803 const float scale, 00804 const float scaleNext, 00805 const fmatrix& prevLevel, 00806 const fmatrix& level, 00807 const fmatrix& nextLevel, 00808 const int sampleStep, 00809 list<location>& locs, 00810 list<float>& strength, 00811 int& numLocs) const; 00812 00813 /** 00814 * This method removes weak locations, depending on the parameter settings 00815 * @param locs list of detected locations. 00816 * @param strength determinant of the hessian matrix for the given location 00817 * Since this should not take much time, the value stored 00818 * is the one at the center of the 3x3x3 neighborhood, and 00819 * \e not the interpolated value for the maximum. 00820 */ 00821 bool selectLocations(list<location>& locs, 00822 list<float>& strength, 00823 int& numLocs) const; 00824 00825 /** 00826 * Compute the orientations for each location. 00827 * 00828 * If the parameters::computeOrientation is set to false, this 00829 * method returns \c true without making any modifications to the locs. 00830 * 00831 * Otherwise, each location will be analyzed using the SURF suggested 00832 * method to detect the orientation. 00833 */ 00834 template<typename T> 00835 bool computeOrientations(const matrix<T>& intImg, 00836 list<location>& locs) const; 00837 00838 /** 00839 * Internal class used to manage the orientation windows. 00840 */ 00841 class orientationAccumulator; 00842 00843 /** 00844 * Circle boundary LUT. 00845 * 00846 * This vector contains the index of the circle border of gaussWeights_ 00847 */ 00848 lattice1D<int> circLUT_; 00849 00850 /** 00851 * Gaussian weights 00852 */ 00853 lattice2D<float> gaussWeights_; 00854 00855 /** 00856 * Number of samples in the circular window used to compute the orientation 00857 */ 00858 int wndSamples_; 00859 00860 /** 00861 * Shadow for the initialKernelStep, ensuring that it is even and divisible 00862 * by three. 00863 */ 00864 int kernelStep_; 00865 00866 /** 00867 * Shadow for the initialKernelSize, ensuring that it is odd and divisible 00868 * by three. 00869 */ 00870 int kernelSize_; 00871 00872 /** 00873 * Shadow value of the parameters always in radians. 00874 */ 00875 float orientationWindowWidth_; 00876 00877 /** 00878 * Shadow value of the parameters 00879 */ 00880 int orientationNumberOfWindows_; 00881 00882 }; 00883 00884 /** 00885 * Read a eExtremaType 00886 * 00887 * @ingroup gStorable 00888 */ 00889 bool read(ioHandler& handler,fastHessianDetection::eExtremaType& data); 00890 00891 /** 00892 * Write a eExtremaType 00893 * 00894 * @ingroup gStorable 00895 */ 00896 bool write(ioHandler& handler, 00897 const fastHessianDetection::eExtremaType& data); 00898 00899 00900 /** 00901 * Read a fastHessianDetection::eLevelSelectionMethod 00902 * 00903 * @ingroup gStorable 00904 */ 00905 bool read(ioHandler& handler, 00906 fastHessianDetection::eLevelSelectionMethod& data); 00907 00908 /** 00909 * Write a fastHessianDetection::eLevelSelectionMethod 00910 * 00911 * @ingroup gStorable 00912 */ 00913 bool write(ioHandler& handler, 00914 const fastHessianDetection::eLevelSelectionMethod& data); 00915 00916 /** 00917 * Read a fastHessianDetection::eLevelSelectionMethod 00918 * 00919 * @ingroup gStorable 00920 */ 00921 bool read(ioHandler& handler, 00922 fastHessianDetection::eLocationSelectionMode& data); 00923 00924 /** 00925 * Write a fastHessianDetection::eLevelSelectionMethod 00926 * 00927 * @ingroup gStorable 00928 */ 00929 bool write(ioHandler& handler, 00930 const fastHessianDetection::eLocationSelectionMode& data); 00931 00932 } 00933 00934 #endif 00935