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
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
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
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
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
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
00180 m_deriche.filter(m_parzen_neg);
00181 m_deriche.filter(m_parzen_pos);
00182
00183
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
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