aimsalgo 6.0.0
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
16#include <cartobase/type/string_conversion.h>
17#include <cartobase/config/verbose.h>
18#include <iostream>
19
21#include <aims/transformation/affinetransformation3d.h>
23
24
25//methode principale:
26
27template <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
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)
108 aims::AffineTransformation3d 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
AimsVector< float, 3 > Point3df
#define cartoDbgMsg(level, message)