aimsalgo  5.1.2
Neuroimaging image processing
ppca_d.h
Go to the documentation of this file.
1 /* This software and supporting documentation are distributed by
2  * Institut Federatif de Recherche 49
3  * CEA/NeuroSpin, Batiment 145,
4  * 91191 Gif-sur-Yvette cedex
5  * France
6  *
7  * This software is governed by the CeCILL-B license under
8  * French law and abiding by the rules of distribution of free software.
9  * You can use, modify and/or redistribute the software under the
10  * terms of the CeCILL-B license as circulated by CEA, CNRS
11  * and INRIA at the following URL "http://www.cecill.info".
12  *
13  * As a counterpart to the access to the source code and rights to copy,
14  * modify and redistribute granted by the license, users are provided only
15  * with a limited warranty and the software's author, the holder of the
16  * economic rights, and the successive licensors have only limited
17  * liability.
18  *
19  * In this respect, the user's attention is drawn to the risks associated
20  * with loading, using, modifying and/or developing or reproducing the
21  * software by the user in light of its specific status of free software,
22  * that may mean that it is complicated to manipulate, and that also
23  * therefore means that it is reserved for developers and experienced
24  * professionals having in-depth computer knowledge. Users are therefore
25  * encouraged to load and test the software's suitability as regards their
26  * requirements in conditions enabling the security of their systems and/or
27  * data to be ensured and, more generally, to use and operate it in the
28  * same conditions as regards security.
29  *
30  * The fact that you are presently reading this means that you have had
31  * knowledge of the CeCILL-B license and that you accept its terms.
32  */
33 
34 
35 
36 #ifndef AIMS_MATH_PPCA_D_H
37 #define AIMS_MATH_PPCA_D_H
38 
39 #include <aims/math/svd.h>
40 #include <aims/math/ppca.h>
41 #include <aims/math/mathelem.h>
42 #include <aims/math/gausslu.h>
43 #include <aims/io/writer.h>
45 
46 
47 namespace aims
48 {
49 
50  template <typename T>
51  void
52  ProbabilisticPcaElement::doIt( const std::list< Point3d >& selectedPoints,
53  const carto::rc_ptr<carto::Volume<T> > & data,
54  double distanceRef )
55  {
56  if( selectedPoints.size() <= (unsigned) data->getSizeT() )
57  {
58  _valid = false ;
59  _computed = true ;
60  return ;
61  }
62  _valid = true ;
63  carto::VolumeRef<T> individuals(
64  std::max(int(selectedPoints.size()), 1), data->getSizeT(), 1, 1,
65  carto::AllocatorContext::fast() );
66  int i = 0 ;
67  std::list< Point3d >::const_iterator iter( selectedPoints.begin() ),
68  last( selectedPoints.end() ) ;
69  Point3df mean ;
70 
71  while( iter != last )
72  {
73  for(int t = 0 ; t < data->getSizeT() ; ++t )
74  individuals( i, t ) = T( data->at( (*iter)[0], (*iter)[1], (*iter)[2],
75  t ) ) ;
76  ++i ; ++iter ;
77  //std::cout << "Indiv " << i << " = " << *iter << std::endl ;
78  mean += Point3df( (*iter)[0], (*iter)[1], (*iter)[2] ) ;
79  }
80  //std::cout << "Center = " << mean / float( individuals.getSizeX() )
81  // << std::endl ;
82  doIt( individuals, distanceRef ) ;
83  }
84 
85  template <typename T>
86  void
88  const carto::rc_ptr<carto::Volume<T> > & matriceIndiv, double distanceRef )
89  {
90  _distanceRef = distanceRef ;
91 
93  matriceIndiv->getSizeY(), 1, 1, 1, carto::AllocatorContext::fast() ) ;
94  _xT = carto::VolumeRef<double>( 1, matriceIndiv->getSizeY(), 1, 1,
95  carto::AllocatorContext::fast() );
96  /* int ignoreVPs = 0 ; */
97  std::cout << "toto" << std::endl << std::endl ;
98 
99  if( matriceIndiv->getSizeX() <= matriceIndiv->getSizeY() )
100  {
101  _valid = false ;
102  _computed = true ;
103  return ;
104  }
105  _valid = true ;
106 
107  //----------------- Just for testing to separate kidney core and cortex
108  int ignoreVPs = 0 ;
109 
110  _computed = true ;
111  int nbFrame = matriceIndiv->getSizeY() ;
112 
113  if( matriceIndiv->getSizeY() < nbFrame )
114  std::cerr << "Beware : not enough data to evaluate svd" << std::endl ;
115 
116  carto::VolumeRef<double> centeredIndivMatrix(
117  matriceIndiv->getSizeX(), matriceIndiv->getSizeY(), 1, 1,
118  carto::AllocatorContext::fast() );
119  _mean = carto::VolumeRef<double>( matriceIndiv->getSizeY(), 1, 1, 1,
120  carto::AllocatorContext::fast() );
121  _mean = 0. ;
122  T val ;
123  for( int ind = 0 ; ind < matriceIndiv->getSizeX() ; ++ind )
124  for( int t = 0 ; t < matriceIndiv->getSizeY() ; ++t )
125  {
126  val = matriceIndiv->at( ind, t ) ;
127  _mean(t) += val ;
128  }
129 
130  //TEMP
131  double meanMean = 0. ;
132  //END TEMP
133 
134  for( int t = 0 ; t < nbFrame ; ++t )
135  {
136  _mean.at(t) /= centeredIndivMatrix->getSizeX() ;
137  for( int ind = 0 ; ind < centeredIndivMatrix->getSizeX() ; ++ind )
138  {
139  centeredIndivMatrix( ind, t ) = matriceIndiv->at(ind, t) - _mean(t) ;
140  meanMean += centeredIndivMatrix( ind, t ) ;
141  }
142  }
143  std::cout << "Mean centered mean = " << meanMean << " (should be 0) " << std::endl ;
144 
145  /* std::cout << "Mean : " ; */
146  /* for( int i = 0 ; i < _mean->getSizeX() ; ++ i ){ */
147  /* std::cout << _mean(i) << " " ; */
148  /* } */
149  /* std::cout << std::endl << _meanMean << std::endl ; */
150 
151 // Writer< carto::VolumeRef< double> > wri02( "centeredIndiv.ima" ) ;
152 // wri02.write(centeredIndivMatrix) ;
153 
154  // Matrice des correlations
155  carto::VolumeRef<double> matVarCov( nbFrame, nbFrame, 1, 1,
156  carto::AllocatorContext::fast() ) ;
157  int x, y, dx = matVarCov->getSizeX(), dy = matVarCov->getSizeY();
158 
159  for( y=0; y<dy; ++y )
160  for( x=0; x<dx; ++x )
161  {
162  for(int k=0; k < centeredIndivMatrix->getSizeX() ;++k)
163  matVarCov(x, y) += centeredIndivMatrix(k, x)
164  * centeredIndivMatrix(k, y);
165  matVarCov(x, y) /= centeredIndivMatrix->getSizeX() - 1 ;
166  }
167 
168 // Writer< carto::VolumeRef< double> > wriMVC( "matVarCov.ima" ) ;
169 // wriMVC.write(matVarCov) ;
170 
171  // Decomposition SVD
172  AimsSVD< double > svd;
174  _EValues = svd.doit( matVarCov );
175 // Writer< carto::VolumeRef< double> > wri04( "eValAvant.ima" ) ;
176 // wri04.write(_EValues) ;
177 
178 // Writer< carto::VolumeRef< double> > wriMVC2( "matVarCov2.ima" ) ;
179 // wriMVC2.write((matVarCov.clone().transpose()).cross( _EValues.cross(matVarCov) ) ) ;
180 //
181 // Writer< carto::VolumeRef< double> > wriMVC3( "matVarCov3.ima" ) ;
182 // wriMVC3.write((matVarCov).cross( _EValues.cross(matVarCov.clone().transpose()) ) ) ;
183 
184  svd.sort(matVarCov, _EValues) ;
185 // Writer< carto::VolumeRef< double> > wri05( "eValApres.ima" ) ;
186 // wri05.write(_EValues) ;
187 
189  carto::AllocatorContext::fast() ) ;
190  for( int i = 0 ; i < nbFrame ; ++i )
191  for( int j = 0 ; j < _nbOfSignificantEV ; ++j )
192  _EVect(i, j) = matVarCov(i, j) ;
193 
194  _Sigma2 = 0. ;
195  for( int i = _nbOfSignificantEV + ignoreVPs ; i < nbFrame ; ++i )
196  _Sigma2 += _EValues(i, i) ;
197 
198  _Sigma2 /= double(nbFrame - ( _nbOfSignificantEV + ignoreVPs ) ) ;
199 
200  for( int c = 0 ; c < _EValues->getSizeX() ; ++c )
201  std::cout << "\tLamda " << c+1 << "EValue = " << _EValues(c, c) ;
202  std::cout <<"\tSigma2 = " << _Sigma2 << std::endl ;
203 
204 // std::cout << "Lamda 1 = " << _EValues(0, 0) << "Lamda 2 = "
205 // << _EValues(1, 1)
206 // <<"\tSigma2 = " << _Sigma2 << std::endl ;
207 
210  carto::AllocatorContext::fast() );
211 
212  for( int i = 0; i < _nbOfSignificantEV ; ++i )
213  _Wi(i, i) = sqrt( _EValues(i) - _Sigma2 ) ;
214 
215  std::cout << "_Wi.dimZ = " << _Wi->getSizeZ()
216  << "\t_Wi.dimT = " << _Wi->getSizeT() << std::endl ;
217 
218  std::cout << "_EVect.dimZ = " << _EVect->getSizeZ()
219  << "\t_EVect.dimT = " << _EVect->getSizeT() << std::endl ;
220 
222 // Writer< carto::VolumeRef< double> > wri0( "Wi.ima" ) ;
223 // wri0.write(_Wi) ;
224 
226 // Writer< carto::VolumeRef< double > > wri1( "Wi2.ima" ) ;
227 // wri1.write(Ci) ;
228 
229  for( y=0; y<dy; ++y )
230  for( x=0; x<dx; ++x )
231  if( x < y )
232  {
233  double val = 0.5 * ( Ci(x, y) + Ci(y, x) ) ;
234  Ci(x, y) = Ci(y, x) = val ;
235  }
236 
237  for( int i = 0; i < nbFrame ; ++i )
238  Ci(i, i) += _Sigma2 ;
239 
240 // Writer< carto::VolumeRef< double> > wri2( "Ci.ima" ) ;
241 // wri2.write(Ci) ;
242 
243  //-------------------------------------------------------------------------
244  double s = 0.00000001 ;
245  carto::VolumeRef< double > u = Ci.deepcopy(); // because it is replaced on SVD output
246  carto::VolumeRef< double > v( Ci->getSizeY(), Ci->getSizeY(), 1, 1,
247  carto::AllocatorContext::fast() );
248 
249  AimsSVD< double > svd2;
250  carto::VolumeRef< double > w = svd2.doit( u, &v );
251 
252  // Set the singular values lower than threshold to zero
253  double ts = s * w.max();
254  int i, n = w->getSizeX();
255  _detCi = 1. ;
256  short unkept = 0 ;
257  for ( i=0; i<n; i++ )
258  {
259  _detCi *= w( i, i ) / _Sigma2 ;
260  if ( w( i, i ) > ts ) w( i, i ) = 1.0f / w( i, i );
261  else {
262  w( i, i ) = 0.0f;
263  ++unkept ;
264  }
265  }
266 
267  std::cout << "Unkept values = " << unkept << std::endl ;
268 
269  _invCi = matrix_product( v, matrix_product( w, transpose( u ) ) );
270 
271 // Writer< carto::VolumeRef< double> > wriI( "invCi.ima" ) ;
272 // wriI.write(_invCi) ;
273 
274  //TEMP
275  carto::VolumeRef<float> ciFloat = Ci.deepcopy();
276 
277 // Writer< carto::VolumeRef< float> > wriI2( "invCi2.ima" ) ;
278 // wriI2.write( AimsInversionLU(ciFloat) ) ;
279 
280 // Writer< carto::VolumeRef< float> > wriI3( "invCi3.ima" ) ;
281 // wriI3.write( AimsInversionLU( AimsInversionLU(ciFloat) ) ) ;
282  // END TEMP
283 
284  std::cout << "_invCiInside.dimZ = " << _invCi->getSizeZ()
285  << "\t_invCiInside.dimT = " << _invCi->getSizeT() << std::endl ;
286 
287 // _normFactor = 1. / ( pow( 2*M_PI, nbFrame/2. ) * pow( _detCi, 0.5 )
288 // * pow( _Sigma2, nbFrame/2. ) ) ;
289  _normFactor = 1. / ( pow(_detCi, 0.5 ) * pow( _Sigma2, nbFrame/2. ) ) ;
290 
291  std::cout << "-0.5 * log( _detCi ) = " << -0.5 * log( _detCi ) << "\t log(_PIj) = " << log(_PIj) << std::endl ;
292  //x << "- (nbFrame/2) * log(_Sigma2) = " << - (nbFrame/2) * log(_Sigma2) << std::endl ;
293 
294  _lnAddFactor = log( 1. / sqrt(_detCi) / pow( _Sigma2, nbFrame/2. ) ) ;
295  //_lnAddFactor = -0.5 * log( _detCi ) /*+ log(_PIj)*/ - (nbFrame/2) * log(_Sigma2) ;
296 
297 
298  //_lnAddFactor = log( _detCi / ( _PIj * _PIj ) ) + nbFrame * log( _Sigma2 ) ;
299 
300  std::cout << "Det Ci = " << _detCi << "\tNorm Factor = " << _normFactor
301  << "\tLn Add Factor = " << _lnAddFactor << "\tCorresp factor = " << exp(_lnAddFactor)<< std::endl ;
302 
303 // carto::VolumeRef<float> invCi2( AimsInversionLU(ciFloat) ) ;
304 // ForEach2d(matVarCov, x, y){
305 // CiT(y, x) = Ci(x, y) ;
306 // CiD(x, y) = Ci(x, y) - Ci(y, x) ;
307 // invCiT(y, x) = _invCi(x, y) ;
308 // invCiD(x, y) = _invCi(x, y) - _invCi(y, x) ;
309 // invCi2T(y, x) = invCi2(x, y) ;
310 // invCi2D(x, y) = invCi2(x, y) - invCi2(y, x) ;
311 // // Wi2T(y, x) = Wi2(x, y) ;
312 // // Wi2D(x, y) = Wi2(x, y) - Wi2(y, x) ;
313 // }
314 // Writer< carto::VolumeRef<double> > w1("matVarCovT.ima") ;
315 // w1.write(matVarCovT) ;
316 // Writer< carto::VolumeRef<double> > w2("matVarCovD.ima") ;
317 // w2.write(matVarCovD) ;
318 // Writer< carto::VolumeRef<double> > w3("CiT.ima") ;
319 // w3.write(CiT) ;
320 // Writer< carto::VolumeRef<double> > w4("CiD.ima") ;
321 // w4.write(CiD) ;
322 // Writer< carto::VolumeRef<double> > w5("invCiT.ima") ;
323 // w5.write(invCiT) ;
324 // Writer< carto::VolumeRef<double> > w6("invCiD.ima") ;
325 // w6.write(invCiD) ;
326 // Writer< carto::VolumeRef<double> > w7("invCi2T.ima") ;
327 // w7.write(invCi2T) ;
328 // Writer< carto::VolumeRef<double> > w8("invCi2D.ima") ;
329 // w8.write(invCi2D) ;
330 
331  for( y=0; y<dy; ++y )
332  for( x=0; x<dx; ++x )
333  if( x < y )
334  {
335  double val = 0.5 * ( _invCi(x, y) + _invCi(y, x) ) ;
336  _invCi(x, y) = _invCi(y, x) = val ;
337  }
338 // ForEach2d( matVarCov, x, y )
339 // invCiD(x, y) = _invCi(x, y) - _invCi(y, x) ;
340 
341 // Writer< carto::VolumeRef<double> > w9("invCiSymD.ima") ;
342 // w9.write(invCiD) ;
343 
344  }
345 
346  template <class T>
347  double
349  const carto::rc_ptr<carto::Volume<T> > & matriceIndiv,
350  double & meanNorm ) const
351  {
352  int ignoreVPs = 0 ;
353 
354  int nbFrame = matriceIndiv->getSizeY() ;
355 
356  if( matriceIndiv->getSizeY() < nbFrame )
357  std::cerr << "Beware : not enough data to evaluate svd" << std::endl ;
358 
359  //-------------------TMP-------------------------------
360  //carto::VolumeRef<T> indMatCopy(matriceIndiv.clone()) ;
361  //Writer< carto::VolumeRef<T> > indWri("indiv.ima") ;
362  //indWri.write(indMatCopy) ;
363 
364  //-------------------TMP-------------------------------
365 
366  carto::VolumeRef<double> centeredIndivMatrix(
367  matriceIndiv->getSizeX(), matriceIndiv->getSizeY(), 1, 1,
368  carto::AllocatorContext::fast() ) ;
369  carto::VolumeRef<double> mean( matriceIndiv->getSizeY(), 1, 1, 1,
370  carto::AllocatorContext::fast() ) ;
371 
372  for( int ind = 0 ; ind < matriceIndiv->getSizeX() ; ++ind )
373  for( int t = 0 ; t < matriceIndiv->getSizeY() ; ++t )
374  mean(t) += matriceIndiv->at( ind, t ) ;
375 
376 
377  meanNorm = 0. ;
378  for( int t = 0 ; t < nbFrame ; ++t )
379  {
380  mean(t) /= centeredIndivMatrix->getSizeX() ;
381  meanNorm += mean(t) * mean(t);
382  for( int ind = 0 ; ind < centeredIndivMatrix->getSizeX() ; ++ind )
383  {
384  centeredIndivMatrix( ind, t ) = matriceIndiv->at(ind, t) - mean(t);
385  }
386  }
387  meanNorm /= mean->getSizeX();
388 
389 
390  // Matrice des correlations
391  carto::VolumeRef<double> matVarCov( nbFrame, nbFrame, 1, 1,
392  carto::AllocatorContext::fast() );
393  int x, y ;
394  for( y=0; y<nbFrame; ++y )
395  for( x=0; x<nbFrame; ++x )
396  {
397  for(int k=0; k < centeredIndivMatrix->getSizeX() ;++k)
398  matVarCov(x, y) += centeredIndivMatrix(k, x)
399  * centeredIndivMatrix(k, y);
400  matVarCov(x, y) /= centeredIndivMatrix->getSizeX() - 1 ;
401  }
402 
403  //Writer< carto::VolumeRef<T> > indWri("indiv.ima") ;
404  //indWri.write(matriceIndiv) ;
405 
406  //Writer< carto::VolumeRef<double> > matVarWri("matVarCov.ima") ;
407  //matVarWri.write(matVarCov) ;
408 
409  // Decomposition SVD
410  AimsSVD< double > svd;
412  carto::VolumeRef<double> EValues = svd.doit( matVarCov );
413 
414  svd.sort(matVarCov, EValues) ;
415 
416 
417  double Sigma2 = 0. ;
418  for( int i = _nbOfSignificantEV + ignoreVPs ; i < nbFrame ; ++i )
419  Sigma2 += EValues(i, i) ;
420 
421  Sigma2 /= double(nbFrame - ( _nbOfSignificantEV + ignoreVPs ) ) ;
422 
423  return Sigma2 ;
424  }
425 
426 
427  template <class T>
429  const carto::rc_ptr<carto::Volume<T> > & data,
430  const std::vector<
431  std::list< Point3d > >& classes,
432  int nbOfSignificantEigenValues,
433  const std::vector<double>& PIj )
434  :
435  _classes(classes), _data(data), _PIj(PIj),
436  _nbOfSignificantEigenValues(nbOfSignificantEigenValues)
437  {
438  //std::cout << "ProbabilisticPca<T>::ProbabilisticPca classes size "
439  // << _classes.size() << std::endl ;
440  if( PIj.size() != 0 )
441  if( PIj.size() == classes.size() )
442  _PIj = PIj ;
443  else
444  throw std::runtime_error( "Inconsistant data : number of classes and "
445  "number of classes prior probabilities are "
446  "different !") ;
447  else
448  {
449  _PIj.reserve( _classes.size() ) ;
450  for( unsigned int c = 0 ; c < _classes.size() ; ++c )
451  _PIj.push_back( 1./_classes.size() ) ;
452  }
453 
454  _discrElements.reserve( _classes.size() ) ;
455  _distanceRef = 0. ;
456 
457  // ------------------ TEST ---------------------
458  carto::VolumeRef<double> eigenValues(
459  _data->getSizeT(), _classes.size(), 1, 1,
460  carto::AllocatorContext::fast() ) ;
461  // ------------------ TEST ---------------------
462 
463 
464  for( unsigned int c = 0 ; c < _classes.size() ; ++c )
465  {
466  if( int(_classes[c].size()) > _data->getSizeT() )
467  {
468  ProbabilisticPcaElement el( _nbOfSignificantEigenValues, _PIj[c] ) ;
469  if( c == 0 ){
470  el.doIt( _classes[c], _data ) ;
471  _distanceRef = log( el.normFactor() ) ;
472  std::cout << "Noise Ref = " << _distanceRef << std::endl ;
473  }
474  el.doIt( _classes[c], _data, _distanceRef ) ;
475 
476  // ------------------ TEST ---------------------
477  for( int t = 0 ; t < _data->getSizeT() ; ++t )
478  eigenValues( t, c ) = el.eigenValues()(t) ;
479  // ------------------ TEST ---------------------
480 
481  std::cout << "Class " << c << " done !" << std::endl ;
482  _discrElements.push_back( el ) ;
483  } else {
484  std::cerr << "Not enough data for element " << c << std::endl ;
485  }
486  }
487 
488  // ------------------ TEST ---------------------
489  Writer< carto::VolumeRef<double> > eigenValuesWri( "classesEigenValues.ima") ;
490  eigenValuesWri.write(eigenValues) ;
491  std::cout << "Probabilistic Pca initization completed" << std::endl ;
492  //std::cout << "ProbabilisticPca<T>::ProbabilisticPca end classes size "
493  // << _classes.size() << std::endl ;
494 
495  }
496 
497  template <class T>
498  double
499  ProbabilisticPca<T>::weight( double norm2, int c, float tolerance )
500  { if( tolerance * norm2 > _discrElements[c].meanNorm() )
501  return 1. ;
502  else
503  return 2 * pow( 0.5, _discrElements[c].meanNorm()
504  / (tolerance * tolerance * norm2 ) ) ;
505  }
506 
507  template <class T>
508  double
509  ProbabilisticPca<T>::wienerFilter( double sigma2, double norm2,
510  double factor )
511  {
512  double res = 1 - factor * factor * sigma2 / norm2 ;
513  if( res < 0. )
514  return 0. ;
515  else
516  return res ;
517  }
518 
519  template <class T>
520  std::vector<double>
522  const carto::rc_ptr<carto::Volume<double> > & x, double,
523  std::vector<double>& maxProbaByClass )
524  {
525  //std::cout << "ProbabilisticPca<T>::andersonScores classes size "
526  // << _classes.size() << std::endl ;
527 
528  std::vector<double> res( _discrElements.size() ) ;
529  //std::cout << "Nb of classes "<< _discrElements.size()<< std::endl ;
530  double scoreSum = 0. ;
531  for( unsigned int c = 0 ; c < _discrElements.size() ; ++c )
532  {
533  //std::cout << "Class " << c << std::endl ;
534 
535  res[c] = _discrElements[c].posteriorProbability( x, 1 ) * _PIj[c] ;
536  if( res[c] > maxProbaByClass[c] )
537  maxProbaByClass[c] = res[c] ;
538  scoreSum += res[c] ;
539  }
540 
541  for( unsigned int c = 0 ; c < _discrElements.size() ; ++c )
542  {
543  res[c] /= scoreSum ;
544  //std::cout << "\t" << res[c] ;
545  }
546  //std::cout << std::endl ;
547 
548  return res ;
549  }
550 
551  template <class T>
552  std::vector<double>
555  double,
556  std::vector<double>&
557  maxProbaByClass )
558  {
559  std::vector<double> res( _discrElements.size() ) ;
560  /* std::vector<double> normFactor ( _classes.size() ) ; */
561  /* for( int i = 0 ; i < _classes.size() ; ++i ) */
562  /* normFactor[i] = pow( _discrElements[c].noiseVariance()
563  / _discrElements[0].noiseVariance(), x->getSizeX() / 2. ) ; */
564 
565  for( unsigned int c = 0 ; c < _discrElements.size() ; ++c )
566  {
567  res[c] = _discrElements[c].posteriorProbability( x, 1 ) ;
568  if( res[c] > maxProbaByClass[c] )
569  maxProbaByClass[c] = res[c] ;
570  /* * *//* wienerFilter( _discrElements[c].noiseVariance(),
571  norm2, 5. ) ; */
572  /* _discrElements[c].normalizedPosteriorProbability( x, 1, norm2 )
573  *//* * weight(norm2, c, 3) */ ;
574  }
575  return res ;
576  }
577 
578  template <class T>
579  int
582  {
583  double lnP ;
584  double lnPMin = _discrElements[0].lnPosteriorProbability( x ) ;
585  int indMin = 0 ;
586  for( unsigned int c = 0 ; c < _discrElements.size() ; ++c )
587  {
588  lnP = _discrElements[c].lnPosteriorProbability( x ) ;
589  //std::cout << "Classe " << c << " : lnP = "<< lnP << std::endl ;
590  if( lnP < lnPMin ){
591  lnPMin = lnP ;
592  indMin = c ;
593  }
594  }
595 
596  //std::cout << "lnPMin = "<< lnPMin << std::endl ;
597  return indMin ;
598  }
599 
600 
601  template <class T>
602  bool
604  const carto::rc_ptr<carto::Volume<T> > & dynamicImage,
606  carto::rc_ptr<carto::Volume<short> > & segmented )
607  {
608  int x, y, z ;
609  if( dynamicImage->getSizeT() != _data->getSizeT() )
610  return false ;
611  if( segmented->getSizeX() != _data->getSizeX() || segmented->getSizeY() != _data->getSizeY()
612  || segmented->getSizeZ() != _data->getSizeZ() )
613  {
614  segmented = carto::VolumeRef<short> ( _data->getSizeX(), _data->getSizeY(),
615  _data->getSizeZ() ) ;
616  segmented->setVoxelSize( _data->getVoxelSize() ) ;
617  }
618 
619  carto::VolumeRef<double> indiv( dynamicImage->getSizeT(), 1, 1, 1,
620  carto::AllocatorContext::fast() ) ;
621  std::vector<int> dim = dynamicImage->getSize();
622  for( z=0; z<dim[2]; ++z )
623  for( y=0; y<dim[1]; ++y )
624  for( x=0; x<dim[0]; ++x )
625  {
626  if( mask->at(x, y, z) )
627  {
628  //std::cout << "x : " << x << ", y : " << y << ", z : " << z
629  // << std::endl ;
630  for( int t = 0 ; t < _data->getSizeT() ; ++t )
631  indiv(t) = dynamicImage->at(x, y, z, t ) ;
632  segmented->at(x, y, z) = affectedTo( indiv ) ;
633  //std::cout << " affected To " << segmented(x, y, z) << std::endl ;
634  }
635  }
636 
637  std::cout << "Probabilistic Pca classification completed" << std::endl ;
638 
639  return true ;
640  }
641 
642  template <class T>
643  bool
645  const carto::rc_ptr<carto::Volume<T> > & dynamicImage,
647  carto::rc_ptr<carto::Volume<float> > & fuzzySegmented,
648  double /* probaThreshold */,
649  double /* andersonScoreThreshold*/,
650  const carto::rc_ptr<carto::Volume<double> > & indivPriorProbabilities )
651  {
652  bool noPriorProba =
653  ( indivPriorProbabilities->getSizeX( ) == 1
654  && indivPriorProbabilities->getSizeY( ) == 1
655  && indivPriorProbabilities->getSizeZ( ) == 1 ) ;
656  int count = 0 ;
657  //double uniformPriorProba ;
658  int x, y, z ;
659  if( noPriorProba )
660  {
661  std::vector<int> mdim = mask->getSize();
662  for( z=0; z<mdim[2]; ++z )
663  for( y=0; y<mdim[1]; ++y )
664  for( x=0; x<mdim[0]; ++x )
665  if( mask->at( x, y, z ) )
666  ++count ;
667  //uniformPriorProba = 1. / count ;
668  }
669  if( dynamicImage->getSizeT() != _data->getSizeT() )
670  return false ;
671  if( fuzzySegmented->getSizeX() != _data->getSizeX()
672  || fuzzySegmented->getSizeY() != _data->getSizeY() ||
673  fuzzySegmented->getSizeZ() != _data->getSizeZ()
674  || fuzzySegmented->getSizeT() != int(_classes.size() ) )
675  {
676  fuzzySegmented.reset( new carto::Volume<float>(
677  _data->getSizeX(), _data->getSizeY(),
678  _data->getSizeZ(), _classes.size() ) );
679  fuzzySegmented->setVoxelSize( _data->getVoxelSize() );
680  }
681 
682  std::vector<double> probabilityRepartition ;
683  std::vector<double> maxProbaByClass( _discrElements.size(), 0. ) ;
684  std::vector<double> max( _discrElements.size(), 0. ) ;
685  carto::VolumeRef<double> indiv( dynamicImage->getSizeT(), 1, 1, 1,
686  carto::AllocatorContext::fast() ) ;
687  carto::VolumeRef<double> maxOnClass( dynamicImage->getSizeX(),
688  dynamicImage->getSizeY(),
689  dynamicImage->getSizeZ() );
690 
691  std::vector<int> ddim = dynamicImage->getSize();
692  for( z=0; z<ddim[2]; ++z )
693  for( y=0; y<ddim[1]; ++y )
694  for( x=0; x<ddim[0]; ++x )
695  {
696  if( mask->at(x, y, z) )
697  {
698  double norm = 0. ;
699  /* std::cout << "x : " << x << ", y : " << y << ", z : " << z
700  << std::endl ; */
701  for( int t = 0 ; t < _data->getSizeT() ; ++t )
702  {
703  indiv(t) = dynamicImage->at(x, y, z, t ) ;
704  norm += indiv(t) * indiv(t);
705  }
706  /* probabilityRepartition = posteriorProbabilities( indiv, norm,
707  maxProbaByClass ) ; */
708  probabilityRepartition = andersonScores(indiv, norm,
709  maxProbaByClass) ;
710  for( int c = 0 ; c < fuzzySegmented->getSizeT() ; ++c )
711  {
712  fuzzySegmented->at(x, y, z, c) = probabilityRepartition[c] ;
713  if( probabilityRepartition[c] > max[c] )
714  max[c] = probabilityRepartition[c] ;
715  if( probabilityRepartition[c] > maxOnClass(x, y, z) )
716  maxOnClass(x, y, z) = probabilityRepartition[c] ;
717  }
718  }
719  }
720 
721  std::cout << "Max on c = " ;
722  for( int c = 0 ; c < fuzzySegmented->getSizeT() ; ++c )
723  std::cout << max[c] << " " << std::endl ;
724 
725 // Writer< carto::VolumeRef< float> > fuzzySegmentedW( "fuzzy.ima" ) ;
726 // fuzzySegmentedW.write( fuzzySegmented ) ;
727 
728  // float f = 0.000001 ;
729 
730  /* ForEach3d(fuzzySegmented, x, y, z ) */
731  /* if( mask(x, y, z) ) */
732  /* for( int c = 0 ; c < fuzzySegmented.dimT() ; ++c ){ */
733  /* if( fuzzySegmented(x, y, z, c) < f * max[c] ) */
734  /* fuzzySegmented(x, y, z, c) = 0. ; */
735 
736  /* fuzzySegmented(x, y, z, c) /= max[c] ; */
737  /* //std::cout << fuzzySegmented(x, y, z, c) << " " << std::endl ; */
738  /* } */
739  //std::cout << std::endl ;
740 
741 
742 // Writer< carto::VolumeRef< float> > pbByClassW( "probaByClass.ima" ) ;
743 // pbByClassW.write( fuzzySegmented ) ;
744 
745  std::cout << "Probabilistic Pca : fuzzy classification completed"
746  << std::endl ;
747 
748  return true ;
749  }
750 
751 
752  template <class T>
753  double
755  {
756  std::vector<double> res( _discrElements.size() ) ;
757  //cout << "Nb of classes "<< _discrElements.size()<< endl ;
758  double scoreSum = 0. ;
759  for( unsigned int c = 0 ; c < _discrElements.size() ; ++c )
760  scoreSum = _discrElements[c].posteriorProbability( x, 1 ) * _PIj[c] ;
761 
762  return scoreSum ;
763  }
764 
765 }
766 
767 #endif
768 
769 
770 
771 
Definition: svd.h:59
void sort(carto::VolumeRef< T > &, carto::VolumeRef< T > &, carto::VolumeRef< T > *v=NULL)
sort the U and V matrices and the W vector in decreasing order
carto::VolumeRef< T > doit(carto::VolumeRef< T > &, carto::VolumeRef< T > *v=NULL)
Singular Value Decomposition.
void setReturnType(SVDReturnType rt)
Definition: svd.h:76
void setVoxelSize(float sizex, float sizey, float sizez, float sizet)
double normFactor() const
Definition: ppca.h:94
const carto::VolumeRef< double > & mean() const
Definition: ppca.h:81
carto::VolumeRef< double > _x
Definition: ppca.h:115
double noiseVariance() const
Definition: ppca.h:82
carto::VolumeRef< double > _Wi
Definition: ppca.h:118
const carto::VolumeRef< double > & eigenValues()
Definition: ppca.h:91
carto::VolumeRef< double > _xT
Definition: ppca.h:116
carto::VolumeRef< double > _invCi
Definition: ppca.h:119
carto::VolumeRef< double > _EValues
Definition: ppca.h:120
carto::VolumeRef< double > _mean
Definition: ppca.h:112
carto::VolumeRef< double > _EVect
Definition: ppca.h:121
void doIt(const carto::rc_ptr< carto::Volume< T > > &individuals, double distanceRef=0.)
Definition: ppca_d.h:87
ProbabilisticPca(const carto::rc_ptr< carto::Volume< T > > &data, const std::vector< std::list< Point3d > > &classes, int nbOfSignificantEigenValues, const std::vector< double > &PIj=std::vector< double >())
Definition: ppca_d.h:428
std::vector< double > andersonScores(const carto::rc_ptr< carto::Volume< double > > &x, double px, std::vector< double > &maxProbaByClass)
Definition: ppca_d.h:521
double pX(const carto::rc_ptr< carto::Volume< double > > &x)
Definition: ppca_d.h:754
bool classification(const carto::rc_ptr< carto::Volume< T > > &dynamicImage, const carto::rc_ptr< carto::Volume< byte > > &mask, carto::rc_ptr< carto::Volume< short > > &segmented)
Definition: ppca_d.h:603
std::vector< double > posteriorProbabilities(const carto::rc_ptr< carto::Volume< double > > &x, double px, std::vector< double > &maxProbaByClass)
Definition: ppca_d.h:553
bool fuzzyClassification(const carto::rc_ptr< carto::Volume< T > > &dynamicImage, const carto::rc_ptr< carto::Volume< byte > > &mask, carto::rc_ptr< carto::Volume< float > > &fuzzySegmented, double thresholdOnMaxPercentage=0., double andersonScoreThreshold=0.2, const carto::rc_ptr< carto::Volume< double > > &indivPriorProbabilities=carto::VolumeRef< double >())
Definition: ppca_d.h:644
int affectedTo(const carto::rc_ptr< carto::Volume< double > > &x)
Definition: ppca_d.h:580
virtual bool write(const T &obj, bool ascii=false, const std::string *format=0)
int getSizeZ() const
VolumeRef< T > deepcopy() const
int getSizeT() const
const T & at(long x, long y=0, long z=0, long t=0) const
int getSizeY() const
int getSizeX() const
float max(float x, float y)
Definition: thickness.h:98
AimsData< T > transpose(const AimsData< T > &thing)
BucketMap< Void > * mask(const BucketMap< Void > &src, const BucketMap< Void > &m, bool intersect=true)
VolumeRef< T > matrix_product(const Volume< T > &v1, const Volume< T > &v2)
AIMSDATA_API float norm(const Tensor &thing)
float norm2(const AimsVector< T, D > &v1)