Milena (Olena)  User documentation 2.0a Id
hit_or_miss.hh
00001 // Copyright (C) 2007, 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_HIT_OR_MISS_HH
00028 # define MLN_MORPHO_HIT_OR_MISS_HH
00029 
00035 
00036 # include <mln/morpho/includes.hh>
00037 # include <mln/pw/all.hh>
00038 # include <mln/fun/p2v/ternary.hh>
00039 # include <mln/fun/cast.hh>
00040 # include <mln/literal/zero.hh>
00041 
00042 
00043 namespace mln
00044 {
00045 
00046   namespace morpho
00047   {
00048 
00049 
00050     extern bool constrained_hit_or_miss;
00051 
00052 
00054 
00057     template <typename I, typename Wh, typename Wm>
00058     mln_concrete(I)
00059     hit_or_miss(const Image<I>& input,
00060                 const Window<Wh>& win_hit, const Window<Wm>& win_miss);
00061 
00062 
00064 
00067     template <typename I, typename Wh, typename Wm>
00068     mln_concrete(I)
00069     hit_or_miss_opening(const Image<I>& input,
00070                         const Window<Wh>& win_hit, const Window<Wm>& win_miss);
00071 
00072 
00074 
00077     template <typename I, typename Wh, typename Wm>
00078     mln_concrete(I)
00079     hit_or_miss_background_opening(const Image<I>& input,
00080                                    const Window<Wh>& win_hit, const Window<Wm>& win_miss);
00081 
00082 
00084 
00087     template <typename I, typename Wh, typename Wm>
00088     mln_concrete(I)
00089     hit_or_miss_closing(const Image<I>& input,
00090                         const Window<Wh>& win_hit, const Window<Wm>& win_miss);
00091 
00092 
00094 
00097     template <typename I, typename Wh, typename Wm>
00098     mln_concrete(I)
00099     hit_or_miss_background_closing(const Image<I>& input,
00100                                    const Window<Wh>& win_hit, const Window<Wm>& win_miss);
00101 
00102 
00103 
00104 # ifndef MLN_INCLUDE_ONLY
00105 
00106 #  ifndef MLN_WO_GLOBAL_VARS
00107 
00108     bool constrained_hit_or_miss = true;
00109 
00110 #  endif // ! MLN_WO_GLOBAL_VARS
00111 
00112     namespace internal
00113     {
00114 
00115       template <typename I, typename Wh, typename Wm>
00116       inline
00117       void
00118       hit_or_miss_tests(const Image<I>&   input_,
00119                         const Window<Wh>& win_hit_,
00120                         const Window<Wm>& win_miss_)
00121       {
00122         const I&  input    = exact(input_);
00123         const Wh& win_hit  = exact(win_hit_);
00124         const Wm& win_miss = exact(win_miss_);
00125 
00126         // Tests.
00127         mln_precondition(input.is_valid());
00128         mln_precondition((win_hit && win_miss).is_empty());
00129 
00130         // Avoid warnings.
00131         (void) input;
00132         (void) win_hit;
00133         (void) win_miss;
00134       }
00135 
00136     } // end of namespace mln::morpho::internal
00137 
00138 
00139     namespace impl
00140     {
00141 
00142       // On sets.
00143 
00144       template <typename I, typename Wh, typename Wm>
00145       inline
00146       mln_concrete(I)
00147       hit_or_miss_logic(const Image<I>& input,
00148                         const Window<Wh>& win_hit,
00149                         const Window<Wm>& win_miss)
00150       {
00151         trace::entering("morpho::impl::hit_or_miss_logic");
00152         internal::hit_or_miss_tests(input, win_hit, win_miss);
00153 
00154         mln_concrete(I) output = logical::and_(erosion(input, win_hit),
00155                                                erosion(complementation(input),
00156                                                        win_miss));
00157 
00158         trace::exiting("morpho::impl::hit_or_miss_logic");
00159         return output;
00160       }
00161 
00162 
00163 
00164       namespace generic
00165       {
00166 
00167         // On functions.
00168 
00169         template <typename I, typename Wh, typename Wm>
00170         inline
00171         mln_concrete(I)
00172         hit_or_miss(const Image<I>& input_,
00173                     const Window<Wh>& win_hit_,
00174                     const Window<Wm>& win_miss_)
00175         {
00176           trace::entering("morpho::impl::generic::hit_or_miss");
00177           internal::hit_or_miss_tests(input_, win_hit_, win_miss_);
00178 
00179           const I& input = exact(input_);
00180           const Wh& win_hit = exact(win_hit_);
00181           const Wm& win_miss = exact(win_miss_);
00182 
00183           typedef mln_value(I) V;
00184           mln_value(I) zero_V = literal::zero;
00185 
00186           mln_concrete(I) output;
00187           initialize(output, input);
00188 
00189           if (constrained_hit_or_miss) // CHMT.
00190           {
00191             if (win_hit.is_centered())
00192             {
00193               mln_concrete(I)
00194                 ero_fg = erosion(input, win_hit),
00195                 dil_bg = dilation(input, win_miss);
00196               data::fill(output,
00197                           fun::p2v::ternary(pw::value(input) == pw::value(ero_fg)
00198                             && pw::value(dil_bg) < pw::value(input),
00199                             fun::cast<V>(pw::value(input) - pw::value(dil_bg)),
00200                             pw::cst(zero_V)));
00201             }
00202             else if (win_miss.is_centered())
00203             {
00204               mln_concrete(I)
00205                 ero_bg = erosion(input, win_miss),
00206                 dil_fg = dilation(input, win_hit);
00207               data::fill(output,
00208                           fun::p2v::ternary(pw::value(input) == pw::value(dil_fg)
00209                             && pw::value(ero_bg) > pw::value(input),
00210                             fun::cast<V>(pw::value(ero_bg) - pw::value(input)),
00211                             pw::cst(zero_V)));
00212             }
00213             else
00214               data::fill(output, zero_V);
00215           }
00216           else // Unconstrained: UHMT.
00217           {
00218             mln_concrete(I)
00219               ero = erosion(input, win_hit),
00220               dil = dilation(input, win_miss);
00221             data::fill(output,
00222                         fun::p2v::ternary(pw::value(dil) < pw::value(ero),
00223                           fun::cast<V>(pw::value(ero) - pw::value(dil)),
00224                           pw::cst(zero_V)));
00225           }
00226 
00227           trace::exiting("morpho::impl::generic::hit_or_miss");
00228           return output;
00229         }
00230 
00231       } // end of namespace mln::morpho::impl::generic
00232 
00233     } // end of mln::morpho::impl
00234 
00235 
00236     namespace internal
00237     {
00238 
00239       template <typename I, typename Wh, typename Wm>
00240       inline
00241       mln_concrete(I)
00242       hit_or_miss_dispatch(trait::image::kind::any,
00243                            const Image<I>& input,
00244                            const Window<Wh>& win_hit,
00245                            const Window<Wm>& win_miss)
00246       {
00247         return impl::generic::hit_or_miss(input, win_hit, win_miss);
00248       }
00249 
00250       template <typename I, typename Wh, typename Wm>
00251       inline
00252       mln_concrete(I)
00253       hit_or_miss_dispatch(trait::image::kind::logic,
00254                            const Image<I>& input,
00255                            const Window<Wh>& win_hit,
00256                            const Window<Wm>& win_miss)
00257       {
00258         return impl::hit_or_miss_logic(input, win_hit, win_miss);
00259       }
00260 
00261 
00262       template <typename I, typename Wh, typename Wm>
00263       inline
00264       mln_concrete(I)
00265       hit_or_miss_dispatch(const Image<I>& input,
00266                            const Window<Wh>& win_hit,
00267                            const Window<Wm>& win_miss)
00268       {
00269         return hit_or_miss_dispatch(mln_trait_image_kind(I)(),
00270                                     exact(input),
00271                                     exact(win_hit),
00272                                     exact(win_miss));
00273       }
00274 
00275     } // end of namespace mln::morpho::internal
00276 
00277 
00278     template <typename I, typename Wh, typename Wm>
00279     inline
00280     mln_concrete(I)
00281     hit_or_miss(const Image<I>& input,
00282                 const Window<Wh>& win_hit,
00283                 const Window<Wm>& win_miss)
00284     {
00285       trace::entering("morpho::hit_or_miss");
00286       internal::hit_or_miss_tests(input, win_hit, win_miss);
00287 
00288       mln_concrete(I) output = internal::hit_or_miss_dispatch(input,
00289                                                               win_hit,
00290                                                               win_miss);
00291       trace::exiting("morpho::hit_or_miss");
00292       return output;
00293     }
00294 
00295 
00296     template <typename I, typename Wh, typename Wm>
00297     inline
00298     mln_concrete(I)
00299     hit_or_miss_opening(const Image<I>& input,
00300                         const Window<Wh>& win_hit,
00301                         const Window<Wm>& win_miss)
00302     {
00303       trace::entering("morpho::hit_or_miss_opening");
00304       internal::hit_or_miss_tests(input, win_hit, win_miss);
00305 
00306       mln_concrete(I) output = dilation(internal::hit_or_miss_dispatch(input,
00307                                                                        win_hit,
00308                                                                        win_miss),
00309                                         win::sym(win_hit));
00310 
00311       trace::exiting("morpho::hit_or_miss_opening");
00312       return output;
00313     }
00314 
00315 
00316     template <typename I, typename Wh, typename Wm>
00317     inline
00318     mln_concrete(I)
00319     hit_or_miss_background_opening(const Image<I>& input,
00320                                    const Window<Wh>& win_hit,
00321                                    const Window<Wm>& win_miss)
00322     {
00323       trace::entering("morpho::hit_or_miss_background_opening");
00324       internal::hit_or_miss_tests(input, win_hit, win_miss);
00325 
00326       mln_concrete(I) output = hit_or_miss_opening(complementation(input),
00327                                                    win_miss,
00328                                                    win_hit);
00329 
00330       mln_postcondition(dilation(internal::hit_or_miss_dispatch(input,
00331                                                                 win_hit,
00332                                                                 win_miss),
00333                                  win::sym(win_miss)) == output);
00334       trace::exiting("morpho::hit_or_miss_background_opening");
00335       return output;
00336     }
00337 
00338 
00339     template <typename I, typename Wh, typename Wm>
00340     inline
00341     mln_concrete(I)
00342     hit_or_miss_closing(const Image<I>& input,
00343                         const Window<Wh>& win_hit,
00344                         const Window<Wm>& win_miss)
00345     {
00346       trace::entering("morpho::hit_or_miss_closing");
00347       internal::hit_or_miss_tests(input, win_hit, win_miss);
00348 
00349       mln_concrete(I) output =
00350           complementation(hit_or_miss_opening(complementation(input),
00351                                               win_hit, win_miss));
00352 
00353       // FIXME: Postcondition.
00354       trace::exiting("morpho::hit_or_miss_closing");
00355       return output;
00356     }
00357 
00358 
00359     template <typename I, typename Wh, typename Wm>
00360     inline
00361     mln_concrete(I)
00362     hit_or_miss_background_closing(const Image<I>& input,
00363                                    const Window<Wh>& win_hit,
00364                                    const Window<Wm>& win_miss)
00365     {
00366       trace::entering("morpho::hit_or_miss_background_closing");
00367       internal::hit_or_miss_tests(input, win_hit, win_miss);
00368 
00369       mln_concrete(I) output = hit_or_miss_closing(input, win_miss, win_hit);
00370 
00371       mln_postcondition(complementation(hit_or_miss_background_opening(
00372                                                   complementation(input),
00373                                                   win_hit, win_miss)) == output);
00374       trace::exiting("morpho::hit_or_miss_background_closing");
00375       return output;
00376     }
00377 
00378 # endif // ! MLN_INCLUDE_ONLY
00379 
00380   } // end of namespace mln::morpho
00381 
00382 } // end of namespace mln
00383 
00384 
00385 #endif // ! MLN_MORPHO_HIT_OR_MISS_HH
 All Classes Namespaces Functions Variables Typedefs Enumerator