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_MORPHO_HIT_OR_MISS_HH
00028 # define MLN_MORPHO_HIT_OR_MISS_HH
00029
00035
00036 # include <mln/morpho/includes.hh>
00037 # include <mln/pw/all.hh>
00038 # include <mln/fun/p2v/ternary.hh>
00039 # include <mln/fun/cast.hh>
00040 # include <mln/literal/zero.hh>
00041
00042
00043 namespace mln
00044 {
00045
00046 namespace morpho
00047 {
00048
00049
00050 extern bool constrained_hit_or_miss;
00051
00052
00054
00057 template <typename I, typename Wh, typename Wm>
00058 mln_concrete(I)
00059 hit_or_miss(const Image<I>& input,
00060 const Window<Wh>& win_hit, const Window<Wm>& win_miss);
00061
00062
00064
00067 template <typename I, typename Wh, typename Wm>
00068 mln_concrete(I)
00069 hit_or_miss_opening(const Image<I>& input,
00070 const Window<Wh>& win_hit, const Window<Wm>& win_miss);
00071
00072
00074
00077 template <typename I, typename Wh, typename Wm>
00078 mln_concrete(I)
00079 hit_or_miss_background_opening(const Image<I>& input,
00080 const Window<Wh>& win_hit, const Window<Wm>& win_miss);
00081
00082
00084
00087 template <typename I, typename Wh, typename Wm>
00088 mln_concrete(I)
00089 hit_or_miss_closing(const Image<I>& input,
00090 const Window<Wh>& win_hit, const Window<Wm>& win_miss);
00091
00092
00094
00097 template <typename I, typename Wh, typename Wm>
00098 mln_concrete(I)
00099 hit_or_miss_background_closing(const Image<I>& input,
00100 const Window<Wh>& win_hit, const Window<Wm>& win_miss);
00101
00102
00103
00104 # ifndef MLN_INCLUDE_ONLY
00105
00106 # ifndef MLN_WO_GLOBAL_VARS
00107
00108 bool constrained_hit_or_miss = true;
00109
00110 # endif // ! MLN_WO_GLOBAL_VARS
00111
00112 namespace internal
00113 {
00114
00115 template <typename I, typename Wh, typename Wm>
00116 inline
00117 void
00118 hit_or_miss_tests(const Image<I>& input_,
00119 const Window<Wh>& win_hit_,
00120 const Window<Wm>& win_miss_)
00121 {
00122 const I& input = exact(input_);
00123 const Wh& win_hit = exact(win_hit_);
00124 const Wm& win_miss = exact(win_miss_);
00125
00126
00127 mln_precondition(input.is_valid());
00128 mln_precondition((win_hit && win_miss).is_empty());
00129
00130
00131 (void) input;
00132 (void) win_hit;
00133 (void) win_miss;
00134 }
00135
00136 }
00137
00138
00139 namespace impl
00140 {
00141
00142
00143
00144 template <typename I, typename Wh, typename Wm>
00145 inline
00146 mln_concrete(I)
00147 hit_or_miss_logic(const Image<I>& input,
00148 const Window<Wh>& win_hit,
00149 const Window<Wm>& win_miss)
00150 {
00151 trace::entering("morpho::impl::hit_or_miss_logic");
00152 internal::hit_or_miss_tests(input, win_hit, win_miss);
00153
00154 mln_concrete(I) output = logical::and_(erosion(input, win_hit),
00155 erosion(complementation(input),
00156 win_miss));
00157
00158 trace::exiting("morpho::impl::hit_or_miss_logic");
00159 return output;
00160 }
00161
00162
00163
00164 namespace generic
00165 {
00166
00167
00168
00169 template <typename I, typename Wh, typename Wm>
00170 inline
00171 mln_concrete(I)
00172 hit_or_miss(const Image<I>& input_,
00173 const Window<Wh>& win_hit_,
00174 const Window<Wm>& win_miss_)
00175 {
00176 trace::entering("morpho::impl::generic::hit_or_miss");
00177 internal::hit_or_miss_tests(input_, win_hit_, win_miss_);
00178
00179 const I& input = exact(input_);
00180 const Wh& win_hit = exact(win_hit_);
00181 const Wm& win_miss = exact(win_miss_);
00182
00183 typedef mln_value(I) V;
00184 mln_value(I) zero_V = literal::zero;
00185
00186 mln_concrete(I) output;
00187 initialize(output, input);
00188
00189 if (constrained_hit_or_miss)
00190 {
00191 if (win_hit.is_centered())
00192 {
00193 mln_concrete(I)
00194 ero_fg = erosion(input, win_hit),
00195 dil_bg = dilation(input, win_miss);
00196 data::fill(output,
00197 fun::p2v::ternary(pw::value(input) == pw::value(ero_fg)
00198 && pw::value(dil_bg) < pw::value(input),
00199 fun::cast<V>(pw::value(input) - pw::value(dil_bg)),
00200 pw::cst(zero_V)));
00201 }
00202 else if (win_miss.is_centered())
00203 {
00204 mln_concrete(I)
00205 ero_bg = erosion(input, win_miss),
00206 dil_fg = dilation(input, win_hit);
00207 data::fill(output,
00208 fun::p2v::ternary(pw::value(input) == pw::value(dil_fg)
00209 && pw::value(ero_bg) > pw::value(input),
00210 fun::cast<V>(pw::value(ero_bg) - pw::value(input)),
00211 pw::cst(zero_V)));
00212 }
00213 else
00214 data::fill(output, zero_V);
00215 }
00216 else
00217 {
00218 mln_concrete(I)
00219 ero = erosion(input, win_hit),
00220 dil = dilation(input, win_miss);
00221 data::fill(output,
00222 fun::p2v::ternary(pw::value(dil) < pw::value(ero),
00223 fun::cast<V>(pw::value(ero) - pw::value(dil)),
00224 pw::cst(zero_V)));
00225 }
00226
00227 trace::exiting("morpho::impl::generic::hit_or_miss");
00228 return output;
00229 }
00230
00231 }
00232
00233 }
00234
00235
00236 namespace internal
00237 {
00238
00239 template <typename I, typename Wh, typename Wm>
00240 inline
00241 mln_concrete(I)
00242 hit_or_miss_dispatch(trait::image::kind::any,
00243 const Image<I>& input,
00244 const Window<Wh>& win_hit,
00245 const Window<Wm>& win_miss)
00246 {
00247 return impl::generic::hit_or_miss(input, win_hit, win_miss);
00248 }
00249
00250 template <typename I, typename Wh, typename Wm>
00251 inline
00252 mln_concrete(I)
00253 hit_or_miss_dispatch(trait::image::kind::logic,
00254 const Image<I>& input,
00255 const Window<Wh>& win_hit,
00256 const Window<Wm>& win_miss)
00257 {
00258 return impl::hit_or_miss_logic(input, win_hit, win_miss);
00259 }
00260
00261
00262 template <typename I, typename Wh, typename Wm>
00263 inline
00264 mln_concrete(I)
00265 hit_or_miss_dispatch(const Image<I>& input,
00266 const Window<Wh>& win_hit,
00267 const Window<Wm>& win_miss)
00268 {
00269 return hit_or_miss_dispatch(mln_trait_image_kind(I)(),
00270 exact(input),
00271 exact(win_hit),
00272 exact(win_miss));
00273 }
00274
00275 }
00276
00277
00278 template <typename I, typename Wh, typename Wm>
00279 inline
00280 mln_concrete(I)
00281 hit_or_miss(const Image<I>& input,
00282 const Window<Wh>& win_hit,
00283 const Window<Wm>& win_miss)
00284 {
00285 trace::entering("morpho::hit_or_miss");
00286 internal::hit_or_miss_tests(input, win_hit, win_miss);
00287
00288 mln_concrete(I) output = internal::hit_or_miss_dispatch(input,
00289 win_hit,
00290 win_miss);
00291 trace::exiting("morpho::hit_or_miss");
00292 return output;
00293 }
00294
00295
00296 template <typename I, typename Wh, typename Wm>
00297 inline
00298 mln_concrete(I)
00299 hit_or_miss_opening(const Image<I>& input,
00300 const Window<Wh>& win_hit,
00301 const Window<Wm>& win_miss)
00302 {
00303 trace::entering("morpho::hit_or_miss_opening");
00304 internal::hit_or_miss_tests(input, win_hit, win_miss);
00305
00306 mln_concrete(I) output = dilation(internal::hit_or_miss_dispatch(input,
00307 win_hit,
00308 win_miss),
00309 win::sym(win_hit));
00310
00311 trace::exiting("morpho::hit_or_miss_opening");
00312 return output;
00313 }
00314
00315
00316 template <typename I, typename Wh, typename Wm>
00317 inline
00318 mln_concrete(I)
00319 hit_or_miss_background_opening(const Image<I>& input,
00320 const Window<Wh>& win_hit,
00321 const Window<Wm>& win_miss)
00322 {
00323 trace::entering("morpho::hit_or_miss_background_opening");
00324 internal::hit_or_miss_tests(input, win_hit, win_miss);
00325
00326 mln_concrete(I) output = hit_or_miss_opening(complementation(input),
00327 win_miss,
00328 win_hit);
00329
00330 mln_postcondition(dilation(internal::hit_or_miss_dispatch(input,
00331 win_hit,
00332 win_miss),
00333 win::sym(win_miss)) == output);
00334 trace::exiting("morpho::hit_or_miss_background_opening");
00335 return output;
00336 }
00337
00338
00339 template <typename I, typename Wh, typename Wm>
00340 inline
00341 mln_concrete(I)
00342 hit_or_miss_closing(const Image<I>& input,
00343 const Window<Wh>& win_hit,
00344 const Window<Wm>& win_miss)
00345 {
00346 trace::entering("morpho::hit_or_miss_closing");
00347 internal::hit_or_miss_tests(input, win_hit, win_miss);
00348
00349 mln_concrete(I) output =
00350 complementation(hit_or_miss_opening(complementation(input),
00351 win_hit, win_miss));
00352
00353
00354 trace::exiting("morpho::hit_or_miss_closing");
00355 return output;
00356 }
00357
00358
00359 template <typename I, typename Wh, typename Wm>
00360 inline
00361 mln_concrete(I)
00362 hit_or_miss_background_closing(const Image<I>& input,
00363 const Window<Wh>& win_hit,
00364 const Window<Wm>& win_miss)
00365 {
00366 trace::entering("morpho::hit_or_miss_background_closing");
00367 internal::hit_or_miss_tests(input, win_hit, win_miss);
00368
00369 mln_concrete(I) output = hit_or_miss_closing(input, win_miss, win_hit);
00370
00371 mln_postcondition(complementation(hit_or_miss_background_opening(
00372 complementation(input),
00373 win_hit, win_miss)) == output);
00374 trace::exiting("morpho::hit_or_miss_background_closing");
00375 return output;
00376 }
00377
00378 # endif // ! MLN_INCLUDE_ONLY
00379
00380 }
00381
00382 }
00383
00384
00385 #endif // ! MLN_MORPHO_HIT_OR_MISS_HH