LTI-Lib latest version v1.9 - last update 10 Apr 2010

ltiQmf.h

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

Generated on Sat Apr 10 15:26:00 2010 for LTI-Lib by Doxygen 1.6.1