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 #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
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 }
00102
00103
00104
00105
00106
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 unsigned
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
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
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
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
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
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
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 }
00301
00302
00303
00304
00305
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 }
00344
00345
00346
00347
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 }
00374
00375 }
00376
00377 }
00378
00379 #endif // ! MLN_WORLD_BINARY_2D_ENLARGE_HH