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 /*---------------------------------------------------------------- 00026 * project ....: LTI Digital Image/Signal Processing Library 00027 * file .......: ltiL1Distance.h 00028 * authors ....: Jochen Wickel 00029 * organization: LTI, RWTH Aachen 00030 * creation ...: 28.6.2000 00031 * revisions ..: $Id: ltiL1Distance.h,v 1.9 2008/10/02 15:34:57 alvarado Exp $ 00032 */ 00033 00034 #ifndef _LTI_L1_DISTANCE_H_ 00035 #define _LTI_L1_DISTANCE_H_ 00036 00037 #include <vector> 00038 #include "ltiPoint.h" 00039 #include "ltiRGBPixel.h" 00040 #include "ltiDistanceFunctor.h" 00041 #include "ltiDistanceType.h" 00042 00043 namespace lti { 00044 00045 /** 00046 * @name City Block Distances Functions. 00047 * 00048 * Global functions to compute the L1 distance between two n-dimensional 00049 * point representations 00050 * 00051 * @ingroup gLinearAlgebra 00052 */ 00053 //@{ 00054 00055 /** 00056 * cityBlockDistance computes the L1 distance between 00057 * the lti::vectors a and b. 00058 */ 00059 template<class T> 00060 typename distanceType<T>::distance_type 00061 cityBlockDistance(const vector<T>& a,const vector<T>& b) { 00062 assert(a.size() == b.size()); 00063 00064 typename vector<T>::const_iterator ait,bit,eit; 00065 typename distanceType<T>::distance_type dist(0); 00066 ait = a.begin(); 00067 bit = b.begin(); 00068 eit = a.end(); 00069 00070 while (ait != eit) { 00071 dist += static_cast<typename distanceType<T>::distance_type> 00072 (lti::abs((*ait)-(*bit))); 00073 ++ait; 00074 ++bit; 00075 } 00076 return dist; 00077 }; 00078 00079 /** 00080 * cityBlockDistance computes the L1 distance between 00081 * the lti::matrix a and b. 00082 */ 00083 template<class T> 00084 typename distanceType<T>::distance_type 00085 cityBlockDistance(const matrix<T>& a,const matrix<T>& b) { 00086 assert(a.size() == b.size()); 00087 00088 typename matrix<T>::const_iterator ait,bit,eit; 00089 typename distanceType<T>::distance_type dist(0); 00090 ait = a.begin(); 00091 bit = b.begin(); 00092 eit = a.end(); 00093 00094 while (ait != eit) { 00095 dist += static_cast<typename distanceType<T>::distance_type> 00096 (lti::abs((*ait)-(*bit))); 00097 ++ait; 00098 ++bit; 00099 } 00100 return dist; 00101 }; 00102 00103 00104 /** 00105 * cityBlockDistance computes the L1 distance between 00106 * the std::vectors a and b. 00107 */ 00108 template<class T> 00109 typename distanceType<T>::distance_type 00110 cityBlockDistance(const std::vector<T>& a,const std::vector<T>& b) { 00111 typename std::vector<T>::const_iterator ita,itb,ite; 00112 assert(a.size()==b.size()); 00113 typename distanceType<T>::distance_type sum(0); 00114 for (ita=a.begin(),itb=b.begin(),ite=a.end(); 00115 ita!=ite; 00116 ++ita,++itb) { 00117 sum+=static_cast<typename distanceType<T>::distance_type> 00118 (lti::abs(*ita-*itb)); 00119 } 00120 return sum; 00121 }; 00122 00123 /** 00124 * cityBlockDistance computes the L1 distance between 00125 * the points a and b. 00126 */ 00127 template<class T > 00128 typename distanceType<T>::distance_type 00129 cityBlockDistance(const tpoint<T>& a,const tpoint<T>& b) { 00130 return (static_cast<typename distanceType<T>::distance_type> 00131 (lti::abs(a.x-b.x)+lti::abs(a.y-b.y))); 00132 } 00133 00134 /** 00135 * cityBlockDistance computes the L1 distance between 00136 * the points a and b. 00137 */ 00138 template<class T> 00139 typename distanceType<T>::distance_type 00140 cityBlockDistance(const tpoint3D<T>& a, const tpoint3D<T>& b) { 00141 return (static_cast<typename distanceType<T>::distance_type> 00142 (lti::abs(a.x-b.x)+lti::abs(a.y-b.y)+lti::abs(a.z-b.z))); 00143 } 00144 00145 /** 00146 * cityBlockDistance computes the L1 distance between 00147 * the RGB values a and b in the RGB color space. 00148 */ 00149 template<class T> 00150 inline typename distanceType<T>::distance_type 00151 cityBlockDistance(const trgbPixel<T>& a, const trgbPixel<T>& b) { 00152 return (static_cast<typename distanceType<T>::distance_type> 00153 (lti::abs(a.getRed()-b.getRed())+ 00154 lti::abs(a.getGreen()-b.getGreen())+ 00155 lti::abs(a.getBlue()-b.getBlue()))); 00156 } 00157 00158 /** 00159 * cityBlockDistance computes the L1 distance between 00160 * the RGB values a and b in the RGB color space. 00161 */ 00162 inline distanceType<rgbPixel>::distance_type 00163 cityBlockDistance(const rgbPixel& a, const rgbPixel& b) { 00164 return 00165 (lti::abs(static_cast<distanceType<rgbPixel>::distance_type> 00166 (a.getRed())-b.getRed())+ 00167 lti::abs(static_cast<distanceType<rgbPixel>::distance_type> 00168 (a.getGreen())-b.getGreen())+ 00169 lti::abs(static_cast<distanceType<rgbPixel>::distance_type> 00170 (a.getBlue())-b.getBlue())); 00171 } 00172 00173 //@} 00174 00175 /** 00176 * Policy class used by several classifiers/trees to measure the 00177 * distance between two points of type T. 00178 * 00179 * The type T MUST define the \a value_type type, which exist for example 00180 * for vectors, (t)points and (t)rgbPixels. 00181 */ 00182 #ifdef _LTI_MSC_6 00183 template <class T, class D=distanceType<T>::distance_type> 00184 #else 00185 template <class T, class D=typename distanceType<T>::distance_type> 00186 #endif 00187 class l1Distantor { 00188 public: 00189 /** 00190 * type returned by the distantor 00191 */ 00192 typedef D distance_type; 00193 00194 /** 00195 * compute the distance between a and b 00196 */ 00197 inline distance_type operator()(const T& a,const T& b) const { 00198 return static_cast<distance_type>(cityBlockDistance(a,b)); 00199 }; 00200 00201 /** 00202 * @name Special methods for Minkowski distances 00203 */ 00204 //@{ 00205 00206 /** 00207 * This member accumulates in the given accumulator, the 00208 * given element. 00209 * 00210 * It can be used when the distance need to be computed manually, but 00211 * using a distantor to still allow the flexibility of changing distances. 00212 * 00213 * For the l1Distantor this is just acc+=abs(elem) 00214 * 00215 * @param element component of the difference between two points. 00216 * @param accumulator variable where the elements will be accumulated. 00217 */ 00218 inline void accumulate(const distance_type element, 00219 distance_type& accumulator) const { 00220 accumulator+=abs(element); 00221 } 00222 00223 /** 00224 * This member accumulates in the given accumulator, the difference 00225 * of the given elements. 00226 * 00227 * It can be used when the distance need to be computed manually, but 00228 * using a distantor to still allow the flexibility of changing distances. 00229 * 00230 * For the l1Distantor this is just acc += abs(elem1-elem2). 00231 * 00232 * @param element1 component of the first point 00233 * @param element2 component of the second point 00234 * @param accumulator variable where the elements will be accumulated. 00235 */ 00236 inline void accumulate(const typename T::value_type element1, 00237 const typename T::value_type element2, 00238 distance_type& accumulator) const { 00239 accumulator+=static_cast<distance_type>(abs(element2-element1)); 00240 } 00241 00242 /** 00243 * Compute from the given accumulator the desired distance 00244 */ 00245 inline distance_type 00246 computeDistance(const distance_type& accumulator) const { 00247 return accumulator; 00248 } 00249 00250 /** 00251 * return the distance between two components, which is in some way 00252 * a component of the total distance (that is the reason for the name). 00253 * 00254 * For this distantor it return abs(element2-element1) 00255 */ 00256 inline distance_type 00257 component(const typename T::value_type element1, 00258 const typename T::value_type element2) const { 00259 return static_cast<distance_type>(abs(element2-element1)); 00260 } 00261 00262 /** 00263 * Return true if the given partial computed from accumulator is less than 00264 * the given distance. 00265 * 00266 * Assume you have accumulated \a acc until now, and you want to check if 00267 * the partial distance derived from this accumulator is less than 00268 * the given distance. So you check accLessThan(accumulator,distance) 00269 * 00270 * For this norm it computes acc < dist 00271 */ 00272 inline bool accLessThan(const distance_type acc, 00273 const distance_type dist) const { 00274 return (acc < dist); 00275 } 00276 00277 /** 00278 * Return true if the given partial computed from accumulator is greater 00279 * than the given distance. 00280 * 00281 * Assume you have accumulated \a acc until now, and you want to check if 00282 * the partial distance derived from this accumulator is greater than 00283 * the given distance. So you check accLessThan(accumulator,distance) 00284 * 00285 * For this norm it computes acc > dist 00286 */ 00287 inline bool accGreaterThan(const distance_type acc, 00288 const distance_type dist) const { 00289 return (acc > dist); 00290 } 00291 00292 //@} 00293 }; 00294 00295 // template <> 00296 // class l1Distantor<rgbPixel> { 00297 // public: 00298 // /** 00299 // * type returned by the distantor 00300 // */ 00301 // typedef int distance_type; 00302 00303 // /** 00304 // * compute the distance between a and b 00305 // */ 00306 // inline distance_type operator()(const rgbPixel& a,const rgbPixel& b) const{ 00307 // return cityBlockDistance(a,b); 00308 // }; 00309 00310 // /** 00311 // * @name Special methods for Minkowski distances 00312 // */ 00313 // //@{ 00314 00315 00316 // /** 00317 // * This member accumulates in the given accumulator, the 00318 // * given element. 00319 // * 00320 // * It can be used when the distance need to be computed manually, but 00321 // * using a distantor to still allow the flexibility of changing distances. 00322 // * 00323 // * For the l1Distantor this is just acc+=abs(elem) 00324 // * 00325 // * @param element component of the difference between two points. 00326 // * @param accumulator variable where the elements will be accumulated. 00327 // */ 00328 // inline void accumulate(const int element, 00329 // distance_type& accumulator) const { 00330 // if (element >= 0) { 00331 // accumulator+=element; 00332 // } else { 00333 // accumulator-=element; 00334 // } 00335 // } 00336 00337 // /** 00338 // * This member accumulates in the given accumulator, the difference 00339 // * of the given elements. 00340 // * 00341 // * It can be used when the distance need to be computed manually, but 00342 // * using a distantor to still allow the flexibility of changing distances. 00343 // * 00344 // * For the l1Distantor this is just acc += abs(elem1-elem2). 00345 // * 00346 // * @param element1 component of the first point 00347 // * @param element2 component of the second point 00348 // * @param accumulator variable where the elements will be accumulated. 00349 // */ 00350 // inline void accumulate(const ubyte element1, 00351 // const ubyte element2, 00352 // distance_type& accumulator) const { 00353 // if (element1>element2) { 00354 // accumulator+=(element1-element2); 00355 // } else { 00356 // accumulator+=(element2-element1); 00357 // } 00358 // } 00359 00360 // /** 00361 // * Compute from the given accumulator the desired distance 00362 // */ 00363 // inline distance_type 00364 // computeDistance(const distance_type& accumulator) const { 00365 // return accumulator; 00366 // } 00367 00368 // /** 00369 // * return the distance between two components, which is in some way 00370 // * a component of the total distance (that is the reason for the name). 00371 // * 00372 // * For this distantor it return abs(element2-element1) 00373 // */ 00374 // inline distance_type 00375 // component(const ubyte element1, 00376 // const ubyte element2) const { 00377 // return abs(static_cast<distance_type>(element2) - 00378 // static_cast<distance_type>(element1)); 00379 // } 00380 00381 // /** 00382 // * Return true if the given partial computed from accumulator is less than 00383 // * the given distance. 00384 // * 00385 // * Assume you have accumulated \a acc until now, and you want to check if 00386 // * the partial distance derived from this accumulator is less than 00387 // * the given distance. So you check accLessThan(accumulator,distance) 00388 // * 00389 // * For this norm it computes acc < dist 00390 // */ 00391 // inline bool accLessThan(const distance_type acc, 00392 // const distance_type dist) const { 00393 // return (acc < dist); 00394 // } 00395 00396 // /** 00397 // * Return true if the given partial computed from accumulator is greater 00398 // * than the given distance. 00399 // * 00400 // * Assume you have accumulated \a acc until now, and you want to check if 00401 // * the partial distance derived from this accumulator is greater than 00402 // * the given distance. So you check accLessThan(accumulator,distance) 00403 // * 00404 // * For this norm it computes acc > dist 00405 // */ 00406 // inline bool accGreaterThan(const distance_type acc, 00407 // const distance_type dist) const { 00408 // return (acc > dist); 00409 // } 00410 // //@} 00411 // }; 00412 00413 /** 00414 * This class computes the L1 distance between two vectors or matrices 00415 * or the L1 norm of a vector. 00416 * 00417 * @ingroup gLinearAlgebra 00418 */ 00419 template <class T> 00420 class l1Distance : public distanceFunctor<T> { 00421 public: 00422 00423 /** 00424 * default constructor 00425 */ 00426 l1Distance(); 00427 00428 /** 00429 * copy constructor 00430 * @param other the object to be copied 00431 */ 00432 l1Distance(const l1Distance<T>& other); 00433 00434 /** 00435 * destructor 00436 */ 00437 virtual ~l1Distance(); 00438 00439 /** 00440 * returns the name of this type ("l1Distance") 00441 */ 00442 virtual const char* getTypeName() const; 00443 00444 /** 00445 * calculate the norm of vector v 00446 * @param v the vector<T> 00447 * @param norm the norm of the vectors 00448 * @return false on error 00449 */ 00450 virtual bool apply(const vector<T>& v, T& norm) const; 00451 00452 /** 00453 * calculate the norm of vector v 00454 * @param v the vector<T> 00455 * @return the norm of the vector 00456 */ 00457 virtual T apply(const vector<T>& v) const; 00458 00459 /** 00460 * calculate the norms of rows or columns of the matrix 00461 * @param m the matrix<T> 00462 * @param norms the norms of the rows/columns 00463 * @return false on error 00464 */ 00465 virtual bool apply(const matrix<T>& m, vector<T>& norms) const; 00466 00467 /** 00468 * calculate something like the norm of the matrix: the matrix 00469 * is seen as a vector. 00470 * @param m the matrix<T> 00471 * @param norm the 'norm' of the matrix 00472 * @return false on error 00473 */ 00474 virtual bool apply(const matrix<T>& m, T& norm) const; 00475 00476 /** 00477 * calculate something like the norm of the matrix: the matrix 00478 * is seen as a vector. 00479 * @param m the matrix<T> 00480 * @return the 'norm' of the matrix 00481 */ 00482 virtual T apply(const matrix<T>& m) const; 00483 00484 /** 00485 * calculate the distance between the vectors a and b 00486 * @param a the first vector<T> 00487 * @param b the second vector<T> 00488 * @param dist the distance between the vectors 00489 * @return false on error -> see status string 00490 */ 00491 virtual bool apply(const vector<T>& a, const vector<T>& b, 00492 T& dist) const; 00493 00494 /** 00495 * calculates the L1 distance between the vectors a and b 00496 * If both vectors have different sizes, the returned value will be 00497 * negative! 00498 * @param a the first vector<T> 00499 * @param b the second vector<T> 00500 * @return the L1 distance between a and b 00501 */ 00502 virtual T apply(const vector<T>& a, const vector<T>& b) const; 00503 00504 /** 00505 * calculate the distances between the rows or columns of the 00506 * matrices a and b, determined by the parameters rowWise. 00507 * @param a the first vector<T> 00508 * @param b the second vector<T> 00509 * @param dists the distances between the matrices 00510 * @return false on error -> see status string 00511 */ 00512 virtual bool apply(const matrix<T>& a, const matrix<T>& b, 00513 vector<T>& dists) const; 00514 00515 /** 00516 * calculate the L1 distance between the matrices a and b 00517 * If both matrices have different sizes, the returned value will be 00518 * negative! 00519 * @param a the first matrix<T> 00520 * @param b the second matrix<T> 00521 * @return the L1 distance between a and b 00522 */ 00523 virtual T apply(const matrix<T>& a, const matrix<T>& b) const; 00524 00525 /** 00526 * calculate the L1 distance between the matrices a and b 00527 * If both matrices have different sizes, the returned value will be 00528 * negative! 00529 * @param a the first matrix<T> 00530 * @param b the second matrix<T> 00531 * @param dist the L1 distance between a and b 00532 * @return false on error 00533 */ 00534 virtual bool apply(const matrix<T>& a, const matrix<T>& b, 00535 T& dist) const; 00536 00537 /** 00538 * Calculate the distance between each row or column of m 00539 * depending on the value of rowWise and the vector v. 00540 * @param m the matrix<T> 00541 * @param v the vector to be compared with 00542 * @param dest the vector with the distances to the vector v 00543 * @return false on error 00544 */ 00545 virtual bool apply(const matrix<T>& m, const vector<T>& v, 00546 vector<T>& dest) const; 00547 00548 /** 00549 * copy data of "other" functor. 00550 * @param other the functor to be copied 00551 * @return a reference to this functor object 00552 */ 00553 l1Distance& copy(const l1Distance& other); 00554 00555 /** 00556 * returns a pointer to a clone of this functor. 00557 */ 00558 virtual functor* clone() const; 00559 00560 typedef typename distanceFunctor<T>::parameters parameters; 00561 00562 }; 00563 00564 } 00565 00566 #endif