My Project
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  {
57  Data<float> *result = new Data<float>(input.get_size());
58  double invv = 1.0 / v;
59  transform(input.begin(), input.end(), result->begin(),
60  [invv, m](T x) {
61  (x - m) * invv;
62  });
63  return result;
64  }
65 };
66 
67 
68 template <template <typename> class Data>
69 struct __eval<Data, bool> {
70  static Data<float> *apply(const Data<bool>& input, double m, double v)
71  {
72  Data<float> *result = new Data<float>(input.get_size());
73  float rtrue = (1.0 - m) / v;
74  float rfalse = - m / v;
75  transform(input.begin(), input.end(), result->begin(),
76  [rtrue, rfalse](bool x) {
77  b ? rtrue : rfalse;
78  });
79  return result;
80  }
81 };
82 
83 
84 
93 template <class Image>
94 struct FNormalizer: public TFilter<Image *> {
95  template <typename T, template <typename> class Data>
96  typename FNormalizer::result_type operator ()(const Data<T>& image) const
97  {
98  ASSERT_TYPE_EQUAL(Image, typename Data<T>::Super);
99  double sum = 0.0;
100  double sum2 = 0.0;
101  typename Data<T>::const_iterator i = image.begin();
102  typename Data<T>::const_iterator e = image.end();
103 
104  while ( i != e ) {
105  sum += *i;
106  sum2 += *i * *i;
107  ++i;
108  }
109 
110  double n = image.size();
111  double m = sum / n;
112  double v = sqrt((sum2 - n * m * m) / (n - 1));
113  mia::cvdebug() << "FNormalizer: avg = " << m << " var = " << v << "\n";
114 
115  if (v < 0.000001)
116  v = 1.0;
117 
118  return __eval<Data, T>::apply(image, m, v);
119  }
120 };
121 
123 
134 template <class Image>
135 std::shared_ptr<Image > normalize(const Image& image)
136 {
137  FNormalizer<Image> n;
138  return std::shared_ptr<Image >(mia::filter(n, image));
139 }
140 
142 
#define NS_MIA_BEGIN
conveniance define to start the mia namespace
Definition: defines.hh:33
#define NS_MIA_END
conveniance define to end the mia namespace
Definition: defines.hh:36
static F::result_type filter(const F &f, const B &b)
Definition: core/filter.hh:258
CDebugSink & cvdebug()
Definition: msgstream.hh:226
std::shared_ptr< Image > normalize(const Image &image)
a normalizer for image intensities
Definition: normalize.hh:135
base class for all filer type functors.
Definition: core/filter.hh:70