Jerome Piovano

Research in Medical Imaging and Computer Vision

/home/jpiovano/src/Odyssee++/trunk/Libs/LevelSet/src/Initializer.h

Go to the documentation of this file.
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,   // # of iterations of the reinitialization PDE
00074                                         float _dt = 0.4    // time step of the reinitialization PDE
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         // FastMarching Initializer 
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                 // Initialization of the fast marching datas
00139                 m_reinit1->init(phi);
00140                 m_reinit2->init(phi);
00141 
00142                 // clear the band
00143                 phi.clear_band();
00144 
00145                 #ifdef PRINT_TIME
00146                 timeval _time;
00147                 Globals::initChrono(_time);
00148                 #endif
00149 
00150                 // we add the points neighboring the zero level set to the alive points
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                         // find the coordinates neighboring the point 'ind'
00159                         Schemes::find_neighbours(phi, ind.position(), inf_coords, sup_coords);
00160 
00161                         //for each point 'inf' and 'sup' neighboring 'ind' ...
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                 // We add to the band the points alive (for the reinit EDP which is done first).
00180                 // we set the value of the others points to '1' ( border condition ) (2 if alive+trial too)
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                 // reinitialization PDE (2*iter because first initialisation)
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                 // init of the trial points from the alive points
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                 // Fast marching
00216                 _reinit_fast_marching(phi);
00217 
00218                 #ifdef PRINT_TIME
00219                 Globals::printChrono("          - FastMarching : ", _time);
00220                 Globals::initChrono(_time);
00221                 #endif
00222 
00223                 // we put the other points at the max value
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                 // reinitialization EDP 
00246                 phi.reinit_PDE(m_iter,m_dt);
00247 
00248                 // Initialization of the fast marching datas
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                 // we add the points neighboring the zero level set to the alive points
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                         // find the coordinates neighboring the point 'ind'
00267                         Schemes::find_neighbours(phi, ind, inf_coords, sup_coords);
00268 
00269                         //for each point 'inf' and 'sup' neighboring 'ind' ...
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                 // trial points are neighbor of alive points
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                 // we remove from the band the points that are not trial nor alive
00297                 // we put their value at max
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                 // Fast marching
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                 // we launch the two fast marching
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                 // we add the alive points to the band
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

For further information, please contact Jerome Piovano - Last update 2008-02-08