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
36template <typename A, typename B>
37void __assert_type_equal (A& a, B& b)
38{
39 static_assert(sizeof(A) == 0);
40}
41
42template <typename A>
43void __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
53template <template <typename> class Data, typename T>
54struct __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
68template <template <typename> class Data>
69struct __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
93template <class Image>
94struct 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
134template <class Image>
135std::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