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

skeleton_constrained.hh

00001 // Copyright (C) 2008, 2009, 2011 EPITA Research and Development
00002 // Laboratory (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_MORPHO_SKELETON_CONSTRAINED_HH
00028 # define MLN_MORPHO_SKELETON_CONSTRAINED_HH
00029 
00036 
00037 # include <mln/core/concept/image.hh>
00038 # include <mln/core/concept/neighborhood.hh>
00039 # include <mln/core/site_set/p_queue_fast.hh>
00040 # include <mln/core/site_set/p_priority.hh>
00041 # include <mln/extension/adjust_duplicate.hh>
00042 # include <mln/extension/adjust_fill.hh>
00043 # include <mln/data/fill.hh>
00044 
00045 # include <mln/util/timer.hh>
00046 
00047 namespace mln
00048 {
00049 
00050   namespace morpho
00051   {
00052 
00053     template <typename I,
00054               typename N, typename F,
00055               typename K, typename R>
00056     mln_ch_value(I, bool)
00057     skeleton_constrained(const Image<I>& input,
00058                          const Neighborhood<N>& nbh, const F& is_simple,
00059                          const Image<K>& constraint, const Image<R>& priority);
00060 
00061 
00062 
00063 # ifndef MLN_INCLUDE_ONLY
00064 
00065 
00066     namespace impl
00067     {
00068 
00069       namespace generic
00070       {
00071 
00072         template <typename I,
00073                   typename N, typename F,
00074                   typename K, typename R>
00075         inline
00076         mln_ch_value(I, bool)
00077           skeleton_constrained(const Image<I>& input_,
00078                                const Neighborhood<N>& nbh_, const F& is_simple,
00079                                const Image<K>& constraint_, const Image<R>& priority_)
00080         {
00081           trace::entering("morpho::skeleton_constrained");
00082 
00083           const I& input      = exact(input_);
00084           const N& nbh        = exact(nbh_);
00085           const K& constraint = exact(constraint_);
00086           const R& priority   = exact(priority_);
00087 
00088           mln_precondition(input.is_valid());
00089           mln_precondition(nbh.is_valid());
00090           mln_precondition(constraint.is_valid());
00091           mln_precondition(priority.is_valid());
00092 
00093           typedef mln_value(I) V;
00094           mlc_is(V, bool)::check();
00095 
00096           extension::adjust_duplicate(input, nbh);
00097           extension::adjust_duplicate(constraint, nbh);
00098           extension::adjust_duplicate(priority, nbh);
00099 
00100           // FIXME: Tests!
00101 
00102           typedef mln_psite(I) P;
00103           typedef p_queue_fast<P> Q;
00104           p_priority<mln_value(R), Q> q;
00105 
00106           mln_concrete(I) output;
00107 
00108           // Initialization.
00109           {
00110             output = duplicate(input);
00111             extension::adjust_duplicate(output, nbh);
00112 
00113             mln_piter(I) p(input.domain());
00114             for_all(p)
00115               if (input(p) == false &&
00116                   is_simple.check(input, p)) // <-- is_simple.check
00117                                       // p is a simple point of the background.
00118               {
00119                 q.push(priority(p), p);
00120               }
00121           }
00122 
00123           // Propagation.
00124           {
00125             P p;
00126 
00127             mln_niter(N) n(nbh, p);
00128             while (! q.is_empty())
00129             {
00130               p = q.pop_front();
00131               for_all(n)
00132                 if (output.has(n) &&
00133                     output(n) == true &&
00134                     constraint(n) == false &&
00135                     is_simple.check(output, n)) // <-- is_simple.check
00136                 {
00137                   output(n) = false; // Remove n from object.
00138                   q.push(priority(n), n);
00139                 }
00140             }
00141           }
00142 
00143           trace::exiting("morpho::skeleton_constrained");
00144           return output;
00145         }
00146 
00147       } // end of namespace mln::morpho::impl::generic
00148 
00149 
00150         template <typename I,
00151                   typename N, typename F,
00152                   typename K, typename R>
00153         inline
00154         mln_ch_value(I, bool)
00155         skeleton_constrained_fast(const Image<I>& input_,
00156                                   const Neighborhood<N>& nbh_,
00157                                   const F& is_simple,
00158                                   const Image<K>& constraint_,
00159                                   const Image<R>& priority_)
00160         {
00161           trace::entering("morpho::skeleton_constrained_fast");
00162 
00163           const I& input      = exact(input_);
00164           const N& nbh        = exact(nbh_);
00165           const K& constraint = exact(constraint_);
00166           const R& priority   = exact(priority_);
00167 
00168           mln_precondition(input.is_valid());
00169           mln_precondition(nbh.is_valid());
00170           mln_precondition(constraint.is_valid());
00171           mln_precondition(priority.is_valid());
00172 
00173           typedef mln_value(I) V;
00174           mlc_is(V, bool)::check();
00175 
00176           // Whatever the value of the extension, results of this fast
00177           // version may differ from the generic one. Indeed, we
00178           // cannot check whether a site belongs to the image or not,
00179           // so we try to not take border site in consideration by
00180           // setting their value to false.
00181           extension::adjust_fill(input, nbh, false);
00182           extension::adjust_fill(constraint, nbh, false);
00183 
00184           // FIXME: Tests!
00185 
00186           typedef p_queue_fast<unsigned> Q;
00187           p_priority<mln_value(R), Q> q;
00188 
00189           mln_concrete(I) output;
00190 
00191           // Initialization.
00192           {
00193             output = duplicate(input);
00194             extension::adjust_fill(output, nbh, false);
00195 
00196             mln_pixter(const I) p_in(input);
00197             for_all(p_in)
00198               if (p_in.val() == false &&
00199                   is_simple.check__(input, p_in)) // <-- is_simple.check
00200                                                   // p is a simple point of the background.
00201               {
00202                 q.push(priority.element(p_in.offset()), p_in);
00203               }
00204           }
00205 
00206           // Propagation.
00207           {
00208             util::array<int> dp = offsets_wrt(input, nbh.foreground());
00209             const unsigned n_nbhs = dp.nelements();
00210             while (! q.is_empty())
00211             {
00212               unsigned p = q.pop_front();
00213 
00214               for (unsigned i = 0; i < n_nbhs; ++i)
00215               {
00216                 unsigned n = p + dp[i];
00217 
00218                 if (output.element(n) == true &&
00219                     constraint.element(n) == false &&
00220                     is_simple.check__(output, n)) // <-- is_simple.check
00221                 {
00222                   output.element(n) = false; // Remove n from object.
00223                   q.push(priority.element(n), n);
00224                 }
00225               }
00226             }
00227           }
00228 
00229           trace::exiting("morpho::skeleton_constrained_fast");
00230           return output;
00231         }
00232 
00233 
00234     } // end of namespace mln::morpho::impl
00235 
00236 
00237     namespace internal
00238     {
00239 
00240       template <typename I,
00241                 typename N, typename F,
00242                 typename K, typename R>
00243       inline
00244       mln_ch_value(I, bool)
00245       skeleton_constrained_dispatch(
00246         mln::trait::image::value_access::any,
00247         mln::trait::image::value_storage::any,
00248         const Image<I>& input,
00249         const Neighborhood<N>& nbh,
00250         const F& is_simple,
00251         const Image<K>& constraint,
00252         const Image<R>& priority)
00253       {
00254         return impl::generic::skeleton_constrained(input, nbh,
00255                                                    is_simple,
00256                                                    constraint,
00257                                                    priority);
00258       }
00259 
00260       template <typename I,
00261                 typename N, typename F,
00262                 typename K, typename R>
00263       inline
00264       mln_ch_value(I, bool)
00265       skeleton_constrained_dispatch(
00266         mln::trait::image::value_access::direct,
00267         mln::trait::image::value_storage::one_block,
00268         const Image<I>& input,
00269         const Neighborhood<N>& nbh,
00270         const F& is_simple,
00271         const Image<K>& constraint,
00272         const Image<R>& priority)
00273       {
00274         return impl::skeleton_constrained_fast(input, nbh,
00275                                                is_simple,
00276                                                constraint,
00277                                                priority);
00278       }
00279 
00280 
00281     } // end of namespace mln::morpho::internal
00282 
00283 
00284     template <typename I,
00285               typename N, typename F,
00286               typename K, typename R>
00287     inline
00288     mln_ch_value(I, bool)
00289     skeleton_constrained(const Image<I>& input,
00290                          const Neighborhood<N>& nbh, const F& is_simple,
00291                          const Image<K>& constraint, const Image<R>& priority)
00292     {
00293       trace::entering("morpho::skeleton_constrained");
00294 
00295       mln_ch_value(I, bool)
00296         output = internal::skeleton_constrained_dispatch(
00297           mln_trait_image_value_access(I)(),
00298           mln_trait_image_value_storage(I)(),
00299           input, nbh, is_simple, constraint, priority);
00300 
00301       trace::exiting("morpho::skeleton_constrained");
00302       return output;
00303     }
00304 
00305 # endif // ! MLN_INCLUDE_ONLY
00306 
00307   } // end of namespace mln::morpho
00308 
00309 } // end of namespace mln
00310 
00311 
00312 #endif // ! MLN_MORPHO_SKELETON_CONSTRAINED_HH

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