00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
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
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 }
00103
00104
00105
00106
00107
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
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
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
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
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
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
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 }
00302
00303
00304
00305
00306
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 }
00348
00349
00350
00351
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 }
00378
00379 }
00380
00381 }
00382
00383 #endif // ! MLN_WORLD_BINARY_2D_ENLARGE_HH