last update 20 Sep 2009 |
00001 /* 00002 * Copyright (C) 1998 - 2005 00003 * Lehrstuhl fuer Technische Informatik, RWTH-Aachen, Germany 00004 * 00005 * 00006 * This file is part of the Computer Vision and Robotics Library (CVR-Lib) 00007 * 00008 * The CVR-Lib is free software; you can redistribute it and/or 00009 * modify it under the terms of the BSD License. 00010 * 00011 * All rights reserved. 00012 * 00013 * Redistribution and use in source and binary forms, with or without 00014 * modification, are permitted provided that the following conditions are met: 00015 * 00016 * 1. Redistributions of source code must retain the above copyright notice, 00017 * this list of conditions and the following disclaimer. 00018 * 00019 * 2. Redistributions in binary form must reproduce the above copyright notice, 00020 * this list of conditions and the following disclaimer in the documentation 00021 * and/or other materials provided with the distribution. 00022 * 00023 * 3. Neither the name of the authors nor the names of its contributors may be 00024 * used to endorse or promote products derived from this software without 00025 * specific prior written permission. 00026 * 00027 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00028 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00029 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00030 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 00031 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00032 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00033 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00034 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00035 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00036 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00037 * POSSIBILITY OF SUCH DAMAGE. 00038 */ 00039 00040 00041 00042 00043 /** 00044 * \file cvrEuclideanDistantor.h 00045 * This file contains the policy classes euclideanDistantor 00046 * and euclideanSqrDistantor, which calculate the L2 distance 00047 * and it square, respecively 00048 * \author Jochen Wickel 00049 * \date 28.06.2000 00050 * 00051 * $Id: cvrEuclideanDistantor.h,v 1.1 2005/03/29 13:26:46 doerfler Exp $ 00052 */ 00053 00054 #ifndef _CVR_EUCLIDEAN_DISTANTOR_H_ 00055 #define _CVR_EUCLIDEAN_DISTANTOR_H_ 00056 00057 #include "cvrDistanceType.h" 00058 #include "cvrEuclideanDistance.h" 00059 00060 00061 namespace cvr { 00062 00063 00064 /** 00065 * Policy class used by several classifiers/trees to measure the square 00066 * of the euclidean distance between two points of type T. 00067 * 00068 * The type T MUST define the \a value_type type, which exist for example 00069 * for vectors, (t)points and (t)rgbPixels. 00070 * 00071 * If you \e really want, you can use this class directly through the 00072 * operator(). 00073 * 00074 * \code 00075 * euclideanSqrDistantor< vector<double> > myDist; 00076 * dvector a,b; 00077 * ... // fill vectors with data 00078 * double dist = myDist(a,b); 00079 * \endcode 00080 * 00081 * But remember that there is also a global template function distanceSqr() 00082 * which is easier to use: 00083 * 00084 * \code 00085 * dvector a,b; 00086 * ... // fill vectors with data 00087 * double dist = distanceSqr(a,b); 00088 * \endcode 00089 * 00090 * You can of course also use the cvr::l2Distance functor, as usual with its 00091 * apply() methods. 00092 */ 00093 template <class T, class D=typename distanceType<T>::square_distance_type> 00094 class euclideanSqrDistantor { 00095 public: 00096 /** 00097 * type returned by the distantor 00098 */ 00099 typedef D distance_type; 00100 00101 /** 00102 * compute the distance between a and b 00103 */ 00104 inline distance_type operator()(const T& a,const T& b) const { 00105 return 00106 static_cast<distance_type>(euclideanDistanceSqr(a,b)); 00107 }; 00108 00109 /** 00110 * @name Special methods for Minkowski distances 00111 */ 00112 //@{ 00113 00114 /** 00115 * This member accumulates in the given accumulator, the 00116 * given element. 00117 * 00118 * It can be used when the distance need to be computed manually, but 00119 * using a distantor to still allow the flexibility of changing distances. 00120 * 00121 * For the euclideanSqrDistantor this is just acc+=(elem*elem). 00122 * 00123 * @param element component of the difference between two points. 00124 * @param accumulator variable where the elements will be accumulated. 00125 */ 00126 inline void accumulate(const distance_type element, 00127 distance_type& accumulator) const { 00128 accumulator+=(element*element); 00129 } 00130 00131 /** 00132 * This member accumulates in the given accumulator, the difference 00133 * of the given elements. 00134 * 00135 * It can be used when the distance need to be computed manually, but 00136 * using a distantor to still allow the flexibility of changing distances. 00137 * 00138 * For the euclideanSqrDistantor this is just acc+=((elem1-elem2)^2). 00139 * 00140 * @param element1 component of the first point 00141 * @param element2 component of the second point 00142 * @param accumulator variable where the elements will be accumulated. 00143 */ 00144 inline void accumulate(const typename T::value_type element1, 00145 const typename T::value_type element2, 00146 distance_type& accumulator) const { 00147 const distance_type tmp = static_cast<distance_type>(element2-element1); 00148 accumulator+=(tmp*tmp); 00149 } 00150 00151 /** 00152 * Compute from the given accumulator the desired distance 00153 */ 00154 inline distance_type 00155 computeDistance(const distance_type& accumulator) const { 00156 return accumulator; 00157 } 00158 00159 /** 00160 * return the distance between two components, which is in some way 00161 * a component of the total distance (that is the reason for the name). 00162 * 00163 * For this distantor it return (element2-element1)^2 00164 */ 00165 inline distance_type 00166 component(const typename T::value_type element1, 00167 const typename T::value_type element2) const { 00168 const distance_type tmp = static_cast<distance_type>(element2-element1); 00169 return tmp*tmp; 00170 } 00171 00172 /** 00173 * Return true if the given partial computed from accumulator is less than 00174 * the given distance. 00175 * 00176 * Assume you have accumulated \a acc until now, and you want to check if 00177 * the partial distance derived from this accumulator is less than 00178 * the given distance. So you check accLessThan(accumulator,distance) 00179 * 00180 * For this norm it computes acc < dist 00181 */ 00182 inline bool accLessThan(const distance_type acc, 00183 const distance_type dist) const { 00184 return (acc < dist); 00185 } 00186 00187 /** 00188 * Return true if the given partial computed from accumulator is greater 00189 * than the given distance. 00190 * 00191 * Assume you have accumulated \a acc until now, and you want to check if 00192 * the partial distance derived from this accumulator is greater than 00193 * the given distance. So you check accLessThan(accumulator,distance) 00194 * 00195 * For this norm it computes acc > dist 00196 */ 00197 inline bool accGreaterThan(const distance_type acc, 00198 const distance_type dist) const { 00199 return (acc > dist); 00200 } 00201 //@} 00202 }; 00203 00204 /** 00205 * Policy class used by several classifiers/trees to measure the 00206 * euclidean distance between two points of type T. 00207 * 00208 * The type T MUST define the \a value_type type, which exist for example 00209 * for vectors, (t)points and (t)rgbPixels. 00210 * 00211 * If you \e really want, you can use this class directly through the 00212 * operator(). 00213 * 00214 * \code 00215 * euclideanDistantor< vector<double> > myDist; 00216 * dvector a,b; 00217 * ... // fill vectors with data 00218 * double dist = myDist(a,b); 00219 * \endcode 00220 * 00221 * But remember that there is also a global template function distanceSqr() 00222 * which can be more easily used: 00223 * 00224 * \code 00225 * dvector a,b; 00226 * ... // fill vectors with data 00227 * double dist = sqrt(distanceSqr(a,b)); 00228 * \endcode 00229 * 00230 * You can of course also use the cvr::l2Distance functor, as usual with its 00231 * apply() methods. 00232 */ 00233 template <class T, class D=typename distanceType<T>::fp_distance_type> 00234 class euclideanDistantor { 00235 public: 00236 /** 00237 * type returned by the distantor 00238 */ 00239 typedef D distance_type; 00240 00241 /** 00242 * compute the distance between a and b 00243 */ 00244 inline distance_type operator()(const T& a,const T& b) const { 00245 return static_cast<distance_type>(euclideanDistance(a,b)); 00246 } 00247 00248 /** 00249 * @name Special methods for Minkowski distances 00250 */ 00251 //@{ 00252 00253 /** 00254 * This member accumulates in the given accumulator, the 00255 * given element. 00256 * 00257 * It can be used when the distance need to be computed manually, but 00258 * using a distantor to still allow the flexibility of changing distances. 00259 * 00260 * For the euclideanDistantor this is just acc+=(elem*elem). 00261 * 00262 * @param element component of the difference between two points. 00263 * @param accumulator variable where the elements will be accumulated. 00264 */ 00265 inline void accumulate(const distance_type element, 00266 distance_type& accumulator) const { 00267 accumulator+=(element*element); 00268 } 00269 00270 /** 00271 * This member accumulates in the given accumulator, the difference 00272 * of the given elements. 00273 * 00274 * It can be used when the distance need to be computed manually, but 00275 * using a distantor to still allow the flexibility of changing distances. 00276 * 00277 * For the euclideanDistantor this is just acc+=((elem2-elem1)^2). 00278 * 00279 * @param element1 component of the first point 00280 * @param element2 component of the second point 00281 * @param accumulator variable where the elements will be accumulated. 00282 */ 00283 inline void accumulate(const typename T::value_type element1, 00284 const typename T::value_type element2, 00285 distance_type& accumulator) const { 00286 const distance_type tmp = static_cast<distance_type>(element2-element1); 00287 accumulator+=(tmp*tmp); 00288 } 00289 00290 /** 00291 * Compute from the given accumulator the desired distance 00292 */ 00293 inline distance_type 00294 computeDistance(const distance_type& accumulator) const { 00295 return sqrt(accumulator); 00296 } 00297 00298 /** 00299 * return the distance between two components, which is in some way 00300 * a component of the total distance (that is the reason for the name). 00301 * 00302 * For this distantor it return abs(element2-element1) 00303 */ 00304 inline distance_type 00305 component(const typename T::value_type element1, 00306 const typename T::value_type element2) const { 00307 return static_cast<distance_type>(abs(element2-element1)); 00308 } 00309 00310 /** 00311 * Return true if the given partial computed from accumulator is less than 00312 * the given distance. 00313 * 00314 * Assume you have accumulated \a acc until now, and you want to check if 00315 * the partial distance derived from this accumulator is less than 00316 * the given distance. So you check accLessThan(accumulator,distance) 00317 * 00318 * For this norm it computes acc < (dist*dist) 00319 */ 00320 inline bool accLessThan(const distance_type acc, 00321 const distance_type dist) const { 00322 return (acc < (dist*dist)); 00323 } 00324 00325 /** 00326 * Return true if the given partial computed from accumulator is greater 00327 * than the given distance. 00328 * 00329 * Assume you have accumulated \a acc until now, and you want to check if 00330 * the partial distance derived from this accumulator is less than 00331 * the given distance. So you check accLessThan(accumulator,distance) 00332 * 00333 * For this norm it computes acc > (dist*dist) 00334 */ 00335 inline bool accGreaterThan(const distance_type acc, 00336 const distance_type dist) const { 00337 return (acc > (dist*dist)); 00338 } 00339 //@} 00340 }; 00341 00342 } 00343 00344 #endif