Jerome Piovano

Research in Medical Imaging and Computer Vision

/home/jpiovano/src/Odyssee++/trunk/Libs/LevelSet/src/SegmentationModule/LocalStatsRegionModule.h

Go to the documentation of this file.
00001 
00009 #ifndef LOCALSTATSREGIONMODULE_H
00010 #define LOCALSTATSREGIONMODULE_H
00011 
00012 //#define SECOND_TERM
00013 
00014 #include <SegmentationModule/RegionModule.h>
00015 #include <DericheFilter.h>
00016 
00017 namespace segmentation {
00018 
00019 
00026         template <unsigned DIM, typename Pixel = float, typename PixelImage = float>
00027         class LocalStatsRegionModule :  public RegionModule<DIM, Pixel, PixelImage> 
00028         {
00029         public:
00030 
00031                 typedef          RegionModule<DIM, Pixel, PixelImage>    base;
00032                 typedef typename base::LevelSet                          LevelSet;
00033                 typedef typename base::Index                             Index;
00034                 typedef typename base::Histogram                         Histogram;
00035                 typedef typename base::ImageType                         ImageType;
00036 
00037                 typedef          BaseImage<DIM, float>                   ImageFloat;
00038                 typedef          DericheFilter<DIM, PixelImage>          DericheFilter;
00039 
00040 
00043 
00044 //TODO garder local variance ?
00045 
00047                 LocalStatsRegionModule(ImageType * _data,                    
00048                                        float       _weight = 1.f,            
00049                                        float       _sigma = 20.0f,           
00050                                        bool        _localVariance = false    
00051                                        );
00052 
00054                 virtual ~LocalStatsRegionModule();
00055 
00057 
00059 
00060                 void set_sigma(float _sigma);
00062                 bool & use_local_variance();
00063 
00065 
00067 
00069                 float value(const LevelSet & phi, const Index & ind);
00071                 float energy(const LevelSet & phi, const Index & ind);
00073                 void init(const LevelSet & phi);
00075                 void update(const LevelSet & phi);
00077                 void save_result(const LevelSet & phi, std::string evodir, int iter);
00078 
00080                 void update_params(const LevelSet & phi);
00081         
00083 
00085 
00086         protected:
00087 
00088                 float          m_sigma;         
00089                 DericheFilter  m_deriche;       
00090                 ImageFloat     m_chi_pos;       
00091                 ImageType      m_data_pos;      
00092                 ImageType      m_data_neg;      
00093 
00094 //TODO garder variance ???
00095                 ImageType  m_var_pos;          
00096                 ImageType  m_var_neg;          
00097                 Pixel      m_image_variance;   
00098                 bool       m_local_variance;   
00099 
00100 #ifdef SECOND_TERM
00101 // debug : variables en plus pr calculer terme en + ds derivee nrj
00102                 ImageType  m_term1_pos;
00103                 ImageType  m_term1_neg;
00104                 ImageType  m_term2_pos;
00105                 ImageType  m_term2_neg;
00106 // debug : variables en plus pr calculer terme en + ds derivee nrj
00107 #endif
00108 
00109 
00110         };
00111 
00112 
00114         // Constructors - Destructor
00115 
00116 
00117         template <unsigned DIM, typename Pixel, typename PixelImage>
00118                 LocalStatsRegionModule<DIM, Pixel, PixelImage>::LocalStatsRegionModule(ImageType * _data, float _weight, float _sigma, bool _local_variance) 
00119                 : RegionModule<DIM, Pixel, PixelImage>(_data, _weight, 0.0f, 0.0f, true), m_sigma(_sigma), m_deriche(_sigma), m_chi_pos(_data->shape()), m_data_pos(_data->shape()), m_data_neg(_data->shape()), m_var_pos(_data->shape()), m_var_neg(_data->shape()), m_image_variance(-1.0f), m_local_variance(_local_variance)
00120 #ifdef SECOND_TERM
00121                 ,m_term1_pos(_data->shape()),m_term2_pos(_data->shape()),m_term1_neg(_data->shape()),m_term2_neg(_data->shape())
00122 #endif
00123         { }
00124 
00125         template <unsigned DIM, typename Pixel, typename PixelImage>
00126                 LocalStatsRegionModule<DIM, Pixel, PixelImage>::~LocalStatsRegionModule() 
00127         { }
00128 
00129 
00131         // Modify/Access member data
00132 
00133         
00134         template <unsigned DIM, typename Pixel, typename PixelImage>
00135                 void LocalStatsRegionModule<DIM, Pixel, PixelImage>::set_sigma(float _sigma)
00136         { 
00137                 m_sigma = _sigma;
00138                 m_deriche.set_isotropic_sigma(_sigma);
00139         }
00140 
00141         template <unsigned DIM, typename Pixel, typename PixelImage>
00142                 bool & LocalStatsRegionModule<DIM, Pixel, PixelImage>::use_local_variance()
00143         {
00144                 return m_local_variance;
00145         }
00146 
00147 
00149         // Member functions
00150 
00151         
00152         template <unsigned DIM, typename Pixel, typename PixelImage>
00153                 float LocalStatsRegionModule<DIM, Pixel, PixelImage>::value(const LevelSet & phi, const Index & ind)
00154         { 
00155                 PixelImage val = (* base::m_data)(ind);
00156 
00157                 //TODO garder local variance ?
00158                 float var_pos = m_local_variance?m_var_pos(ind)/m_chi_pos(ind):m_image_variance;
00159                 float var_neg = m_local_variance?m_var_neg(ind)/(1-m_chi_pos(ind)):m_image_variance;
00160 
00161                 float ll_pos = -0.5f*log(2*M_PI*var_pos) - 0.5f*Maths::sqr(val-m_data_pos(ind)/   m_chi_pos(ind) )/var_pos;
00162                 float ll_neg = -0.5f*log(2*M_PI*var_neg) - 0.5f*Maths::sqr(val-m_data_neg(ind)/(1-m_chi_pos(ind)))/var_pos;
00163 
00164 #ifdef SECOND_TERM
00165                 ll_pos += 2*val*m_term1_pos(ind)/var1 - 2*m_term2_pos(ind)/var_pos;
00166                 ll_neg += 2*val*m_term1_neg(ind)/var2 - 2*m_term2_neg(ind)/var_neg;
00167 #endif
00168 
00169                 return -(ll_neg - ll_pos)/3.0;
00170         }       
00171 
00172         template <unsigned DIM, typename Pixel, typename PixelImage>
00173                 float LocalStatsRegionModule<DIM, Pixel, PixelImage>::energy(const LevelSet & phi, const Index & ind)
00174         {
00175                 //TODO 
00176                 return 0;
00177         }
00178 
00179         template <unsigned DIM, typename Pixel, typename PixelImage>
00180                 void LocalStatsRegionModule<DIM, Pixel, PixelImage>::init(const LevelSet & phi)
00181         {
00182                 base::init(phi);
00183                 update_params(phi);
00184         }
00185 
00186         template <unsigned DIM, typename Pixel, typename PixelImage>
00187                 void LocalStatsRegionModule<DIM, Pixel, PixelImage>::update(const LevelSet & phi)
00188         { 
00189                 update_params(phi);
00190         }
00191 
00192          template <unsigned DIM, typename Pixel, typename PixelImage>
00193                  void LocalStatsRegionModule<DIM, Pixel, PixelImage>::update_params(const LevelSet & phi) 
00194         {
00195                 // computation of the variance of the image
00196                 if(!m_local_variance && (m_image_variance<0)) {
00197                         PixelImage min;
00198                         PixelImage max;
00199                         PixelImage mean;
00200                         
00201                         Misc<DIM,PixelImage>::stats(*base::m_data, min, max, mean, &m_image_variance);
00202                 }
00203 
00204 
00205                 // computation of m_chi_pos, m_data_pos, m_data_neg
00206                 for (typename ImageType::template iterator<domain> ind=base::m_data->begin() ; ind!=base::m_data->end() ; ++ind ){
00207                         const Pixel      _phi = phi(ind);
00208                         const PixelImage _val = (*base::m_data)(ind);
00209 
00210                         if (_phi>=0) {
00211                                 m_chi_pos(ind)   = 1.0f;
00212                                 m_data_pos(ind)  = _val;
00213                                 m_data_neg(ind) = 0.0f;
00214                                 if(m_local_variance) {
00215                                         m_var_pos(ind) = _val;
00216                                         m_var_neg(ind) = 0.0f;
00217                                 }
00218                         }
00219                         else {
00220                                 m_chi_pos(ind)   = 0.0f;
00221                                 m_data_pos(ind)  = 0.0f;
00222                                 m_data_neg(ind) = _val;
00223                                 if(m_local_variance) {
00224                                         m_var_pos(ind) = 0.0f;
00225                                         m_var_neg(ind) = _val;
00226                                 }
00227                         }
00228                 }
00229 
00230 #pragma omp parallel sections
00231 {
00232         #pragma omp section
00233                 m_deriche.filter(m_chi_pos);
00234         #pragma omp section
00235                 m_deriche.filter(m_data_pos);
00236         #pragma omp section
00237                 m_deriche.filter(m_data_neg);
00238 }
00239 
00240 
00241 #ifdef SECOND_TERM
00242                 // computation of m_term1_pos, m_term2_pos, m_term1_neg, m_term2_neg
00243                 for (typename ImageType::template iterator<domain> ind=base::m_data->begin() ; ind!=base::m_data->end() ; ++ind ){
00244                         const Pixel      _phi = phi(ind);
00245                         const PixelImage _val = (*base::m_data)(ind);
00246 
00247                         if (_phi>=0) {
00248                                 m_term1_pos(ind) = ((*m_data)(ind) - (m_data_pos(ind)/m_chi_pos(ind))) / m_chi_pos(ind);
00249                                 m_term2_pos(ind) = ((*m_data)(ind) - (m_data_pos(ind)/m_chi_pos(ind))) * (m_data_pos(ind)/m_chi_pos(ind))  / m_chi_pos(ind);
00250                                 m_term1_neg(ind) = 0.0f;
00251                                 m_term2_neg(ind) = 0.0f;
00252                         }
00253                         else {
00254                                 m_term1_pos(ind) = 0.0f;
00255                                 m_term2_pos(ind) = 0.0f;
00256                                 m_term1_neg(ind) = ((*m_data)(ind) - (m_data_neg(ind)/(1 - m_chi_pos(ind))))  / (1 - m_chi_pos(ind));
00257                                 m_term2_neg(ind) = ((*m_data)(ind) - (m_data_neg(ind)/(1 - m_chi_pos(ind)))) * (m_data_neg(ind)/(1 - m_chi_pos(ind)))  / (1 - m_chi_pos(ind));
00258                         }
00259                 }
00260                 
00261 #pragma omp parallel sections
00262 {
00263         #pragma omp section
00264                 m_deriche.filter(m_term1_pos);
00265         #pragma omp section
00266                 m_deriche.filter(m_term2_pos);
00267         #pragma omp section
00268                 m_deriche.filter(m_term1_neg);
00269         #pragma omp section
00270                 m_deriche.filter(m_term2_neg);
00271 }
00272 #endif
00273 
00274                 //TODO garder variance ?
00275                 if(m_local_variance) {
00276                                 
00277                         for (typename ImageType::template iterator<domain> ind=base::m_data->begin() ; ind!=base::m_data->end() ; ++ind ){
00278                                 const Pixel      _phi = phi(ind);
00279                                 const PixelImage _val = (*base::m_data)(ind);   
00280                                 if (_phi>=0) {
00281                                         m_var_pos(ind) = Maths::sqr(m_var_pos(ind) - m_data_pos(ind)/m_chi_pos(ind));
00282                                         m_var_neg(ind) = 0.0f;
00283                                 }
00284                                 else {
00285                                         m_var_pos(ind) = 0.0f;
00286                                         m_var_neg(ind) = Maths::sqr(m_var_neg(ind) - m_data_neg(ind)/(1-m_chi_pos(ind)));
00287                                 }
00288                         }
00289 #pragma omp parallel sections
00290 {
00291         #pragma omp section
00292                         m_deriche.filter(m_var_pos);
00293         #pragma omp section
00294                         m_deriche.filter(m_var_neg);    
00295 }
00296                 }
00297         }
00298 
00299         template <unsigned DIM, typename Pixel, typename PixelImage>
00300                 void LocalStatsRegionModule<DIM, Pixel, PixelImage>::save_result(const LevelSet & phi, std::string evodir, int iter)
00301         {
00302                 base::save_result(phi, evodir, iter);
00303 
00304                 ImageType tmp(phi.shape());
00305                 for (typename LevelSet::template iterator<domain> i=phi.begin() ; i!=phi.end() ; ++i ){
00306                         if(phi(i) > 0) tmp(i) = m_data_pos(i)/m_chi_pos(i);
00307                         else           tmp(i) = m_data_neg(i)/(1-m_chi_pos(i));
00308                 }
00309 
00310                 std::ostringstream name;
00311                 std::ofstream file;
00312                 std::ofstream file2;
00313 
00314                 name.str("");
00315                 name << evodir << "LocalStats_result_" << std::setw(6) << std::setfill('0') << iter << ".inr";
00316                 file.open(name.str().c_str());
00317                 file << format("inrimage") << tmp ;
00318                 file.close();
00319                 std::cout <<  " - Saved " << name.str() << " ..."  << std::endl;
00320         }
00321 }
00322 
00323 #endif // LOCALSTATSREGIONMODULE_H

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