CVR-Lib last update 20 Sep 2009

cvrFastHessianDetection.h

Go to the documentation of this file.
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 

Generated on Sun Sep 20 22:07:59 2009 for CVR-Lib by Doxygen 1.5.8