latest version v1.9 - last update 10 Apr 2010 |
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