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 APPS_GRAPH_MORPHO_MORPHO_HH
00027 # define APPS_GRAPH_MORPHO_MORPHO_HH
00028
00039 # include <mln/core/alias/complex_image.hh>
00040 # include <mln/core/image/image2d.hh>
00041
00042 # include <mln/core/image/dmorph/image_if.hh>
00043
00044 # include <mln/core/image/dmorph/extension_ima.hh>
00045
00046 # include <mln/core/routine/extend.hh>
00047 # include <mln/core/routine/duplicate.hh>
00048
00049 # include <mln/core/site_set/p_n_faces_piter.hh>
00050 # include <mln/core/image/complex_neighborhoods.hh>
00051 # include <mln/core/image/complex_neighborhood_piter.hh>
00052
00053 # include <mln/world/inter_pixel/dim2/is_pixel.hh>
00054 # include <mln/world/inter_pixel/dim2/is_edge.hh>
00055 # include <mln/world/inter_pixel/neighb2d.hh>
00056
00057 # include <mln/data/paste.hh>
00058
00059 # include <mln/morpho/dilation.hh>
00060 # include <mln/morpho/erosion.hh>
00061
00062 # include <mln/topo/is_n_face.hh>
00063
00064
00065
00066
00067
00068
00069 namespace trait
00070 {
00072 template <typename I>
00073 struct graph
00074 {
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086 };
00087
00088
00089
00090
00091
00093 template <typename T>
00094 struct graph< mln::image2d<T> >
00095 {
00096
00097 static
00098 const mln::world::inter_pixel::dim2::is_pixel& is_vertex()
00099 {
00100 static mln::world::inter_pixel::dim2::is_pixel is_vertex_fun;
00101 return is_vertex_fun;
00102 }
00103
00104
00105 static
00106 const mln::world::inter_pixel::dim2::is_edge& is_edge()
00107 {
00108 static mln::world::inter_pixel::dim2::is_edge is_edge_fun;
00109 return is_edge_fun;
00110 }
00111
00112
00113 static
00114 const mln::window2d& v2e()
00115 {
00116 return mln::world::inter_pixel::v2e().win();
00117 }
00118
00119
00120 static
00121 const mln::world::inter_pixel::dbl_window2d& e2v()
00122 {
00123 return mln::world::inter_pixel::e2v().win();
00124 }
00125 };
00126
00127
00128
00129
00130
00132 template <typename G, typename V>
00133 struct graph< mln::complex_image<1, G, V> >
00134 {
00135
00136 static
00137 const mln::topo::is_n_face<0>& is_vertex()
00138 {
00139 static mln::topo::is_n_face<0> is_vertex_fun;
00140 return is_vertex_fun;
00141 }
00142
00143
00144 static
00145 const mln::topo::is_n_face<1>& is_edge()
00146 {
00147 static mln::topo::is_n_face<1> is_edge_fun;
00148 return is_edge_fun;
00149 }
00150
00151
00152 static
00153 const mln::complex_higher_window<1, G>& v2e()
00154 {
00155 static mln::complex_higher_window<1, G> v2e_win;
00156 return v2e_win;
00157 }
00158
00159
00160 static
00161 const mln::complex_lower_window<1, G>& e2v()
00162 {
00163 static mln::complex_lower_window<1, G> e2v_win;
00164 return e2v_win;
00165 }
00166 };
00167
00168 }
00169
00170
00171
00172
00173
00174
00177 template <typename I>
00178 inline
00179 mln_concrete(I)
00180 combine(const mln::Image<I>& vertices_, const mln::Image<I>& edges_)
00181 {
00182 typedef trait::graph<I> T;
00183 const I& vertices = mln::exact(vertices_);
00184 const I& edges = mln::exact(edges_);
00185
00186 mln_precondition(vertices.domain() == edges.domain());
00187 mln_concrete(I) output;
00188 mln::initialize(output, vertices);
00189 mln::data::fill(output, false);
00190 mln::data::paste(vertices | T::is_vertex(), output);
00191 mln::data::paste(edges | T::is_edge(), output);
00192 return output;
00193 }
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00217 template <typename I>
00218 inline
00219 mln_concrete(I)
00220 dilation_e2v(const mln::Image<I>& input)
00221 {
00222 typedef trait::graph<I> T;
00223
00224 mln_concrete(I) output;
00225 mln::initialize(output, mln::exact(input));
00226 mln::data::fill(output, false);
00227 mln::data::paste(mln::morpho::dilation(mln::extend(input | T::is_vertex(),
00228 input),
00229 T::v2e()),
00230 output);
00231 return output;
00232 }
00233
00235 template <typename I>
00236 inline
00237 mln_concrete(I)
00238 erosion_v2e(const mln::Image<I>& input)
00239 {
00240 typedef trait::graph<I> T;
00241
00242 mln_concrete(I) output;
00243 mln::initialize(output, mln::exact(input));
00244 mln::data::fill(output, false);
00245 mln::data::paste(mln::morpho::erosion(mln::extend(input | T::is_edge(),
00246 input),
00247 T::e2v()),
00248 output);
00249 return output;
00250 }
00251
00253 template <typename I>
00254 inline
00255 mln_concrete(I)
00256 erosion_e2v(const mln::Image<I>& input)
00257 {
00258 typedef trait::graph<I> T;
00259
00260 mln_concrete(I) output;
00261 mln::initialize(output, mln::exact(input));
00262 mln::data::fill(output, false);
00263 mln::data::paste(mln::morpho::erosion(mln::extend(input | T::is_vertex(),
00264 input),
00265 T::v2e()),
00266 output);
00267 return output;
00268 }
00269
00271 template <typename I>
00272 inline
00273 mln_concrete(I)
00274 dilation_v2e(const mln::Image<I>& input)
00275 {
00276 typedef trait::graph<I> T;
00277
00278 mln_concrete(I) output;
00279 mln::initialize(output, mln::exact(input));
00280 mln::data::fill(output, false);
00281 mln::data::paste(mln::morpho::dilation(mln::extend(input | T::is_edge(),
00282 input),
00283 T::e2v()),
00284 output);
00285 return output;
00286 }
00287
00288
00289
00290
00291
00292
00294 template <typename I>
00295 inline
00296 mln_concrete(I)
00297 dilation_vertex(const mln::Image<I>& input)
00298 {
00299 return dilation_e2v(dilation_v2e(input));
00300 }
00301
00303 template <typename I>
00304 inline
00305 mln_concrete(I)
00306 erosion_vertex(const mln::Image<I>& input)
00307 {
00308 return erosion_e2v(erosion_v2e(input));
00309 }
00310
00311
00313 template <typename I>
00314 inline
00315 mln_concrete(I)
00316 dilation_edge(const mln::Image<I>& input)
00317 {
00318 return dilation_v2e(dilation_e2v(input));
00319 }
00320
00322 template <typename I>
00323 inline
00324 mln_concrete(I)
00325 erosion_edge(const mln::Image<I>& input)
00326 {
00327 return erosion_v2e(erosion_e2v(input));
00328 }
00329
00330
00332 template <typename I>
00333 inline
00334 mln_concrete(I)
00335 dilation_graph(const mln::Image<I>& input)
00336 {
00337 return combine(dilation_vertex(input), dilation_edge(input));
00338 }
00339
00341 template <typename I>
00342 inline
00343 mln_concrete(I)
00344 erosion_graph(const mln::Image<I>& input)
00345 {
00346 return combine(erosion_vertex(input), erosion_edge(input));
00347 }
00348
00349
00350
00351
00352
00353
00354 template <typename I>
00355 inline
00356 mln_concrete(I)
00357 alpha1(const mln::Image<I>& input)
00358 {
00359 mln_concrete(I) vertices;
00360 mln::initialize(vertices, input);
00361 mln::data::fill(vertices, true);
00362 return combine(vertices, input);
00363 }
00364
00365 template <typename I>
00366 inline
00367 mln_concrete(I)
00368 beta1(const mln::Image<I>& input)
00369 {
00370 return combine(dilation_e2v(input), input);
00371 }
00372
00373 template <typename I>
00374 inline
00375 mln_concrete(I)
00376 alpha2(const mln::Image<I>& input)
00377 {
00378 return combine(input, erosion_v2e(input));
00379 }
00380
00381 template <typename I>
00382 inline
00383 mln_concrete(I)
00384 beta2(const mln::Image<I>& input)
00385 {
00386 mln_concrete(I) edges;
00387 mln::initialize(edges, input);
00388 mln::data::fill(edges, false);
00389 return combine(input, edges);
00390 }
00391
00392 template <typename I>
00393 inline
00394 mln_concrete(I)
00395 alpha3(const mln::Image<I>& input)
00396 {
00397 return combine(erosion_e2v(input), erosion_v2e(erosion_e2v(input)));
00398 }
00399
00400 template <typename I>
00401 inline
00402 mln_concrete(I)
00403 beta3(const mln::Image<I>& input)
00404 {
00405 return combine(dilation_e2v(dilation_v2e(input)), dilation_v2e(input));
00406 }
00407
00408
00409
00410
00411
00412
00414 template <typename I>
00415 inline
00416 mln_concrete(I)
00417 opening_vertex(const mln::Image<I>& input)
00418 {
00419 return dilation_vertex(erosion_vertex(input));
00420 }
00421
00423 template <typename I>
00424 inline
00425 mln_concrete(I)
00426 closing_vertex(const mln::Image<I>& input)
00427 {
00428 return erosion_vertex(dilation_vertex(input));
00429 }
00430
00431
00433 template <typename I>
00434 inline
00435 mln_concrete(I)
00436 opening_edge(const mln::Image<I>& input)
00437 {
00438 return dilation_edge(erosion_edge(input));
00439 }
00440
00442 template <typename I>
00443 inline
00444 mln_concrete(I)
00445 closing_edge(const mln::Image<I>& input)
00446 {
00447 return erosion_edge(dilation_edge(input));
00448 }
00449
00450
00452 template <typename I>
00453 inline
00454 mln_concrete(I)
00455 opening_graph(const mln::Image<I>& input)
00456 {
00457 return combine(opening_vertex(input), opening_edge(input));
00458 }
00459
00461 template <typename I>
00462 inline
00463 mln_concrete(I)
00464 closing_graph(const mln::Image<I>& input)
00465 {
00466 return combine(closing_vertex(input), closing_edge(input));
00467 }
00468
00469
00470
00471
00472
00473
00475 template <typename I>
00476 inline
00477 mln_concrete(I)
00478 half_opening_vertex(const mln::Image<I>& input)
00479 {
00480 return dilation_e2v(erosion_v2e(input));
00481 }
00482
00484 template <typename I>
00485 inline
00486 mln_concrete(I)
00487 half_closing_vertex(const mln::Image<I>& input)
00488 {
00489 return erosion_e2v(dilation_v2e(input));
00490 }
00491
00492
00494 template <typename I>
00495 inline
00496 mln_concrete(I)
00497 half_opening_edge(const mln::Image<I>& input)
00498 {
00499 return dilation_v2e(erosion_e2v(input));
00500 }
00501
00503 template <typename I>
00504 inline
00505 mln_concrete(I)
00506 half_closing_edge(const mln::Image<I>& input)
00507 {
00508 return erosion_v2e(dilation_e2v(input));
00509 }
00510
00511
00513 template <typename I>
00514 inline
00515 mln_concrete(I)
00516 half_opening_graph(const mln::Image<I>& input)
00517 {
00518 return combine(half_opening_vertex(input), half_opening_edge(input));
00519 }
00520
00522 template <typename I>
00523 inline
00524 mln_concrete(I)
00525 half_closing_graph(const mln::Image<I>& input)
00526 {
00527 return combine(half_closing_vertex(input), half_closing_edge(input));
00528 }
00529
00530
00531
00532
00533
00534
00536 template <typename I>
00537 inline
00538 mln_concrete(I)
00539 opening(const mln::Image<I>& input, unsigned lambda)
00540 {
00541 unsigned i = lambda / 2;
00542 unsigned j = lambda % 2;
00543 mln_concrete(I) output = mln::duplicate(input);
00544 for (unsigned m = 0; m < i; ++m)
00545 output = erosion_graph(output);
00546 for (unsigned m = 0; m < j; ++m)
00547 output = half_opening_graph(output);
00548 for (unsigned m = 0; m < i; ++m)
00549 output = dilation_graph(output);
00550 return output;
00551 }
00552
00554 template <typename I>
00555 inline
00556 mln_concrete(I)
00557 closing(const mln::Image<I>& input, unsigned lambda)
00558 {
00559 unsigned i = lambda / 2;
00560 unsigned j = lambda % 2;
00561 mln_concrete(I) output = mln::duplicate(input);
00562 for (unsigned m = 0; m < i; ++m)
00563 output = dilation_graph(output);
00564 for (unsigned m = 0; m < j; ++m)
00565 output = half_closing_graph(output);
00566 for (unsigned m = 0; m < i; ++m)
00567 output = erosion_graph(output);
00568 return output;
00569 }
00570
00571
00572
00573
00574
00576 template <typename I>
00577 inline
00578 mln_concrete(I)
00579 asf(const mln::Image<I>& input, unsigned lambda)
00580 {
00581 mln_concrete(I) output = mln::duplicate(input);
00582 for (unsigned m = 1; m <= lambda; ++m)
00583 output = opening(closing(output, m), m);
00584 return output;
00585 }
00586
00587 #endif // ! APPS_GRAPH_MORPHO_MORPHO_HH