aimsalgo  5.1.2
Neuroimaging image processing
minimisation_d.h
Go to the documentation of this file.
1 /* Copyright (C) 2000-2013 CEA
2  *
3  * This software and supporting documentation were developed by
4  * bioPICSEL
5  * CEA/DSV/I²BM/MIRCen/LMN, Batiment 61,
6  * 18, route du Panorama
7  * 92265 Fontenay-aux-Roses
8  * France
9  */
10 
11 
12 #ifndef AIMS_REGISTRATION_MINIMISATION_D_H
13 #define AIMS_REGISTRATION_MINIMISATION_D_H
14 
15 
18 #include <iostream>
19 
20 #include <aims/io/motionW.h>
23 
24 
25 //methode principale:
26 
27 template <class T>
29 {
30 
31  //on charge l'ensemble des points a apparier
32  std::vector<Point3df> ptstest = displacementField.getpointstest();
33  std::vector<Point3df> ptsref = displacementField.getpointsref();
34  int size = ptstest.size();
35  unsigned sizekept = unsigned ( double(ptstest.size())*_Pkept );
36 
37 // Point3dd sumtest(0,0,0);
38 // std::vector<Point3df>::iterator it, ite = ptstest.end();
39 // for(it = ptstest.begin(); it!=ite; ++it) {
40 // sumtest[0] += (*it)[0];
41 // sumtest[1] += (*it)[1];
42 // sumtest[2] += (*it)[2];
43 // }
44 // std::cout << "!! Test points sum: " << carto::toString(sumtest) << std::endl;
45 //
46 // Point3dd sumref(0,0,0);
47 // ite = ptsref.end();
48 // for(it = ptsref.begin(); it!=ite; ++it) {
49 // sumref[0] += (*it)[0];
50 // sumref[1] += (*it)[1];
51 // sumref[2] += (*it)[2];
52 // }
53 // std::cout << "!! Ref points sum: " << carto::toString(sumref) << std::endl;
54 
55  Motion m;
56 
57  if ((sizekept > 0) && (ptsref.size() > 0))
58  {
59  // Calcul de la transformation LS choisie
60  switch(_transfo)
61  {
62  case 1:
63  {
64  // std::cout<<"Calcul transfo rigide..."<<std::endl;
65  aims::RigidLeastSquareEstimation leastSquareEstimation(ptstest, ptsref);
66  m = *(leastSquareEstimation.motion());
67  break;
68  }
69 
70  case 2:
71  {
72  // std::cout<<"Calcul transfo similitude..."<<std::endl;
73  aims::SimiLeastSquareEstimation leastSquareEstimation(ptstest, ptsref);
74  m = *(leastSquareEstimation.motion());
75  break;
76  }
77 
78  case 3:
79  {
80  // std::cout<<"Calcul transfo affine..."<<std::endl;
81  aims::AffineLeastSquareEstimation leastSquareEstimation(ptstest, ptsref);
82  m = *(leastSquareEstimation.motion());
83  break;
84  }
85 
86  default:
87  {
88  m.setToIdentity();
89  throw std::runtime_error("The transformation chosen is not valid !") ;
90  break;
91  }
92  }
93 
94  //ROBUSTESSE DEBUT
95 
96  // Le tri des residus pour ref et test
97  std::multimap<float, Point3df> mt;
98  std::multimap<float, Point3df> mr;
99 
100  std::multimap<float, Point3df>::iterator itt;
101  std::multimap<float, Point3df>::iterator itr;
102 
103  // Diverses variables utiles
104  Point3df r; // point residu courant
105  float r2; // norme carree de r
106  unsigned indice; // indice de boucle multiple (variable locale boucle impossible)
107  Motion rigide_kept;
108  Motion similitude_kept;
109 
110  // La liste des points ref et test ayant les plus petits residus
111  std::vector<Point3df> ptstestkept;
112  std::vector<Point3df> ptsrefkept;
113 
114 
115  for(int boucle=0; boucle < 3; boucle++)
116  {
117 
118 // std::cout << "Minimisation - s : " << size << ", m : " << m << std::endl << std::flush;
119 
120  mt.clear(); mr.clear();
121  ptstestkept.clear(); ptsrefkept.clear();
122 
123  for(int l = 0; l < size; l++)
124  {
125  Point3df x = ptstest[l];
126  Point3df y = ptsref[l];
127 
128  r = y - m.transform(x); //calcul du residu pour chaque point
129  r2 = r.norm(); // sa norme carree
130  mt.insert(std::pair<float, Point3df>(r2, x) ); //insertion du residu et du point test dans map
131  mr.insert(std::pair<float, Point3df>(r2, y) ); //insertion du residu et du point test dans map
132  }
133 
134  // On remplit les listes avec une partie seulement des meilleurs residus
135  for (itt = mt.begin(),itr = mr.begin(), indice = 0 ;indice<sizekept;++itt,++itr,++indice)
136  {
137  ptstestkept.push_back( (*itt).second );
138  ptsrefkept.push_back( (*itr).second );
139  }
140 
141  // Calcul de la transformation LS choisie
142  switch(_transfo)
143  {
144  case 1:
145  {
146  // cout<<"Calcul transfo rigide..."<<cout;
147  aims::RigidLeastSquareEstimation leastSquareEstimation_kept(ptstestkept, ptsrefkept);
148  m = *(leastSquareEstimation_kept.motion());
149  break;
150  }
151 
152  case 2:
153  {
154  // cout<<"Calcul transfo similitude..."<<cout;
155  aims::SimiLeastSquareEstimation leastSquareEstimation_kept(ptstestkept, ptsrefkept);
156  m = *(leastSquareEstimation_kept.motion());
157  break;
158  }
159 
160  case 3:
161  {
162  // cout<<"Calcul transfo affine..."<<cout;
163  aims::AffineLeastSquareEstimation leastSquareEstimation_kept(ptstestkept, ptsrefkept);
164  m = *(leastSquareEstimation_kept.motion());
165  break;
166  }
167 
168  default:
169  {
170  m.setToIdentity();
171  throw std::runtime_error("The transformation chosen is not valid !") ;
172  break;
173  }
174  }
175  } // fin boucle robustesse
176  }
177  else
178  {
179  cartoDbgMsg( 1, "Not enough information in reference or test image to estimate transformation" );
180  }
181 
182  return (m);
183 }
184 
185 
186 #endif
187 
float norm() const
std::vector< Point3df > getpointstest()
std::vector< Point3df > getpointsref()
Motion quaternion(DisplacementField< T > &displacementField)
Point3dd transform(double x, double y, double z) const
#define cartoDbgMsg(level, message)