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
00175
00176
00177
00178
00179
00182 template <typename I>
00183 inline
00184 mln_concrete(I)
00185 combine(const mln::Image<I>& vertices_, const mln::Image<I>& edges_)
00186 {
00187 typedef trait::graph<I> T;
00188 const I& vertices = mln::exact(vertices_);
00189 const I& edges = mln::exact(edges_);
00190
00191 mln_precondition(vertices.domain() == edges.domain());
00192 mln_concrete(I) output;
00193 mln::initialize(output, vertices);
00194 mln::data::fill(output, false);
00195 mln::data::paste(vertices | T::is_vertex(), output);
00196 mln::data::paste(edges | T::is_edge(), output);
00197 return output;
00198 }
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00222 template <typename I>
00223 inline
00224 mln_concrete(I)
00225 dilation_e2v(const mln::Image<I>& input)
00226 {
00227 typedef trait::graph<I> T;
00228
00229 mln_concrete(I) output;
00230 mln::initialize(output, mln::exact(input));
00231 mln::data::fill(output, false);
00232 mln::data::paste(mln::morpho::dilation(mln::extend(input | T::is_vertex(),
00233 input),
00234 T::v2e()),
00235 output);
00236 return output;
00237 }
00238
00240 template <typename I>
00241 inline
00242 mln_concrete(I)
00243 erosion_v2e(const mln::Image<I>& input)
00244 {
00245 typedef trait::graph<I> T;
00246
00247 mln_concrete(I) output;
00248 mln::initialize(output, mln::exact(input));
00249 mln::data::fill(output, false);
00250 mln::data::paste(mln::morpho::erosion(mln::extend(input | T::is_edge(),
00251 input),
00252 T::e2v()),
00253 output);
00254 return output;
00255 }
00256
00258 template <typename I>
00259 inline
00260 mln_concrete(I)
00261 erosion_e2v(const mln::Image<I>& input)
00262 {
00263 typedef trait::graph<I> T;
00264
00265 mln_concrete(I) output;
00266 mln::initialize(output, mln::exact(input));
00267 mln::data::fill(output, false);
00268 mln::data::paste(mln::morpho::erosion(mln::extend(input | T::is_vertex(),
00269 input),
00270 T::v2e()),
00271 output);
00272 return output;
00273 }
00274
00276 template <typename I>
00277 inline
00278 mln_concrete(I)
00279 dilation_v2e(const mln::Image<I>& input)
00280 {
00281 typedef trait::graph<I> T;
00282
00283 mln_concrete(I) output;
00284 mln::initialize(output, mln::exact(input));
00285 mln::data::fill(output, false);
00286 mln::data::paste(mln::morpho::dilation(mln::extend(input | T::is_edge(),
00287 input),
00288 T::e2v()),
00289 output);
00290 return output;
00291 }
00292
00293
00294
00295
00296
00297
00299 template <typename I>
00300 inline
00301 mln_concrete(I)
00302 dilation_vertex(const mln::Image<I>& input)
00303 {
00304 return dilation_e2v(dilation_v2e(input));
00305 }
00306
00308 template <typename I>
00309 inline
00310 mln_concrete(I)
00311 erosion_vertex(const mln::Image<I>& input)
00312 {
00313 return erosion_e2v(erosion_v2e(input));
00314 }
00315
00316
00318 template <typename I>
00319 inline
00320 mln_concrete(I)
00321 dilation_edge(const mln::Image<I>& input)
00322 {
00323 return dilation_v2e(dilation_e2v(input));
00324 }
00325
00327 template <typename I>
00328 inline
00329 mln_concrete(I)
00330 erosion_edge(const mln::Image<I>& input)
00331 {
00332 return erosion_v2e(erosion_e2v(input));
00333 }
00334
00335
00337 template <typename I>
00338 inline
00339 mln_concrete(I)
00340 dilation_graph(const mln::Image<I>& input)
00341 {
00342 return combine(dilation_vertex(input), dilation_edge(input));
00343 }
00344
00346 template <typename I>
00347 inline
00348 mln_concrete(I)
00349 erosion_graph(const mln::Image<I>& input)
00350 {
00351 return combine(erosion_vertex(input), erosion_edge(input));
00352 }
00353
00354
00355
00356
00357
00358
00359 template <typename I>
00360 inline
00361 mln_concrete(I)
00362 alpha1(const mln::Image<I>& input)
00363 {
00364 mln_concrete(I) vertices;
00365 mln::initialize(vertices, input);
00366 mln::data::fill(vertices, true);
00367 return combine(vertices, input);
00368 }
00369
00370 template <typename I>
00371 inline
00372 mln_concrete(I)
00373 beta1(const mln::Image<I>& input)
00374 {
00375 return combine(dilation_e2v(input), input);
00376 }
00377
00378 template <typename I>
00379 inline
00380 mln_concrete(I)
00381 alpha2(const mln::Image<I>& input)
00382 {
00383 return combine(input, erosion_v2e(input));
00384 }
00385
00386 template <typename I>
00387 inline
00388 mln_concrete(I)
00389 beta2(const mln::Image<I>& input)
00390 {
00391 mln_concrete(I) edges;
00392 mln::initialize(edges, input);
00393 mln::data::fill(edges, false);
00394 return combine(input, edges);
00395 }
00396
00397 template <typename I>
00398 inline
00399 mln_concrete(I)
00400 alpha3(const mln::Image<I>& input)
00401 {
00402 return combine(erosion_e2v(input), erosion_v2e(erosion_e2v(input)));
00403 }
00404
00405 template <typename I>
00406 inline
00407 mln_concrete(I)
00408 beta3(const mln::Image<I>& input)
00409 {
00410 return combine(dilation_e2v(dilation_v2e(input)), dilation_v2e(input));
00411 }
00412
00413
00414
00415
00416
00417
00419 template <typename I>
00420 inline
00421 mln_concrete(I)
00422 opening_vertex(const mln::Image<I>& input)
00423 {
00424 return dilation_vertex(erosion_vertex(input));
00425 }
00426
00428 template <typename I>
00429 inline
00430 mln_concrete(I)
00431 closing_vertex(const mln::Image<I>& input)
00432 {
00433 return erosion_vertex(dilation_vertex(input));
00434 }
00435
00436
00438 template <typename I>
00439 inline
00440 mln_concrete(I)
00441 opening_edge(const mln::Image<I>& input)
00442 {
00443 return dilation_edge(erosion_edge(input));
00444 }
00445
00447 template <typename I>
00448 inline
00449 mln_concrete(I)
00450 closing_edge(const mln::Image<I>& input)
00451 {
00452 return erosion_edge(dilation_edge(input));
00453 }
00454
00455
00457 template <typename I>
00458 inline
00459 mln_concrete(I)
00460 opening_graph(const mln::Image<I>& input)
00461 {
00462 return combine(opening_vertex(input), opening_edge(input));
00463 }
00464
00466 template <typename I>
00467 inline
00468 mln_concrete(I)
00469 closing_graph(const mln::Image<I>& input)
00470 {
00471 return combine(closing_vertex(input), closing_edge(input));
00472 }
00473
00474
00475
00476
00477
00478
00480 template <typename I>
00481 inline
00482 mln_concrete(I)
00483 half_opening_vertex(const mln::Image<I>& input)
00484 {
00485 return dilation_e2v(erosion_v2e(input));
00486 }
00487
00489 template <typename I>
00490 inline
00491 mln_concrete(I)
00492 half_closing_vertex(const mln::Image<I>& input)
00493 {
00494 return erosion_e2v(dilation_v2e(input));
00495 }
00496
00497
00499 template <typename I>
00500 inline
00501 mln_concrete(I)
00502 half_opening_edge(const mln::Image<I>& input)
00503 {
00504 return dilation_v2e(erosion_e2v(input));
00505 }
00506
00508 template <typename I>
00509 inline
00510 mln_concrete(I)
00511 half_closing_edge(const mln::Image<I>& input)
00512 {
00513 return erosion_v2e(dilation_e2v(input));
00514 }
00515
00516
00518 template <typename I>
00519 inline
00520 mln_concrete(I)
00521 half_opening_graph(const mln::Image<I>& input)
00522 {
00523 return combine(half_opening_vertex(input), half_opening_edge(input));
00524 }
00525
00527 template <typename I>
00528 inline
00529 mln_concrete(I)
00530 half_closing_graph(const mln::Image<I>& input)
00531 {
00532 return combine(half_closing_vertex(input), half_closing_edge(input));
00533 }
00534
00535
00536
00537
00538
00539
00541 template <typename I>
00542 inline
00543 mln_concrete(I)
00544 opening(const mln::Image<I>& input, unsigned lambda)
00545 {
00546 unsigned i = lambda / 2;
00547 unsigned j = lambda % 2;
00548 mln_concrete(I) output = mln::duplicate(input);
00549 for (unsigned m = 0; m < i; ++m)
00550 output = erosion_graph(output);
00551 for (unsigned m = 0; m < j; ++m)
00552 output = half_opening_graph(output);
00553 for (unsigned m = 0; m < i; ++m)
00554 output = dilation_graph(output);
00555 return output;
00556 }
00557
00559 template <typename I>
00560 inline
00561 mln_concrete(I)
00562 closing(const mln::Image<I>& input, unsigned lambda)
00563 {
00564 unsigned i = lambda / 2;
00565 unsigned j = lambda % 2;
00566 mln_concrete(I) output = mln::duplicate(input);
00567 for (unsigned m = 0; m < i; ++m)
00568 output = dilation_graph(output);
00569 for (unsigned m = 0; m < j; ++m)
00570 output = half_closing_graph(output);
00571 for (unsigned m = 0; m < i; ++m)
00572 output = erosion_graph(output);
00573 return output;
00574 }
00575
00576
00577
00578
00579
00581 template <typename I>
00582 inline
00583 mln_concrete(I)
00584 asf(const mln::Image<I>& input, unsigned lambda)
00585 {
00586 mln_concrete(I) output = mln::duplicate(input);
00587 for (unsigned m = 1; m <= lambda; ++m)
00588 output = opening(closing(output, m), m);
00589 return output;
00590 }
00591
00592 #endif // ! APPS_GRAPH_MORPHO_MORPHO_HH