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 .......: ltiDownsampling.h 00027 * authors ....: Pablo Alvarado 00028 * organization: LTI, RWTH Aachen 00029 * creation ...: 11.5.2000 00030 * revisions ..: $Id: ltiDownsampling.h,v 1.12 2006/02/07 18:45:41 ltilib Exp $ 00031 */ 00032 00033 #ifndef _LTI_DOWNSAMPLING_H_ 00034 #define _LTI_DOWNSAMPLING_H_ 00035 00036 #include "ltiObject.h" 00037 #include "ltiFilter.h" 00038 #include "ltiLinearKernels.h" 00039 00040 namespace lti { 00041 /** 00042 * This functor is used to downsample images. 00043 * 00044 * Here, the process of downsampling means to first filter the image with 00045 * (usually) a low pass filter, and then take each n-th pixel, where n is an 00046 * integer number. 00047 * 00048 * The downsampling::parameters specify which kind of filter should be 00049 * used and which downsampling factor. If you do not want or need 00050 * to low-pass filter the image first, than take a look at lti::decimation. 00051 * 00052 * If you need to "downsample" an image with a non-integer factor take a look 00053 * to lti::scaling. 00054 * 00055 * @see lti::decimation, lti::upsampling, lti::filledUpsampling,lti::scaling 00056 * 00057 * @ingroup gLinearFilters 00058 * 00059 * Example: 00060 * \code 00061 * 00062 * #include "ltiDownsampling.h" 00063 * #include "ltiGaussKernel2D.h" 00064 * 00065 * lti::channel chnl1,chnl2; 00066 * 00067 * ... 00068 * 00069 * lti::downsampling downsampler; // downsampling functor 00070 * lti::downsampling::parameters param; // downsampling parameters 00071 * 00072 * // a gaussian kernel to use before the downsampling 00073 * lti::gaussKernel2D<lti::channel::value_type> gkernel; 00074 * 00075 * param.setKernel(gkernel); // use the gaussian kernel 00076 * 00077 * downsampler.setParameters(param); // use the given parameters 00078 * 00079 * downsampler.apply(chnl1,chnl2); // channel 1 will be downsampled an the 00080 * // result will be left on channel 2. 00081 * 00082 * \endcode 00083 */ 00084 class downsampling : public filter { 00085 public: 00086 /** 00087 * the parameters for the class downsampling 00088 */ 00089 class parameters : public filter::parameters { 00090 public: 00091 /** 00092 * default constructor 00093 */ 00094 parameters(); 00095 00096 /** 00097 * copy constructor 00098 * @param other the parameters object to be copied 00099 */ 00100 parameters(const parameters& other); 00101 00102 /** 00103 * destructor 00104 */ 00105 ~parameters(); 00106 00107 /** 00108 * returns name of this type 00109 */ 00110 const char* getTypeName() const; 00111 00112 /** 00113 * copy the contents of a parameters object 00114 * @param other the parameters object to be copied 00115 * @return a reference to this parameters object 00116 */ 00117 parameters& copy(const parameters& other); 00118 00119 /** 00120 * returns a pointer to a clone of the parameters 00121 */ 00122 virtual functor::parameters* clone() const; 00123 00124 /** 00125 * returns the kernel in use. If it is not set yet, an 00126 * lti::invalidParameters exception will be thrown 00127 * @return a const reference to the filter kernel. 00128 */ 00129 const mathObject& getKernel() const; 00130 00131 /** 00132 * sets the filter kernel to be used. 00133 * A copy of the given parameter will be made! 00134 * 00135 * Default value: see attribute lti::downsampling::parameters::kernel 00136 * @param aKernel the filter kernel to be used 00137 */ 00138 void setKernel(const mathObject& aKernel); 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 write(ioHandler& handler,const bool complete=true) const; 00148 00149 /** 00150 * write the parameters in the given ioHandler 00151 * @param handler the ioHandler to be used 00152 * @param complete if true (the default) the enclosing begin/end will 00153 * be also written, otherwise only the data block will be written. 00154 * @return true if write was successful 00155 */ 00156 virtual bool read(ioHandler& handler,const bool complete=true); 00157 00158 # ifdef _LTI_MSC_6 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 public due to another bug, so please 00164 * NEVER EVER call this method directly: use read() instead! 00165 */ 00166 bool readMS(ioHandler& handler,const bool complete=true); 00167 00168 /** 00169 * this function is required by MSVC only, as a workaround for a 00170 * very awful bug, which exists since MSVC V.4.0, and still by 00171 * V.6.0 with all bugfixes (so called "service packs") remains 00172 * there... This method is public due to another bug, so please 00173 * NEVER EVER call this method directly: use write() instead! 00174 */ 00175 bool writeMS(ioHandler& handler,const bool complete=true) const; 00176 # endif 00177 00178 /** 00179 * The filter to be used. 00180 * 00181 * This should be a separable kernel of the same type as the object 00182 * to be decimated, with only one filter pair. If not, some time will 00183 * be required to construct an adequate filter kernel! 00184 * 00185 * The default value for the kernel is a 3x3 separable kernel, with 00186 * row/column kernel of the form (0.25 0.5 0.25)x(0.25 0.5 0.25). 00187 */ 00188 mathObject* kernel; 00189 00190 /** 00191 * the downsampling factor 00192 * 00193 * Only the pixels with coordinates x=n*factor.x or y=m*factor.y, 00194 * (n and m integers) will be taken. 00195 * 00196 * The default value is (2,2). 00197 */ 00198 point factor; 00199 }; 00200 00201 /** 00202 * default constructor 00203 */ 00204 downsampling(); 00205 00206 /** 00207 * Constructor with parameters object 00208 */ 00209 downsampling(const parameters& par); 00210 00211 /** 00212 * create a downsampling functor with a parameter set which includes 00213 * the given filter kernel 00214 */ 00215 downsampling(const mathObject& aKernel); 00216 00217 /** 00218 * copy constructor 00219 * @param other the object to be copied 00220 */ 00221 downsampling(const downsampling& other); 00222 00223 /** 00224 * destructor 00225 */ 00226 virtual ~downsampling(); 00227 00228 /** 00229 * returns the name of this type ("downsampling") 00230 */ 00231 virtual const char* getTypeName() const; 00232 00233 /** 00234 * operates on the given parameter. 00235 * @param srcdest channel8 with the source data. The result 00236 * will be left here too. 00237 * @return true if successful, false otherwise. 00238 */ 00239 bool apply(channel8& srcdest) const; 00240 00241 /** 00242 * operates on the given parameter. 00243 * @param srcdest channel with the source data. The result 00244 * will be left here too. 00245 * @return true if successful, false otherwise. 00246 */ 00247 bool apply(matrix<float>& srcdest) const; 00248 00249 /** 00250 * operates on the given parameter. 00251 * @param srcdest dmatrix with the source data. The result 00252 * will be left here too. 00253 * @return true if successful, false otherwise. 00254 */ 00255 bool apply(dmatrix& srcdest) const; 00256 00257 /** 00258 * downsample a color image by splitting it into the RGB components, 00259 * downsampling each channel and merging the results 00260 * @param srcdest image with the source data. The result 00261 * will be left here too. 00262 * @return true if successful, false otherwise. 00263 */ 00264 bool apply(image& srcdest) const; 00265 00266 /** 00267 * operates on the given parameter. 00268 * @param srcdest vector<channel8::value_type> with the source data. 00269 * The result will be left here too. 00270 * @return true if successful, false otherwise. 00271 */ 00272 bool apply(vector<channel8::value_type>& srcdest) const; 00273 00274 /** 00275 * operates on the given parameter. 00276 * @param srcdest vector<channel::value_type> with the source data. 00277 * The result will be left here too. 00278 * @return true if successful, false otherwise. 00279 */ 00280 bool apply(vector<channel::value_type>& srcdest) const; 00281 00282 /** 00283 * operates on a copy of the given parameters. 00284 * @param src channel8 with the source data. 00285 * @param dest channel8 where the result will be left. 00286 * @return true if successful, false otherwise. 00287 */ 00288 bool apply(const channel8& src,channel8& dest) const; 00289 00290 /** 00291 * operates on a copy of the given parameters. 00292 * @param src channel with the source data. 00293 * @param dest channel where the result will be left. 00294 * @return true if successful, false otherwise. 00295 */ 00296 bool apply(const matrix<float>& src,matrix<float>& dest) const; 00297 00298 /** 00299 * operates on a copy of the given parameters. 00300 * @param src dmatrix with the source data. 00301 * @param dest dmatrix where the result will be left. 00302 * @return true if successful, false otherwise. 00303 */ 00304 bool apply(const dmatrix& src,dmatrix& dest) const; 00305 00306 /** 00307 * downsample a color image by splitting it into the RGB components, 00308 * downsampling each channel and merging the results 00309 * @param src image with the source data. 00310 * @param dest image where the result will be left. 00311 * @return true if successful, false otherwise. 00312 */ 00313 bool apply(const image& src,image& dest) const; 00314 00315 /** 00316 * operates on a copy of the given parameters. 00317 * @param src vector<channel8::value_type> with the source data. 00318 * @param dest vector<channel8::value_type> where the result will be left. 00319 * @return true if successful, false otherwise. 00320 */ 00321 bool apply(const vector<channel8::value_type>& src, 00322 vector<channel8::value_type>& dest) const; 00323 00324 /** 00325 * operates on a copy of the given parameters. 00326 * @param src vector<channel::value_type> with the source data. 00327 * @param dest vector<channel::value_type> where the result will be left. 00328 * @return true if successful, false otherwise. 00329 */ 00330 bool apply(const vector<channel::value_type>& src, 00331 vector<channel::value_type>& dest) const; 00332 00333 /** 00334 * copy data of "other" functor. 00335 * @param other the functor to be copied 00336 * @return a reference to this functor object 00337 */ 00338 downsampling& copy(const downsampling& other); 00339 00340 /** 00341 * returns a pointer to a clone of this functor. 00342 */ 00343 virtual functor* clone() const; 00344 00345 /** 00346 * returns used parameters 00347 */ 00348 const parameters& getParameters() const; 00349 00350 /** 00351 * shortcut to set the filter kernel 00352 * A copy of the given parameter will be made! 00353 * @param aKernel the filter kernel to be used 00354 */ 00355 void setKernel(const mathObject& aKernel); 00356 00357 private: 00358 /** 00359 * convolution algorithms (private classes of lti::downsampling) 00360 * The type T is the type of the elements of the object to be filtered 00361 * The (optional) type U is the type of the accumulator variable for 00362 * the filter. 00363 */ 00364 template <class T,class U> 00365 class convolve { 00366 protected: 00367 /** 00368 * accumulates src*filter in result 00369 */ 00370 inline void accumulate(const T& filter,const T& src, U& result); 00371 00372 /** 00373 * get the result with the proper typecasting and normalization 00374 */ 00375 inline T getResult(const U& result); 00376 00377 /** 00378 * set normalization 00379 */ 00380 inline void setNorm(const T& theNorm); 00381 00382 /** 00383 * normalization constant. Taken from filter kernel 00384 */ 00385 T norm; 00386 00387 }; 00388 00389 /** 00390 * convolution algorithm for a vector * kernel1D 00391 * The type T is the type of the elements of the vector and kernel1D 00392 * The (optional) type U is the type of the accumulator variable for 00393 * the filter. 00394 */ 00395 template <class T,class U> 00396 class convolve1D : public convolve<T,U> { 00397 public: 00398 /** 00399 * default constructor 00400 */ 00401 convolve1D(); 00402 00403 /** 00404 * destructor 00405 */ 00406 ~convolve1D(); 00407 00408 /** 00409 * try to get a Kernel from the parameters. 00410 * If it is not possible to get it, return false; 00411 * This will not copy the kernel, it just will keep a reference to it! 00412 * @param kern the mathObject with the kernel. 00413 * @return true if kernel could be set and false otherwise 00414 */ 00415 bool setKernel(const mathObject* kern); 00416 00417 /** 00418 * convolves the vector src with the filter kernel and 00419 * leaves the result in dest. 00420 * 00421 * Consistency checks should be done by the apply methods! 00422 * 00423 * @param src vector to be filtered 00424 * @param kern filter kernel 00425 * @param dest destination vector for the result 00426 */ 00427 void apply(const vector<T>& src, 00428 vector<T>& dest, 00429 const downsampling::parameters& param); 00430 00431 /** 00432 * convolves the columns 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 * @param allLines if true, all lines will be filtered, otherwise only 00442 * the lines needed for the downsampling specified in the 00443 * parameters will be filtered 00444 */ 00445 void applyCol(const matrix<T>& src, 00446 matrix<T>& dest, 00447 const downsampling::parameters& param); 00448 00449 /** 00450 * convolves the rows of matrix src with the filter kernel and 00451 * leaves the result in dest. 00452 * 00453 * Consistency checks should be done by the apply methods! 00454 * 00455 * @param src matrix to be filtered 00456 * @param kern filter kernel 00457 * @param dest destination matrix for the result 00458 */ 00459 void applyRow(const matrix<T>& src, 00460 matrix<T>& dest, 00461 const downsampling::parameters& param); 00462 00463 protected: 00464 const kernel1D<T>* kernel; 00465 00466 private: 00467 kernel1D<T>* tmpKernel; 00468 }; 00469 00470 /** 00471 * convolution algorithm for a matrix * kernel2D 00472 * The type T is the type of the elements of the vector an kernel1D 00473 * The (optional) type U is the type of the accumulator variable for 00474 * the filter. 00475 */ 00476 template <class T,class U=T> 00477 class convolve2D : public convolve<T,U> { 00478 public: 00479 /** 00480 * default constructor 00481 */ 00482 convolve2D(); 00483 00484 /** 00485 * destructor 00486 */ 00487 ~convolve2D(); 00488 00489 /** 00490 * try to get a Kernel from the parameters. 00491 * If it is not possible to get it, return false; 00492 * This will not copy the kernel, it just will keep a reference to it! 00493 * @param kern the mathObject with the kernel. 00494 * @return true if kernel could be set and false otherwise 00495 */ 00496 bool setKernel(const mathObject* kern); 00497 00498 /** 00499 * get kernel type 00500 */ 00501 inline bool isKernelSeparable() const; 00502 00503 /** 00504 * convolves the matrix src with the filter kernel and 00505 * leaves the result in dest. 00506 * 00507 * Consistency checks should be done by the apply methods! 00508 * 00509 * @param src matrix to be filtered 00510 * @param kern filter kernel 00511 * @param dest result 00512 */ 00513 void apply(const matrix<T>& src, 00514 matrix<T>& dest, 00515 const downsampling::parameters& param); 00516 00517 /** 00518 * convolves the matrix src with the separable filter kernel and 00519 * leaves the result in dest. 00520 * 00521 * Consistency checks should be done by the apply methods! 00522 * 00523 * @param src matrix to be filtered 00524 * @param kern filter kernel 00525 * @param dest result 00526 */ 00527 void applySep(const matrix<T>& src, 00528 matrix<T>& dest, 00529 const downsampling::parameters& param); 00530 00531 protected: 00532 const kernel2D<T>* kernel; 00533 const sepKernel<T>* sKernel; 00534 private: 00535 kernel2D<T>* tmpKernel; 00536 sepKernel<T>* tmpSKernel; 00537 }; 00538 }; 00539 } 00540 00541 #include "ltiDownsampling_template.h" 00542 00543 #endif