last update 20 Sep 2009 |
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