Jerome Piovano

Research in Medical Imaging and Computer Vision

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

Go to the documentation of this file.
00001 
00009 #ifndef PARZENREGIONMODULE_H
00010 #define PARZENREGIONMODULE_H
00011 
00012 #include <SegmentationModule/RegionModule.h>
00013 #include <DericheFilter.h>
00014 #include <vector>
00015 
00016 namespace segmentation {
00017 
00018 
00025         template <unsigned DIM, typename Pixel, typename PixelImage = float> 
00026         class ParzenRegionModule : public RegionModule<DIM, Pixel, PixelImage>
00027         {
00028         public:
00029         
00030                 typedef          RegionModule<DIM, Pixel, PixelImage>    base;
00031                 typedef typename base::LevelSet                          LevelSet;
00032                 typedef typename base::Index                             Index;
00033                 typedef typename base::Histogram                         Histogram;
00034                 typedef typename base::ImageType                         ImageType;
00035 
00036                 typedef          DericheFilter<1, float>                 DericheFilter;
00037 
00040 
00042                 ParzenRegionModule(ImageType * _data,                
00043                                    float       _weight = 1.f,        
00044                                    float       _sigma = 4,           
00045                                    bool        _adaptive = true      
00046                                    );
00047 
00049                 virtual ~ParzenRegionModule();
00050 
00052 
00054 
00056                 void set_sigma(float _sigma);
00057 
00059 
00061 
00063                 float value(const LevelSet & phi, const Index & ind);
00065                 float energy(const LevelSet & phi, const Index & ind);
00067                 void init(const LevelSet & phi);
00069                 void update(const LevelSet & phi);
00071                 void save_result(const LevelSet & phi, std::string evodir, int iter);
00072 
00074                 void update_parzen_params();
00075 
00077 
00079 
00080         protected:
00081 
00082                 float                 m_sigma;       
00083                 DericheFilter         m_deriche;     
00084                 std::vector<Pixel>    m_ll_pos;      
00085                 std::vector<Pixel>    m_ll_neg;      
00086                 Image1D<float>        m_parzen_pos;  
00087                 Image1D<float>        m_parzen_neg;  
00088                 
00090         };
00091 
00092 
00096 
00097         // Constructors - Destructor
00098 
00099 
00100         template <unsigned DIM, typename Pixel, typename PixelImage>
00101                 ParzenRegionModule<DIM, Pixel, PixelImage>::ParzenRegionModule(ImageType * _data, float _weight, float _sigma, bool _adaptive)
00102                 :RegionModule<DIM, Pixel, PixelImage>(_data, _weight, _adaptive), m_sigma(_sigma), m_deriche(_sigma)
00103         { }
00104 
00105         template <unsigned DIM, typename Pixel, typename PixelImage>
00106                 ParzenRegionModule<DIM, Pixel, PixelImage>::~ParzenRegionModule() 
00107         { }
00108 
00109 
00111         // Modify/Access member data 
00112 
00113 
00114         template <unsigned DIM, typename Pixel, typename PixelImage>
00115                 void ParzenRegionModule<DIM, Pixel, PixelImage>::set_sigma(float _sigma)
00116         { 
00117                 m_sigma = _sigma;
00118                 m_deriche.set_isotropic_sigma(_sigma);
00119         }
00120 
00121 
00123         // Member functions
00124 
00125 
00126         template <unsigned DIM, typename Pixel, typename PixelImage>
00127                 float ParzenRegionModule<DIM, Pixel, PixelImage>::value(const LevelSet & phi, const Index & ind)
00128         {
00129                 PixelImage val = (* base::m_data)(ind);
00130                 const Pixel ll_pos = m_ll_pos[base::m_hist_pos->get_index(val)];
00131                 const Pixel ll_neg = m_ll_neg[base::m_hist_neg->get_index(val)];
00132 
00133                 return  Globals::delta(phi(ind)) * (ll_pos - ll_neg);
00134         }       
00135 
00136         template <unsigned DIM, typename Pixel, typename PixelImage>
00137                 float ParzenRegionModule<DIM, Pixel, PixelImage>::energy(const LevelSet & phi, const Index & ind)
00138         {
00139                 PixelImage val = (* base::m_data)(ind);
00140                 float ll_pos = m_ll_pos[base::m_hist_pos->get_index(val)];
00141                 float ll_neg = m_ll_neg[base::m_hist_neg->get_index(val)];
00142                 float h = Globals::heaviside(phi(ind));
00143 
00144                 return -(1-h)*ll_pos - h*ll_neg;
00145         }
00146 
00147         template <unsigned DIM, typename Pixel, typename PixelImage>
00148                 void ParzenRegionModule<DIM, Pixel, PixelImage>::init(const LevelSet & phi)
00149         {
00150                 base::init(phi);
00151                 base::init_histograms(phi);
00152                 update_parzen_params();
00153         }
00154 
00155         template <unsigned DIM, typename Pixel, typename PixelImage>
00156                 void ParzenRegionModule<DIM, Pixel, PixelImage>::update(const LevelSet & phi)
00157         { 
00158                 base::update_histograms(phi);
00159                 update_parzen_params();
00160         }
00161 
00162         template <unsigned DIM, typename Pixel, typename PixelImage>
00163                 void ParzenRegionModule<DIM, Pixel, PixelImage>::update_parzen_params()
00164         { 
00165                 // if the size of the histogram has changed, resize parzen densities and log-likelihood
00166                 if (m_parzen_neg.size() != base::hist_neg()->size()){
00167                         m_parzen_neg.resize(base::hist_neg()->size());
00168                         m_ll_neg.resize(base::hist_neg()->size());
00169                 }
00170                 if (m_parzen_pos.size() != base::hist_pos()->size()){
00171                         m_parzen_pos.resize(base::hist_pos()->size());
00172                         m_ll_pos.resize(base::hist_pos()->size());
00173                 }
00174 
00175                 // initialize the parzen densities from the histograms
00176                 for(int i=0; i < m_parzen_neg.size() ; i++) m_parzen_neg(i) = base::hist_neg()->data()[i];
00177                 for(int i=0; i < m_parzen_pos.size() ; i++) m_parzen_pos(i) = base::hist_pos()->data()[i];
00178 
00179                 // smooth the parzen densities
00180                 m_deriche.filter(m_parzen_neg);
00181                 m_deriche.filter(m_parzen_pos);
00182 
00183                 // normalize the parzen densities
00184                 float sum_neg=0.0f;
00185                 float sum_pos=0.0f;
00186                 for(int i=0; i < m_parzen_neg.size() ; i++) sum_neg += m_parzen_neg(i);
00187                 for(int i=0; i < m_parzen_pos.size() ; i++) sum_pos += m_parzen_pos(i);
00188                 for(int i=0; i < m_parzen_neg.size() ; i++) m_parzen_neg(i) /= sum_neg;
00189                 for(int i=0; i < m_parzen_pos.size() ; i++) m_parzen_pos(i) /= sum_pos;
00190 
00191                 // log likelihood computation
00192                 for(int i=0; i < m_ll_neg.size(); i++)  m_ll_neg[i] = log(m_parzen_neg(i)+Globals::EPS);
00193                 for(int i=0; i < m_ll_pos.size(); i++)  m_ll_pos[i] = log(m_parzen_pos(i)+Globals::EPS);
00194         }
00195 
00196         template <unsigned DIM, typename Pixel, typename PixelImage>
00197                 void ParzenRegionModule<DIM, Pixel, PixelImage>::save_result(const LevelSet & phi, std::string evodir, int iter) 
00198         {
00199                 base::save_histograms(evodir, iter);
00200 
00201                 std::ostringstream name;
00202                 std::ofstream file;
00203 
00204                 name.str("");
00205                 name << evodir << "Parzen_pos_" << std::setw(6) << std::setfill('0') << iter << ".txt";
00206                 file.open(name.str().c_str());
00207                 for(int i=0; i < m_parzen_pos.size() ; i++) 
00208                         file << i + base::m_hist_pos->min() << " " << m_parzen_pos(i) << std::endl;
00209                 file.close();
00210                 std::cout <<  " - Saved " << name.str() << " ..."  << std::endl;
00211 
00212                 name.str("");
00213                 name << evodir << "Parzen_neg_" << std::setw(6) << std::setfill('0') << iter << ".txt";
00214                 file.open(name.str().c_str());
00215                 for(int i=0; i < m_parzen_neg.size() ; i++) 
00216                         file << i + base::m_hist_neg->min()<< " " << m_parzen_neg(i) << std::endl;
00217                 file.close();
00218                 std::cout <<  " - Saved " << name.str() << " ..."  << std::endl;
00219         }
00220 }
00221 
00222 #endif // PARZENREGIONMODULE_H

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