• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List

labeled_image.hh

00001 // Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
00002 //
00003 // This file is part of Olena.
00004 //
00005 // Olena is free software: you can redistribute it and/or modify it under
00006 // the terms of the GNU General Public License as published by the Free
00007 // Software Foundation, version 2 of the License.
00008 //
00009 // Olena is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012 // General Public License for more details.
00013 //
00014 // You should have received a copy of the GNU General Public License
00015 // along with Olena.  If not, see <http://www.gnu.org/licenses/>.
00016 //
00017 // As a special exception, you may use this file as part of a free
00018 // software project without restriction.  Specifically, if other files
00019 // instantiate templates or use macros or inline functions from this
00020 // file, or you compile this file and link it with other files to produce
00021 // an executable, this file does not by itself cause the resulting
00022 // executable to be covered by the GNU General Public License.  This
00023 // exception does not however invalidate any other reasons why the
00024 // executable file might be covered by the GNU General Public License.
00025 
00026 #ifndef MLN_CORE_IMAGE_IMORPH_LABELED_IMAGE_HH
00027 # define MLN_CORE_IMAGE_IMORPH_LABELED_IMAGE_HH
00028 
00032 
00033 # include <mln/core/image/dmorph/image_if.hh>
00034 # include <mln/core/concept/function.hh>
00035 # include <mln/core/internal/image_identity.hh>
00036 # include <mln/core/site_set/box.hh>
00037 
00038 # include <mln/accu/pair.hh>
00039 # include <mln/accu/nil.hh>
00040 # include <mln/accu/center.hh>
00041 
00042 # include <mln/labeling/compute.hh>
00043 # include <mln/labeling/pack.hh>
00044 # include <mln/labeling/relabel.hh>
00045 
00046 # include <mln/util/array.hh>
00047 
00048 # include <mln/pw/cst.hh>
00049 # include <mln/pw/value.hh>
00050 
00051 # ifndef NDEBUG
00052 #  include <mln/accu/stat/max.hh>
00053 #  include <mln/data/compute.hh>
00054 # endif // ! NDEBUG
00055 
00056 
00057 namespace mln
00058 {
00059 
00060   // Forward declarations.
00061   template <typename I> struct labeled_image;
00062   namespace accu
00063   {
00064     template <typename T> struct nil;
00065     template <typename T> struct bbox;
00066   }
00067 
00068 
00069   namespace internal
00070   {
00071 
00073     template <typename I>
00074     struct data< labeled_image<I> >
00075     {
00076       data(const I& ima, const mln_value(I)& nlabels);
00077 
00078       I ima_;
00079       mln_value(I) nlabels_;
00080       mutable util::array< box<mln_psite(I)> > bboxes_;
00081     };
00082 
00083   } // end of namespace mln::internal
00084 
00085 
00086   namespace trait
00087   {
00088 
00089     template <typename I>
00090     struct image_< labeled_image<I> > : image_< I > // Same as I except...
00091     {
00092       // ...these changes.
00093       typedef trait::image::category::identity_morpher category;
00094       typedef mln_internal_trait_image_speed_from(I) speed; // Un-fastest.
00095       typedef trait::image::value_access::indirect value_access;
00096 
00097       typedef trait::image::value_io::read_only value_io;
00098       typedef trait::image::pw_io::read pw_io;
00099 
00100       // extended domain
00101       typedef trait::image::ext_value::multiple  ext_value;
00102       typedef trait::image::ext_io::read_only    ext_io;
00103     };
00104 
00105   } // end of namespace mln::trait
00106 
00107 
00108 
00120   //
00121   template <typename I>
00122   class labeled_image
00123     : public internal::image_identity< const I, mln_domain(I), labeled_image<I> >
00124   {
00125     typedef internal::image_identity< const I, mln_domain(I), labeled_image<I> >
00126             super_;
00127 
00128   public:
00129 
00131     typedef labeled_image< tag::image_<I> > skeleton;
00132 
00134     typedef mln_result(accu::shape::bbox<mln_psite(I)>) bbox_t;
00135 
00139     labeled_image();
00140 
00142     labeled_image(const I& ima, const mln_value(I)& nlabels);
00144 
00147     void init_(const I& ima, const mln_value(I)& nlabels);
00148 
00150     void init_from_(const labeled_image<I>& model);
00151 
00154     //
00160     template <typename F>
00161     void relabel(const Function_v2v<F>& f);
00162     //
00165     template <typename F>
00166     void relabel(const Function_v2b<F>& f);
00168 
00170     void pack_();
00171 
00173     mln_value(I) nlabels() const;
00174 
00176     void update_();
00177 
00179     const bbox_t& bbox(const mln_value(I)& label) const;
00180 
00182     const util::array<bbox_t>& bboxes() const;
00183 
00185       p_if<mln_box(I),
00186            fun::eq_v2b_expr_<pw::value_<I>, pw::cst_<mln_value(I)> > >
00187       subdomain(const mln_value(I)& label) const;
00188   };
00189 
00190 
00191   // init_
00192 
00193   //FIXME: not enough generic? We would like 'J' instead of
00194   // 'labeled_image<I>'.
00195   template <typename I, typename J>
00196   void init_(tag::image_t, labeled_image<I>& target,
00197                            const labeled_image<J>& model);
00198 
00199 
00200 
00201   namespace make
00202   {
00203 
00204     template <typename I>
00205     mln::labeled_image<I>
00206     labeled_image(const Image<I>& ima, const mln_value(I)& nlabels);
00207 
00208   } // end of namespace mln::make
00209 
00210 
00211 
00212 
00213 # ifndef MLN_INCLUDE_ONLY
00214 
00215 
00216   // internal::data< labeled_image<I> >
00217 
00218   namespace internal
00219   {
00220 
00221 
00222     // data< labeled_image<I> >
00223 
00224     template <typename I>
00225     inline
00226     data< labeled_image<I> >::data(const I& ima, const mln_value(I)& nlabels)
00227       : ima_(ima), nlabels_(nlabels)
00228     {
00229     }
00230 
00231   } // end of namespace mln::internal
00232 
00233 
00234   template <typename I>
00235   inline
00236   labeled_image<I>::labeled_image()
00237   {
00238   }
00239 
00240   template <typename I>
00241   inline
00242   labeled_image<I>::labeled_image(const I& ima, const mln_value(I)& nlabels)
00243   {
00244     init_(ima, nlabels);
00245   }
00246 
00247   template <typename I>
00248   inline
00249   void
00250   labeled_image<I>::init_(const I& ima, const mln_value(I)& nlabels)
00251   {
00252     mln_precondition(data::compute(accu::meta::stat::max(), ima) == nlabels);
00253     this->data_ = new internal::data< labeled_image<I> >(ima, nlabels);
00254     this->update_();
00255  }
00256 
00257   template <typename I>
00258   inline
00259   void
00260   labeled_image<I>::init_from_(const labeled_image<I>& model)
00261   {
00262     this->data_
00263       = new internal::data< labeled_image<I> >(duplicate(model.hook_data_()->ima_),
00264                                                  model.nlabels());
00265     this->data_->bboxes_ = model.hook_data_()->bboxes_;
00266   }
00267 
00268   template <typename I>
00269   template <typename F>
00270   inline
00271   void
00272   labeled_image<I>::relabel(const Function_v2v<F>& f_)
00273   {
00274     const F& f = exact(f_);
00275     labeling::relabel_inplace(this->data_->ima_, this->data_->nlabels_, f);
00276 
00280     pack_();
00281 
00284     this->update_();
00285   }
00286 
00287   template <typename I>
00288   template <typename F>
00289   inline
00290   void
00291   labeled_image<I>::relabel(const Function_v2b<F>& f_)
00292   {
00293     const F& f = exact(f_);
00294     labeling::relabel_inplace(this->data_->ima_, this->data_->nlabels_, f);
00295 
00298     this->update_();
00299   }
00300 
00301   template <typename I>
00302   inline
00303   void
00304   labeled_image<I>::pack_()
00305   {
00306     labeling::pack_inplace(this->data_->ima_, this->data_->nlabels_);
00307 
00310     this->update_();
00311   }
00312 
00313 
00314   template <typename I>
00315   inline
00316   mln_value(I)
00317   labeled_image<I>::nlabels() const
00318   {
00319     return this->data_->nlabels_;
00320   }
00321 
00322 
00323   // init_
00324 
00325   template <typename I, typename J>
00326   void init_(tag::image_t, labeled_image<I>& target,
00327              const labeled_image<J>& model)
00328   {
00329     I ima;
00330     init_(tag::image, ima, model);
00331     target.init_(ima, model.nlabels());
00332   }
00333 
00334 
00335   template <typename I>
00336   void
00337   labeled_image<I>::update_()
00338   {
00339     this->data_->bboxes_ = labeling::compute(accu::meta::shape::bbox(),
00340                                              this->data_->ima_,
00341                                              this->data_->nlabels_);
00342   }
00343 
00344 
00345   template <typename I>
00346   const typename labeled_image<I>::bbox_t&
00347   labeled_image<I>::bbox(const mln_value(I)& label) const
00348   {
00349     return this->data_->bboxes_[label];
00350   }
00351 
00352 
00353   template <typename I>
00354   const util::array<typename labeled_image<I>::bbox_t>&
00355   labeled_image<I>::bboxes() const
00356   {
00357       return this->data_->bboxes_;
00358   }
00359 
00360 
00361   template <typename I>
00362   p_if<mln_box(I),
00363        fun::eq_v2b_expr_<pw::value_<I>, pw::cst_<mln_value(I)> > >
00364   labeled_image<I>::subdomain(const mln_value(I)& label) const
00365   {
00366     return ((this->data_->ima_ | bbox(label))
00367             | (pw::value(this->data_->ima_) == pw::cst(label))).domain();
00368   }
00369 
00370 
00371   // Make routines.
00372 
00373   namespace make
00374   {
00375 
00376     template <typename I>
00377     mln::labeled_image<I>
00378     labeled_image(const Image<I>& ima, const mln_value(I)& nlabels)
00379     {
00380       mln_precondition(exact(ima).is_valid());
00381       mln::labeled_image<I> tmp(exact(ima), nlabels);
00382       return tmp;
00383     }
00384 
00385   } // end of namespace mln::make
00386 
00387 
00388 # endif // ! MLN_INCLUDE_ONLY
00389 
00390 } // end of namespace mln
00391 
00392 
00393 #endif // ! MLN_CORE_IMAGE_IMORPH_LABELED_IMAGE_HH

Generated on Thu Sep 8 2011 18:32:03 for Milena (Olena) by  doxygen 1.7.1