[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | Main Page ]

metrics.hxx VIGRA

1 /************************************************************************/
2 /* */
3 /* Copyright 2014 by Thorsten Beier and Ullrich Koethe */
4 /* */
5 /* This file is part of the VIGRA computer vision library. */
6 /* The VIGRA Website is */
7 /* http://hci.iwr.uni-heidelberg.de/vigra/ */
8 /* Please direct questions, bug reports, and contributions to */
9 /* ullrich.koethe@iwr.uni-heidelberg.de or */
10 /* vigra@informatik.uni-hamburg.de */
11 /* */
12 /* Permission is hereby granted, free of charge, to any person */
13 /* obtaining a copy of this software and associated documentation */
14 /* files (the "Software"), to deal in the Software without */
15 /* restriction, including without limitation the rights to use, */
16 /* copy, modify, merge, publish, distribute, sublicense, and/or */
17 /* sell copies of the Software, and to permit persons to whom the */
18 /* Software is furnished to do so, subject to the following */
19 /* conditions: */
20 /* */
21 /* The above copyright notice and this permission notice shall be */
22 /* included in all copies or substantial portions of the */
23 /* Software. */
24 /* */
25 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND */
26 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES */
27 /* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */
28 /* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT */
29 /* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */
30 /* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */
31 /* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */
32 /* OTHER DEALINGS IN THE SOFTWARE. */
33 /* */
34 /************************************************************************/
35 #ifndef VIGRA_METRIC_HXX
36 #define VIGRA_METRIC_HXX
37 
38 #include <vigra/numerictraits.hxx>
39 #include <vigra/multi_array.hxx>
40 
41 #include <cmath>
42 
43 namespace vigra{
44 namespace metrics{
45 
46 
47  template<class T>
48  class ChiSquared{
49  public:
50  ChiSquared(){}
51  T operator()(const T & a,const T & b)const{
52  return opImpl(&a,&a+1,&b);
53  }
54  template<class A, class B>
55  T operator()(const A & a,const B & b)const{
56  return opImpl(a.begin(),a.end(),b.begin());
57  }
58  private:
59  template<class ITER_A,class ITER_B>
60  T opImpl(
61  ITER_A iterA ,ITER_A endA ,ITER_B iterB
62  )const{
63  T res = 0.0;
64  while(iterA!=endA){
65  const T aa=static_cast<T>(*iterA);
66  const T bb=static_cast<T>(*iterB);
67  const T sum = aa + bb;
68  const T diff = aa - bb;
69  if(sum> static_cast<T>(0.0000001))
70  res+=(diff*diff)/sum;
71  ++iterA;
72  ++iterB;
73  }
74  return res*T(0.5);
75  }
76  };
77 
78  template<class T>
79  class HellingerDistance{
80  public:
81  HellingerDistance(){}
82  T operator()(const T & a,const T & b)const{
83  return opImpl(&a,&a+1,&b);
84  }
85  template<class A, class B>
86  T operator()(const A & a,const B & b)const{
87  return opImpl(a.begin(),a.end(),b.begin());
88  }
89  private:
90  template<class ITER_A,class ITER_B>
91  T opImpl(
92  ITER_A iterA ,ITER_A endA ,ITER_B iterB
93  )const{
94  T res = 0.0;
95  while(iterA!=endA){
96  const T aa=std::sqrt(static_cast<T>(*iterA));
97  const T bb=std::sqrt(static_cast<T>(*iterB));
98  const T diff = aa - bb;
99  res+=diff*diff;
100  ++iterA;
101  ++iterB;
102  }
103  return std::sqrt(res)/std::sqrt(2.0);
104  }
105  };
106 
107  template<class T,unsigned int NORM,bool TAKE_ROOT=true>
108  class PNorm{
109  public:
110  PNorm(){}
111  T operator()(const T & a,const T & b)const{
112  return opImpl(&a,&a+1,&b);
113  }
114  template<class A, class B>
115  T operator()(const A & a,const B & b)const{
116  return opImpl(a.begin(),a.end(),b.begin());
117  }
118  private:
119  template<class ITER_A,class ITER_B>
120  T opImpl(
121  ITER_A iterA ,ITER_A endA ,ITER_B iterB
122  )const{
123  T res = static_cast<T>(0.0);
124  while(iterA!=endA){
125  const T aa=static_cast<T>(*iterA);
126  const T bb=static_cast<T>(*iterB);
127  const T diff = aa-bb;
128  res+= std::abs(std::pow((double)diff,(int)NORM));
129  ++iterA;
130  ++iterB;
131  }
132  return TAKE_ROOT ? std::pow(res,static_cast<T>(1)/static_cast<T>(NORM)) : res;
133  }
134  };
135 
136  template<class T>
137  class SquaredNorm
138  : public PNorm<T,2,false>{
139  public:
140  SquaredNorm()
141  : PNorm<T,2,false>(){
142  }
143  };
144 
145  template<class T>
146  class Norm
147  : public PNorm<T,2,true>{
148  public:
149  Norm()
150  : PNorm<T,2,true>(){
151  }
152  };
153 
154  template<class T>
155  class Manhattan
156  : public PNorm<T,1,false>{
157  public:
158  Manhattan()
159  : PNorm<T,1,false>(){
160  }
161  };
162 
163  template<class T>
164  class SymetricKlDivergenz{
165  public:
166  SymetricKlDivergenz(){}
167  T operator()(const T & a,const T & b)const{
168  return opImpl(&a,&a+1,&b);
169  }
170  template<class A, class B>
171  T operator()(const A & a,const B & b)const{
172  return opImpl(a.begin(),a.end(),b.begin());
173  }
174  private:
175  template<class ITER_A,class ITER_B>
176  T opImpl(
177  ITER_A iterA ,ITER_A endA ,ITER_B iterB
178  )const{
179  T res = static_cast<T>(0.0);
180  while(iterA!=endA){
181  const T aa=static_cast<T>(*iterA);
182  const T bb=static_cast<T>(*iterB);
183  const T val = std::log(aa/bb)*(aa - bb);
184  if(!isinf(val) && !isnan(val))
185  res+=val;
186  ++iterA;
187  ++iterB;
188  }
189  return res/static_cast<T>(2.0);
190  }
191  };
192 
193  template<class T>
194  class BhattacharyaDistance{
195  public:
196  BhattacharyaDistance(){}
197  T operator()(const T & a,const T & b)const{
198  return opImpl(&a,&a+1,&b);
199  }
200  template<class A, class B>
201  T operator()(const A & a,const B & b)const{
202  return opImpl(a.begin(),a.end(),b.begin());
203  }
204  private:
205  template<class ITER_A,class ITER_B>
206  T opImpl(
207  ITER_A iterA ,ITER_A endA ,ITER_B iterB
208  )const{
209  T res = static_cast<T>(0.0);
210  while(iterA!=endA){
211  const T aa=static_cast<T>(*iterA);
212  const T bb=static_cast<T>(*iterB);
213  res+=std::sqrt(aa*bb);
214  ++iterA;
215  ++iterB;
216  }
217  return std::sqrt( static_cast<T>(1.0)-res);
218  }
219  };
220 
221  enum MetricType{
222  ChiSquaredMetric=0,
223  HellingerMetric=1,
224  SquaredNormMetric=2,
225  NormMetric=3,
226  ManhattanMetric=4,
227  SymetricKlMetric=5,
228  BhattacharyaMetric=6
229  };
230 
231 
232  template<class T>
233  class Metric{
234  public:
235 
236  Metric(const MetricType metricType = ManhattanMetric)
237  : metricType_(metricType){
238 
239  }
240 
241  template<class A, class B>
242  T operator()(const A & a,const B & b)const{
243  switch(static_cast<unsigned int>(metricType_)){
244  case 0:
245  return chiSquared_(a,b);
246  case 1:
247  return hellingerDistance_(a,b);
248  case 2:
249  return squaredNorm_(a,b);
250  case 3:
251  return norm_(a,b);
252  case 4:
253  return manhattan_(a,b);
254  case 5:
255  return symetricKlDivergenz_(a,b);
256  case 6 :
257  return bhattacharyaDistance_(a,b);
258  default :
259  return 0;
260  }
261  }
262  private:
263  MetricType metricType_;
264  ChiSquared<T> chiSquared_;
265  HellingerDistance<T> hellingerDistance_;
266  SquaredNorm<T> squaredNorm_;
267  Norm<T> norm_;
268  Manhattan<T> manhattan_;
269  SymetricKlDivergenz<T> symetricKlDivergenz_;
270  BhattacharyaDistance<T> bhattacharyaDistance_;
271  };
272 
273 } // end namespace metric
274 } // end namepsace vigra
275 
276 
277 #endif //VIGRA_METRIC_HXX
NumericTraits< V >::Promote sum(TinyVectorBase< V, SIZE, D1, D2 > const &l)
sum of the vector's elements
Definition: tinyvector.hxx:2073
linalg::TemporaryMatrix< T > log(MultiArrayView< 2, T, C > const &v)
FFTWComplex< R >::NormType abs(const FFTWComplex< R > &a)
absolute value (= magnitude)
Definition: fftw3.hxx:1002
SquareRootTraits< FixedPoint< IntBits, FracBits > >::SquareRootResult sqrt(FixedPoint< IntBits, FracBits > v)
square root.
Definition: fixedpoint.hxx:616

© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de)
Heidelberg Collaboratory for Image Processing, University of Heidelberg, Germany

html generated using doxygen and Python
vigra 1.11.0