CVR-Lib last update 20 Sep 2009

cvrGenericInterpolation.h

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 1998 - 2005
00003  * Lehrstuhl fuer Technische Informatik, RWTH-Aachen, Germany
00004  *
00005  *
00006  * This file is part of the Computer Vision and Robotics Library (CVR-Lib)
00007  *
00008  * The CVR-Lib is free software; you can redistribute it and/or
00009  * modify it under the terms of the BSD License.
00010  *
00011  * All rights reserved.
00012  *
00013  * Redistribution and use in source and binary forms, with or without
00014  * modification, are permitted provided that the following conditions are met:
00015  *
00016  * 1. Redistributions of source code must retain the above copyright notice,
00017  *    this list of conditions and the following disclaimer.
00018  *
00019  * 2. Redistributions in binary form must reproduce the above copyright notice,
00020  *    this list of conditions and the following disclaimer in the documentation
00021  *    and/or other materials provided with the distribution.
00022  *
00023  * 3. Neither the name of the authors nor the names of its contributors may be
00024  *    used to endorse or promote products derived from this software without
00025  *    specific prior written permission.
00026  *
00027  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00028  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00029  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00030  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00031  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00032  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00033  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00034  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00035  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00036  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00037  * POSSIBILITY OF SUCH DAMAGE.
00038  */
00039 
00040 
00041 
00042 /**
00043  * \file   cvrGenericInterpolation.h
00044  *         Contains the functor genericInterpolation which uses LUT
00045  *         for interpolation kernels
00046  * \author Pablo Alvarado
00047  * \date   12.06.2001
00048  *
00049  * $Id: cvrGenericInterpolation.h,v 1.5 2007/11/17 20:03:13 alvarado Exp $
00050  */
00051 
00052 #ifndef _CVR_GENERIC_INTERPOLATION_H_
00053 #define _CVR_GENERIC_INTERPOLATION_H_
00054 
00055 #include "cvrImage.h"
00056 #include "cvrVector.h"
00057 #include "cvrMatrix.h"
00058 #include "cvrFixedGridInterpolation.h"
00059 
00060 namespace cvr {
00061 
00062   /**
00063    * This functor uses a generic interpolation concept based on look-up-tables
00064    * for the interpolation kernels.
00065    *
00066    * The LUTs allow to considerably accelerate the computation times, but a
00067    * little bit precision is lost due to the unavoidable quantization present
00068    * in the LUT.
00069    *
00070    * The type T of the template is the type of the elements of the vector
00071    * or matrix used.
00072    */
00073   template <class T>
00074   class genericInterpolation : public fixedGridInterpolation<T> {
00075   public:
00076 
00077     /**
00078      * Types for interpolation kernels.
00079      */
00080     enum eInterpolationKernelType {
00081       BilinearKernel, /**< Bilinear interpolation kernel.
00082                        * The neighborhood size is always 2x2.
00083                        * This implementation
00084                        * is slower than the optimized version in the functor
00085                        * cvr::bilinearInterpolation, but is provided for
00086                        * completeness.
00087                        */
00088       BicubicKernel,  /**< Bicubic interpolation.
00089                        * The neighborhood size is always 4x4.
00090                        * The kernel provided here is after Sonka et.al.
00091                        * pp. 67
00092                        *
00093                        * \f[ h(x)=\begin{cases}
00094                        * 1-2|x|^2+|x|^3 & \text{for $0\leq|x|\leq 1$} \\
00095                        * 4-8|x|+5|x|^2-|x|^3 & \text{for $1\leq|x|\leq 2$}\\
00096                        * 0 & \text{otherwise}
00097                        * \end{cases} \f]
00098                        */
00099       GenericKernel   /**< Generic interpolation.
00100                        * The generic interpolation uses the kernelLUT given
00101                        * in the parameters.
00102                        */
00103     };
00104 
00105     /**
00106      * The parameters for the class genericInterpolation
00107      */
00108     class parameters : public fixedGridInterpolation<T>::parameters {
00109     public:
00110 
00111       /**
00112        * default constructor
00113        */
00114       parameters();
00115 
00116       /**
00117        * Constructor to set explicitly the desired boundaryType
00118        */
00119       parameters(const eBoundaryType btype);
00120 
00121       /**
00122        * copy constructor
00123        * @param other the parameters object to be copied
00124        */
00125       parameters(const parameters& other);
00126 
00127       /**
00128        * destructor
00129        */
00130       ~parameters();
00131 
00132       /**
00133        * copy the contents of a parameters object
00134        * @param other the parameters object to be copied
00135        * @return a reference to this parameters object
00136        */
00137       parameters& copy(const parameters& other);
00138 
00139       /**
00140        * copy the contents of a parameters object
00141        * @param other the parameters object to be copied
00142        * @return a reference to this parameters object
00143        */
00144       parameters& operator=(const parameters& other);
00145 
00146       /**
00147        * Returns the name of this type.
00148        */
00149       virtual const std::string& name() const;
00150 
00151       /**
00152        * returns a pointer to a clone of the parameters
00153        */
00154       virtual parameters* clone() const;
00155 
00156       /**
00157        * returns a pointer to a new instance of the parameters
00158        */
00159       virtual parameters* newInstance() const;
00160 
00161       /**
00162        * write the parameters in the given ioHandler
00163        * @param handler the ioHandler to be used
00164        * @param complete if true (the default) the enclosing begin/end will
00165        *        be also written, otherwise only the data block will be written.
00166        * @return true if write was successful
00167        */
00168       virtual bool write(ioHandler& handler, const bool complete=true) const;
00169 
00170       /**
00171        * read the parameters from the given ioHandler
00172        * @param handler the ioHandler to be used
00173        * @param complete if true (the default) the enclosing begin/end will
00174        *        be also written, otherwise only the data block will be written.
00175        * @return true if write was successful
00176        */
00177       virtual bool read(ioHandler& handler, const bool complete=true);
00178 
00179       // ------------------------------------------------
00180       // the parameters
00181       // ------------------------------------------------
00182 
00183       /**
00184        * Interpolation type to be used.
00185        *
00186        * Default: Bicubic
00187        */
00188       eInterpolationKernelType kernelType;
00189 
00190       /**
00191        * Number of samples in the interpolation table for a unit interval.
00192        *
00193        * The total number of elements in the LUT will be this value multiplied
00194        * by the number of unit intervals of the interpolation kernel.
00195        *
00196        * Default value: 256
00197        */
00198       int numSamplesPerInterval;
00199 
00200       /**
00201        * Generic interpolation kernel.
00202        *
00203        * If the kernelType is GenericKernel then this kernel LUT will be used.
00204        * To be a valid kernel, this vector must have a size \a n times
00205        * numSamplesPerInterval, with \a n even.  If the validity of the
00206        * kernel LUT cannot be confirmed, a Bilinear Kernel will be used
00207        * instead, but setParameters will return false.
00208        *
00209        * Default value: empty kernel
00210        */
00211       fvector kernelLUT;
00212     };
00213 
00214     /**
00215      * default constructor
00216      */
00217     genericInterpolation();
00218 
00219     /**
00220      * Construct an interpolator with the given parameters
00221      */
00222     genericInterpolation(const parameters& params);
00223 
00224     /**
00225      * Construct an interpolator with the given boundary type
00226      */
00227     genericInterpolation(const eBoundaryType boundaryType);
00228 
00229     /**
00230      * copy constructor
00231      * @param other the object to be copied
00232      */
00233     genericInterpolation(const genericInterpolation<T>& other);
00234 
00235     /**
00236      * destructor
00237      */
00238     virtual ~genericInterpolation();
00239 
00240     /**
00241      * Returns the interpolated value of the vector at the real valued
00242      * position x.
00243      * @param src vector<T> with the source data.
00244      * @param x the real valued position to be interpolated.
00245      * @return the interpolated value of the vector.
00246      */
00247     T apply(const vector<T>& src,const float& x) const;
00248 
00249     /**
00250      * Returns the interpolated value of the vector specified with
00251      * use() at the real valued position x.
00252      * @param x the real valued position to be interpolated.
00253      * @return the interpolated value of the vector.  */
00254     T apply(const float& x) const;
00255 
00256     /**
00257      * Returns the interpolated value of the matrix at the real valued
00258      * position (row,col).
00259      *
00260      * @param src matrix<T> with the source data.
00261      * @param row which row
00262      * @param col which column
00263      * @return the interpolated value of the matrix.
00264      */
00265     T apply(const matrix<T>& src,
00266             const float& row,
00267             const float& col) const;
00268 
00269     /**
00270      * Returns the interpolated value of the matrix at the real valued
00271      * position p.
00272      *
00273      * @param src matrix<T> with the source data.
00274      * @param p the real valued position to be interpolated.
00275      * @return the interpolated value of the matrix.
00276      */
00277     T apply(const matrix<T>& src,const fpoint& p) const;
00278 
00279     /**
00280      * Returns the interpolated value of the matrix specified with
00281      * use() at the real valued position (row,col).
00282      *
00283      * @param row which row
00284      * @param col which column
00285      * @return the interpolated value of the matrix.  */
00286     T apply(const float& row, const float& col) const;
00287 
00288     /**
00289      * Returns the interpolated value of the matrix specified with
00290      * use() at the real valued position p.
00291      *
00292      * @param p the real valued position to be interpolated.
00293      * @return the interpolated value of the matrix.
00294      */
00295     T apply(const fpoint& p) const;
00296 
00297     /**
00298      * Returns the interpolated value of the matrix at the real valued
00299      * position (row,col).  This method is not virtual and can be used
00300      * if this interpolation type is used as template parameter in time
00301      * critical situations
00302      *
00303      * @param src matrix<T> with the source data.
00304      * @param row which row
00305      * @param col which column
00306      * @return the interpolated value of the matrix.
00307      */
00308     T interpolate(const matrix<T>& src,
00309                   const float row,
00310                   const float col) const;
00311 
00312     /**
00313      * Returns the interpolated value of the matrix specified with
00314      * use() at the real valued position (row,col).  This method is
00315      * not virtual and can be used if this interpolation type is used
00316      * as template parameter in time critical situations
00317      *
00318      * @param row which row
00319      * @param col which column
00320      * @return the interpolated value of the matrix.
00321      */
00322     inline T interpolate(const float row, const float col) const;
00323 
00324     /**
00325      * Returns the interpolated value of the matrix at the real valued
00326      * position (row,col).
00327      *
00328      * This method does not check if the given coordinates and the rest of
00329      * used points in the src matrix lie within the valid range.  This is
00330      * left to you.  Please consider that for the generic interpolation
00331      * not only the point(trunc(col),trunc(row)) is used, but a nxn
00332      * neighborhood centered such that (col,row) is nearest to the center.
00333      *
00334      * This method is not virtual and can be used in time critical situations,
00335      * where you prefer to take the boundary control by yourself.
00336      *
00337      * @param src matrix<T> with the source data.
00338      * @param row which row
00339      * @param col which column
00340      * @return the interpolated value of the matrix.
00341      */
00342     inline T interpolateUnchk(const matrix<T>& src,
00343                               const float row,
00344                               const float col) const;
00345 
00346     /**
00347      * Returns the interpolated value of the matrix specified with
00348      * use() at the real valued position (row,col).  This method is
00349      * not virtual and can be used if this interpolation type is used
00350      * as template parameter in time critical situations
00351      *
00352      * @param row which row
00353      * @param col which column
00354      * @return the interpolated value of the matrix.
00355      */
00356     inline T interpolateUnchk(const float row,
00357                               const float col) const;
00358 
00359     /**
00360      * copy data of "other" functor.
00361      * @param other the functor to be copied
00362      * @return a reference to this functor object
00363      */
00364     genericInterpolation& copy(const genericInterpolation& other);
00365 
00366     /**
00367      * Alias for copy member
00368      * @param other the functor to be copied
00369      * @return a reference to this functor object
00370      */
00371     genericInterpolation<T>& operator=(const genericInterpolation<T>& other);
00372 
00373     /**
00374      * Returns the name of this type.
00375      */
00376     virtual const std::string& name() const;
00377 
00378     /**
00379      * returns a pointer to a clone of this functor.
00380      */
00381     virtual genericInterpolation* clone() const;
00382 
00383     /**
00384      * returns a pointer to a new instance of this functor.
00385      */
00386     virtual genericInterpolation* newInstance() const;
00387 
00388     /**
00389      * returns used parameters
00390      */
00391     const parameters& getParameters() const;
00392 
00393     /**
00394      * returns used parameters
00395      */
00396     virtual bool updateParameters();
00397 
00398 
00399     /**
00400      * This method returns which pixel range around the interpolated postition
00401      * is considered by the interpolation functor.
00402      *
00403      * This is very useful for other functors to decide whether they should
00404      * call the interpolate() methods or the faster interpolateUnchk() methods.
00405      *
00406      * If the returned value is \f$a\f$ and the interpolated position is
00407      * \f$(x,y)\f$ all pixels with coordinates in
00408      * \f$ [x-a .. x+a] \times [y-a .. y+a] \f$
00409      * may be considered by the interpolation functor.
00410      */
00411     int getRangeOfInfluence() const;
00412 
00413 
00414     /**
00415      * Return a read only reference to the last computed LUT.
00416      *
00417      * This method is mainly used for debugging purposes.
00418      */
00419     inline const vector<float>& getLUT() const;
00420 
00421     /**
00422      * Compute the generic interpolated value for the given coefficients
00423      * and values.
00424      *
00425      * This method is provided for convenience only.  Use at your own
00426      * risk.
00427      *
00428      * @param fx fractional term between 0.0f (inclusive) and 1.0f (exclusive)
00429      * @param data pointer to an array with the support samples.  It has at
00430      *             least \a n elements, with \a n the number of unit intervals
00431      *             in the interpolation kernel.
00432      *             Their position will be assumed to be from
00433      *             -(n/2-1) to n/2, so that the
00434      *             interval 0..1 lies exaclty in the middle.
00435      *
00436      * @return interpolated value between the three values
00437      */
00438     inline T compute(const float fx,const T* data) const;
00439 
00440     /**
00441      * Compute the generic interpolated value for the given coefficients
00442      * and values.
00443      *
00444      * This method is provided for convenience only.  Use at your own
00445      * risk.
00446      *
00447      * @param fy fractional term between 0.0 and 1.0
00448      * @param fx fractional term between 0.0 and 1.0
00449      * @param data pointer to an array of arrays with the support samples.
00450      *
00451      * @return interpolated value between the four corners
00452      */
00453     inline T compute(const float fy,
00454                      const float fx,
00455                      const T** data) const;
00456 
00457   protected:
00458     /**
00459      * range of influence
00460      */
00461     int rangeOfInfluence_;
00462 
00463     /**
00464      * The interpolation kernel is traversed in revers order than
00465      * the data.  To save the first computation time, we store the
00466      * sample index for the first element of the last interval
00467      */
00468     int lastIntervalFirstSample_;
00469 
00470     /**
00471      * Number of intervals really used.
00472      *
00473      * The value given in the parameters might be ignored depending on the
00474      * chosen kernel type.
00475      */
00476     int numberOfIntervals_;
00477 
00478     /**
00479      * This is the number that need to be substracted  to a position point
00480      * to get the first valid support sample.
00481      * It is usually numberOfIntervals/2 - 1;
00482      */
00483     int firstSampleOffset_;
00484 
00485     /**
00486      * Interval size taken from the parameters numSamplesPerInterval;
00487      */
00488     int intervalSize_;
00489 
00490     /**
00491      * @name Buffers
00492      */
00493     /**
00494      * For the two dimensional interpolation, this vector will administrate
00495      * the memory array required.
00496      */
00497     vector<T> column_;
00498 
00499     /**
00500      * This pointer will always point to the first element of column
00501      */
00502     T* firstElemColumn_;
00503 
00504     /**
00505      * This is a small window that can be used to save temporarily the
00506      * sample supporting points
00507      */
00508     mutable matrix<T> buffer_;
00509 
00510     /**
00511      * This pointer to arrays is initialized to have the proper size, but
00512      * you have to set the second pointers by yourself
00513      */
00514     mutable const T** rows_;
00515 
00516     /**
00517      * This is initialized to point a the buffer's rows.
00518      */
00519     const T** bufferRows_;
00520 
00521     //@}
00522 
00523     /**
00524      * @name Kernel initialization routines
00525      */
00526     //@{
00527     /**
00528      * Interpolation kernel.
00529      *
00530      * This is initialized by the initLUT
00531      */
00532     vector<float> interpolationKernel_;
00533 
00534     /**
00535      * Initialize the interpolation kernel LUT based on the parameters
00536      * settings.
00537      *
00538      * The LUT has only positive entries, but represents the interval from
00539      * -halfSize+1 to halfSize.  No use of the symmetrical properties of the
00540      * kernel are exploited to improve efficiency, since less comparisons are
00541      * required.
00542      */
00543     bool initLUT();
00544 
00545     /**
00546      * Initialization of the bilinear kernel.
00547      * Two unit intervals wlll be initialized.
00548      */
00549     bool initBilinearLUT();
00550 
00551     /**
00552      * Initialization of the bicubic kernel.
00553      * Four unit intervals wlll be initialized.
00554      * The kernel provided here is after Sonka et.al. page 67:
00555      * \code
00556      *           /
00557      *          |  1-2|x|^2 + |x|^3           for 0<=x<=1
00558      *  h(x) = <   4-8|x|^2 + 5|x|^2 - |x|^3  for 1<x<=2
00559      *          |  0                          otherwise
00560      *           \
00561      * \endcode
00562      */
00563     bool initBicubicLUT();
00564 
00565     /**
00566      * Generic kernel initialization.
00567      *
00568      * This method checks that the kernelLUT in the parameters is a valid
00569      * kernel and sets all required attributes.
00570      */
00571     bool initGenericLUT();
00572 
00573     //@}
00574   };
00575 }
00576 
00577 #include "cvrGenericInterpolation_inline.h"
00578 
00579 #endif
00580 

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