00001
00009 #ifndef INITIALIZER_H
00010 #define INITIALIZER_H
00011
00012 #ifdef _USE_INTEL_COMPILER
00013 #include <omp.h>
00014 #endif
00015
00016 #include <LevelSet.h>
00017 #include <FastMarching.h>
00018 #include <Schemes.h>
00019 #include <Globals.h>
00020
00021 namespace levelset {
00022
00023 template <unsigned DIM, typename Pixel> class LevelSet;
00024
00029 template<unsigned DIM, typename Pixel = float>
00030 class Initializer
00031 {
00032 public:
00033
00034 typedef LevelSet<DIM, Pixel> LevelSetType;
00035
00038
00040 Initializer(){}
00042 virtual ~Initializer(){}
00043
00045
00047
00049 virtual void init_band(LevelSetType & phi) = 0 ;
00051 virtual void reinit_band(LevelSetType & phi) = 0 ;
00053 };
00054
00059 template<unsigned DIM, typename Pixel = float>
00060 class FastMarchingInitializer : public Initializer<DIM, Pixel>
00061 {
00062 public:
00063
00064 typedef Initializer<DIM, Pixel> base;
00065 typedef typename base::LevelSetType LevelSetType;
00066 typedef typename LevelSetType::Index Index;
00067 typedef Schemes<DIM,Pixel> Schemes;
00068
00071
00073 FastMarchingInitializer(int _iter = 2,
00074 float _dt = 0.4
00075 );
00077 virtual ~FastMarchingInitializer();
00078
00080
00082
00084 void init_band(LevelSetType & phi);
00086 void reinit_band(LevelSetType & phi);
00088 int& iter();
00090 float& dt();
00091
00092 protected:
00093
00095 void _add_alive_point(LevelSetType & phi, const Index & ind);
00097 void _reinit_fast_marching(LevelSetType & phi);
00098 private:
00099
00101
00103
00104 int m_iter;
00105 float m_dt;
00106 Eikonal<DIM, Pixel, +1> * m_reinit1;
00107 Eikonal<DIM, Pixel, -1> * m_reinit2;
00108
00110 };
00111
00112
00116
00117
00118
00119
00120 template<unsigned DIM, typename Pixel>
00121 FastMarchingInitializer<DIM, Pixel>::FastMarchingInitializer(int _iter, float _dt)
00122 : base(), m_iter(_iter), m_dt(_dt)
00123 {
00124 m_reinit1 = new Eikonal<DIM, Pixel, +1>();
00125 m_reinit2 = new Eikonal<DIM, Pixel, -1>();
00126 }
00127
00128 template<unsigned DIM, typename Pixel>
00129 FastMarchingInitializer<DIM, Pixel>::~FastMarchingInitializer()
00130 {
00131 delete m_reinit1;
00132 delete m_reinit2;
00133 }
00134
00135 template<unsigned DIM, typename Pixel>
00136 void FastMarchingInitializer<DIM, Pixel>::init_band(LevelSetType & phi)
00137 {
00138
00139 m_reinit1->init(phi);
00140 m_reinit2->init(phi);
00141
00142
00143 phi.clear_band();
00144
00145 #ifdef PRINT_TIME
00146 timeval _time;
00147 Globals::initChrono(_time);
00148 #endif
00149
00150
00151 int inf_coords[DIM];
00152 int sup_coords[DIM];
00153 for (typename LevelSetType::template iterator<domain> ind=phi.begin() ; ind!=phi.end() ; ++ind ){
00154
00155 const Pixel _phi = phi(ind);
00156 bool add = false;
00157
00158
00159 Schemes::find_neighbours(phi, ind.position(), inf_coords, sup_coords);
00160
00161
00162 for (int i=0 ; i<DIM ; i++){
00163 Index inf = ind.position();
00164 Index sup = ind.position();
00165 inf(i+1) = inf_coords[i];
00166 sup(i+1) = sup_coords[i];
00167 if (_phi * phi(inf) <= 0) { add = true; _add_alive_point(phi,inf); }
00168 if (_phi * phi(sup) <= 0) { add = true; _add_alive_point(phi,sup); }
00169 }
00170
00171 if (add) { _add_alive_point(phi,ind.position());}
00172 }
00173
00174 #ifdef PRINT_TIME
00175 Globals::printChrono(" - points neighboring the zero level set : ", _time);
00176 Globals::initChrono(_time);
00177 #endif
00178
00179
00180
00181 for (typename LevelSetType::template iterator<domain> ind=phi.begin() ; ind!=phi.end() ; ++ind ){
00182 const Pixel _phi = phi(ind);
00183 if (_phi>0) {
00184 if ((*m_reinit1)(ind) == 2) phi(ind) = 1;
00185 else phi.add_point(ind.position());
00186 }
00187 else {
00188 if ((*m_reinit2)(ind) == 2) phi(ind) = -1;
00189 else phi.add_point(ind.position());
00190 }
00191 }
00192
00193 #ifdef PRINT_TIME
00194 Globals::printChrono(" - add to the band the points alive: ", _time);
00195 Globals::initChrono(_time);
00196 #endif
00197
00198
00199 phi.reinit_PDE(m_iter,m_dt);
00200
00201 #ifdef PRINT_TIME
00202 Globals::printChrono(" - reinitialization PDE: ", _time);
00203 Globals::initChrono(_time);
00204 #endif
00205
00206
00207 m_reinit1->init_trial_from_alive();
00208 m_reinit2->init_trial_from_alive();
00209
00210 #ifdef PRINT_TIME
00211 Globals::printChrono(" - init of the trial points from the alive points : ", _time);
00212 Globals::initChrono(_time);
00213 #endif
00214
00215
00216 _reinit_fast_marching(phi);
00217
00218 #ifdef PRINT_TIME
00219 Globals::printChrono(" - FastMarching : ", _time);
00220 Globals::initChrono(_time);
00221 #endif
00222
00223
00224 for (typename LevelSetType::template iterator<domain> ind=phi.begin() ; ind!=phi.end() ; ++ind ){
00225 const Pixel _phi = phi(ind);
00226 if (_phi>0 && (*m_reinit1)(ind)==2) phi(ind) = phi.thickness();
00227 else if (_phi<0 && (*m_reinit2)(ind)==2) phi(ind) = -phi.thickness();
00228 }
00229
00230 #ifdef PRINT_TIME
00231 Globals::printChrono(" - put the other points at the max value : ", _time);
00232 #endif
00233
00234 }
00235
00236 template<unsigned DIM, typename Pixel>
00237 void FastMarchingInitializer<DIM, Pixel>::reinit_band(LevelSetType & phi)
00238 {
00239
00240 #ifdef PRINT_TIME
00241 timeval _time;
00242 Globals::initChrono(_time);
00243 #endif
00244
00245
00246 phi.reinit_PDE(m_iter,m_dt);
00247
00248
00249 m_reinit1->init(phi);
00250 m_reinit2->init(phi);
00251
00252 #ifdef PRINT_TIME
00253 Globals::printChrono(" - reinitialization PDE : ", _time);
00254 Globals::initChrono(_time);
00255 #endif
00256
00257
00258 int inf_coords[DIM];
00259 int sup_coords[DIM];
00260 for (unsigned int i = 0 ; i < phi.nb_points() ; i++){
00261
00262 const Index& ind = phi.get_point(i);
00263 const Pixel _phi = phi(ind);
00264 bool add = false;
00265
00266
00267 Schemes::find_neighbours(phi, ind, inf_coords, sup_coords);
00268
00269
00270 for (int i=0 ; i<DIM ; i++){
00271 Index inf = ind;
00272 Index sup = ind;
00273 inf(i+1) = inf_coords[i];
00274 sup(i+1) = sup_coords[i];
00275 if (_phi * phi(inf) <= 0) { add = true; _add_alive_point(phi,inf); }
00276 if (_phi * phi(sup) <= 0) { add = true; _add_alive_point(phi,sup); }
00277 }
00278
00279 if (add) { _add_alive_point(phi,ind);}
00280 }
00281
00282 #ifdef PRINT_TIME
00283 Globals::printChrono(" - points neighboring the zero level set : ", _time);
00284 Globals::initChrono(_time);
00285 #endif
00286
00287
00288 m_reinit1->init_trial_from_alive();
00289 m_reinit2->init_trial_from_alive();
00290
00291 #ifdef PRINT_TIME
00292 Globals::printChrono(" - init of the trial points from the alive points : ", _time);
00293 Globals::initChrono(_time);
00294 #endif
00295
00296
00297
00298 int i = 0;
00299 while (i<phi.nb_points()){
00300 const Index& ind = phi.get_point(i);
00301 const Pixel _phi = phi(ind);
00302
00303 if (_phi>0 && (*m_reinit1)(ind) == 2){
00304 phi(ind) = phi.thickness();
00305 phi.remove_point(ind);
00306 }
00307 else if (_phi<=0 && (*m_reinit2)(ind) == 2) {
00308 phi(ind) = -phi.thickness();
00309 phi.remove_point(ind);
00310 }
00311 else i++;
00312 }
00313
00314 #ifdef PRINT_TIME
00315 Globals::printChrono(" - remove from the band the points not alive or trial : ", _time);
00316 #endif
00317
00318
00319 _reinit_fast_marching(phi);
00320
00321 #ifdef PRINT_TIME
00322 Globals::printChrono(" - FastMarching : ", _time);
00323 #endif
00324 }
00325
00326 template<unsigned DIM, typename Pixel>
00327 int& FastMarchingInitializer<DIM, Pixel>::iter()
00328 {
00329 return m_iter;
00330 }
00331
00332 template<unsigned DIM, typename Pixel>
00333 float& FastMarchingInitializer<DIM, Pixel>::dt()
00334 {
00335 return m_dt;
00336 }
00337
00338 template<unsigned DIM, typename Pixel>
00339 void FastMarchingInitializer<DIM, Pixel>::_add_alive_point(LevelSetType & phi, const Index & ind)
00340 {
00341 if (phi(ind)>0) {
00342 m_reinit1->add_alive_point(ind);
00343 m_reinit2->add_forbidden_point(ind);
00344 }
00345 else {
00346 m_reinit1->add_forbidden_point(ind);
00347 m_reinit2->add_alive_point(ind);
00348 }
00349 }
00350
00351 template<unsigned DIM, typename Pixel>
00352 void FastMarchingInitializer<DIM, Pixel>::_reinit_fast_marching(LevelSetType & phi)
00353 {
00354
00355 if ( phi.thickness()>0 ) {
00356 #pragma omp parallel sections
00357 {
00358 #pragma omp section
00359 m_reinit1->run( phi.thickness());
00360 #pragma omp section
00361 m_reinit2->run(-phi.thickness());
00362 }
00363 }
00364 else {
00365 #pragma omp parallel sections
00366 {
00367 #pragma omp section
00368 m_reinit1->run();
00369 #pragma omp section
00370 m_reinit2->run();
00371 }
00372 }
00373
00374
00375 for (unsigned int i = 0 ; i < m_reinit1->nb_alive_points() ; i++)
00376 phi.add_point(m_reinit1->get_alive_point(i));
00377
00378 for (unsigned int i = 0 ; i < m_reinit2->nb_alive_points() ; i++)
00379 phi.add_point(m_reinit2->get_alive_point(i));
00380 }
00381 }
00382
00383 #endif // INITIALIZER_H