latest version v1.9 - last update 10 Apr 2010 |
00001 /* 00002 * Copyright (C) 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 .......: ltiQuickMedian.h 00027 * authors ....: Guy Wafo 00028 * organization: LTI, RWTH Aachen 00029 * creation ...: 27.3.2001 00030 * revisions ..: $Id: ltiQuickMedian.h,v 1.7 2006/02/08 12:40:45 ltilib Exp $ 00031 */ 00032 00033 #ifndef _LTI_QUICKMEDIAN_H_ 00034 #define _LTI_QUICKMEDIAN_H_ 00035 00036 #include "ltiFunctor.h" 00037 #include "ltiVector.h" 00038 #include "ltiMatrix.h" 00039 00040 namespace lti { 00041 00042 /** 00043 * This class is used to extract the median of the elements of a 00044 * given vector or matrix. The median is defined as the element at 00045 * the middle position of the sorted vector. The algorithm used is 00046 * based on the quick sort. 00047 * For vectors (or matrices) with an even number n of elements, the 00048 * median will be the element at (n/2) or (n/2)-1 depending on the 00049 * parameter settings. 00050 * 00051 * The type of the vector elements (T) must accept the operators < 00052 * and >. 00053 * 00054 * @ingroup gStats 00055 */ 00056 template <class T> 00057 class quickMedian : public functor { 00058 public: 00059 00060 /** 00061 * The parameters for the class quickMedian 00062 */ 00063 class parameters : public functor::parameters { 00064 public: 00065 /** 00066 * Default constructor 00067 */ 00068 parameters() 00069 : functor::parameters() { 00070 evenCase = TakeLower; 00071 }; 00072 00073 /** 00074 * copy constructor 00075 * @param other the parameters object to be copied 00076 */ 00077 parameters(const parameters& other) 00078 : functor::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 "quickMedian<T>::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 functor::parameters::copy(other); 00103 # else 00104 // ...so we have to use this workaround. 00105 // Conditional on that, copy may not be virtual. 00106 functor::parameters& (functor::parameters::* p_copy) 00107 (const functor::parameters&) = 00108 functor::parameters::copy; 00109 (this->*p_copy)(other); 00110 # endif 00111 00112 evenCase = other.evenCase; 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 * This enum specifies how to consider the case of vectors with 00126 * an even number of elements. 00127 */ 00128 enum eEvenCase { 00129 TakeLower, /**< take the element with the lower index, i.e. N/2-1 with 00130 * N the number of elements of the vector 00131 */ 00132 TakeHigher /**< take the element with the higher index, i.e. N/2 with 00133 * N the number of elements of the vector 00134 */ 00135 }; 00136 00137 /** 00138 * Specifies how to consider the case when the number of elements of 00139 * the vector is even (see eEvenCase). 00140 * 00141 * This parameter has no effect for odd-sized vectors. 00142 * 00143 * Default value: TakeLower 00144 */ 00145 eEvenCase evenCase; 00146 }; 00147 00148 /** 00149 * Default constructor 00150 */ 00151 quickMedian(); 00152 00153 /** 00154 * Constructor with indicator what to do for even-sized vectors 00155 */ 00156 quickMedian(const typename parameters::eEvenCase evenCase); 00157 00158 /** 00159 * copy constructor 00160 * @param other the object to be copied 00161 */ 00162 quickMedian(const quickMedian<T>& other); 00163 00164 /** 00165 * destructor 00166 */ 00167 virtual ~quickMedian(); 00168 00169 /** 00170 * returns the name of this type ("quickMedian") 00171 */ 00172 virtual const char* getTypeName() const; 00173 00174 /** 00175 * operates on the given matrix, which WILL BE modified. 00176 * The resulting matrix contain the elements less or equal than the median 00177 * for the indexes (x,y) such that (x+y*rows() < rows()*columns()/2), 00178 * and higher or equal otherwise. 00179 * 00180 * @param srcdest matrix<T> with the source data. The result 00181 * will be left here too. 00182 * @return the median of the matrix 00183 */ 00184 T apply(matrix<T>& srcdest) const; 00185 00186 /** 00187 * calculates the median of the given matrix, which is NOT modified. 00188 * The elements of the matrix will be considered as part of a vector 00189 * with "columns()" times "rows()" elements. 00190 * @param src matrix<T> with the source data. 00191 * @param dest the median value of the given matrix. 00192 * @return the median of the matrix (as reference to the dest parameter) 00193 */ 00194 T& apply(const matrix<T>& src,T& dest) const; 00195 00196 /** 00197 * operates on the given parameter. 00198 * The resulting vector contains the elements less or equal than the median 00199 * for the indexes <code>x</code> such that <code>x < size()/2</code>, 00200 * and higher or equal otherwise. 00201 * 00202 * @param srcdest vector<T> with the source data. The result 00203 * will be left here too. 00204 * @return a reference to the <code>srcdest</code>. 00205 */ 00206 T apply(vector<T>& srcdest) const; 00207 00208 /** 00209 * operates on the given parameter. 00210 * @param src vector<T> with the source data. 00211 * @param dest the median value 00212 * @return a reference to the <code>dest</code> variable. 00213 */ 00214 T& apply(const vector<T>& src, T& dest) const; 00215 00216 /** 00217 * operates on the given parameter. 00218 * @param src vector<T> with the source data. 00219 * @param dest the partially sorted vector. The elements at the 00220 * first half of the vector are less or equal than the median 00221 * and on the other half greater or equal. 00222 * @param median the median value 00223 * @return a reference to the <code>median</code> variable. 00224 */ 00225 T& apply(const vector<T>& src, vector<T>& dest,T& median) const; 00226 00227 /** 00228 * operates on the given parameter. 00229 * The resulting vector contains the elements less or equal than the median 00230 * for the indexes <code>x</code> such that <code>x < size()/2</code>, 00231 * and higher or equal otherwise. 00232 * 00233 * @param srcdest vector<T> with the source data. The result 00234 * will be left here too. 00235 * @return the median value. 00236 */ 00237 T apply(std::vector<T>& srcdest) const; 00238 00239 /** 00240 * operates on the given parameter. 00241 * @param src vector<T> with the source data. 00242 * @param dest the median value 00243 * @return a reference to the <code>dest</code> variable. 00244 */ 00245 T& apply(const std::vector<T>& src, T& dest) const; 00246 00247 /** 00248 * operates on the given parameter. 00249 * @param src vector<T> with the source data. 00250 * @param dest the partially sorted vector. The elements at the 00251 * first half of the vector are less or equal than the median 00252 * and on the other half greater or equal. 00253 * @param median the median value 00254 * @return a reference to the <code>median</code> variable. 00255 */ 00256 T& apply(const std::vector<T>& src, std::vector<T>& dest,T& median) const; 00257 00258 /** 00259 * copy data of "other" functor. 00260 * @param other the functor to be copied 00261 * @return a reference to this functor object 00262 */ 00263 quickMedian& copy(const quickMedian& other); 00264 00265 /** 00266 * returns a pointer to a clone of this functor. 00267 */ 00268 virtual functor* clone() const; 00269 00270 /** 00271 * returns used parameters 00272 */ 00273 const parameters& getParameters() const; 00274 00275 protected: 00276 /** 00277 * this method calculates the median in a recursively form 00278 */ 00279 T findMedian(vector<T>& vct, 00280 const int& begin, 00281 const int& end, 00282 const int& medianPos) const; 00283 00284 /** 00285 * this method chooses a pivot-value and ensures that lower values lie 00286 * at the left and higher values at the right of its final position, which 00287 * will be returned. 00288 */ 00289 int partition(vector<T>& vct, 00290 const int& begin, 00291 const int& end) const; 00292 00293 /** 00294 * this method calculates the median in a recursively form 00295 */ 00296 T findMedian(std::vector<T>& vct, 00297 const int& begin, 00298 const int& end, 00299 const int& medianPos) const; 00300 00301 /** 00302 * this method chooses a pivot-value and ensures that lower values lie 00303 * at the left and higher values at the right of its final position, which 00304 * will be returned. 00305 */ 00306 int partition(std::vector<T>& vct, 00307 const int& begin, 00308 const int& end) const; 00309 00310 }; 00311 00312 /** 00313 * This class is used to extract the median of the elements of a 00314 * given vector or matrix, partitioning at the same time a second 00315 * vector. The median is defined as the element at the middle 00316 * position of the sorted vector. The algorithm used is based on 00317 * the quick sort. 00318 * 00319 * The difference with the lti::quickMedian functor is that you can 00320 * "sort" a second vector, which might contain for example the indices 00321 * of the elements. This way, you can easily find out, which elements of the 00322 * original vector are under the median, and which ones above. 00323 * 00324 * @see lti::quickMedian, lti::sort, lti::sort2 00325 * 00326 * For vectors (or matrices) with an even number n of elements, the 00327 * median will be the element at (n/2) or (n/2)-1 depending on the 00328 * parameter settings. 00329 * 00330 * The type of the vector elements (T) must accept the operators < 00331 * and >. 00332 * 00333 * @ingroup gStats 00334 */ 00335 template <class T,class U> 00336 class quickMedian2 : public quickMedian<T> { 00337 public: 00338 00339 typedef typename quickMedian<T>::parameters parameters; 00340 00341 /** 00342 * default constructor 00343 */ 00344 quickMedian2(); 00345 00346 /** 00347 * copy constructor 00348 * @param other the object to be copied 00349 */ 00350 quickMedian2(const quickMedian2<T,U>& other); 00351 00352 /** 00353 * destructor 00354 */ 00355 virtual ~quickMedian2(); 00356 00357 /** 00358 * returns the name of this type ("quickMedian2") 00359 */ 00360 virtual const char* getTypeName() const; 00361 00362 /** 00363 * operates on the given parameter. 00364 * The resulting keys vector contains the elements less or equal than the 00365 * median for the indexes <code>x</code> such that 00366 * <code>x < size()/2</code>, and higher or equal otherwise. 00367 * 00368 * Both vectors must have the same size. 00369 * 00370 * @param keys vector<T> with the key data. The median of this data 00371 * is partially sorted while looking for the median. 00372 * @param data vector<U> with data to be sorted the same way as the keys. 00373 * You can for example use a ivector initialized with the 00374 * index values (i.e. data(i)=i), so that after the apply 00375 * method you can check which elements are below the median 00376 * and which above. 00377 * 00378 * @return a the median value of keys. 00379 */ 00380 T apply(vector<T>& keys,vector<U>& data) const; 00381 00382 /** 00383 * returns a pointer to a clone of this functor. 00384 */ 00385 virtual functor* clone() const; 00386 00387 protected: 00388 /** 00389 * this method calculates the median in a recursively form 00390 */ 00391 T findMedian(vector<T>& vct, 00392 vector<U>& data, 00393 const int& begin, 00394 const int& end, 00395 const int& medianPos) const; 00396 00397 /** 00398 * this method chooses a pivot-value and ensures that lower values lie 00399 * at the left and higher values at the right of its final position, which 00400 * will be returned. 00401 */ 00402 int partition(vector<T>& vct, 00403 vector<U>& data, 00404 const int& begin, 00405 const int& end) const; 00406 }; 00407 00408 00409 00410 } 00411 00412 #include "ltiQuickMedian_template.h" 00413 00414 #endif