latest version v1.9 - last update 10 Apr 2010 |
00001 /* 00002 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006 00003 * Lehrstuhl fuer Technische Informatik, RWTH-Aachen, Germany 00004 * 00005 * This file is part of the LTI-Computer Vision Library (LTI-Lib) 00006 * 00007 * The LTI-Lib is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public License (LGPL) 00009 * as published by the Free Software Foundation; either version 2.1 of 00010 * the License, or (at your option) any later version. 00011 * 00012 * The LTI-Lib is distributed in the hope that it will be 00013 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty 00014 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with the LTI-Lib; see the file LICENSE. If 00019 * not, write to the Free Software Foundation, Inc., 59 Temple Place - 00020 * Suite 330, Boston, MA 02111-1307, USA. 00021 */ 00022 00023 00024 /*---------------------------------------------------------------- 00025 * project ....: LTI Digital Image/Signal Processing Library 00026 * file .......: ltiQmf.h 00027 * authors ....: Pablo Alvarado 00028 * organization: LTI, RWTH Aachen 00029 * creation ...: 14.12.2000 00030 * revisions ..: $Id: ltiQmf.h,v 1.10 2006/02/08 11:41:47 ltilib Exp $ 00031 */ 00032 00033 #ifndef _LTI_QMF_H_ 00034 #define _LTI_QMF_H_ 00035 00036 #include "ltiFilter.h" 00037 #include "ltiLinearKernels.h" 00038 #include "ltiImage.h" 00039 #include "ltiTree.h" 00040 00041 namespace lti { 00042 /** 00043 * This class implements dyadic wavelet-transform as quadrature mirror 00044 * filters. 00045 * The original paper which describes this method is: 00046 * S. G. Mallat, "A theory for multiresolution signal decomposition: The 00047 * wavelet representation", In: IEEE Transactions on Pattern Analysis and 00048 * Machine Intelligence, 11(7), 1989, pp. 674-693. 00049 * 00050 * It can be used with separable filters only, and that's why only 00051 * 1D kernels are allowed in the parameters class. (see 00052 * lti::haarKernel, lti::tap9Symmetric, lti::daubechies16Kernel, 00053 * lti::battleLemarieKernel) 00054 * 00055 * Due to the extreme high dynamic in the resulting channels, this only 00056 * makes sense to be applied on lti::channel's 00057 * The reason for this class to be a lti::filter and not a 00058 * lti::transform is due to the fact that this %functor is %sort of 00059 * special %convolution, and it shares the same %parameters that all 00060 * the other filters, particularly the 00061 * lti::modifier::parameters::boundaryType is used. 00062 * For the inverse transformation see lti::qmfInverse 00063 */ 00064 class qmf : public filter { 00065 public: 00066 /** 00067 * the parameters for the class qmf 00068 */ 00069 class parameters : public filter::parameters { 00070 public: 00071 /** 00072 * default constructor 00073 */ 00074 parameters(); 00075 00076 /** 00077 * copy constructor 00078 * @param other the parameters object to be copied 00079 */ 00080 parameters(const parameters& other); 00081 00082 /** 00083 * destructor 00084 */ 00085 ~parameters(); 00086 00087 /** 00088 * returns name of this type 00089 */ 00090 const char* getTypeName() const; 00091 00092 /** 00093 * copy the contents of a parameters object 00094 * @param other the parameters object to be copied 00095 * @return a reference to this parameters object 00096 */ 00097 parameters& copy(const parameters& other); 00098 00099 /** 00100 * copy the contents of a parameters object 00101 * @param other the parameters object to be copied 00102 * @return a reference to this parameters object 00103 */ 00104 parameters& operator=(const parameters& other); 00105 00106 /** 00107 * returns a pointer to a clone of the parameters 00108 */ 00109 virtual functor::parameters* clone() const; 00110 00111 /** 00112 * returns the kernel in use. If it is not set yet, an 00113 * lti::invalidParameters exception will be thrown 00114 * @return a const reference to the filter kernel. 00115 */ 00116 const mathObject& getKernel() const; 00117 00118 /** 00119 * sets the filter kernel to be used. 00120 * A copy of the given %parameter will be made! 00121 * @param aKernel the filter kernel to be used 00122 * 00123 * Note that the expected parameter is a filter kernel and NOT the 00124 * wavelet coefficients. Remember that the kernel can be constructed 00125 * by mirroring the wavelet coefficients. This kernel is also the 00126 * low-pass kernel h(k). The high-pass kernel g(k) will be constructed 00127 * using the fact that g(k)=(-1)^k h(1-k) 00128 */ 00129 void setKernel(const mathObject& aKernel); 00130 00131 /** 00132 * write the parameters in the given ioHandler 00133 * @param handler the ioHandler to be used 00134 * @param complete if true (the default) the enclosing begin/end will 00135 * be also written, otherwise only the data block will be written. 00136 * @return true if write was successful 00137 */ 00138 virtual bool write(ioHandler& handler,const bool complete=true) const; 00139 00140 /** 00141 * write the parameters in the given ioHandler 00142 * @param handler the ioHandler to be used 00143 * @param complete if true (the default) the enclosing begin/end will 00144 * be also written, otherwise only the data block will be written. 00145 * @return true if write was successful 00146 */ 00147 virtual bool read(ioHandler& handler,const bool complete=true); 00148 00149 # ifdef _LTI_MSC_6 00150 /** 00151 * this function is required by MSVC only, as a workaround for a 00152 * very awful bug, which exists since MSVC V.4.0, and still by 00153 * V.6.0 with all bugfixes (so called "service packs") remains 00154 * there... This method is also public due to another bug, so please 00155 * NEVER EVER call this method directly: use read() instead 00156 */ 00157 bool readMS(ioHandler& handler,const bool complete=true); 00158 00159 /** 00160 * this function is required by MSVC only, as a workaround for a 00161 * very awful bug, which exists since MSVC V.4.0, and still by 00162 * V.6.0 with all bugfixes (so called "service packs") remains 00163 * there... This method is also public due to another bug, so please 00164 * NEVER EVER call this method directly: use write() instead 00165 */ 00166 bool writeMS(ioHandler& handler,const bool complete=true) const; 00167 # endif 00168 00169 // ------------------------------------------------ 00170 // the parameters 00171 // ------------------------------------------------ 00172 00173 /** 00174 * The kernel is the 1D low-pass filter, which must hold several 00175 * conditions: 00176 * 00177 * Let H(w) be the Fourier-Transformation of the kernel: 00178 * 00179 * |H(0)| = 1; 00180 * kernel[n] = O(n^-2) for n->infinity 00181 * |H(w)|^2 + |H(w+Pi)|^2 = 1; 00182 * The high-pass filter g(n) can be calculated from the kernel as: 00183 * g(n) = (-1)^n kernel[1-k] 00184 * 00185 * The LTI-Lib has some usual kernel predefined: 00186 * @see lti::tap9Symmetric, lti::battleLemarieKernel, 00187 * lti::daubechies16Kernel, lti::haarKernel 00188 * 00189 * The default kernel is the 9-Tap Symetric kernel 00190 */ 00191 kernel1D<float> kernel; 00192 00193 /** 00194 * How many levels must have the result. This value should be >= 1 00195 * For 1, the original channel will be returned 00196 * Default value: 3 00197 */ 00198 int levels; 00199 }; 00200 00201 /** 00202 * default constructor 00203 */ 00204 qmf(); 00205 00206 /** 00207 * Constructor with parameters 00208 */ 00209 qmf(const parameters& par); 00210 00211 /** 00212 * copy constructor 00213 * @param other the object to be copied 00214 */ 00215 qmf(const qmf& other); 00216 00217 /** 00218 * destructor 00219 */ 00220 virtual ~qmf(); 00221 00222 /** 00223 * returns the name of this type ("qmf") 00224 */ 00225 virtual const char* getTypeName() const; 00226 00227 /** 00228 * operates on the given %parameter. 00229 * @param srcdest channel with the source data. The result 00230 * will be left here too. 00231 * @return true if successful, false otherwise. 00232 */ 00233 bool apply(vector<float>& srcdest); 00234 00235 /** 00236 * operates on a copy of the given %parameters. 00237 * @param src vector with the source data. 00238 * @param dest vector where the result will be left. 00239 * @return true if successful, false otherwise. 00240 */ 00241 bool apply(const vector<float>& src,vector<float>& dest); 00242 00243 /** 00244 * operates on the given %parameter. 00245 * @param srcdest channel with the source data. The result 00246 * will be left here too. 00247 * @return true if successful, false otherwise. 00248 */ 00249 bool apply(channel& srcdest); 00250 00251 /** 00252 * operates on a copy of the given %parameters. 00253 * @param src channel with the source data. 00254 * @param dest channel where the result will be left. 00255 * @return true if successful, false otherwise. 00256 */ 00257 bool apply(const channel& src,channel& dest); 00258 00259 /* 00260 * return the result as a tree, where only the first child at each 00261 * level can have more children. The second child results from the 00262 * low-pass at Y and high-pass at X. The third child results from the 00263 * high-pass at X and Y. The fourth child is created with the low-pass at 00264 * X and high-pass at Y. 00265 * @param src channel with the source data. 00266 * @param dest channel where the result will be left. 00267 * @return true if successful, false otherwise. 00268 */ 00269 //bool apply(const channel& src,tree<channel>& dest) const; 00270 00271 00272 /** 00273 * generate the appropriate high-pass kernel which correponds to the 00274 * low-pass kernel given as argument. Please note that a low-pass KERNEL 00275 * is expected an NOT the corresponding wavelet coefficients. 00276 * @param src the original kernel, which should be a low-pass kernel. 00277 * @param hpk the kernel where the resulting high-pass kernel will be 00278 * left. 00279 */ 00280 void generateHighPassKernel(const kernel1D<float>& src, 00281 kernel1D<float>& hpk) const; 00282 00283 /** 00284 * copy data of "other" functor. 00285 * @param other the functor to be copied 00286 * @return a reference to this functor object 00287 */ 00288 qmf& copy(const qmf& other); 00289 00290 /** 00291 * returns a pointer to a clone of this functor. 00292 */ 00293 virtual functor* clone() const; 00294 00295 /** 00296 * returns used parameters 00297 */ 00298 const parameters& getParameters() const; 00299 00300 /** 00301 * returns a vector of points with the bottom-left coordinates of 00302 * each band. The first element of the vector will correspond to 00303 * the last valid indices of the original vector/image. The 00304 * second one will be the first one divided by two, and so on. If 00305 * the last apply was made for vectors, the 'y' component of the 00306 * points will be zero. 00307 */ 00308 const vector<point>& getLastPartitioning() const; 00309 00310 protected: 00311 00312 vector<point> lastPartitioning; 00313 00314 private: 00315 /** 00316 * convolution algorithms (private classes of lti::qmf) 00317 * The type T is the type of the elements of the object to be filtered 00318 * The (optional) type U is the type of the accumulator variable for 00319 * the filter. 00320 */ 00321 template <class T,class U> 00322 class convolve { 00323 public: 00324 /** 00325 * default constructor 00326 */ 00327 convolve(); 00328 00329 /** 00330 * default constructor 00331 */ 00332 convolve(const kernel1D<T>& kern); 00333 00334 /** 00335 * accumulates src*filter in result 00336 */ 00337 inline void accumulate(const T& filter,const T& src, U& result); 00338 00339 /** 00340 * get the result with the proper typecasting and normalization 00341 */ 00342 inline T getResult(const U& result); 00343 00344 /** 00345 * set normalization 00346 */ 00347 inline void setNorm(const T& theNorm); 00348 00349 /** 00350 * generate the appropriate high-pass kernel which correponds to the 00351 * low-pass kernel given as argument. Please note that a low-pass KERNEL 00352 * is expected an NOT the corresponding wavelet coefficients. 00353 * @param src the original kernel, which should be a low-pass kernel. 00354 * @param hpk the kernel where the resulting high-pass kernel will be 00355 * left. 00356 */ 00357 void generateHighPassKernel(const kernel1D<T>& src, 00358 kernel1D<T>& hpk) const; 00359 00360 protected: 00361 /** 00362 * normalization constant. Taken from filter kernel 00363 */ 00364 T norm; 00365 00366 /** 00367 * the low-pass filter kernel 00368 */ 00369 kernel1D<T> lpKernel; 00370 00371 /** 00372 * the high-pass filter kernel 00373 */ 00374 kernel1D<T> hpKernel; 00375 }; 00376 00377 /** 00378 * convolution algorithm for a vector * kernel1D 00379 * The type T is the type of the elements of the vector and kernel1D 00380 * The type U is the type of the accumulator variable for 00381 * the filter. 00382 */ 00383 template <class T,class U> 00384 class convolve1D : public convolve<T,U> { 00385 public: 00386 /** 00387 * default constructor 00388 */ 00389 convolve1D(const kernel1D<T>& kern); 00390 00391 /** 00392 * destructor 00393 */ 00394 ~convolve1D(); 00395 00396 /** 00397 * convolves the vector src with the filter kernel and 00398 * leaves the result in dest. 00399 * 00400 * Consistency checks should be done by the apply methods! 00401 * 00402 * @param src vector to be filtered 00403 * @param kern filter kernel 00404 * @param dest destination vector for the result 00405 */ 00406 void apply(const vector<T>& src, 00407 const int& from, 00408 const int& to, 00409 vector<T>& dest, 00410 const qmf::parameters& param); 00411 00412 /** 00413 * convolves the columns of matrix src with the filter kernel and 00414 * leaves the result in dest. 00415 * 00416 * Consistency checks should be done by the apply methods! 00417 * 00418 * @param src matrix to be filtered 00419 * @param kern filter kernel 00420 * @param dest destination matrix for the result 00421 * 00422 * @param allLines if true, all lines will be filtered, otherwise only 00423 * the lines needed for the downsampling specified in the 00424 * parameters will be filtered 00425 */ 00426 void applyCol(const matrix<T>& src, 00427 const rectangle& area, 00428 matrix<T>& dest, 00429 const qmf::parameters& param); 00430 00431 /** 00432 * convolves the rows of matrix src with the filter kernel and 00433 * leaves the result in dest. 00434 * 00435 * Consistency checks should be done by the apply methods! 00436 * 00437 * @param src matrix to be filtered 00438 * @param kern filter kernel 00439 * @param dest destination matrix for the result 00440 */ 00441 void applyRow(const matrix<T>& src, 00442 const rectangle& area, 00443 matrix<T>& dest, 00444 const qmf::parameters& param); 00445 00446 /** 00447 * set the initialization flag 00448 */ 00449 void reinitialize(); 00450 00451 protected: 00452 00453 /** 00454 * initialize boundaries flag. If true, the flags will be initialized 00455 * otherwise the last calculations will be assumed to be right! 00456 */ 00457 bool initialize; 00458 00459 /** 00460 * size of the block being filtered 00461 */ 00462 int blockSize; 00463 00464 /** 00465 * position of the first element belonging to the high-pass band 00466 */ 00467 int boundary; 00468 00469 /** 00470 * @name indices 00471 * indices for the middle data block, where the filter kernel can be 00472 * applied without boundary problems 00473 */ 00474 //@{ 00475 /** 00476 * begin of low-pass middle block 00477 */ 00478 int lbegin; 00479 00480 /** 00481 * begin of high-pass middle block 00482 */ 00483 int hbegin; 00484 00485 /** 00486 * flag to indicate that the low-pass border was fix to fit downsampling 00487 * factor 00488 */ 00489 bool lpfixed; 00490 00491 /** 00492 * flag to indicate that the high-pass border was fix to fit downsampling 00493 * factor 00494 */ 00495 bool hpfixed; 00496 00497 /** 00498 * end of low-pass middle block 00499 */ 00500 int lend; 00501 00502 /** 00503 * end of high-pass middle block 00504 */ 00505 int hend; 00506 00507 /** 00508 * begin of middle block 00509 */ 00510 int begin; 00511 00512 /** 00513 * end of middle block 00514 */ 00515 int end; 00516 //@} 00517 00518 }; 00519 00520 00521 }; 00522 } 00523 00524 #endif