cmeans.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 
22 #include <mia/core/probmap.hh>
24 #include <mia/core/factory.hh>
25 
27 
28 
29 
31 public:
32  typedef std::vector<double> DVector;
34  typedef std::vector<std::pair<double, double>> NormalizedHistogram;
35 
37  public:
38  typedef std::pair<unsigned short, DVector> value_type;
39  typedef std::vector<value_type> Map;
40 
41  SparseProbmap() = delete;
42  SparseProbmap (size_t size);
43  SparseProbmap (const std::string& filename);
44 
45  value_type& operator [](int i){
46  return m_map[i];
47  }
48 
49  const value_type& operator [](int i) const{
50  return m_map[i];
51  }
52 
53  Map::const_iterator begin() const {
54  return m_map.begin();
55  }
56  Map::iterator begin() {
57  return m_map.begin();
58  }
59 
60  Map::const_iterator end() const {
61  return m_map.end();
62  }
63  Map::iterator end() {
64  return m_map.end();
65  }
66 
67  bool save(const std::string& filename) const;
68 
69 
70  DVector get_fuzzy(double x) const;
71 
72  size_t size() const {
73  return m_map.size();
74  }
75  private:
76  Map m_map;
77 
78  };
79 
80 
82  public:
85  static const char *data_descr;
86  static const char *type_descr;
87  virtual DVector run(const NormalizedHistogram& nh) const = 0;
88  };
89  typedef std::shared_ptr<Initializer> PInitializer;
90 
91  CMeans(double epsilon, PInitializer class_center_initializer);
92 
93  ~CMeans();
94 
95  SparseProbmap run(const SparseHistogram& histogram, DVector& class_centers) const;
96 
97  SparseProbmap run(const SparseHistogram& histogram, DVector& class_centers, bool de_normalize_results) const;
98 
99 private:
100  PInitializer m_cci;
101  struct CMeansImpl *impl;
102 
103 };
104 
133 template <typename T, template <class > class Field>
134 void cmeans_evaluate_probabilities(const Field<T>& image, const Field<float>& gain,
135  const std::vector<double>& class_centers,
136  std::vector<Field<float>>& pv)
137 {
138  assert(image.size() == gain.size());
139  assert(class_centers.size() == pv.size());
140 #ifndef NDEBUG
141  for (auto i: pv)
142  assert(image.size() == i.size());
143 #endif
144 
145  auto ii = image.begin();
146  auto ie = image.end();
147  auto ig = gain.begin();
148  typedef typename Field<float>::iterator prob_iterator;
149 
150  std::vector<prob_iterator> ipv(pv.size());
151  transform(pv.begin(), pv.end(), ipv.begin(), [](Field<float>& p){return p.begin();});
152 
153  std::vector<double> gain_class_centers(class_centers.size());
154 
155  while (ii != ie) {
156  double x = *ii;
157  for(auto iipv: ipv)
158  *iipv = 0.0;
159 
160  const double vgain = *ig;
161  transform(class_centers.begin(), class_centers.end(), gain_class_centers.begin(),
162  [vgain](double x){return vgain * x;});
163 
164  if ( x < gain_class_centers[0]) {
165  *ipv[0] = 1.0;
166  } else {
167  unsigned j = 1;
168  bool value_set = false;
169  while (!value_set && (j < class_centers.size()) ) {
170  // between two centers
171  if (x < gain_class_centers[j]) {
172 
173  double p0 = x - gain_class_centers[j-1];
174  double p1 = x - gain_class_centers[j];
175  double p02 = p0 * p0;
176  double p12 = p1 * p1;
177  double normalizer = 1.0/(p02 + p12);
178  *ipv[j] = p02 * normalizer;
179  *ipv[j - 1] = p12 * normalizer;
180  value_set = true;
181  }
182  ++j;
183  }
184  if (!value_set)
185  *ipv[class_centers.size() - 1] = 1.0;
186  }
187  ++ii; ++ig;
188  for (unsigned i = 0; i < class_centers.size(); ++i)
189  ++ipv[i];
190  }
191 }
192 
214 template <typename T, template <class> class Field>
215 double cmeans_update_class_centers(const Field<T>& image, const Field<float>& gain,
216  const std::vector<Field<float>>& pv,
217  std::vector<double>& class_centers)
218 {
219  double residuum = 0.0;
220 
221  for (size_t i = 0; i < class_centers.size(); ++i) {
222  double cc = class_centers[i];
223  double sum_prob = 0.0;
224  double sum_weight = 0.0;
225 
226  auto ie = image.end();
227  auto ii = image.begin();
228  auto ig = gain.begin();
229  auto ip = pv[i].begin();
230 
231  while (ii != ie) {
232  if (*ip > 0.0) {
233  auto v = *ip * *ip * *ig;
234  sum_prob += v * *ig;
235  sum_weight += v * *ii;
236  }
237  ++ii;
238  ++ig;
239  ++ip;
240  }
241 
242 
243  if (sum_prob != 0.0) // move slowly in the direction of new center
244  cc = sum_weight / sum_prob;
245  else {
246  cvwarn() << "class[" << i << "] has no probable members, keeping old value:" <<
247  sum_prob << ":" <<sum_weight <<"\n";
248 
249  }
250  double delta = (cc - class_centers[i]) * 0.5;
251  residuum += delta * delta;
252  class_centers[i] += delta;
253 
254  }// end update class centers
255  return sqrt(residuum);
256 }
257 
258 
260 
261 // the class that has only the size as a parameter
263 public:
264  CMeansInitializerSizedPlugin(const char *name);
265 protected:
266  size_t get_size_param() const;
267 private:
268  size_t m_size;
269 
270 };
271 
273 #ifdef __GNUC__
274 #pragma GCC diagnostic push
275 #pragma GCC diagnostic ignored "-Wattributes"
276 #endif
278 extern template class EXPORT_CORE TFactory<CMeans::Initializer>;
279 #ifdef __GNUC__
280 #pragma GCC diagnostic pop
281 #endif
285 
286 template <> const char * const TPluginHandler<TFactory<CMeans::Initializer>>::m_help;
287 
288 
290 
294 
295 
297 
std::shared_ptr< Initializer > PInitializer
Definition: cmeans.hh:89
the singleton that a plug-in handler really is
Definition: handler.hh:157
THandlerSingleton< TFactoryPluginHandler< CMeansInitializerPlugin > > CMeansInitializerPluginHandler
Definition: cmeans.hh:289
double cmeans_update_class_centers(const Field< T > &image, const Field< float > &gain, const std::vector< Field< float >> &pv, std::vector< double > &class_centers)
Definition: cmeans.hh:215
TFactory< CMeans::Initializer > CMeansInitializerPlugin
Definition: cmeans.hh:259
std::vector< value_type > Map
Definition: cmeans.hh:39
#define NS_MIA_BEGIN
conveniance define to start the mia namespace
Definition: defines.hh:33
Definition: cmeans.hh:30
Initializer plugin_data
Definition: cmeans.hh:83
CSparseHistogram::Compressed SparseHistogram
Definition: cmeans.hh:33
Map::const_iterator begin() const
Definition: cmeans.hh:53
Map::iterator end()
Definition: cmeans.hh:63
#define FACTORY_TRAIT(F)
This is tha base of all plugins that create "things", like filters, cost functions time step operator...
Definition: factory.hh:49
std::pair< unsigned short, DVector > value_type
Definition: cmeans.hh:38
size_t size() const
Definition: cmeans.hh:72
std::vector< std::pair< int, unsigned long > > Compressed
std::vector< double > DVector
Definition: cmeans.hh:32
Initializer plugin_type
Definition: cmeans.hh:84
Map::const_iterator end() const
Definition: cmeans.hh:60
vstream & cvwarn()
send warnings to this stream adapter
Definition: msgstream.hh:311
#define EXPORT_CORE
Macro to manage Visual C++ style dllimport/dllexport.
Definition: defines.hh:101
The base class for all plug-in created object.
Definition: product_base.hh:40
static const char * data_descr
Definition: cmeans.hh:85
the Base class for all plugn handlers that deal with factory plugins.
Definition: factory.hh:93
static const char * type_descr
Definition: cmeans.hh:86
std::vector< std::pair< double, double > > NormalizedHistogram
Definition: cmeans.hh:34
Map::iterator begin()
Definition: cmeans.hh:56
The generic base for all plug-ins.
Definition: plugin_base.hh:170
The basic template of all plugin handlers.
Definition: handler.hh:56
void cmeans_evaluate_probabilities(const Field< T > &image, const Field< float > &gain, const std::vector< double > &class_centers, std::vector< Field< float >> &pv)
evaluate the probabilities for a c-means classification with gain field
Definition: cmeans.hh:134
#define NS_MIA_END
conveniance define to end the mia namespace
Definition: defines.hh:36