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

video.hh

00001 // Copyright (C) 2007, 2008, 2009 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_CANVAS_LABELING_VIDEO_HH
00028 # define MLN_CANVAS_LABELING_VIDEO_HH
00029 
00036 
00037 # include <mln/core/concept/image.hh>
00038 # include <mln/data/fill.hh>
00039 # include <mln/literal/zero.hh>
00040 # include <mln/extension/adjust_fill.hh>
00041 
00042 # include <mln/canvas/labeling/internal/tests.hh>
00043 # include <mln/canvas/labeling/internal/find_root_fastest.hh>
00044 # include <mln/canvas/labeling/generic.hh>
00045 
00046 namespace mln
00047 {
00048 
00049   namespace canvas
00050   {
00051 
00052     namespace labeling
00053     {
00054 
00055       template <typename I, typename N, typename L, typename F>
00056       mln_ch_value(I, L)
00057       video(const Image<I>& input, const Neighborhood<N>& nbh,
00058             L& nlabels, F& functor);
00059 
00060 
00061 # ifndef MLN_INCLUDE_ONLY
00062 
00063 
00064       // Implementations.
00065 
00066       namespace impl
00067       {
00068 
00069         template <typename I, typename N, typename L, typename F>
00070         mln_ch_value(I, L)
00071         video_fastest(const Image<I>& input_,
00072                       const Neighborhood<N>& nbh_,
00073                       L& nlabels, F& f)
00074         {
00075           trace::entering("canvas::impl::video_fastest");
00076 
00077           // FIXME: Test?!
00078 
00079           const I& input = exact(input_);
00080           const N& nbh   = exact(nbh_);
00081 
00082           extension::adjust(input, nbh);
00083 
00084           // Auxiliary data.
00085           mln_ch_value(I, bool) deja_vu;
00086           mln_ch_value(I, unsigned) parent;
00087 
00088           // Output.
00089           mln_ch_value(I, L) output;
00090           bool status;
00091 
00092           // Initialization.
00093           {
00094             initialize(deja_vu, input);
00095             mln::data::fill(deja_vu, true);
00096             extension::fill(deja_vu, false); // So that the extension is ignored.
00097 
00098             initialize(parent, input);
00099 
00100             initialize(output, input);
00101             mln::data::fill(output, L(literal::zero));
00102             nlabels = 0;
00103 
00104             f.init_(); // Client initialization.
00105           }
00106 
00107           // First Pass.
00108           {
00109             util::array<int> dp = positive_offsets_wrt(input, nbh);
00110             const unsigned n_nbhs = dp.nelements();
00111 
00112             mln_bkd_pixter(const I) px(input); // Backward.
00113             for_all(px)
00114             {
00115               unsigned p = px.offset();
00116               if (! f.handles_(p))
00117                 continue;
00118 
00119               // Make-Set.
00120               parent.element(p) = p;
00121               f.init_attr_(p);
00122               for (unsigned i = 0; i < n_nbhs; ++i)
00123               {
00124                 unsigned n = p + dp[i];
00125                 if (deja_vu.element(n)) // Only false in the external border.
00126                 {
00127                   if (f.equiv_(n, p))
00128                   {
00129                     // Do-Union.
00130                     unsigned r = internal::find_root_fastest(parent, n);
00131                     if (r != p)
00132                     {
00133                       parent.element(r) = p;
00134                       f.merge_attr_(r, p);
00135                     }
00136                   }
00137                   else
00138                     f.do_no_union_(n, p);
00139                 }
00140               }
00141             }
00142           }
00143 
00144           // Second Pass.
00145           {
00146             mln_fwd_pixter(const I) px(input); // Forward.
00147             for_all(px)
00148             {
00149               unsigned p = px.offset();
00150               if (! f.handles_(p))
00151                 continue;
00152               if (parent.element(p) == p) // if p is root
00153               {
00154                 if (f.labels_(p))
00155                 {
00156                   if (nlabels == mln_max(L))
00157                   {
00158                     status = false;
00159                     trace::warning("labeling aborted! Too many labels for \
00160                                         this label type: nlabels > \
00161                                         max(label_type).");
00162                     return output;
00163                   }
00164                   output.element(p) = ++nlabels;
00165                   f.set_new_label_(p, nlabels);
00166                 }
00167               }
00168               else
00169               {
00170                 L lbl = output.element(parent.element(p));
00171                 output.element(p) = lbl;
00172                 f.set_label_(p, lbl);
00173               }
00174             }
00175             status = true;
00176           }
00177 
00178           f.finalize();
00179           trace::exiting("canvas::impl::video_fastest");
00180           return output;
00181         }
00182 
00183       } // end of namespace mln::canvas::impl
00184 
00185 
00186 
00187       // Dispatch.
00188 
00189       namespace internal
00190       {
00191 
00192         template <typename I, typename N, typename L, typename F>
00193         inline
00194         mln_ch_value(I, L)
00195         video_dispatch(metal::false_,
00196                        const Image<I>& input,
00197                        const Neighborhood<N>& nbh, L& nlabels,
00198                        F& functor)
00199         {
00200           return impl::generic::labeling(input, nbh, nlabels,
00201                                          exact(input).domain(), functor);
00202         }
00203 
00204         template <typename I, typename N, typename L, typename F>
00205         inline
00206         mln_ch_value(I, L)
00207         video_dispatch(metal::true_,
00208                        const Image<I>& input,
00209                        const Neighborhood<N>& nbh, L& nlabels,
00210                        F& functor)
00211         {
00212           return impl::video_fastest(input, nbh, nlabels, functor);
00213         }
00214 
00215         template <typename I, typename N, typename L, typename F>
00216         inline
00217         mln_ch_value(I, L)
00218         video_dispatch(const Image<I>& input,
00219                        const Neighborhood<N>& nbh, L& nlabels,
00220                        F& functor)
00221         {
00222           enum {
00223             test = mlc_equal(mln_trait_image_speed(I),
00224                              trait::image::speed::fastest)::value
00225             &&
00226             mln_is_simple_neighborhood(N)::value
00227           };
00228           return video_dispatch(metal::bool_<test>(),
00229                                 input, nbh, nlabels,
00230                                 functor);
00231         }
00232 
00233 
00234       } // end of namespace mln::canvas::internal
00235 
00236 
00237 
00238       // Facades.
00239 
00240 
00241       template <typename I, typename N, typename L, typename F>
00242       inline
00243       mln_ch_value(I, L)
00244       video(const Image<I>& input, const Neighborhood<N>& nbh,
00245             L& nlabels, F& functor)
00246       {
00247         trace::entering("canvas::video");
00248 
00249         internal::labeling_tests(input, nbh, nlabels, functor);
00250 
00251         mln_ch_value(I, L) output;
00252         output = internal::video_dispatch(input, nbh, nlabels,
00253                                                    functor);
00254 
00255         trace::exiting("canvas::video");
00256         return output;
00257       }
00258 
00259 # endif // ! MLN_INCLUDE_ONLY
00260 
00261     } // end of namespace mln::canvas::labeling
00262 
00263   } // end of namespace mln::canvas
00264 
00265 } // end of namespace mln
00266 
00267 
00268 #endif // ! MLN_CANVAS_LABELING_VIDEO_HH

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