normalize.hh
Go to the documentation of this file.
1 /* -*- mia-c++ -*-
2  *
3  * This file is part of MIA - a toolbox for medical image analysis
4  * Copyright (c) Leipzig, Madrid 1999-2017 Gert Wollny
5  *
6  * MIA is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with MIA; if not, see <http://www.gnu.org/licenses/>.
18  *
19  */
20 
21 #include <cmath>
22 #include <iostream>
23 #include <memory>
24 #include <mia/core/filter.hh>
25 #include <mia/core/msgstream.hh>
26 
28 
36 template <typename A, typename B>
37 void __assert_type_equal (A& a, B& b)
38 {
39  static_assert(sizeof(A) == 0);
40 }
41 
42 template <typename A>
43 void __assert_type_equal (A& /*a*/, A& /*b*/)
44 {
45 }
46 
47 #define ASSERT_TYPE_EQUAL(A, B) \
48  { \
49  A *a; B *b; \
50  __assert_type_equal(a,b); \
51  }
52 
53 template <template <typename> class Data, typename T>
54 struct __eval {
55  static Data<float> *apply(const Data<T> &input, double m, double v) {
56  Data<float> *result = new Data<float>(input.get_size());
57  double invv = 1.0/v;
58  transform(input.begin(), input.end(), result->begin(),
59  [invv,m](T x){(x - m) * invv;});
60  return result;
61  }
62 };
63 
64 
65 template <template <typename> class Data>
66 struct __eval<Data, bool> {
67  static Data<float> *apply(const Data<bool> &input, double m, double v) {
68 
69  Data<float> *result = new Data<float>(input.get_size());
70  float rtrue = (1.0 - m) / v;
71  float rfalse = - m / v;
72 
73  transform(input.begin(), input.end(), result->begin(),
74  [rtrue, rfalse](bool x){b ? rtrue : rfalse;});
75  return result;
76  }
77 };
78 
79 
80 
89 template <class Image>
90 struct FNormalizer: public TFilter<Image *>
91 {
92  template <typename T, template <typename> class Data>
93  typename FNormalizer::result_type operator ()(const Data<T> &image) const {
94  ASSERT_TYPE_EQUAL(Image, typename Data<T>::Super);
95  double sum = 0.0;
96  double sum2 = 0.0;
97  typename Data<T>::const_iterator i = image.begin();
98  typename Data<T>::const_iterator e = image.end();
99  while ( i != e ) {
100  sum += *i;
101  sum2 += *i * *i;
102  ++i;
103  }
104  double n = image.size();
105  double m = sum / n;
106  double v = sqrt((sum2 - n * m * m) / (n - 1));
107 
108  mia::cvdebug() << "FNormalizer: avg = " << m << " var = " << v << "\n";
109 
110  if (v < 0.000001)
111  v = 1.0;
112 
113  return __eval<Data, T>::apply(image, m, v);
114 
115  }
116 };
117 
119 
130 template <class Image>
131 std::shared_ptr<Image > normalize(const Image& image)
132 {
133  FNormalizer<Image> n;
134  return std::shared_ptr<Image >(mia::filter(n, image));
135 }
136 
138 
CDebugSink & cvdebug()
Definition: msgstream.hh:216
base class for all filer type functors.
Definition: core/filter.hh:70
std::shared_ptr< Image > normalize(const Image &image)
a normalizer for image intensities
Definition: normalize.hh:131
#define NS_MIA_BEGIN
conveniance define to start the mia namespace
Definition: defines.hh:33
static F::result_type filter(const F &f, const B &b)
Definition: core/filter.hh:250
#define NS_MIA_END
conveniance define to end the mia namespace
Definition: defines.hh:36