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