latest version v1.9 - last update 10 Apr 2010 |
00001 /* 00002 * Copyright (C) 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 .......: ltiMaximumFilter.h 00027 * authors ....: Pablo Alvarado 00028 * organization: LTI, RWTH Aachen 00029 * creation ...: 08.01.2002 00030 * revisions ..: $Id: ltiMaximumFilter.h,v 1.10 2006/02/08 11:26:30 ltilib Exp $ 00031 */ 00032 00033 #ifndef _LTI_MAXIMUM_FILTER_H_ 00034 #define _LTI_MAXIMUM_FILTER_H_ 00035 00036 #include "ltiObject.h" 00037 #include "ltiMatrix.h" 00038 #include "ltiFilter.h" 00039 #include <cstring> 00040 00041 namespace lti { 00042 /** 00043 * This is an efficient implementation of the non-linear maximum filter. 00044 * It assigns each pixel the maximal value in the region defined by 00045 * the parameter kernelSize. 00046 * 00047 * The template parameter T defines the type of the matrix or vector 00048 * to be filtered. 00049 * 00050 * An instance of this class cannot be used from different threads (not 00051 * thread-save). If you have multiple threads, use simply one functor for 00052 * each thread. 00053 * 00054 * @see parameters 00055 */ 00056 template<class T> 00057 class maximumFilter : public filter { 00058 public: 00059 00060 /** 00061 * the parameters for the class maximumFilter 00062 */ 00063 class parameters : public filter::parameters { 00064 public: 00065 /** 00066 * default constructor to initialize a kernel of k x k size centered 00067 * at (0,0) 00068 */ 00069 parameters(const int k = 3) : filter::parameters() { 00070 initSquare(k); 00071 } 00072 00073 /** 00074 * copy constructor 00075 * @param other the parameters object to be copied 00076 */ 00077 parameters(const parameters& other) 00078 : filter::parameters() { 00079 copy(other); 00080 }; 00081 00082 /** 00083 * destructor 00084 */ 00085 ~parameters() {}; 00086 00087 /** 00088 * returns name of this type 00089 */ 00090 const char* getTypeName() const { 00091 return "maximumFilter::parameters"; 00092 }; 00093 00094 /** 00095 * copy the contents of a parameters object 00096 * @param other the parameters object to be copied 00097 * @return a reference to this parameters object 00098 */ 00099 parameters& copy(const parameters& other) { 00100 # ifndef _LTI_MSC_6 00101 // MS Visual C++ 6 is not able to compile this... 00102 filter::parameters::copy(other); 00103 # else 00104 // ...so we have to use this workaround. 00105 // Conditional on that, copy may not be virtual. 00106 filter::parameters& (filter::parameters::* p_copy) 00107 (const filter::parameters&) = 00108 filter::parameters::copy; 00109 (this->*p_copy)(other); 00110 # endif 00111 00112 kernelSize = other.kernelSize; 00113 00114 return *this; 00115 }; 00116 00117 /** 00118 * returns a pointer to a clone of the parameters 00119 */ 00120 virtual functor::parameters* clone() const { 00121 return new parameters(*this); 00122 }; 00123 00124 /** 00125 * write the parameters in the given ioHandler 00126 * @param handler the ioHandler to be used 00127 * @param complete if true (the default) the enclosing begin/end will 00128 * be also written, otherwise only the data block will be 00129 * written. 00130 * @return true if write was successful 00131 */ 00132 # ifndef _LTI_MSC_6 00133 virtual bool write(ioHandler& handler,const bool complete=true) const 00134 # else 00135 bool writeMS(ioHandler& handler,const bool complete=true) const 00136 # endif 00137 { 00138 bool b = true; 00139 if (complete) { 00140 b = handler.writeBegin(); 00141 } 00142 00143 if (b) { 00144 lti::write(handler,"kernelSize",kernelSize); 00145 } 00146 00147 # ifndef _LTI_MSC_6 00148 // This is the standard C++ code, which MS Visual C++ 6 is not 00149 // able to compile... 00150 b = b && filter::parameters::write(handler,false); 00151 # else 00152 bool (modifier::parameters::* p_writeMS)(ioHandler&, 00153 const bool) const = 00154 modifier::parameters::writeMS; 00155 b = b && (this->*p_writeMS)(handler,false); 00156 # endif 00157 00158 if (complete) { 00159 b = b && handler.writeEnd(); 00160 } 00161 00162 return b; 00163 } 00164 00165 # ifdef _LTI_MSC_6 00166 virtual bool write(ioHandler& handler, 00167 const bool complete = true) const { 00168 // ...we need this workaround to cope with another really 00169 // awful MSVC bug. 00170 return writeMS(handler,complete); 00171 } 00172 # endif 00173 00174 /** 00175 * read the parameters from 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 read, otherwise only the data block will be read. 00179 * @return true if write was successful 00180 */ 00181 # ifndef _LTI_MSC_6 00182 virtual bool read(ioHandler& handler,const bool complete = true) 00183 # else 00184 bool readMS(ioHandler& handler,const bool complete=true) 00185 # endif 00186 { 00187 bool b = true; 00188 if (complete) { 00189 b = handler.readBegin(); 00190 } 00191 00192 if (b) { 00193 lti::read(handler,"kernelSize",kernelSize); 00194 } 00195 00196 # ifndef _LTI_MSC_6 00197 // This is the standard C++ code, which MS Visual C++ 6 is not 00198 // able to compile... 00199 b = b && filter::parameters::read(handler,false); 00200 # else 00201 bool (modifier::parameters::* p_readMS)(ioHandler&,const bool) = 00202 modifier::parameters::readMS; 00203 b = b && (this->*p_readMS)(handler,false); 00204 # endif 00205 00206 if (complete) { 00207 b = b && handler.readEnd(); 00208 } 00209 00210 return b; 00211 } 00212 00213 # ifdef _LTI_MSC_6 00214 virtual bool read(ioHandler& handler,const bool complete=true) { 00215 // ...we need this workaround to cope with another really awful MSVC 00216 // bug. 00217 return readMS(handler,complete); 00218 } 00219 # endif 00220 00221 /** 00222 * The rectangular kernel defines the region around the actual pixel 00223 * in which the maximum value will be determined. 00224 * 00225 * Default value: rectangle(-1,-1,1,1), i.e. a 3x3 kernel 00226 */ 00227 rectangle kernelSize; 00228 00229 /** 00230 * Initialize the parameters for a symmetric square kernel sizeXsize. 00231 * If the size is even, it will be "fixed" to the next odd number 00232 */ 00233 void initSquare(const int size) { 00234 int realSize(size); 00235 if ((size % 2) == 0) { 00236 realSize++; 00237 } 00238 00239 realSize/=2; 00240 kernelSize.ul.x = -realSize; 00241 kernelSize.ul.y = -realSize; 00242 kernelSize.br.x = +realSize; 00243 kernelSize.br.y = +realSize; 00244 }; 00245 00246 }; 00247 00248 /** 00249 * default constructor 00250 */ 00251 maximumFilter(); 00252 00253 /** 00254 * constructor with a set of parameters 00255 */ 00256 maximumFilter(const parameters& par); 00257 00258 /** 00259 * constructor to initialize the parameters with an square filter 00260 * of k x k size. 00261 */ 00262 maximumFilter(const int k); 00263 00264 /** 00265 * copy constructor 00266 * @param other the object to be copied 00267 */ 00268 maximumFilter(const maximumFilter& other); 00269 00270 /** 00271 * destructor 00272 */ 00273 virtual ~maximumFilter(); 00274 00275 /** 00276 * returns the name of this type ("maximumFilter") 00277 */ 00278 virtual const char* getTypeName() const; 00279 00280 /** 00281 * operates on the given %parameter. 00282 * @param srcdest matrix<T> with the source data. The result 00283 * will be left here too. 00284 * @return true if successful, false otherwise. 00285 */ 00286 bool apply(matrix<T>& srcdest); 00287 00288 /** 00289 * operates on the given %parameter. 00290 * @param srcdest vector<T> with the source data. The result 00291 * will be left here too. 00292 * @return true if successful, false otherwise. 00293 */ 00294 bool apply(vector<T>& srcdest); 00295 00296 /** 00297 * operates on a copy of the given %parameters. 00298 * @param src matrix<T> with the source data. 00299 * @param dest matrix<T> where the result will be left. 00300 * @return true if successful, false otherwise. 00301 */ 00302 bool apply(const matrix<T>& src,matrix<T>& dest); 00303 00304 /** 00305 * operates on a copy of the given %parameters. 00306 * @param src vector<T> with the source data. 00307 * @param dest vector<T> where the result will be left. 00308 * @return true if successful, false otherwise. 00309 */ 00310 bool apply(const vector<T>& src,vector<T>& dest); 00311 00312 /** 00313 * copy data of "other" functor. 00314 * @param other the functor to be copied 00315 * @return a reference to this functor object 00316 */ 00317 maximumFilter& copy(const maximumFilter& other); 00318 00319 /** 00320 * returns a pointer to a clone of this functor. 00321 */ 00322 virtual functor* clone() const; 00323 00324 /** 00325 * returns used parameters 00326 */ 00327 const parameters& getParameters() const; 00328 00329 /** 00330 * shortcut to set the parameters with the given kernel size 00331 */ 00332 bool setKernelSize(const rectangle& ksize); 00333 00334 /** 00335 * shortcut to set the parameters with a square kernel (see also 00336 * parameters::initSquare) 00337 */ 00338 bool setSquareKernel(const int& ksize); 00339 00340 /** 00341 * set functor's parameters. 00342 * This member makes a copy of <em>theParam</em>: the functor 00343 * will keep its own copy of the parameters! 00344 * @return true if successful, false otherwise 00345 */ 00346 virtual bool updateParameters(); 00347 00348 00349 protected: 00350 /** 00351 * applies the vertical part of the kernel to the matrix 00352 * @param src matrix<T> with the source data. 00353 * @param dest matrix<T> where the result will be left. 00354 * @result a reference to the <code>dest</code>. 00355 */ 00356 bool applyCol(const matrix<T>& src,matrix<T>& dest); 00357 00358 /** 00359 * calculate the real index in an vector of size srcSize for a 00360 * mirrored boundary 00361 */ 00362 inline int getMirrorIndex(const int& x, 00363 const int& srcSize, 00364 bool& mirror) const; 00365 00366 /** 00367 * Sorted elements. The memory is administrated by setParameters 00368 * and the destructor. 00369 */ 00370 T* rawBuffer; 00371 00372 /** 00373 * pointer to the buffer withing rawBuffer (there are elements after 00374 * and before used to check boundary conditions 00375 */ 00376 T* buffer; 00377 00378 00379 /** 00380 * insert the element "elem" in the buffer of size "size" pointed by 00381 * the attribute buffer. The last element of the buffer is supposed 00382 * to be uninitialized. 00383 */ 00384 void insert(const int size,const T elem); 00385 00386 /** 00387 * insert the element "elem" in the given buffer of size "size" 00388 */ 00389 void insdel(const int size,const T insElem,const T delElem); 00390 }; 00391 00392 00393 00394 } 00395 #endif