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

hit_or_miss.hh

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

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