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