aimsalgo 6.0.0
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>
44#include <cartobase/type/string_conversion.h>
45
46
47namespace 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() ) ;
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
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
221 _Wi = matrix_product( _EVect, _Wi );
222// Writer< carto::VolumeRef< double> > wri0( "Wi.ima" ) ;
223// wri0.write(_Wi) ;
224
225 carto::VolumeRef<double> Ci = matrix_product( _Wi, transpose( _Wi ) );
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
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
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
@ MatrixOfSingularValues
Definition svd.h:64
carto::VolumeRef< T > doit(carto::VolumeRef< T > &, carto::VolumeRef< T > *v=NULL)
Singular Value Decomposition.
void setReturnType(SVDReturnType rt)
Definition svd.h:76
carto::VolumeRef< double > _x
Definition ppca.h:115
double noiseVariance() const
Definition ppca.h:82
carto::VolumeRef< double > _Wi
Definition ppca.h:118
carto::VolumeRef< double > _xT
Definition ppca.h:116
carto::VolumeRef< double > _invCi
Definition ppca.h:119
carto::VolumeRef< double > _EValues
Definition ppca.h:120
const carto::VolumeRef< double > & mean() const
Definition ppca.h:81
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
float posteriorProbability(const carto::rc_ptr< carto::Volume< double > > &x, float pX, unsigned int classNb)
Definition ppca.h:163
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
const T & at(long x, long y=0, long z=0, long t=0) const
int getSizeY() const
int getSizeX() const
VolumeRef< T > deepcopy() const
BucketMap< Void > * mask(const BucketMap< Void > &src, const BucketMap< Void > &m, bool intersect=true)
AimsData< T > transpose(const AimsData< T > &thing)
T max(const Volume< T > &vol)
AIMSDATA_API float norm(const Tensor &thing)
AimsVector< float, 3 > Point3df
float norm2(const AimsVector< T, D > &v1)