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

crest.hh

00001 // Copyright (C) 2009, 2010, 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_TOPO_SKELETON_CREST_HH
00028 # define MLN_TOPO_SKELETON_CREST_HH
00029 
00033 
00034 # include <mln/core/concept/image.hh>
00035 # include <mln/core/concept/neighborhood.hh>
00036 # include <mln/data/fill.hh>
00037 # include <mln/extension/adjust.hh>
00038 # include <mln/border/equalize.hh>
00039 
00040 
00041 namespace mln
00042 {
00043 
00044   namespace topo
00045   {
00046 
00047     namespace skeleton
00048     {
00049 
00050 
00062       //
00092       template <typename I, typename D, typename N>
00093       mln_concrete(I)
00094       crest(const Image<I>& input, const Image<D>& dist_map,
00095             const Neighborhood<N>& nbh, unsigned psi_threshold);
00096 
00099       template <typename I, typename D, typename N>
00100       mln_concrete(I)
00101       crest(const Image<I>& input, const Image<D>& dist_map,
00102             const Neighborhood<N>& nbh);
00103 
00104 
00105 
00106 # ifndef MLN_INCLUDE_ONLY
00107 
00108       // IMPLEMENTATIONS
00109 
00110       namespace impl
00111       {
00112 
00113         namespace generic
00114         {
00115 
00116           template <typename I, typename D, typename N>
00117           mln_concrete(I)
00118           crest(const Image<I>& input_, const Image<D>& dist_map_,
00119                 const Neighborhood<N>& nbh_, unsigned psi_threshold)
00120           {
00121             trace::entering("topo::skeleton::impl::generic::crest");
00122             const I& input = exact(input_);
00123             const D& dist_map = exact(dist_map_);
00124             const N& nbh = exact(nbh_);
00125 
00126             mlc_equal(mln_value(I), bool)::check();
00127             mln_precondition(input.is_valid());
00128             mln_precondition(dist_map.is_valid());
00129             mln_precondition(nbh.is_valid());
00130 
00131             mln_concrete(I) is_crest;
00132             initialize(is_crest, input);
00133             data::fill(is_crest, false);
00134 
00135             mln_piter(I) p(input.domain());
00136             mln_niter(N) n(nbh, p);
00137             for_all(p)
00138             {
00139               if (!input(p) || dist_map(p) < static_cast<mln_value(D)>(0))
00140                 continue;
00141 
00142               unsigned nb_eq = 0;
00143               unsigned nb_lt = 0;
00144               for_all(n)
00145                 if (input.domain().has(n)
00146                     // We want to only consider sites which are part of
00147                     // the skeleton. If this test is removed, sometimes
00148                     // edge sites are considered as sites with a high PSI
00149                     // which is wrong.
00150                     && dist_map(n) > static_cast<mln_value(D)>(0))
00151                 {
00152                   if (dist_map(n) == dist_map(p))
00153                     ++nb_eq;
00154                   else if (dist_map(n) < dist_map(p))
00155                     ++nb_lt;
00156                 }
00157 
00158               if ((nb_lt + nb_eq) >= psi_threshold) // Pixel Superiority index
00159                 is_crest(p) = true;
00160             }
00161 
00162             trace::exiting("topo::skeleton::impl::generic::crest");
00163             return is_crest;
00164           }
00165 
00166         } // end of namespace mln::topo::skeleton::impl::generic
00167 
00168 
00169 
00170 
00171         template <typename I, typename D, typename N>
00172         mln_concrete(I)
00173         crest_fastest_2d(const Image<I>& input_, const Image<D>& dist_map_,
00174                          const Neighborhood<N>& nbh_, unsigned psi_threshold)
00175         {
00176           trace::entering("topo::skeleton::impl::crest_fastest_2d");
00177 
00178           const I& input = exact(input_);
00179           const D& dist_map = exact(dist_map_);
00180           const N& nbh = exact(nbh_);
00181 
00182           mlc_equal(mln_value(I), bool)::check();
00183           mln_precondition(input.is_valid());
00184           mln_precondition(dist_map.is_valid());
00185           mln_precondition(nbh.is_valid());
00186           mln_precondition(input.domain() == dist_map.domain());
00187 
00188           extension::adjust(input, nbh);
00189           border::equalize(input, dist_map, input.border());
00190 
00191           mln_concrete(I) is_crest;
00192           initialize(is_crest, input);
00193           data::fill(is_crest, false);
00194 
00195 
00196           mln_pixter(const I) p(input);
00197           util::array<int> dp = mln::offsets_wrt(input, nbh);
00198           unsigned n_nbhs = dp.nelements();
00199           for_all(p)
00200           {
00201             if (!p.val()
00202                 || dist_map.element(p) < static_cast<mln_value(D)>(0))
00203               continue;
00204 
00205             unsigned nb_eq = 0;
00206             unsigned nb_lt = 0;
00207             for (unsigned i = 0; i < n_nbhs; ++i)
00208             {
00209               unsigned n = p.offset() + dp[i];
00210               if (// We want to only consider sites which are part of
00211                   // the skeleton. If this test is removed, sometimes
00212                   // edge sites are considered as sites with a high PSI
00213                   // which is wrong.
00214                 dist_map.element(n) > static_cast<mln_value(D)>(0))
00215               {
00216                 if (dist_map.element(n) == dist_map.element(p))
00217                   ++nb_eq;
00218                 else if (dist_map.element(n) < dist_map.element(p))
00219                   ++nb_lt;
00220               }
00221 
00222               if ((nb_lt + nb_eq) >= psi_threshold) // Pixel Superiority index
00223                 is_crest.element(p) = true;
00224             }
00225 
00226           }
00227 
00228           trace::exiting("topo::skeleton::impl::crest_fastest_2d");
00229           return is_crest;
00230         }
00231 
00232       } // end of namespace mln::topo::skeleton::impl
00233 
00234 
00235       // DISPATCH
00236 
00237       namespace internal
00238       {
00239 
00240         template <typename I, typename D, typename N>
00241         mln_concrete(I)
00242         crest_dispatch_2d(mln::trait::image::value_storage::any,
00243                           mln::trait::image::value_access::any,
00244                           mln::trait::image::ext_domain::any,
00245                           const Image<I>& input, const Image<D>& dist_map,
00246                           const Neighborhood<N>& nbh, unsigned psi_threshold)
00247         {
00248           return skeleton::impl::generic::crest(input, dist_map,
00249                                                 nbh, psi_threshold);
00250         }
00251 
00252 
00253         template <typename I, typename D, typename N>
00254         mln_concrete(I)
00255         crest_dispatch_2d(mln::trait::image::value_storage::one_block,
00256                           mln::trait::image::value_access::direct,
00257                           mln::trait::image::ext_domain::some,
00258                           const Image<I>& input, const Image<D>& dist_map,
00259                           const Neighborhood<N>& nbh, unsigned psi_threshold)
00260         {
00261           return skeleton::impl::crest_fastest_2d(input, dist_map,
00262                                                   nbh, psi_threshold);
00263         }
00264 
00265 
00266         template <typename I, typename D, typename N>
00267         mln_concrete(I)
00268         crest_dispatch(const Image<I>& input, const Image<D>& dist_map,
00269               const Neighborhood<N>& nbh, unsigned psi_threshold)
00270         {
00271           unsigned dim = mln_site_(I)::dim;
00272 
00273           if (dim == 2)
00274             return
00275               crest_dispatch_2d(mln_trait_image_value_storage(I)(),
00276                                 mln_trait_image_value_access(I)(),
00277                                 mln_trait_image_ext_domain(I)(),
00278                                 input, dist_map, nbh, psi_threshold);
00279 
00280           return impl::generic::crest(input, dist_map, nbh, psi_threshold);
00281         }
00282 
00283 
00284       } // end of namespace mln::topo::skeleton::internal
00285 
00286 
00287       // FACADES
00288 
00289       template <typename I, typename D, typename N>
00290       mln_concrete(I)
00291       crest(const Image<I>& input, const Image<D>& dist_map,
00292             const Neighborhood<N>& nbh, unsigned psi_threshold)
00293       {
00294         trace::entering("topo::skeleton::crest");
00295 
00296         mlc_equal(mln_value(I), bool)::check();
00297         mln_precondition(exact(input).is_valid());
00298         mln_precondition(exact(dist_map).is_valid());
00299         mln_precondition(exact(nbh).is_valid());
00300 
00301         mln_concrete(I)
00302           output = internal::crest_dispatch(input, dist_map,
00303                                             nbh, psi_threshold);
00304 
00305         trace::exiting("topo::skeleton::crest");
00306         return output;
00307       }
00308 
00309 
00310       template <typename I, typename D, typename N>
00311       mln_concrete(I)
00312       crest(const Image<I>& input, const Image<D>& dist_map,
00313             const Neighborhood<N>& nbh)
00314       {
00315         return crest(input, dist_map, nbh, 6);
00316       }
00317 
00318 # endif // ! MLN_INCLUDE_ONLY
00319 
00320 
00321     } // end of namespace mln::topo::skeleton
00322 
00323   } // end of namespace mln::topo
00324 
00325 } // end of namespace mln
00326 
00327 #endif // ! MLN_TOPO_SKELETON_CREST_HH

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