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

rag_and_labeled_wsl.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_MAKE_RAG_AND_LABELED_WSL_HH
00027 # define MLN_MAKE_RAG_AND_LABELED_WSL_HH
00028 
00037 
00038 # include <map>
00039 
00040 # include <mln/core/concept/image.hh>
00041 # include <mln/core/concept/neighborhood.hh>
00042 # include <mln/core/image/image2d.hh>
00043 # include <mln/core/alias/box2d.hh>
00044 # include <mln/extension/adjust_fill.hh>
00045 # include <mln/util/graph.hh>
00046 # include <mln/util/couple.hh>
00047 
00048 
00049 namespace mln
00050 {
00051 
00052   namespace make
00053   {
00054 
00064 
00091     template <typename I, typename N>
00092     util::couple<util::graph,mln_concrete(I)>
00093     rag_and_labeled_wsl(const Image<I>& wshd_,
00094                         const Neighborhood<N>& nbh_,
00095                         const mln_value(I)& nbasins);
00096 
00097 
00098 
00099 # ifndef MLN_INCLUDE_ONLY
00100 
00101 
00102     namespace internal
00103     {
00104 
00105       template <typename I, typename N>
00106       inline
00107       void
00108       rag_and_labeled_wsl_tests(const Image<I>& wshd,
00109                                 const Neighborhood<N>& nbh,
00110                                 const mln_value(I)&)
00111       {
00112         mln_precondition(exact(wshd).is_valid());
00113         mln_precondition(exact(nbh).is_valid());
00114         (void) wshd;
00115         (void) nbh;
00116       }
00117 
00118     } // end of namespace mln::make::internal
00119 
00120 
00121     namespace impl
00122     {
00123 
00124       namespace generic
00125       {
00126 
00127         template <typename I, typename N>
00128         inline
00129         util::couple<util::graph,mln_concrete(I)>
00130         rag_and_labeled_wsl(const Image<I>& wshd_,
00131                             const Neighborhood<N>& nbh_,
00132                             const mln_value(I)& nbasins)
00133         {
00134           trace::entering("make::impl::generic::rag_and_labeled_wsl");
00135 
00136           internal::rag_and_labeled_wsl_tests(wshd_, nbh_, nbasins);
00137           const I& wshd = exact(wshd_);
00138           const N& nbh = exact(nbh_);
00139           typedef mln_value(I) L;
00140 
00141           extension::adjust_fill(wshd, nbh, 0u);
00142 
00143           mln_concrete(I) output(wshd.domain());
00144 
00145           // FIXME: we would like to not use mln_value() but 0 instead.
00146           // We can't do that because graph edges are numbered from 0.
00147           data::fill(output, mln_max(mln_value(I)).prev());
00148 
00149           std::map<util::couple<L,L>, mln_value(I)> c2la;
00150           util::array<util::couple<L,L> > la2c;
00151           mln_value(I) nlabels = literal::zero;
00152 
00153           L l1, l2;
00154           mln_piter(I) p(wshd.domain());
00155           mln_niter(N) n(nbh, p);
00156           for_all(p)
00157           {
00158             if (wshd(p) != 0u)
00159               continue;
00160             // p is in the watershed line.
00161             l1 = l2 = 0;
00162             for_all(n)
00163               if (wshd.has(n) && wshd(n) != 0u)
00164               {
00165                 if (l1 == 0u) // First label to be stored.
00166                   l1 = wshd(n);
00167                 else
00168                   if (wshd(n) != l1) // Useless: && l2 == 0)
00169                   { // Second label to be stored.
00170                     mln_invariant(l2 == 0u);
00171                     l2 = wshd(n);
00172                     break;
00173                   }
00174               }
00175             if (l2 == 0u || l1 == 0u)
00176               continue;
00177             if (l2 < l1)
00178               std::swap(l1, l2);
00179 
00180             // adjacency l1 l2
00181             util::couple<L,L> c = make::couple(l2,l1);
00182             if (c2la.find(c) == c2la.end())
00183             {
00184               c2la[c] = nlabels++;
00185               la2c.append(c);
00186             }
00187             output(p) = c2la[c];
00188 
00189           }
00190 
00191           // Construct graph.
00192           util::graph g;
00193           g.add_vertices(nbasins.next());
00194           for (unsigned i = 0; i < la2c.nelements(); ++i)
00195             g.add_edge(la2c[i].first(), la2c[i].second());
00196 
00197           trace::exiting("make::impl::generic::rag_and_labeled_wsl");
00198           return make::couple(g, output);
00199         }
00200 
00201       } // end of namespace mln::make::impl::generic
00202 
00203     } // end of namespace mln::make::impl
00204 
00205 
00206 
00207     namespace internal
00208     {
00209 
00210       template <typename I, typename N>
00211       inline
00212       util::couple<util::graph,mln_concrete(I)>
00213       rag_and_labeled_wsl_dispatch(const Image<I>& wshd,
00214                                    const Neighborhood<N>& nbh,
00215                                    const mln_value(I)& nbasins)
00216       {
00217         return make::impl::generic::rag_and_labeled_wsl(wshd, nbh, nbasins);
00218       }
00219 
00220     } // end of namespace mln::make::internal
00221 
00222 
00223 
00224     // Facade
00225 
00226     template <typename I, typename N>
00227     inline
00228     util::couple<util::graph,mln_concrete(I)>
00229     rag_and_labeled_wsl(const Image<I>& wshd,
00230                         const Neighborhood<N>& nbh,
00231                         const mln_value(I)& nbasins)
00232     {
00233       trace::entering("make::rag_and_labeled_wsl");
00234 
00235       internal::rag_and_labeled_wsl_tests(wshd, nbh, nbasins);
00236 
00237       util::couple<util::graph,mln_concrete(I)>
00238         result = internal::rag_and_labeled_wsl_dispatch(wshd, nbh, nbasins);
00239 
00240       trace::exiting("make::rag_and_labeled_wsl");
00241       return result;
00242     }
00243 
00244 
00245 # endif // ! MLN_INCLUDE_ONLY
00246 
00247 
00248   } // end of namespace mln::make
00249 
00250 } // end of namespace mln
00251 
00252 
00253 #endif // ! MLN_MAKE_RAG_AND_LABELED_WSL_HH

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