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

gradient.hh

00001 // Copyright (C) 2008, 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_MORPHO_ELEMENTARY_GRADIENT_HH
00027 # define MLN_MORPHO_ELEMENTARY_GRADIENT_HH
00028 
00032 
00033 # include <mln/morpho/includes.hh>
00034 # include <mln/accu/stat/min_max.hh>
00035 
00036 
00037 namespace mln
00038 {
00039 
00040   namespace morpho
00041   {
00042 
00043     namespace elementary
00044     {
00045 
00046 
00047       template <typename I, typename N>
00048       mln_concrete(I)
00049       gradient(const Image<I>& input, const Neighborhood<N>& nbh);
00050 
00051 
00052 # ifndef MLN_INCLUDE_ONLY
00053 
00054       namespace internal
00055       {
00056 
00057         template <typename I, typename N>
00058         void
00059         gradient_tests(const Image<I>& input, const Neighborhood<N>& nbh)
00060         {
00061           mln_precondition(exact(input).is_valid());
00062           mln_precondition(exact(nbh).is_valid());
00063           (void) input;
00064           (void) nbh;
00065         }
00066 
00067       } // end of namespace mln::morpho::elementary::tests
00068 
00069 
00070       namespace impl
00071       {
00072 
00073         template <typename I, typename N>
00074         mln_concrete(I)
00075         gradient_on_function(const Image<I>& input_, const Neighborhood<N>& nbh_)
00076         {
00077           trace::entering("morpho::elementary::impl::gradient_on_function");
00078 
00079           const I& input = exact(input_);
00080           const N& nbh   = exact(nbh_);
00081           internal::gradient_tests(input, nbh);
00082 
00083           accu::stat::min_max<mln_value(I)> a;
00084 
00085           extension::adjust_duplicate(input, nbh);
00086 
00087           mln_concrete(I) output;
00088           initialize(output, input);
00089 
00090           mln_piter(I) p(input.domain());
00091           mln_niter(N) n(nbh, p);
00092           for_all(p)
00093             {
00094               a.take_as_init(input(p));
00095               for_all(n) if (input.has(n))
00096                 a.take(input(n));
00097               output(p) = a.second() - a.first();
00098             }
00099 
00100           trace::exiting("morpho::elementary::impl::gradient_on_function");
00101           return output;
00102         }
00103 
00104         template <typename I, typename N>
00105         mln_concrete(I)
00106         gradient_on_set(const Image<I>& input_, const Neighborhood<N>& nbh_)
00107         {
00108           trace::entering("morpho::elementary::impl::gradient_on_set");
00109 
00110           const I& input = exact(input_);
00111           const N& nbh   = exact(nbh_);
00112           internal::gradient_tests(input, nbh);
00113 
00114           extension::adjust_duplicate(input, nbh);
00115 
00116           mln_concrete(I) output;
00117           initialize(output, input);
00118           data::fill(output, false);
00119 
00120           mln_piter(I) p(input.domain());
00121           mln_niter(N) n(nbh, p);
00122           for_all(p)
00123             if (input(p) == true)
00124               {
00125                 for_all(n) if (input.has(n))
00126                   if (input(n) == false)
00127                     {
00128                       output(p) = true;
00129                       break;
00130                     }
00131               }
00132             else // input(p) == false
00133               {
00134                 for_all(n) if (input.has(n))
00135                   if (input(n) == true)
00136                     {
00137                       output(p) = true;
00138                       break;
00139                     }
00140               }
00141 
00142           trace::exiting("morpho::elementary::impl::gradient_on_set");
00143           return output;
00144         }
00145 
00146 
00147         template <typename I, typename N>
00148         mln_concrete(I)
00149         gradient_on_function_fastest(const Image<I>& input_, const Neighborhood<N>& nbh_)
00150         {
00151           trace::entering("morpho::elementary::impl::gradient_on_function_fastest");
00152 
00153           const I& input = exact(input_);
00154           const N& nbh   = exact(nbh_);
00155           internal::gradient_tests(input, nbh);
00156 
00157           accu::stat::min_max<mln_value(I)> a;
00158           extension::adjust_duplicate(input, nbh);
00159 
00160           typedef mln_concrete(I) O;
00161           O output;
00162           initialize(output, input);
00163 
00164           mln_pixter(const I) p_in(input);
00165           mln_pixter(O) p_out(output);
00166           mln_nixter(const I, N) n(p_in, nbh);
00167           for_all_2(p_in, p_out)
00168             {
00169               a.take_as_init(p_in.val());
00170               for_all(n)
00171                 a.take(n.val());
00172               p_out.val() = a.second() - a.first();
00173             }
00174 
00175           trace::exiting("morpho::elementary::impl::gradient_on_function_fastest");
00176           return output;
00177         }
00178 
00179       } // end of namespace mln::morpho::elementary::impl
00180 
00181 
00182       namespace internal
00183       {
00184 
00185         // Dispatch.
00186 
00187         template <typename I, typename N>
00188         mln_concrete(I)
00189         gradient_dispatch(trait::image::kind::any,
00190                           trait::image::speed::any,
00191                           const Image<I>& input, const Neighborhood<N>& nbh)
00192         {
00193           return impl::gradient_on_function(input, nbh);
00194         }
00195 
00196         template <typename I, typename N>
00197         mln_concrete(I)
00198         gradient_dispatch(trait::image::kind::any,
00199                           trait::image::speed::fastest,
00200                           const Image<I>& input, const Neighborhood<N>& nbh)
00201         {
00202           return impl::gradient_on_function_fastest(input, nbh);
00203         }
00204 
00205         template <typename I, typename N>
00206         mln_concrete(I)
00207         gradient_dispatch(trait::image::kind::logic,
00208                           trait::image::speed::any,
00209                           const Image<I>& input, const Neighborhood<N>& nbh)
00210         {
00211           return impl::gradient_on_set(input, nbh);
00212         }
00213 
00214         // May be redundant with the previous version but fixes an ambiguity
00215         // with image*d<bool> which is fasted AND logic.
00216         template <typename I, typename N>
00217         mln_concrete(I)
00218         gradient_dispatch(trait::image::kind::logic,
00219                           trait::image::speed::fastest,
00220                           const Image<I>& input, const Neighborhood<N>& nbh)
00221         {
00222           return impl::gradient_on_set(input, nbh);
00223         }
00224 
00225         template <typename I, typename N>
00226         mln_concrete(I)
00227         gradient_dispatch(const Image<I>& input, const Neighborhood<N>& nbh)
00228         {
00229           return gradient_dispatch(mln_trait_image_kind(I)(),
00230                                    mln_trait_image_speed(I)(),
00231                                    input, nbh);
00232         }
00233 
00234       } // end of namespace mln::morpho::elementary::internal
00235 
00236 
00237       // Facade.
00238 
00239       template <typename I, typename N>
00240       mln_concrete(I)
00241         gradient(const Image<I>& input, const Neighborhood<N>& nbh)
00242       {
00243         trace::entering("morpho::elementary::gradient");
00244 
00245         internal::gradient_tests(input, nbh);
00246         mln_concrete(I) output = internal::gradient_dispatch(input, nbh);
00247         
00248         trace::exiting("morpho::elementary::gradient");
00249         return output;
00250       }
00251 
00252 # endif // ! MLN_INCLUDE_ONLY
00253 
00254     } // end of namespace mln::morpho::elementary
00255 
00256   } // end of namespace mln::morpho
00257 
00258 } // end of namespace mln
00259 
00260 
00261 #endif // ! MLN_MORPHO_ELEMENTARY_GRADIENT_HH

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