LTI-Lib latest version v1.9 - last update 10 Apr 2010

ltiL1Distance.h

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

Generated on Sat Apr 10 15:25:43 2010 for LTI-Lib by Doxygen 1.6.1