00001
00009 #ifndef LOCALSTATSREGIONMODULE_H
00010 #define LOCALSTATSREGIONMODULE_H
00011
00012
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
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
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
00102 ImageType m_term1_pos;
00103 ImageType m_term1_neg;
00104 ImageType m_term2_pos;
00105 ImageType m_term2_neg;
00106
00107 #endif
00108
00109
00110 };
00111
00112
00114
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
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
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
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
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
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
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
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
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