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

ltiConvolution.h

00001 /*
00002  * Copyright (C) 1999, 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 .......: ltiConvolution.h
00027  * authors ....: Pablo Alvarado
00028  * organization: LTI, RWTH Aachen
00029  * creation ...: 19.04.99
00030  * revisions ..: $Id: ltiConvolution.h,v 1.14 2006/02/07 18:41:04 ltilib Exp $
00031  */
00032 
00033 #ifndef _LTI_CONVOLUTION_H_
00034 #define _LTI_CONVOLUTION_H_
00035 
00036 #include <vector>
00037 #include "ltiFilter.h"
00038 #include "ltiArray.h"
00039 #include "ltiMatrix.h"
00040 #include "ltiTypes.h"
00041 #include "ltiLinearKernels.h"
00042 
00043 namespace lti {
00044   /**
00045    * Convolution %functor.
00046    *
00047    * This functor convolves a %filter kernel (given in the
00048    * convolution::parameters) with a vector or matrix.
00049    *
00050    * The kernel must be have of the kernel types provided by the library:
00051    * - lti::kernel1D<T> if you want to filter vectors
00052    * - lti::kernel2D<T> for non-separable kernels (to filter channels)
00053    * - lti::sepKernel<T> for separable kernels (to filter channels)
00054    *
00055    * @see lti::gaussKernel1D, lti::gaussKernel2D, lti::gaborKernel
00056    *
00057    * Even if the setKernel() method accepts lti::mathObject objects, only
00058    * the previous ones are accepted.
00059    *
00060    * In the normal case, the type of the filter kernel has to be the
00061    * same as the type of the channel (or matrix) to be filter.  For
00062    * example, if you want to filter a channel (of floats) you will
00063    * require a kernel of floats.
00064    *
00065    * If you try to use different types for the kernel and the matrix, this
00066    * functor will try to cast the kernel to the proper type first (and this
00067    * will take some time).
00068    *
00069    * For the convolution of kernels and matrices (or channels) of
00070    * fixed point types (e.g. channel8), you must make use of the norm-term in
00071    * the kernel. (see kernel1D<T>::norm).
00072    *
00073    * \b Note that the convolution with sepKernels that are symmetric,
00074    * e.g gaussKernel2D or anti-symmetric like the gradient part of
00075    * sobelKernelX is optimized. It is assumed (by definition) that the
00076    * middle element of an anti-symmetric kernel is 0.
00077    *
00078    * @ingroup gLinearFilters
00079    *
00080    * Example using a gaussian kernel
00081    *
00082    * \code
00083    * // the channel to be filtered:
00084    * lti::channel data,result;
00085    *
00086    * // ... initialize channel here ...
00087    *
00088    * // gauss filter kernel with dimensions 5x5, and a variance of 1.3
00089    * lti::gaussKernel2D<lti::channel::value_type> kernel(5,1.3);
00090    *
00091    * lti::convolution filter;                        // convolution operator
00092    * lti::convolution::parameters param;             // parameters
00093    * param.setKernel(kernel);                        // use the gauss kernel
00094    * filter.setParameters(param);                    // use given parameters
00095    *
00096    * // filter the channel and leave the result there too
00097    * filter.apply(data);
00098    * \endcode
00099    *
00100    * You can also create the functor with a given filter kernel:
00101    *
00102    * \code
00103    * lti::convolution filter(lti::gaussKernel2D<lti::channel::value_type>(5,1.3);
00104    * filter.apply(data); // parameters already set in the constructor!
00105    * \endcode
00106    *
00107    * The filter kernel can also be change, changing the parameters or with
00108    * the shortcut setKernel():
00109    *
00110    * \code
00111    * param.setKernel(anotherKernel);
00112    * filter.setParamters(param);
00113    *
00114    * // this is equivalent to:
00115    *
00116    * filter.setKernel(anotherKernel);
00117    *
00118    * \endcode 
00119    */
00120   class convolution : public filter {
00121   public:
00122     /**
00123      * parameters of the lti::convolution functor
00124      */
00125     class parameters : public filter::parameters {
00126     public:
00127       /**
00128        * default constructor
00129        */
00130       parameters();
00131 
00132       /**
00133        * copy constructor
00134        * @param other the parameters object to be copied
00135        */
00136       parameters(const parameters& other);
00137 
00138       /**
00139        * destructor
00140        */
00141       virtual ~parameters();
00142 
00143       /**
00144        * returns name of this type
00145        */
00146       const char* getTypeName() const;
00147 
00148       /**
00149        * copy the contents of other parameter object
00150        * @param other the parameters object to be copied
00151        * @return a reference to this object
00152        */
00153       parameters& copy(const parameters& other);
00154 
00155       /**
00156        * returns a pointer to a clone of this parameters
00157        */
00158       virtual functor::parameters* clone() const;
00159 
00160       /**
00161        * returns the kernel in use.  If it is not set yet, an
00162        * lti::invalidParameters exception will be thrown
00163        * @return a const reference to the filter kernel.
00164        */
00165       const mathObject& getKernel() const;
00166 
00167       /**
00168        * sets the filter kernel to be used.
00169        * A copy of the given %parameter will be made!
00170        * @param aKernel the filter kernel to be used
00171        */
00172       void setKernel(const mathObject& aKernel);
00173 
00174       /**
00175        * write the parameters in the given ioHandler
00176        * @param handler the ioHandler to be used
00177        * @param complete if true (the default) the enclosing begin/end will
00178        *        be also written, otherwise only the data block will be written.
00179        * @return true if write was successful
00180        */
00181       virtual bool write(ioHandler& handler,const bool complete=true) const;
00182 
00183       /**
00184        * write the parameters in the given ioHandler
00185        * @param handler the ioHandler to be used
00186        * @param complete if true (the default) the enclosing begin/end will
00187        *        be also written, otherwise only the data block will be written.
00188        * @return true if write was successful
00189        */
00190       virtual bool read(ioHandler& handler,const bool complete=true);
00191 
00192 #     ifdef _LTI_MSC_6
00193       /**
00194        * this function is required by MSVC only, as a workaround for a
00195        * very awful bug, which exists since MSVC V.4.0, and still by
00196        * V.6.0 with all bugfixes (so called "service packs") remains
00197        * there...  This method is public due to another bug, so please
00198        * NEVER EVER call this method directly: use read() instead!
00199        */
00200       bool readMS(ioHandler& handler,const bool complete=true);
00201 
00202       /**
00203        * this function is required by MSVC only, as a workaround for a
00204        * very awful bug, which exists since MSVC V.4.0, and still by
00205        * V.6.0 with all bugfixes (so called "service packs") remains
00206        * there...  This method is public due to another bug, so please
00207        * NEVER EVER call this method directly: use write() instead!
00208        */
00209       bool writeMS(ioHandler& handler,const bool complete=true) const;
00210 #     endif
00211 
00212     protected:
00213       /**
00214        * pointer to the filter kernel copy
00215        */
00216       mathObject* kernel;
00217     };
00218 
00219     /**
00220      * default constructor
00221      */
00222     convolution();
00223 
00224     /**
00225      * default constructor with parameters
00226      */
00227     convolution(const parameters& par);
00228 
00229     /**
00230      * construct a convolution functor with a parameters set
00231      * which includes the given filter kernel.
00232      *
00233      * @param aKernel kernel object with which you want to convolve.
00234      * @param boundary Boundary assumption (Zero, Mirror, Periodic, Constant or
00235      *                 NoBoundary).  @see eBoundaryType
00236      */
00237     convolution(const mathObject& aKernel,
00238                 const eBoundaryType& boundary = Zero);
00239 
00240     /**
00241      * copy constructor
00242      * @param other the other functor to be copied
00243      */
00244     convolution(const convolution& other);
00245 
00246     /**
00247      * destructor
00248      */
00249     virtual ~convolution();
00250 
00251     /**
00252      * returns the name of this type
00253      */
00254     virtual const char* getTypeName() const;
00255 
00256     /**
00257      * operates on the given %parameter.
00258      * @param srcdest channel8 with the source data.  The result
00259      *                will be left here too.
00260      * @return true if successful, false otherwise.
00261      */
00262     bool apply(matrix<channel8::value_type>& srcdest) const;
00263 
00264     /**
00265      * operates on the given %parameter.
00266      * @param srcdest channel with the source data.  The result
00267      *                will be left here too.
00268      * @return true if successful, false otherwise.
00269      */
00270     bool apply(matrix<channel::value_type>& srcdest) const;
00271 
00272     /**
00273      * operates on the given %parameter.
00274      * @param srcdest dmatrix with the source data.  The result
00275      *                will be left here too.
00276      * @return true if successful, false otherwise.
00277      */
00278     bool apply(dmatrix& srcdest) const;
00279 
00280 
00281     /**
00282      * operates on the given %parameter.
00283      * @param srcdest vector<channel8::value_type> with the source data.
00284      *                The result will be left here too.
00285      * @return true if successful, false otherwise.
00286      */
00287     bool apply(vector<channel8::value_type>& srcdest) const;
00288 
00289     /**
00290      * operates on the given %parameter.
00291      * @param srcdest vector<channel::value_type> with the source data.
00292      *                The result will be left here too.
00293      * @return true if successful, false otherwise.
00294      */
00295     bool apply(vector<channel::value_type>& srcdest) const;
00296 
00297     /**
00298      * operates on the given %parameter.
00299      * @param srcdest dvector with the source data.
00300      *                The result will be left here too.
00301      * @return true if successful, false otherwise.
00302      */
00303     bool apply(dvector& srcdest) const;
00304 
00305 
00306     /**
00307      * operates on a copy of the given parameters.
00308      * @param src matrix<channel8::value_type> with the source data.
00309      * @param dest matrix<channel8::value_type> where the result will be left.
00310      * @return true if successful, false otherwise.
00311      */
00312     bool apply(const matrix<channel8::value_type>& src,
00313                matrix<channel8::value_type>& dest) const;
00314 
00315     /**
00316      * operates on a copy of the given parameters.
00317      * @param src matrix<channel::value_type> with the source data.
00318      * @param dest matrix<channel::value_type> where the result will be left.
00319      * @return true if successful, false otherwise.
00320      */
00321     bool apply(const matrix<channel::value_type>& src,
00322                matrix<channel::value_type>& dest) const;
00323 
00324     /**
00325      * operates on a copy of the given parameters.
00326      * @param src dmatrix with the source data.
00327      * @param dest dmatrix where the result will be left.
00328      * @return true if successful, false otherwise.
00329      */
00330     bool apply(const dmatrix& src,dmatrix& dest) const;
00331 
00332     /**
00333      * operates on a copy of the given parameters.
00334      * @param src vector<channel8::value_type> with the source data.
00335      * @param dest vector<channel8::value_type> where the result will be left.
00336      * @return true if successful, false otherwise.
00337      */
00338     bool apply(const vector<channel8::value_type>& src,
00339                      vector<channel8::value_type>& dest) const;
00340 
00341     /**
00342      * operates on a copy of the given parameters.
00343      * @param src vector<channel::value_type> with the source data.
00344      * @param dest vector<channel::value_type> where the result will be left.
00345      * @return true if successful, false otherwise.
00346      */
00347     bool apply(const vector<channel::value_type>& src,
00348                      vector<channel::value_type>& dest) const;
00349 
00350     /**
00351      * operates on a copy of the given parameters.
00352      * @param src dvector with the source data.
00353      * @param dest dvector where the result will be left.
00354      * @return true if successful, false otherwise.
00355      */
00356     bool apply(const dvector& src,
00357                      dvector& dest) const;
00358 
00359     /**
00360      * Split the given color image in its RGB components, filter each of them
00361      * (as lti::channel) and merge the results.
00362      * @param src image to be filtered.
00363      * @param dest resulting filtered image.
00364      * @return true if successful, false otherwise
00365      */
00366     bool apply(const image& src,
00367                      image& dest) const;
00368 
00369     /**
00370      * Split the given color image in its RGB components, filter each of them
00371      * (as lti::channel) and merge the results.
00372      * @param srcdest image to be filtered.  The result is left here too.
00373      * @return true if successful, false otherwise
00374      */
00375     bool apply(image& srcdest) const;
00376 
00377     /**
00378      * copy data of "other" functor.
00379      */
00380     convolution& copy(const convolution& other);
00381 
00382     /**
00383      * returns a pointer to a clone of the functor.
00384      */
00385     virtual functor* clone() const;
00386 
00387     /**
00388      * returns used parameters
00389      */
00390     const parameters& getParameters() const;
00391 
00392     /**
00393      * shortcut to set the filter kernel in the functor parameters.
00394      * The other parameters remain unchanged.
00395      */
00396     void setKernel(const mathObject& aKernel);
00397 
00398   private:
00399     /**
00400      * This is the accumulator class needed by the convolution helper to
00401      * act as a linear convolution operator for gray valued images.
00402      *
00403      * The type T is the type of the elements of the object to be filtered
00404      * The (optional) type U is the type of the accumulator variable for
00405      * the filter.
00406      */
00407     template<class T,class U=T>
00408     class accumulator {
00409     public:
00410       /**
00411        * Default constructor
00412        */
00413       accumulator();
00414 
00415       /**
00416        * Accumulate the values of filter and src
00417        */
00418       inline void accumulate(const T& filter,const T& src);
00419 
00420       /**
00421        * Accumulate the values of T(0) and src
00422        */
00423       inline void accumulateZero(const T& src);
00424 
00425       /**
00426        * Accumulate the values of filter and srcL and srcR
00427      * for symmetric filter kernel
00428      * src:       srcL  *  middle  *  srcR
00429      * filter:      *  *  *  middle  *  *  *
00430      * used filter part:  *  *  *  middle
00431        */
00432       inline void accumulateSym(const T& filter,const T& srcL,const T& srcR);
00433 
00434       /**
00435        * Accumulate the values of filter and src
00436      * for asymmetric filter kernel
00437      * src:       srcL  *  middle  *  srcR
00438      * filter:      *  *  *  middle  *  *  *
00439      * used filter part:  *  *  *  middle
00440        */
00441       inline void accumulateASym(const T& filter,const T& srcL,const T& srcR);
00442 
00443       /**
00444        * Get the state of the accumulator
00445        */
00446       inline T getResult() const;
00447 
00448       /**
00449        * Reset the state of the accumulator
00450        */
00451       inline void reset();
00452 
00453       /**
00454        * set norm
00455        */
00456       inline void setNorm(const T& norm);
00457 
00458     protected:
00459       /**
00460        * the accumulated value
00461        */
00462       U state;
00463 
00464       /**
00465        * norm
00466        */
00467       T norm;
00468     };
00469 
00470 
00471 
00472   };
00473 }
00474 
00475 #include "ltiConvolution_template.h"
00476 
00477 #endif

Generated on Sat Apr 10 15:25:17 2010 for LTI-Lib by Doxygen 1.6.1