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

labeled_image_base.hh

00001 // Copyright (C) 2009, 2010 EPITA Research and Development Laboratory
00002 // (LRDE)
00003 //
00004 // This file is part of Olena.
00005 //
00006 // Olena is free software: you can redistribute it and/or modify it under
00007 // the terms of the GNU General Public License as published by the Free
00008 // Software Foundation, version 2 of the License.
00009 //
00010 // Olena is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013 // General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU General Public License
00016 // along with Olena.  If not, see <http://www.gnu.org/licenses/>.
00017 //
00018 // As a special exception, you may use this file as part of a free
00019 // software project without restriction.  Specifically, if other files
00020 // instantiate templates or use macros or inline functions from this
00021 // file, or you compile this file and link it with other files to produce
00022 // an executable, this file does not by itself cause the resulting
00023 // executable to be covered by the GNU General Public License.  This
00024 // exception does not however invalidate any other reasons why the
00025 // executable file might be covered by the GNU General Public License.
00026 
00027 #ifndef MLN_CORE_IMAGE_IMORPH_LABELED_IMAGE_BASE_HH
00028 # define MLN_CORE_IMAGE_IMORPH_LABELED_IMAGE_BASE_HH
00029 
00033 
00034 # include <mln/core/image/dmorph/image_if.hh>
00035 # include <mln/core/concept/function.hh>
00036 # include <mln/core/internal/image_identity.hh>
00037 # include <mln/core/site_set/box.hh>
00038 
00039 # include <mln/accu/shape/bbox.hh>
00040 
00041 # include <mln/labeling/relabel.hh>
00042 
00043 # include <mln/util/array.hh>
00044 # include <mln/value/next.hh>
00045 
00046 # include <mln/pw/cst.hh>
00047 # include <mln/pw/value.hh>
00048 
00049 # include <mln/make/relabelfun.hh>
00050 
00051 
00052 namespace mln
00053 {
00054 
00055   // Forward declaration.
00056   template <typename I, typename E>
00057   class labeled_image_base;
00058 
00059 
00060   namespace internal
00061   {
00062 
00064     template <typename I, typename E>
00065     struct data< labeled_image_base<I,E> >
00066     {
00067       data(const I& ima, const mln_value(I)& nlabels);
00068       data(const I& ima, const mln_value(I)& nlabels,
00069            const util::array<mln_box(I)>& bboxes);
00070 
00071       I ima_;
00072       mln_value(I) nlabels_;
00073       mutable util::array< box<mln_psite(I)> > bboxes_;
00074     };
00075 
00076   } // end of namespace mln::internal
00077 
00078 
00079 
00080   namespace trait
00081   {
00082 
00083     template <typename I, typename E>
00084     struct image_< labeled_image_base<I,E> > : image_< I > // Same as I except...
00085     {
00086       // ...these changes.
00087       typedef trait::image::category::identity_morpher category;
00088       typedef mln_internal_trait_image_speed_from(I) speed; // Un-fastest.
00089       typedef trait::image::value_access::indirect value_access;
00090 
00091       typedef trait::image::value_io::read_only value_io;
00092       typedef trait::image::pw_io::read pw_io;
00093 
00094       // extended domain
00095       typedef trait::image::ext_value::multiple  ext_value;
00096       typedef trait::image::ext_io::read_only    ext_io;
00097     };
00098 
00099   } // end of namespace mln::trait
00100 
00101 
00102 
00115   template <typename I, typename E>
00116   class labeled_image_base
00117     : public internal::image_identity< const I, mln_domain(I), E >
00118   {
00119     typedef internal::image_identity< const I, mln_domain(I), E >
00120             super_;
00121 
00122   public:
00124     typedef mln_result(accu::shape::bbox<mln_psite(I)>) bbox_t;
00125 
00129     labeled_image_base();
00131 
00134     //
00138     // FIXME: currently the label is kept contiguous for
00139     // performance reasons. Do we want to be less restrictive?
00140     template <typename F>
00141     void relabel(const Function_v2v<F>& f);
00142     //
00145     template <typename F>
00146     void relabel(const Function_v2b<F>& f);
00148 
00150     mln_value(I) nlabels() const;
00151 
00153     const bbox_t& bbox(const mln_value(I)& label) const;
00154 
00156     const util::array<bbox_t>& bboxes() const;
00157 
00159     p_if<mln_box(I),
00160          fun::eq_v2b_expr_<pw::value_<I>, pw::cst_<mln_value(I)> > >
00161     subdomain(const mln_value(I)& label) const;
00162 
00163   protected:
00165     void update_data(const fun::i2v::array<mln_value(I)>& relabel_fun);
00166 
00167     template <typename F>
00168     void relabel_(const Function_v2v<F>& f);
00169 
00170     template <typename F>
00171     void relabel_(const Function_v2b<F>& f);
00172 
00175     void init_update_data_();
00176     void prepare_update_data_(const mln_value(I)& lbl,
00177                               const mln_value(I)& new_lbl);
00178     void update_data_(const fun::i2v::array<mln_value(I)>& relabel_fun);
00180   };
00181 
00182 
00183 
00184 
00185 # ifndef MLN_INCLUDE_ONLY
00186 
00187 
00188   // internal::data< labeled_image_base<I,E> >
00189 
00190   namespace internal
00191   {
00192 
00193 
00194     // data< labeled_image_base<I,E> >
00195 
00196     template <typename I, typename E>
00197     inline
00198     data< labeled_image_base<I,E> >::data(const I& ima, const mln_value(I)& nlabels)
00199       : ima_(ima), nlabels_(nlabels)
00200     {
00201     }
00202 
00203     template <typename I, typename E>
00204     inline
00205     data< labeled_image_base<I,E> >::data(const I& ima, const mln_value(I)& nlabels,
00206                                    const util::array<mln_box(I)>& bboxes)
00207       : ima_(ima), nlabels_(nlabels), bboxes_(bboxes)
00208     {
00209     }
00210 
00211 
00212   } // end of namespace mln::internal
00213 
00214 
00215   template <typename I, typename E>
00216   inline
00217   labeled_image_base<I,E>::labeled_image_base()
00218   {
00219   }
00220 
00221 
00222   template <typename I, typename E>
00223   template <typename F>
00224   inline
00225   void
00226   labeled_image_base<I,E>::relabel(const Function_v2v<F>& f_)
00227   {
00228     const F& f = exact(f_);
00229     mln_value(I) new_nlabels;
00230 
00231     fun::i2v::array<mln_value(I)>
00232       packed_relabel_fun = make::relabelfun(f,
00233                                             this->data_->nlabels_,
00234                                             new_nlabels);
00235 
00236     labeling::relabel_inplace(this->data_->ima_, this->data_->nlabels_,
00237                               packed_relabel_fun);
00238 
00239     this->data_->nlabels_ = new_nlabels;
00240 
00241     exact(this)->relabel_(f);
00242 
00244     update_data(packed_relabel_fun);
00245   }
00246 
00247 
00248   template <typename I, typename E>
00249   template <typename F>
00250   inline
00251   void
00252   labeled_image_base<I,E>::relabel(const Function_v2b<F>& f_)
00253   {
00254     const F& f = exact(f_);
00255 
00256     // Relabel the underlying image.
00257     typedef fun::i2v::array<mln_value(I)> fv2v_t;
00258     fv2v_t fv2v = make::relabelfun(f,
00259                                    this->data_->nlabels_,
00260                                    this->data_->nlabels_);
00261 
00262     labeling::relabel_inplace(this->data_->ima_, this->data_->nlabels_, fv2v);
00263 
00264     exact(this)->relabel_(f);
00265 
00266     // Then, merge or delete bounding boxes according to this relabeling.
00267     update_data(fv2v);
00268   }
00269 
00270   template <typename I, typename E>
00271   inline
00272   mln_value(I)
00273   labeled_image_base<I,E>::nlabels() const
00274   {
00275     return this->data_->nlabels_;
00276   }
00277 
00278 
00279   template <typename I, typename E>
00280   void
00281   labeled_image_base<I,E>::update_data(const fun::i2v::array<mln_value(I)>& relabel_fun)
00282   {
00283     util::array<accu::shape::bbox<mln_psite(I)> >
00284       new_bboxes(mln::value::next(this->data_->nlabels_));
00285 
00286     exact(this)->init_update_data_();
00287 
00288     for (unsigned i = 1; i < this->data_->bboxes_.size(); ++i)
00289       if (relabel_fun(i) != 0)
00290       {
00291         new_bboxes[relabel_fun(i)].take(this->data_->bboxes_[i]);
00292         exact(this)->prepare_update_data_(i, relabel_fun(i));
00293       }
00294 
00295     convert::from_to(new_bboxes, this->data_->bboxes_);
00296 
00297     mln_assertion(new_bboxes.size() == this->data_->bboxes_.size());
00298 
00299     exact(this)->update_data_(relabel_fun);
00300   }
00301 
00302 
00303   template <typename I, typename E>
00304   const typename labeled_image_base<I,E>::bbox_t&
00305   labeled_image_base<I,E>::bbox(const mln_value(I)& label) const
00306   {
00307     return this->data_->bboxes_[label];
00308   }
00309 
00310 
00311   template <typename I, typename E>
00312   const util::array<typename labeled_image_base<I,E>::bbox_t>&
00313   labeled_image_base<I,E>::bboxes() const
00314   {
00315     return this->data_->bboxes_;
00316   }
00317 
00318 
00319   template <typename I, typename E>
00320   p_if<mln_box(I),
00321        fun::eq_v2b_expr_<pw::value_<I>, pw::cst_<mln_value(I)> > >
00322   labeled_image_base<I,E>::subdomain(const mln_value(I)& label) const
00323   {
00324     return ((this->data_->ima_ | bbox(label))
00325             | (pw::value(this->data_->ima_) == pw::cst(label))).domain();
00326   }
00327 
00328 
00329 
00330   template <typename I, typename E>
00331   template <typename F>
00332   void
00333   labeled_image_base<I,E>::relabel_(const Function_v2v<F>& f)
00334   {
00335     (void) f;
00336     // No-Op.
00337   }
00338 
00339   template <typename I, typename E>
00340   template <typename F>
00341   void
00342   labeled_image_base<I,E>::relabel_(const Function_v2b<F>& f)
00343   {
00344     (void) f;
00345     // No-Op.
00346   }
00347 
00348   template <typename I, typename E>
00349   void
00350   labeled_image_base<I,E>::update_data_(
00351     const fun::i2v::array<mln_value(I)>& relabel_fun)
00352   {
00353     (void) relabel_fun;
00354     // No-Op.
00355   }
00356 
00357   template <typename I, typename E>
00358   void
00359   labeled_image_base<I,E>::prepare_update_data_(const mln_value(I)& lbl,
00360                                                 const mln_value(I)& new_lbl)
00361   {
00362     (void) lbl;
00363     (void) new_lbl;
00364     // No-Op.
00365   }
00366 
00367   template <typename I, typename E>
00368   void
00369   labeled_image_base<I,E>::init_update_data_()
00370   {
00371     // No-Op.
00372   }
00373 
00374 
00375 # endif // ! MLN_INCLUDE_ONLY
00376 
00377 } // end of namespace mln
00378 
00379 
00380 #endif // ! MLN_CORE_IMAGE_IMORPH_LABELED_IMAGE_BASE_HH

Generated on Tue Oct 4 2011 15:24:01 for Milena (Olena) by  doxygen 1.7.1