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

metrics.hxx |

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
vigra
Definition: accessor.hxx:43
vigra::sum
NumericTraits< V >::Promote sum(TinyVectorBase< V, SIZE, D1, D2 > const &l)
sum of the vector&#39;s elements
Definition: tinyvector.hxx:2073
vigra::linalg::log
linalg::TemporaryMatrix< T > log(MultiArrayView< 2, T, C > const &v)
vigra::abs
FFTWComplex< R >::NormType abs(const FFTWComplex< R > &a)
absolute value (= magnitude)
Definition: fftw3.hxx:1002
vigra::sqrt
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