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

enlarge.hh

00001 // Copyright (C) 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_WORLD_BINARY_2D_ENLARGE_HH
00027 # define MLN_WORLD_BINARY_2D_ENLARGE_HH
00028 
00034 
00035 
00036 # include <iostream>
00037 
00038 # include <mln/core/image/image2d.hh>
00039 # include <mln/core/routine/initialize.hh>
00040 
00041 # include <mln/value/int_u8.hh>
00042 # include <mln/fun/p2v/ternary.hh>
00043 # include <mln/fun/v2b/threshold.hh>
00044 
00045 # include <mln/data/transform.hh>
00046 
00047 # include <mln/pw/image.hh>
00048 # include <mln/pw/cst.hh>
00049 # include <mln/pw/value.hh>
00050 # include <mln/opt/at.hh>
00051 
00052 # include <mln/geom/min_row.hh>
00053 # include <mln/geom/min_col.hh>
00054 
00055 # include <mln/core/routine/duplicate.hh>
00056 
00057 
00058 namespace mln
00059 {
00060 
00061   namespace world
00062   {
00063 
00064     namespace binary_2d
00065     {
00066 
00073       //
00074       template <typename I>
00075       mln_concrete(I)
00076       enlarge(const Image<I>& input, unsigned n);
00077 
00078 
00079 # ifndef MLN_INCLUDE_ONLY
00080 
00081 
00082       // Internal routines.
00083 
00084       namespace internal
00085       {
00086 
00087         inline
00088         float
00089         val(bool b)
00090         {
00091           return b ? 1 : 0;
00092         }
00093 
00094         inline
00095         int
00096         do_threshold(float value)
00097         {
00098           return static_cast<int>(255.f * value);
00099         }
00100 
00101       } // end of namespace mln::world::binary_2d
00102 
00103 
00104 
00105 
00106       // Implementation.
00107 
00108       namespace impl
00109       {
00110 
00112         inline
00113         image2d<value::int_u8>
00114         enlargex2(const image2d<bool>& input)
00115         {
00116           using value::int_u8;
00117 
00118           mln_precondition(input.is_valid());
00119 
00120           def::coord
00121             mrow = geom::min_row(input),
00122             mcol = geom::min_col(input);
00123 
00124           image2d<int_u8> output(make::box2d(mrow, mcol,
00125                                              mrow + 2 * input.nrows() - 1,
00126                                              mcol + 2 * input.ncols() - 1));
00127           float value;
00128 
00129           // row 0
00130           opt::at(output, mrow, mcol) = internal::do_threshold(opt::at(input, mrow, mcol));
00131 
00132           for (unsigned col = 2; col < output.ncols(); col += 2)
00133           {
00134             value = internal::val(opt::at(input, mrow, mcol + col / 2));
00135             value += internal::val(opt::at(input, mrow, mcol + col / 2 - 1));
00136             opt::at(output, mrow, mcol + col) = internal::do_threshold(value / 2);
00137           }
00138 
00139           for (unsigned col = 1; col < output.ncols(); col += 2)
00140             opt::at(output, mrow, mcol + col)
00141               = internal::do_threshold(opt::at(input, mrow, mcol + col / 2));
00142 
00143           // col 0
00144 
00145           for (unsigned row = 2; row < output.nrows(); row += 2)
00146           {
00147             value = internal::val(opt::at(input, mrow + row / 2, mcol));
00148             value += internal::val(opt::at(input, mrow + row / 2 - 1, mcol));
00149             opt::at(output, mrow + row, mcol) = internal::do_threshold(value / 2);
00150           }
00151 
00152           for (unsigned row = 1; row < output.nrows(); row += 2)
00153             opt::at(output, mrow + row, mcol)
00154               = internal::do_threshold(opt::at(input, mrow + row / 2, mcol));
00155 
00156           // others
00157 
00158           for (unsigned row = 2; row < output.nrows(); row += 2)
00159           {
00160             for (unsigned col = 2; col < output.ncols(); col += 2)
00161             {
00162               value = internal::val(opt::at(input, mrow + row / 2, mcol + col / 2));
00163               value += internal::val(opt::at(input, mrow + row / 2 - 1, mcol + col / 2));
00164               value += internal::val(opt::at(input, mrow + row / 2, mcol + col / 2 - 1));
00165               value += internal::val(opt::at(input, mrow + row / 2 - 1, mcol + col / 2 - 1));
00166               opt::at(output, mrow + row, mcol + col)
00167                 = internal::do_threshold(value / 4);
00168             }
00169             for (unsigned col = 1; col < output.ncols(); col += 2)
00170             {
00171               value = internal::val(opt::at(input, mrow + row / 2, mcol + col / 2));
00172               value += internal::val(opt::at(input, mrow + row / 2 - 1, mcol + col / 2));
00173               opt::at(output, mrow + row, mcol + col) = internal::do_threshold(value / 2);
00174             }
00175           }
00176 
00177           for (unsigned row = 1; row < output.nrows(); row += 2)
00178           {
00179             for (unsigned col = 2; col < output.ncols(); col += 2)
00180             {
00181               value = internal::val(opt::at(input, mrow + row / 2, mcol + col / 2));
00182               value += internal::val(opt::at(input, mrow + row / 2, mcol + col / 2 - 1));
00183               opt::at(output, mrow + row, mcol + col) = internal::do_threshold(value / 2);
00184             }
00185             for (unsigned col = 1; col < output.ncols(); col += 2)
00186               opt::at(output, mrow + row, mcol + col)
00187                 = internal::do_threshold(opt::at(input, mrow + row / 2, mcol + col / 2));
00188           }
00189 
00190           return output;
00191         }
00192 
00193 
00194 
00195         inline
00196         image2d<value::int_u8>
00197         enlargex2(const image2d<value::int_u8>& input)
00198         {
00199           using value::int_u8;
00200 
00201           unsigned
00202             mrow = geom::min_row(input),
00203                  mcol = geom::min_col(input);
00204 
00205           image2d<int_u8> output(make::box2d(mrow, mcol,
00206                                              mrow + 2 * input.nrows() - 1,
00207                                              mcol + 2 * input.ncols() - 1));
00208           unsigned value;
00209 
00210           // row 0
00211           opt::at(output, mrow, mcol) = (opt::at(input, mrow, mcol));
00212 
00213           for (unsigned col = 2; col < output.ncols(); col += 2)
00214           {
00215             value = (opt::at(input, mrow, mcol + col / 2));
00216             value += (opt::at(input, mrow, mcol + col / 2 - 1));
00217             opt::at(output, mrow, mcol + col) = (value / 2);
00218           }
00219 
00220           for (unsigned col = 1; col < output.ncols(); col += 2)
00221             opt::at(output, mrow, mcol + col) = (opt::at(input, mrow, mcol + col / 2));
00222 
00223           // col 0
00224 
00225           for (unsigned row = 2; row < output.nrows(); row += 2)
00226           {
00227             value = (opt::at(input, mrow + row / 2, mcol));
00228             value += (opt::at(input, mrow + row / 2 - 1, mcol));
00229             opt::at(output, mrow + row, mcol) = (value / 2);
00230           }
00231 
00232           for (unsigned row = 1; row < output.nrows(); row += 2)
00233             opt::at(output, mrow + row, mcol) = (opt::at(input, mrow + row / 2, mcol));
00234 
00235           // others
00236 
00237           for (unsigned row = 2; row < output.nrows(); row += 2)
00238           {
00239             for (unsigned col = 2; col < output.ncols(); col += 2)
00240             {
00241               value = (opt::at(input, mrow + row / 2, mcol + col / 2));
00242               value += (opt::at(input, mrow + row / 2 - 1, mcol + col / 2));
00243               value += (opt::at(input, mrow + row / 2, mcol + col / 2 - 1));
00244               value += (opt::at(input, mrow + row / 2 - 1, mcol + col / 2 - 1));
00245               opt::at(output, mrow + row, mcol + col) = ((unsigned(value)+2) / 4);
00246             }
00247             for (unsigned col = 1; col < output.ncols(); col += 2)
00248             {
00249               value = (opt::at(input, mrow + row / 2, mcol + col / 2));
00250               value += (opt::at(input, mrow + row / 2 - 1, mcol + col / 2));
00251               opt::at(output, mrow + row, mcol + col) = (value / 2);
00252             }
00253           }
00254 
00255           for (unsigned row = 1; row < output.nrows(); row += 2)
00256           {
00257             for (unsigned col = 2; col < output.ncols(); col += 2)
00258             {
00259               value = (opt::at(input, mrow + row / 2, mcol + col / 2));
00260               value += (opt::at(input, mrow + row / 2, mcol + col / 2 - 1));
00261               opt::at(output, mrow + row, mcol + col) = (value / 2);
00262             }
00263             for (unsigned col = 1; col < output.ncols(); col += 2)
00264               opt::at(output, mrow + row, mcol + col)
00265                 = (opt::at(input, mrow + row / 2, mcol + col / 2));
00266           }
00267 
00268           return output;
00269         }
00270 
00271 
00272         template <typename I>
00273         inline
00274         mln_ch_value(I,value::int_u8)
00275         do_enlarge_gl(const I& input, unsigned n)
00276         {
00277           using value::int_u8;
00278 
00279           mln_ch_value(I,int_u8) output = enlargex2(input);
00280 
00281           while (--n)
00282             output = enlargex2(output);
00283 
00284           return output;
00285         }
00286 
00287 
00288         template <typename I>
00289         inline
00290         mln_concrete(I)
00291         do_enlarge_bool(const I& input, unsigned n)
00292         {
00293           mln_ch_value(I,value::int_u8) tmp = do_enlarge_gl(input, n);
00294           I output
00295             = data::transform(tmp, fun::v2b::threshold<value::int_u8>(150));
00296           return output;
00297         }
00298 
00299 
00300       } // end of namespace mln::world::binary_2d::impl
00301 
00302 
00303 
00304 
00305       // Dispatch
00306 
00307       namespace internal
00308       {
00309 
00310         template<typename I>
00311         inline
00312         mln_concrete(I)
00313         enlarge_dispatch(const I& input, const bool&, unsigned n)
00314         {
00315           return impl::do_enlarge_bool(input, n);
00316         }
00317 
00318         template<typename I>
00319         inline
00320         mln_concrete(I)
00321         enlarge_dispatch(const I& input, const value::int_u8&, unsigned n)
00322         {
00323           return impl::do_enlarge_gl(input, n);
00324         }
00325 
00326         template<typename I>
00327         inline
00328         mln_concrete(I)
00329         enlarge_dispatch(const I& input, const mln_value(I)&, unsigned n)
00330         {
00331           mlc_abort(I)::check();
00332           return mln_concrete(I)();
00333         }
00334 
00335         template<typename I>
00336         inline
00337         mln_concrete(I)
00338         enlarge_dispatch(const Image<I>& input, unsigned n)
00339         {
00340           return enlarge_dispatch(exact(input), mln_value(I)(), n);
00341         }
00342 
00343       } // end of namespace mln::world::binary_2d::internal
00344 
00345 
00346 
00347       // Facade
00348 
00349       template <typename I>
00350       inline
00351       mln_concrete(I)
00352       enlarge(const Image<I>& input, unsigned n)
00353       {
00354         trace::entering("mln::world::binary_2d::enlarge");
00355 
00356         mln_precondition(exact(input).is_valid());
00357         typedef mln_site(I) S;
00358         mlc_bool(S::dim == 2)::check();
00359 
00360         mln_concrete(I) output;
00361         if (n == 0)
00362             output = duplicate(input);
00363         else
00364             output = internal::enlarge_dispatch(input, n);
00365 
00366         trace::exiting("mln::world::binary_2d::enlarge");
00367         return output;
00368       }
00369 
00370 
00371 # endif // ! MLN_INCLUDE_ONLY
00372 
00373     } // end of namespace mln::world::binary_2d
00374 
00375   } // end of namespace mln::world
00376 
00377 } // mln
00378 
00379 #endif // ! MLN_WORLD_BINARY_2D_ENLARGE_HH

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