Milena (Olena)
User documentation 2.0a Id
|
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