LRE
Sign In
Sign Up
Sign In
Sign Up
Manage this list
×
Keyboard Shortcuts
Thread View
j
: Next unread message
k
: Previous unread message
j a
: Jump to all threads
j l
: Jump to MailingList overview
2024
December
November
October
September
August
July
June
May
April
March
February
January
2023
December
November
October
September
August
July
June
May
April
March
February
January
2022
December
November
October
September
August
July
June
May
April
March
February
January
2021
December
November
October
September
August
July
June
May
April
March
February
January
2020
December
November
October
September
August
July
June
May
April
March
February
January
2019
December
November
October
September
August
July
June
May
April
March
February
January
2018
December
November
October
September
August
July
June
May
April
March
February
January
2017
December
November
October
September
August
July
June
May
April
March
February
January
2016
December
November
October
September
August
July
June
May
April
March
February
January
2015
December
November
October
September
August
July
June
May
April
March
February
January
2014
December
November
October
September
August
July
June
May
April
March
February
January
2013
December
November
October
September
August
July
June
May
April
March
February
January
2012
December
November
October
September
August
July
June
May
April
March
February
January
2011
December
November
October
September
August
July
June
May
April
March
February
January
2010
December
November
October
September
August
July
June
May
April
March
February
January
2009
December
November
October
September
August
July
June
May
April
March
February
January
2008
December
November
October
September
August
July
June
May
April
March
February
January
2007
December
November
October
September
August
July
June
May
April
March
February
January
2006
December
November
October
September
August
July
June
May
April
March
February
January
2005
December
November
October
September
August
July
June
May
April
March
February
January
2004
December
November
October
September
August
July
June
May
April
March
List overview
Download
Olena-patches
February 2009
----- 2024 -----
December 2024
November 2024
October 2024
September 2024
August 2024
July 2024
June 2024
May 2024
April 2024
March 2024
February 2024
January 2024
----- 2023 -----
December 2023
November 2023
October 2023
September 2023
August 2023
July 2023
June 2023
May 2023
April 2023
March 2023
February 2023
January 2023
----- 2022 -----
December 2022
November 2022
October 2022
September 2022
August 2022
July 2022
June 2022
May 2022
April 2022
March 2022
February 2022
January 2022
----- 2021 -----
December 2021
November 2021
October 2021
September 2021
August 2021
July 2021
June 2021
May 2021
April 2021
March 2021
February 2021
January 2021
----- 2020 -----
December 2020
November 2020
October 2020
September 2020
August 2020
July 2020
June 2020
May 2020
April 2020
March 2020
February 2020
January 2020
----- 2019 -----
December 2019
November 2019
October 2019
September 2019
August 2019
July 2019
June 2019
May 2019
April 2019
March 2019
February 2019
January 2019
----- 2018 -----
December 2018
November 2018
October 2018
September 2018
August 2018
July 2018
June 2018
May 2018
April 2018
March 2018
February 2018
January 2018
----- 2017 -----
December 2017
November 2017
October 2017
September 2017
August 2017
July 2017
June 2017
May 2017
April 2017
March 2017
February 2017
January 2017
----- 2016 -----
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
June 2016
May 2016
April 2016
March 2016
February 2016
January 2016
----- 2015 -----
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
----- 2014 -----
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
----- 2013 -----
December 2013
November 2013
October 2013
September 2013
August 2013
July 2013
June 2013
May 2013
April 2013
March 2013
February 2013
January 2013
----- 2012 -----
December 2012
November 2012
October 2012
September 2012
August 2012
July 2012
June 2012
May 2012
April 2012
March 2012
February 2012
January 2012
----- 2011 -----
December 2011
November 2011
October 2011
September 2011
August 2011
July 2011
June 2011
May 2011
April 2011
March 2011
February 2011
January 2011
----- 2010 -----
December 2010
November 2010
October 2010
September 2010
August 2010
July 2010
June 2010
May 2010
April 2010
March 2010
February 2010
January 2010
----- 2009 -----
December 2009
November 2009
October 2009
September 2009
August 2009
July 2009
June 2009
May 2009
April 2009
March 2009
February 2009
January 2009
----- 2008 -----
December 2008
November 2008
October 2008
September 2008
August 2008
July 2008
June 2008
May 2008
April 2008
March 2008
February 2008
January 2008
----- 2007 -----
December 2007
November 2007
October 2007
September 2007
August 2007
July 2007
June 2007
May 2007
April 2007
March 2007
February 2007
January 2007
----- 2006 -----
December 2006
November 2006
October 2006
September 2006
August 2006
July 2006
June 2006
May 2006
April 2006
March 2006
February 2006
January 2006
----- 2005 -----
December 2005
November 2005
October 2005
September 2005
August 2005
July 2005
June 2005
May 2005
April 2005
March 2005
February 2005
January 2005
----- 2004 -----
December 2004
November 2004
October 2004
September 2004
August 2004
July 2004
June 2004
May 2004
April 2004
March 2004
olena-patches@lrde.epita.fr
12 participants
266 discussions
Start a n
N
ew thread
3289: Cleanup Fabien's 1st try.
by Thierry Geraud
https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox
Index: ChangeLog from Thierry Geraud <thierry.geraud(a)lrde.epita.fr> Cleanup Fabien's 1st try. * fabien/regional_maxima.hh, * fabien/labeling.hh: Fix paren balancing. Cleanup a bit. labeling.hh | 387 ++++++++++++++++++++++++++++------------------------- regional_maxima.hh | 7 2 files changed, 214 insertions(+), 180 deletions(-) Index: fabien/regional_maxima.hh --- fabien/regional_maxima.hh (revision 3288) +++ fabien/regional_maxima.hh (working copy) @@ -122,12 +122,13 @@ + // Facade. template <typename I, typename N, typename L> mln_ch_value(I, L) regional_maxima(const Image<I>& input_, const Neighborhood<N>& nbh_, - bool increasing, L& nlabels) + L& nlabels) { trace::entering("labeling::regional_maxima"); @@ -137,8 +138,8 @@ typedef impl::regional_maxima_functor<I> F; F f(exact(input)); - mln_ch_value(I, L) output = canvas::labeling_sorted(input, nbh, increasing, - f, nlabels); + mln_ch_value(I, L) output = canvas::labeling_sorted(input, nbh, nlabels, + f, false); trace::exiting("labeling::regional_maxima"); return output; Index: fabien/labeling.hh --- fabien/labeling.hh (revision 3288) +++ fabien/labeling.hh (working copy) @@ -40,6 +40,9 @@ # include <mln/literal/zero.hh> # include <mln/convert/to_upper_window.hh> +# include <mln/level/sort_psites.hh> +# include <mln/level/sort_offsets.hh> + namespace mln { @@ -47,11 +50,20 @@ namespace canvas { - // General version. - template <typename I, typename N, typename F, typename L> + template <typename I, typename N, typename L, + typename F> + mln_ch_value(I, L) + labeling_video(const Image<I>& input, const Neighborhood<N>& nbh, L& nlabels, + F& functor); + + + template <typename I, typename N, typename L, + typename F> mln_ch_value(I, L) - labeling(const Image<I>& input, const Neighborhood<N>& nbh, - F& functor, L& nlabels); + labeling_sorted(const Image<I>& input, const Neighborhood<N>& nbh, L& nlabels, + F& functor, bool increasing); + + # ifndef MLN_INCLUDE_ONLY @@ -61,10 +73,11 @@ namespace internal { - template <typename I, typename N, typename F, typename L> + template <typename I, typename N, typename L, + typename F> void - labeling_tests(const Image<I>& input_, const Neighborhood<N>& nbh_, - const F& f, const L& nlabels) + labeling_tests(const Image<I>& input_, const Neighborhood<N>& nbh_, const L& nlabels, + const F& f) { const I& input = exact(input_); const N& nbh = exact(nbh_); @@ -74,8 +87,8 @@ (void) input; (void) nbh; - (void) f; (void) nlabels; + (void) f; } } // end of namespace mln::canvas::internal @@ -101,10 +114,11 @@ return parent(x) = find_root(parent, parent(x)); } - template <typename I, typename N, typename S, typename F, typename L> + template <typename I, typename N, typename L, + typename S, typename F> mln_ch_value(I, L) - labeling(const Image<I>& input_, const Neighborhood<N>& nbh_, - S& s, F& f, L& nlabels) + labeling(const Image<I>& input_, const Neighborhood<N>& nbh_, L& nlabels, + const S& s, F& f) { trace::entering("canvas::impl::generic::labeling"); @@ -199,7 +213,7 @@ - // Fastest video version + // Fastest video version. template <typename I> static inline @@ -212,110 +226,112 @@ return parent.element(x) = find_root(parent, parent.element(x)); } - // FIXME: Use the same functer for the generic and the fastest versions - - template <typename I, typename N, typename F, typename L> - mln_ch_value(I, L) - labeling_fastest_video(const Image<I>& input_, const Neighborhood<N>& nbh_, - F& f, L& nlabels) - { - trace::entering("canvas::impl::labeling"); - - // FIXME: Test?! - - const I& input = exact(input_); - const N& nbh = exact(nbh_); - - // Local type. - typedef mln_psite(I) P; - - // Auxiliary data. - mln_ch_value(I, bool) deja_vu; - mln_ch_value(I, P) parent; - - // Output. - mln_ch_value(I, L) output; - bool status; - - // Initialization. - { - initialize(deja_vu, input); - mln::data::fill(deja_vu, false); - - initialize(parent, input); - - initialize(output, input); - mln::data::fill(output, L(literal::zero)); - nlabels = 0; - - f.init(); // Client initialization. - } - - // First Pass. - { - mln_pixter(const S) p(f.s); - mln_nixter(const S, N) n(p, nbh); - for_all(p) if (f.handles(p)) - { - // Make-Set. - parent.element(p) = p; - f.init_attr(p); - - for_all(n) - if (input.has(n) && deja_vu(n)) - { - if (f.equiv(n, p)) - { - // Do-Union. - unsigned r = find_root_fastest(parent, n); - if (r != p) - { - parent.element(r) = p; - f.merge_attr(r, p); - } - } - else - f.do_no_union(n, p); - (p) = true; - } - } - - // Second Pass. - { - mln_bkd_pixter(S) p(f.s); - for_all(p) if (f.handles(p)) - { - if (parent.element(p) == p) // if p is root - { - if (f.labels(p)) - { - if (nlabels == mln_max(L)) - { - status = false; - return output; - } - output.element(p) = ++nlabels; - } - } - else - output.element(p) = output(parent.element(p)); - } - status = true; - } +// // FIXME: Use the same functer for the generic and the fastest versions - trace::exiting("canvas::impl::labeling"); - return output; - } +// template <typename I, typename N, typename L, +// typename F> +// mln_ch_value(I, L) +// labeling_fastest_video(const Image<I>& input_, const Neighborhood<N>& nbh_, +// F& f, L& nlabels) +// { +// trace::entering("canvas::impl::labeling"); + +// // FIXME: Test?! + +// const I& input = exact(input_); +// const N& nbh = exact(nbh_); + +// // Local type. +// typedef mln_psite(I) P; + +// // Auxiliary data. +// mln_ch_value(I, bool) deja_vu; +// mln_ch_value(I, P) parent; + +// // Output. +// mln_ch_value(I, L) output; +// bool status; + +// // Initialization. +// { +// initialize(deja_vu, input); +// mln::data::fill(deja_vu, false); + +// initialize(parent, input); + +// initialize(output, input); +// mln::data::fill(output, L(literal::zero)); +// nlabels = 0; + +// f.init(); // Client initialization. +// } + +// // First Pass. +// { +// mln_pixter(const S) p(f.s); +// mln_nixter(const S, N) n(p, nbh); +// for_all(p) if (f.handles(p)) +// { +// // Make-Set. +// parent.element(p) = p; +// f.init_attr(p); + +// for_all(n) +// if (input.has(n) && deja_vu(n)) +// { +// if (f.equiv(n, p)) +// { +// // Do-Union. +// unsigned r = find_root_fastest(parent, n); +// if (r != p) +// { +// parent.element(r) = p; +// f.merge_attr(r, p); +// } +// } +// else +// f.do_no_union(n, p); +// (p) = true; +// } +// } +// } + +// // Second Pass. +// { +// mln_bkd_pixter(S) p(f.s); +// for_all(p) if (f.handles(p)) +// { +// if (parent.element(p) == p) // if p is root +// { +// if (f.labels(p)) +// { +// if (nlabels == mln_max(L)) +// { +// status = false; +// return output; +// } +// output.element(p) = ++nlabels; +// } +// } +// else +// output.element(p) = output(parent.element(p)); +// } +// status = true; +// } + +// trace::exiting("canvas::impl::labeling"); +// return output; +// } // Fastest sorted version - template <typename I, typename N, typename S, typename F, typename L> + template <typename I, typename N, typename L, + typename S, typename F> mln_ch_value(I, L) - labeling_fastest_sorted(const Image<I>& input_, - const Neighborhood<N>& nbh_, - S& s, F& f, L& nlabels) + labeling_sorted_fastest(const Image<I>& input_, const Neighborhood<N>& nbh_, L& nlabels, + const S& s, F& f) { trace::entering("canvas::impl::labeling"); @@ -324,8 +340,6 @@ const I& input = exact(input_); const N& nbh = exact(nbh_); - typedef typename F::S S; - // Local type. typedef mln_psite(I) P; @@ -391,6 +405,7 @@ deja_vu.element(p) = true; } + } // Second Pass. { @@ -431,71 +446,84 @@ namespace internal { - // Video +// // Video - template <typename I, typename N, typename F, typename L> - inline - mln_ch_value(I, L) - labeling_video(metal::false_, const Image<I>& input, - const Neighborhood<N>& nbh, F& functor, L& nlabels) - { - return impl::generic::labeling(input, nbh, input.domain(), - functor, nlabels); - } +// template <typename I, typename N, typename L, +// typename F> +// inline +// mln_ch_value(I, L) +// labeling_video(metal::false_, const Image<I>& input, +// const Neighborhood<N>& nbh, L& nlabels, F& functor) +// { +// return impl::generic::labeling(input, nbh, input.domain(), +// nlabels, functor); +// } + +// template <typename I, typename N, typename L, +// typename F> +// inline +// mln_ch_value(I, L) +// labeling_video(metal::true_, const Image<I>& input, +// const Neighborhood<N>& nbh, L& nlabels, F& functor) +// { +// return impl::labeling_fastest_video(input, nbh, nlabels, functor); +// } + +// template <typename I, typename N, typename L, +// typename F> +// inline +// mln_ch_value(I, L) +// labeling_video_dispatch(const Image<I>& input, const Neighborhood<N>& nbh, +// L& nlabels, F& functor) +// { +// enum { +// test = mlc_equal(mln_trait_image_speed(I), +// trait::image::speed::fastest)::value +// && +// mln_is_simple_neighborhood(N)::value +// }; +// return impl::generic::labeling_video(metal::bool_<test>(), input, +// nbh, nlabels, functor); +// } - template <typename I, typename N, typename F, typename L> - inline - mln_ch_value(I, L) - labeling_video(metal::true_, const Image<I>& input, - const Neighborhood<N>& nbh, F& functor, L& nlabels) - { - return impl::labeling_fastest_video(input, nbh, functor, nlabels); - } - - template <typename I, typename N, typename F, typename L> - inline - mln_ch_value(I, L) - labeling_video_dispatch(const Image<I>& input, const Neighborhood<N>& nbh, - F& functor, L& nlabels) - { - enum { - test = mlc_equal(mln_trait_image_speed(I), - trait::image::speed::fastest)::value - && - mln_is_simple_neighborhood(N)::value - }; - return impl::generic::labeling_video(metal::bool_<test>(), input, - nbh, functor, nlabels); - } + // Sorted dispatch. - // Sorted - - template <typename I, typename N, typename S, typename F, typename L> + template <typename I, typename N, typename L, typename F> inline mln_ch_value(I, L) - labeling_sorted(metal::false_, const Image<I>& input, - const Neighborhood<N>& nbh, F& functor, L& nlabels) - { - return impl::generic::labeling(input, nbh, s, functor, nlabels); + labeling_sorted_dispatch(metal::false_, + const Image<I>& input, const Neighborhood<N>& nbh, L& nlabels, + F& functor, bool increasing) + { + p_array<mln_psite(I)> s = + increasing ? + level::sort_psites_increasing(input) : + level::sort_psites_decreasing(input); + return impl::generic::labeling(input, nbh, nlabels, + s, functor); } - template <typename I, typename N, typename S, typename F, typename L> + template <typename I, typename N, typename L, typename F> inline mln_ch_value(I, L) - labeling_sorted(metal::true_, const Image<I>& input, - const Neighborhood<N>& nbh, F& functor, L& nlabels) - { - return impl::labeling_fastest_sorted(input, nbh, s, - functor, nlabels); + labeling_sorted_dispatch(metal::true_, + const Image<I>& input, const Neighborhood<N>& nbh, L& nlabels, + F& functor, bool increasing) + { + util::array<unsigned> s = + increasing ? + level::sort_offsets_increasing(input) : + level::sort_offsets_decreasing(input); + return impl::labeling_sorted_fastest(input, nbh, nlabels, + s, functor); } - template <typename I, typename N, typename S, typename F, typename L> + template <typename I, typename N, typename L, typename F> inline mln_ch_value(I, L) - labeling_sorted_dispatch(const Image<I>& input, - const Neighborhood<N>& nbh, - F& functor, L& nlabels) + labeling_sorted_dispatch(const Image<I>& input, const Neighborhood<N>& nbh, L& nlabels, + F& functor, bool increasing) { enum { test = mlc_equal(mln_trait_image_speed(I), @@ -503,8 +531,9 @@ && mln_is_simple_neighborhood(N)::value }; - return impl::generic::labeling_sorted(metal::bool_<test>(), input, - nbh, s, functor, nlabels); + return labeling_sorted_dispatch(metal::bool_<test>(), + input, nbh, nlabels, + functor, increasing); } @@ -512,39 +541,43 @@ - // Facade. + // Facades. + - template <typename I, typename N, typename F, typename L> + template <typename I, typename N, typename L, + typename F> inline mln_ch_value(I, L) - labeling_video(const Image<I>& input, const Neighborhood<N>& nbh, - F& functor, L& nlabels) + labeling_video(const Image<I>& input, const Neighborhood<N>& nbh, L& nlabels, + F& functor) { trace::entering("canvas::labeling_video"); - internal::labeling_tests(input, nbh, functor, nlabels); + internal::labeling_tests(input, nbh, nlabels, functor); mln_ch_value(I, L) output; - output = internal::labeling_video_dispatch(input, nbh, - functor, nlabels); + output = internal::labeling_video_dispatch(input, nbh, nlabels, + functor); trace::exiting("canvas::labeling_video"); return output; } - template <typename I, typename N, typename F, typename L> + + template <typename I, typename N, typename L, + typename F> inline mln_ch_value(I, L) - labeling_sorted(const Image<I>& input, const Neighborhood<N>& nbh, - bool increasing, F& functor, L& nlabels) + labeling_sorted(const Image<I>& input, const Neighborhood<N>& nbh, L& nlabels, + F& functor, bool increasing) { trace::entering("canvas::labeling_sorted"); - internal::labeling_tests(input, nbh, functor, nlabels); + internal::labeling_tests(input, nbh, nlabels, functor); mln_ch_value(I, L) output; - output = internal::labeling_sorted_dispatch(input, nbh, s, - functor, nlabels); + output = internal::labeling_sorted_dispatch(input, nbh, nlabels, + functor, increasing); trace::exiting("canvas::labeling_sorted"); return output;
15 years, 10 months
1
0
0
0
3288: Add a topological wst following Laurent's ISMM09 scheme.
by Thierry Geraud
https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox
Index: ChangeLog from Thierry Geraud <thierry.geraud(a)lrde.epita.fr> Add a topological wst following Laurent's ISMM09 scheme. * theo/esiee/laurent/ismm09/main.cc: Copy to... * theo/esiee/laurent/ismm09/topo_wst.cc: ...this new file. Update. * theo/esiee/laurent/ismm09/main.cc (T, E): Remove useless typedefs. main.cc | 4 --- topo_wst.cc | 76 ++++++++++++++++++++++++------------------------------------ 2 files changed, 31 insertions(+), 49 deletions(-) Index: theo/esiee/laurent/ismm09/topo_wst.cc --- theo/esiee/laurent/ismm09/topo_wst.cc (revision 3286) +++ theo/esiee/laurent/ismm09/topo_wst.cc (working copy) @@ -7,9 +7,7 @@ #include <mln/io/pgm/save.hh> #include <mln/debug/println.hh> -#include <mln/morpho/meyer_wst.hh> -#include <mln/labeling/compute.hh> -#include <mln/accu/count.hh> +#include <mln/debug/iota.hh> #include "pseudo_tree.hh" #include "cplx2d.hh" @@ -20,7 +18,7 @@ void usage(char* argv[]) { std::cerr << "usage: " << argv[0] << " input.pgm" << std::endl; - std::cerr << "Laurent ISMM 2009 scheme." << std::endl; + std::cerr << "Laurent topological watershed transform thru ISMM 2009 scheme." << std::endl; abort(); } @@ -40,6 +38,7 @@ image2d<int_u8> f; io::pgm::load(f, argv[1]); + debug::println("f:", f); // g: weights on edges. @@ -47,67 +46,54 @@ mln_VAR(g, cplx2d::f_to_g(f) ); debug::println("g:", g); - typedef mln_value_(g_t) T; // <--- Type of edge values. - typedef mln_psite_(g_t) E; // <--- Type of edges. + // r: one pixel is one region. - // w: watershed labeling on edges. + typedef label_16 L; + L l_max = f.nsites(); - typedef label_16 L; // <--- Type of labels. - L l_max; - mln_VAR( w, morpho::meyer_wst(g, cplx2d::e2e(), l_max) ); - debug::println("w:", w); - - - mln_VAR( is_w_line, pw::value(w) == pw::cst(0) ); - mln_VAR( g_line, g | is_w_line ); - debug::println("g | line:", g_line); - - mln_VAR(w_ext, cplx2d::extend_w_edges_to_all_faces(w)); + image2d<L> w_ext(2 * f.nrows() - 1, 2 * f.ncols() - 1); + data::fill(w_ext, 0); // Useless but for display! + mln_VAR( w_pixel, w_ext | cplx2d::is_pixel ); + { + mln_fwd_piter_(w_pixel_t) p(w_pixel.domain()); + unsigned l = 0; + for_all(p) + w_pixel(p) = ++l; + } debug::println("w_ext:", w_ext); // e -> (l1, l2) mln_VAR( e_to_l1_l2, function_e_to_l1_l2(w_ext, cplx2d::e2p()) ); -// { -// // Test adjacency "e -> (l1, l2)". -// L l1, l2; -// mln_piter_(g_t) e(g.domain()); -// for_all(e) -// if (w(e) == 0) -// { -// e_to_l1_l2(e, l1, l2); -// std::cout << e << "=" << l1 << '|' << l2 << " "; -// } -// std::cout << std::endl; -// } - // a: array "label -> attribute". - typedef unsigned A; // <--- Type of attributes. + typedef int_u8 A; // <--- Type of attributes. - util::array<A> a = labeling::compute(accu::meta::count(), - g, // image of values - w, // image of labels - l_max); + util::array<A> a(l_max.next()); + { + mln_fwd_piter_(box2d) p(f.domain()); + unsigned l = 0; + for_all(p) + a[++l] = f(p); + } util::array<L> ls = sort_by_increasing_attributes(a, l_max); -// { -// std::cout << "ls:" << std::endl; -// for (unsigned i = 1; i <= l_max; ++i) -// std::cout << ls[i] << "(" << a[ls[i]] << ") "; -// std::cout << std::endl -// << std::endl; -// } + { + std::cout << "ls:" << std::endl; + for (unsigned i = 1; i <= l_max; ++i) + std::cout << ls[i] << "(" << a[ls[i]] << ") "; + std::cout << std::endl + << std::endl; + } // -> pseudo-tree - compute_pseudo_tree(w, g, ls, a, e_to_l1_l2); - + compute_pseudo_tree(w_ext, g, ls, a, e_to_l1_l2); } Property changes on: theo/esiee/laurent/ismm09/topo_wst.cc ___________________________________________________________________ Added: svn:mergeinfo Index: theo/esiee/laurent/ismm09/main.cc --- theo/esiee/laurent/ismm09/main.cc (revision 3287) +++ theo/esiee/laurent/ismm09/main.cc (working copy) @@ -47,9 +47,6 @@ mln_VAR(g, cplx2d::f_to_g(f) ); debug::println("g:", g); - typedef mln_value_(g_t) T; // <--- Type of edge values. - typedef mln_psite_(g_t) E; // <--- Type of edges. - // w: watershed labeling on edges. @@ -109,5 +106,4 @@ // -> pseudo-tree compute_pseudo_tree(w, g, ls, a, e_to_l1_l2); - }
15 years, 10 months
1
0
0
0
r3287: Handle fastest version of functor
by Fabien Freling
URL:
https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox
ChangeLog: 2009-02-05 Fabien Freling <freling(a)lrde.epita.fr> Handle fastest version of functor. * fabien/labeling.hh: . * fabien/regional_maxima.hh: Fastest version of functor --- labeling.hh | 44 ++++++++++++++-------------- regional_maxima.hh | 81 ++++++++++++++++++++--------------------------------- 2 files changed, 54 insertions(+), 71 deletions(-) Index: trunk/milena/sandbox/fabien/regional_maxima.hh =================================================================== --- trunk/milena/sandbox/fabien/regional_maxima.hh (revision 3286) +++ trunk/milena/sandbox/fabien/regional_maxima.hh (revision 3287) @@ -69,74 +69,55 @@ // Generic functor. - template <typename I_, typename N_, typename L_> + template <typename I> struct regional_maxima_functor { - typedef mln_psite(I_) P; + typedef mln_psite(I) P; // requirements from mln::canvas::labeling: - typedef I_ I; - typedef N_ N; - typedef L_ L; - typedef p_array<P> S; - const I& input; - const N& nbh; - S s; + + // Generic implementation void init() { data::fill(attr, true); } bool handles(const P&) const { return true; } - bool labels(const P& p) const { return attr(p); } - bool equiv(const P& n, const P& p) const { return input(n) == - input(p); } - void do_no_union(const P& n, const P& p) { mln_invariant(input(n) > - input(p)); - attr(p) = false; } + bool labels(const P& p) const { return attr.element(p); } + bool equiv(const P& n, const P& p) const { return input.element(n) == + input.element(p); } + void do_no_union(const P& n, const P& p) { mln_invariant(input.element(n) > + input.element(p)); + attr.element(p) = false; } void init_attr(const P&) {} - void merge_attr(const P& r, const P& p) { attr(p) = attr(p) && - attr(r); } + void merge_attr(const P& r, const P& p) { attr.element(p) = attr.element(p) && + attr.element(r); } + + // Fastest implementation + + void init_() { data::fill(attr, true); } + bool handles_(unsigned p) const { return true; } + bool labels_(unsigned p) const { return attr.element(p); } + bool equiv_(unsigned n, unsigned p) const { return input.element(n) == + input.element(p); } + void do_no_union_(unsigned n, unsigned p) { mln_invariant(input.element(n) > + input.element(p)); + attr.element(p) = false; } + void init_attr_(const P&) {} + void merge_attr_(unsigned r, unsigned p) { attr.element(p) = attr.element(p) && + attr.element(r); } // end of requirements mln_ch_value(I, bool) attr; regional_maxima_functor(const I_& input, const N_& nbh) - : input(input), - nbh(nbh), - s(level::sort_psites_decreasing(input)) + : input(input) { initialize(attr, input); } }; - // Generic implementation. - - namespace generic - { - - template <typename I, typename N, typename L> - mln_ch_value(I, L) - regional_maxima(const I& input, const N& nbh, - L& nlabels) - { - trace::entering("labeling::impl::generic::regional_maxima"); - - // FIXME: abort if L is not wide enough to encode the set of - // maxima. - - typedef impl::regional_maxima_functor<I,N,L> F; - F f(exact(input), exact(nbh)); - mln_ch_value(I, L) output = canvas::labeling(input, nbh, f, nlabels); - - trace::exiting("labeling::impl::generic::regional_maxima"); - return output; - } - - } // end of namespace mln::labeling::impl::generic - - } // end of namespace mln::labeling::impl @@ -146,7 +127,7 @@ template <typename I, typename N, typename L> mln_ch_value(I, L) regional_maxima(const Image<I>& input_, const Neighborhood<N>& nbh_, - L& nlabels) + bool increasing, L& nlabels) { trace::entering("labeling::regional_maxima"); @@ -154,8 +135,10 @@ const N& nbh = exact(nbh_); mln_precondition(input.is_valid()); - // Calls the only (generic) impl. - mln_ch_value(I, L) output = impl::generic::regional_maxima(input, nbh, nlabels); + typedef impl::regional_maxima_functor<I> F; + F f(exact(input)); + mln_ch_value(I, L) output = canvas::labeling_sorted(input, nbh, increasing, + f, nlabels); trace::exiting("labeling::regional_maxima"); return output; Index: trunk/milena/sandbox/fabien/labeling.hh =================================================================== --- trunk/milena/sandbox/fabien/labeling.hh (revision 3286) +++ trunk/milena/sandbox/fabien/labeling.hh (revision 3287) @@ -101,10 +101,10 @@ return parent(x) = find_root(parent, parent(x)); } - template <typename I, typename N, typename F, typename L> + template <typename I, typename N, typename S, typename F, typename L> mln_ch_value(I, L) labeling(const Image<I>& input_, const Neighborhood<N>& nbh_, - F& f, L& nlabels) + S& s, F& f, L& nlabels) { trace::entering("canvas::impl::generic::labeling"); @@ -113,8 +113,6 @@ const I& input = exact(input_); const N& nbh = exact(nbh_); - typedef typename F::S S; - // Local type. typedef mln_psite(I) P; @@ -228,8 +226,6 @@ const I& input = exact(input_); const N& nbh = exact(nbh_); - typedef typename F::S S; - // Local type. typedef mln_psite(I) P; @@ -315,7 +311,7 @@ // Fastest sorted version - template <typename I, typename N, typename F, typename L> + template <typename I, typename N, typename S, typename F, typename L> mln_ch_value(I, L) labeling_fastest_sorted(const Image<I>& input_, const Neighborhood<N>& nbh_, @@ -443,8 +439,8 @@ labeling_video(metal::false_, const Image<I>& input, const Neighborhood<N>& nbh, F& functor, L& nlabels) { - // FIXME:s = input.domain() - return impl::generic::labeling(input, nbh, functor, nlabels); + return impl::generic::labeling(input, nbh, input.domain(), + functor, nlabels); } template <typename I, typename N, typename F, typename L> @@ -468,35 +464,37 @@ && mln_is_simple_neighborhood(N)::value }; - return impl::generic::labeling_video(metal::bool_<test>(), input, nbh, - functor, nlabels); + return impl::generic::labeling_video(metal::bool_<test>(), input, + nbh, functor, nlabels); } // Sorted - template <typename I, typename N, typename F, typename L> + template <typename I, typename N, typename S, typename F, typename L> inline mln_ch_value(I, L) labeling_sorted(metal::false_, const Image<I>& input, const Neighborhood<N>& nbh, F& functor, L& nlabels) { - return impl::generic::labeling(input, nbh, functor, nlabels); + return impl::generic::labeling(input, nbh, s, functor, nlabels); } - template <typename I, typename N, typename F, typename L> + template <typename I, typename N, typename S, typename F, typename L> inline mln_ch_value(I, L) labeling_sorted(metal::true_, const Image<I>& input, const Neighborhood<N>& nbh, F& functor, L& nlabels) { - return impl::labeling_fastest_sorted(input, nbh, functor, nlabels); + return impl::labeling_fastest_sorted(input, nbh, s, + functor, nlabels); } - template <typename I, typename N, typename F, typename L> + template <typename I, typename N, typename S, typename F, typename L> inline mln_ch_value(I, L) - labeling_sorted_dispatch(const Image<I>& input, const Neighborhood<N>& nbh, + labeling_sorted_dispatch(const Image<I>& input, + const Neighborhood<N>& nbh, F& functor, L& nlabels) { enum { @@ -505,8 +503,8 @@ && mln_is_simple_neighborhood(N)::value }; - return impl::generic::labeling_video(metal::bool_<test>(), input, nbh, - functor, nlabels); + return impl::generic::labeling_sorted(metal::bool_<test>(), input, + nbh, s, functor, nlabels); } @@ -527,7 +525,8 @@ internal::labeling_tests(input, nbh, functor, nlabels); mln_ch_value(I, L) output; - output = internal::labeling_dispatch(input, nbh, functor, nlabels); + output = internal::labeling_video_dispatch(input, nbh, + functor, nlabels); trace::exiting("canvas::labeling_video"); return output; @@ -537,14 +536,15 @@ inline mln_ch_value(I, L) labeling_sorted(const Image<I>& input, const Neighborhood<N>& nbh, - F& functor, L& nlabels) + bool increasing, F& functor, L& nlabels) { trace::entering("canvas::labeling_sorted"); internal::labeling_tests(input, nbh, functor, nlabels); mln_ch_value(I, L) output; - output = internal::labeling_dispatch(input, nbh, functor, nlabels); + output = internal::labeling_sorted_dispatch(input, nbh, s, + functor, nlabels); trace::exiting("canvas::labeling_sorted"); return output;
15 years, 10 months
1
0
0
0
3286: Clean-up Laurent's code.
by Thierry Geraud
https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox
Index: ChangeLog from Thierry Geraud <thierry.geraud(a)lrde.epita.fr> Clean-up Laurent's code. * theo/esiee/laurent/ismm09/main.cc (p1_from, p2_from, e_to_labels_t): Move... * theo/esiee/laurent/ismm09/trash.hh: ...here. * theo/esiee/laurent/ismm09/main.cc (data__paste_values, cplx2d): Move... * theo/esiee/laurent/ismm09/cplx2d.hh: ...in this new file. * theo/esiee/laurent/ismm09/main.cc (compute_pseudo_tree): Move... * theo/esiee/laurent/ismm09/pseudo_tree.hh: ...in this new file. * theo/esiee/laurent/ismm09/main.cc (include): Dispatch... * theo/esiee/laurent/ismm09/util.hh, * theo/esiee/laurent/ismm09/cplx2d.hh, * theo/esiee/laurent/ismm09/pseudo_tree.hh: ...in those files. * theo/color/change_attributes.hh (extinct_rec__, extinct_attributes__): New. color/change_attributes.hh | 62 +++ esiee/laurent/ismm09/cplx2d.hh | 148 +++++++ esiee/laurent/ismm09/main.cc | 671 +----------------------------------- esiee/laurent/ismm09/pseudo_tree.hh | 449 ++++++++++++++++++++++++ esiee/laurent/ismm09/trash.hh | 44 ++ esiee/laurent/ismm09/util.hh | 10 6 files changed, 745 insertions(+), 639 deletions(-) Index: theo/esiee/laurent/ismm09/trash.hh --- theo/esiee/laurent/ismm09/trash.hh (revision 3285) +++ theo/esiee/laurent/ismm09/trash.hh (working copy) @@ -36,6 +36,50 @@ } + inline + point2d p1_from_e(const point2d& e) + { + return e + (is_row_odd(e) ? up : left); + } + + inline + point2d p2_from_e(const point2d& e) + { + return e + (is_row_odd(e) ? down : right); + } + + + + struct e_to_labels_t + { + template <typename W, typename L> + inline + void + operator()(const W& w, const point2d& e, L& l1, L& l2) const + { + mln_precondition(w(e) == 0); + l1 = 0; + l2 = 0; + mln_niter(dbl_neighb2d) n(e2e(), e); + for_all(n) + if (w.has(n) && w(n) != 0) + { + if (l1 == 0) // First label to be stored. + l1 = w(n); + else + if (w(n) != l1 && l2 == 0) // Second label to be stored. + l2 = w(n); + else + mln_invariant(w(n) == l1 || w(n) == l2); + } + mln_invariant(l1 != 0 && l2 != 0); + if (l1 > l2) + std::swap(l1, l2); + mln_postcondition(l2 >= l1); + } + }; + + } // end of namespace mln Index: theo/esiee/laurent/ismm09/main.cc --- theo/esiee/laurent/ismm09/main.cc (revision 3285) +++ theo/esiee/laurent/ismm09/main.cc (working copy) @@ -1,620 +1,20 @@ #include <mln/core/var.hh> -#include <mln/core/image/image2d.hh> -#include <mln/core/alias/neighb2d.hh> -#include <mln/make/double_neighb2d.hh> - -#include <mln/core/image/image_if.hh> -#include <mln/core/routine/extend.hh> - #include <mln/value/label_16.hh> #include <mln/value/int_u8.hh> #include <mln/io/pgm/load.hh> #include <mln/io/pgm/save.hh> #include <mln/debug/println.hh> -#include <mln/data/fill.hh> -#include <mln/data/paste.hh> -#include <mln/labeling/compute.hh> -#include <mln/level/sort_psites.hh> - -#include <mln/core/site_set/p_queue.hh> -#include <mln/core/site_set/p_priority.hh> - -#include <mln/morpho/gradient.hh> #include <mln/morpho/meyer_wst.hh> -#include <mln/morpho/tree/data.hh> -#include <mln/morpho/tree/compute_attribute_image.hh> - +#include <mln/labeling/compute.hh> #include <mln/accu/count.hh> +#include "pseudo_tree.hh" +#include "cplx2d.hh" -namespace mln -{ - - - - template <typename I, typename J> - void data__paste_values(const Image<I>& input_, Image<J>& output_) - { - const I& input = exact(input_); - J& output = exact(output_); - - mln_fwd_piter(I) pi(input.domain()); - mln_fwd_piter(J) po(output.domain()); - for_all_2(pi, po) - output(po) = input(pi); - } - - - - namespace cplx2d - { - - // Neighborhoods. - - typedef neighb< win::multiple<window2d, bool(*)(const point2d&)> > dbl_neighb2d; - - inline - bool is_row_odd(const point2d& p) - { - return p.row() % 2; - } - - // Edge to (the couple of) pixels. - const dbl_neighb2d& e2p() - { - static bool e2p_h[] = { 0, 1, 0, - 0, 0, 0, - 0, 1, 0 }; - static bool e2p_v[] = { 0, 0, 0, - 1, 0, 1, - 0, 0, 0 }; - static dbl_neighb2d nbh = make::double_neighb2d(is_row_odd, e2p_h, e2p_v); - return nbh; - } - - - // Edge to neighboring edges. - const dbl_neighb2d& e2e() - { - static bool e2e_h[] = { 0, 0, 1, 0, 0, - 0, 1, 0, 1, 0, - 0, 0, 0, 0, 0, - 0, 1, 0, 1, 0, - 0, 0, 1, 0, 0 }; - static bool e2e_v[] = { 0, 0, 0, 0, 0, - 0, 1, 0, 1, 0, - 1, 0, 0, 0, 1, - 0, 1, 0, 1, 0, - 0, 0, 0, 0, 0 }; - static dbl_neighb2d nbh = make::double_neighb2d(is_row_odd, e2e_h, e2e_v); - return nbh; - } - - - // Predicates. - - typedef fun::C<bool (*)(const mln::point2d&)> predicate_t; - - inline - bool is_pixel(const point2d& p) - { - // Original pixels. - return p.row() % 2 == 0 && p.col() % 2 == 0; - } - - inline - bool is_edge(const point2d& p) - { - // Edges between pixels. - return p.row() % 2 + p.col() % 2 == 1; - } - - inline - bool is_point(const point2d& p) - { - // Points in-between pixels. - return p.row() % 2 && p.col() % 2; - } - - - - image_if< image2d<value::int_u8>, predicate_t > - f_to_g(const image2d<value::int_u8>& f) - { - - image2d<value::int_u8> f_(2 * f.nrows() - 1, 2 * f.ncols() - 1); - data::fill(f_, 0); // Useless but for display! - - data__paste_values(f, (f_ | is_pixel).rw()); - - mln_VAR(g, f_ | is_edge); - data::paste(morpho::gradient(extend(g, f_), - e2p().win()), - g); - - return g; - } - - - template <typename W> - image2d<mln_value(W)> - extend_w_edges_to_all_faces(W& w) - { - mln_VAR(w_ext, w.unmorph_()); - - // edges (1D-faces) -> pixels (2D-faces) - data::paste(morpho::dilation(extend(w_ext | is_pixel, - pw::value(w_ext)), - c4().win()), - w_ext); - - // edges (1D-faces) -> points (0D-faces) - data::paste(morpho::erosion(extend(w_ext | is_point, - pw::value(w_ext)), - c4().win()), - w_ext); - - return w_ext; - } - - - inline - point2d p1_from_e(const point2d& e) - { - return e + (is_row_odd(e) ? up : left); - } - - inline - point2d p2_from_e(const point2d& e) - { - return e + (is_row_odd(e) ? down : right); - } - - - // Function-Object "e -> (l1, l2)". - - struct e_to_labels_t - { - template <typename W, typename L> - inline - void - operator()(const W& w, const point2d& e, L& l1, L& l2) const - { - mln_precondition(w(e) == 0); - l1 = 0; - l2 = 0; - mln_niter(dbl_neighb2d) n(e2e(), e); - for_all(n) - if (w.has(n) && w(n) != 0) - { - if (l1 == 0) // First label to be stored. - l1 = w(n); - else - if (w(n) != l1 && l2 == 0) // Second label to be stored. - l2 = w(n); - else - mln_invariant(w(n) == l1 || w(n) == l2); - } - mln_invariant(l1 != 0 && l2 != 0); - if (l1 > l2) - std::swap(l1, l2); - mln_postcondition(l2 >= l1); - } - }; - - - } // end of namespace mln::cplx2d - - - - template <typename A, typename L> - util::array<L> - sort_by_increasing_attributes(const util::array<A>& a, L l_max) - { - typedef std::pair<A,L> pair_t; - std::vector<pair_t> v; - v.reserve(l_max.next()); - - v.push_back(pair_t(mln_min(A), 0)); // First elt, even after sorting. - for (L l = 1; l <= l_max; ++l) - v.push_back(pair_t(a[l], l)); - - std::sort(v.begin(), v.end()); - - util::array<L> ls(l_max.next()); - for (unsigned i = 1; i <= l_max; ++i) - ls[i] = v[i].second; - - return ls; - } - - - - // Find-Root for a region labeled with 'l'. - - template <typename L> - inline - L find_root_l(util::array<L>& lpar, L l) - { - if (lpar[l] == l) - return l; - else - return lpar[l] = find_root_l(lpar, lpar[l]); - } - - - - template <typename I> - inline - mln_psite(I) - find_root_e(I& z_epar, mln_psite(I) e) - { - if (z_epar(e) == e) - return e; - else - return z_epar(e) = find_root_e(z_epar, z_epar(e)); - } - - - - // Test emptiness of the queue of a set of regions. - - template <typename Qs, typename L> - bool test_q_emptiness(const Qs& qs, L l, util::array<L>& lpar) - { - L l_ = l; - while (lpar[l_] != l_) - { - if (! qs[l_].is_empty()) - return false; - l_ = lpar[l_]; - } - return true; - } - - - // Get smallest edge. - - template <typename Q_, - typename W, typename L, typename F, - typename E> - void - get_smallest_edge(Q_& q_, // in-out - L l, const W& w, util::array<L>& lpar, const F& e_to_labels, // in - E& e) // out - { - typedef mln_element(Q_) Q; // q_ is an array of queues with type Q. - - // Test that, when a region has merged, its edge queue has been - // emptied. - mln_invariant(test_q_emptiness(q_, l, lpar)); - - L lr = find_root_l(lpar, l); - Q& q = q_[lr]; - - while (! q.is_empty()) - { - e = q.pop_front(); - - L l1, l2; - e_to_labels(w, e, // input - l1, l2); // output - - mln_invariant(l1 != l2); - - L l1r = find_root_l(lpar, l1), - l2r = find_root_l(lpar, l2); - - mln_invariant(l1r == lr || l2r == lr); - - if (l1r == l2r) - // 'e' is an internal edge => forget it. - continue; - - // Otherwise 'e' has been found. - return; - } - - mln_invariant(0); // We should not be here! - } - - - - - // ################################################################### - // ################################################################### - // ################################################################### - // ################################################################### - // ################################################################### - - - - template <typename W, - typename G, - typename L, typename A, - typename F> - void - compute_pseudo_tree(const W& w, - const G& g, - const util::array<L>& ls, - const A& a, - const F& e_to_labels) - { - - typedef mln_value(G) T; // <--- Type of edge values. - typedef mln_psite(G) E; // <--- Type of edges. - - const L l_max = ls.nelements() - 1; - - mln_VAR( g_line, g | (pw::value(w) == 0) ); - - - // Edges -> Priority queue. - - typedef p_priority< T, p_queue<E> > Q; - util::array<Q> q(l_max.next()); - - { - L l1, l2; - - mln_piter(g_line_t) e(g_line.domain()); - for_all(e) - { - mln_invariant(w(e) == 0); - e_to_labels(w, e, // input - l1, l2); // output - q[l1].push(mln_max(T) - g(e), e); - q[l2].push(mln_max(T) - g(e), e); - } - } - - - - // Initialization. - // ----------------------------------- - - - - // Information "label l -> edge e". - - E null = E(0,0); // Impossible value. FIXME: lack of genericity. - - - util::array<E> edge(l_max.next()); - for (L l = 0; l <= l_max; ++l) - edge[l] = null; - - - util::array<L> lpar(l_max.next()); - for (L l = 0; l <= l_max; ++l) - lpar[l] = l; // Make-Set. - - - // To know if an edge is out of a given region (label l), we - // maintain the information about region merging using an - // union-find structure named "lpar". - // - // In the following "lpar[l]" is shortly denoted by lr, meaning - // l-root. - - - // Given a region R with label l and an edge e = (l1, l2) from the - // priority queue, we get know if that edge is out of the set of - // regions containing l: we shall have l1r = lr or l2r = lr. - - // Please note that an edge (l1, l2) is internal to a set of - // regions if l1r = l2r. - - - - - mln_ch_value(g_line_t, E) - epar, // Edge forest. - z_epar; // Auxiliary data: edge forest with compression and balancing. - - { - initialize(epar, g_line); - initialize(z_epar, g_line); - mln_piter(g_line_t) e(g_line.domain()); - for_all(e) - { - // Make-Set. - epar(e) = e; - z_epar(e) = e; - } - debug::println("epar (init):", epar); // epar(e) == e so we depict the edges! - } - - - - // GO GO GO !!! - - - for (unsigned i = 1; i < l_max; ++i) - { - L l = ls[i]; // Region label. - E e; - get_smallest_edge(q, // in-out - l, w, lpar, e_to_labels, // in - e); // out - // FIXME: the call below is performed above!!! - L l1, l2; - e_to_labels(w, e, l1, l2); - - L l1r = find_root_l(lpar, l1), - l2r = find_root_l(lpar, l2); - - // Consistency tests. - { - if (i > 1) - { - L former_l = ls[i-1]; - mln_invariant(a[l] >= a[former_l]); - } - mln_invariant(epar(e) == e); // 'e' has not been processed yet. - mln_invariant(l1 != l2); // It is a valid edge, i.e., between 2 different regions... - mln_invariant(l1r != l2r); // ...that are not already merged. - - L lr = find_root_l(lpar, l); - mln_invariant(lr == l // Either l is not deja-vu - || ((lr == l1r && lr != l2r) || // or l belongs to l1r xor l2r. - (lr == l2r && lr != l1r))); - } - - - - // aa(e) = a[l]; // FIXME: Re-activate. - - - - /* - std::cout << "l = " << l - << " e = " << e - << " (l1, l2) = (" << l1 << ", " << l2 << ") => " - << " merging R" << l1r << " and R" << l2r - << std::endl; - */ - - - // Merging both regions. - { - if (l2r < l1r) - std::swap(l1r, l2r); - mln_invariant(l2r > l1r); - lpar[l1r] = l2r; - - /* - std::cout << "q[l1r] = " << q[l1r] << std::endl; - std::cout << "q[l2r] = " << q[l2r] << std::endl; - */ - - - q[l2r].insert(q[l1r]); - q[l1r].clear(); - - - /* - std::cout << "q[l2r] = " << q[l2r] << std::endl - << std::endl; - */ - - - /* - // Displaying lpar. - { - std::cout << "lpar = "; - for (unsigned i = 1; i <= l_max; ++i) - { - L l = v[i].second; - std::cout << l << "->" << lpar[l] << " "; - } - std::cout << std::endl; - } - */ - } - - E e1 = edge[l1], - e2 = edge[l2]; - - if (e1 == null && e2 == null) - { - // New edge-component (singleton) - // Put differently: new edge-node! - edge[l1] = e; - edge[l2] = e; - // after: - // e - // / \ - // l1 l2 - } - else if (e1 != null && e2 != null) - { - // Two trees shall merge. - E e1r = find_root_e(z_epar, e1), - e2r = find_root_e(z_epar, e2); - mln_invariant(e1r != e2r); // Otherwise, there's a bug! - // before: - // e1r e2r - // |... |... - // e1 e2 - // / \ / \ - // l1 . l2 . - epar(e1r) = e; z_epar(e1r) = e; - epar(e2r) = e; z_epar(e2r) = e; - // after: - // e - // / \ - // e1r e2r - // |... |... - // e1 e2 - // / \ / \ - // l1 . l2 . - } - else if (e1 != null && e2 == null) - { - E e1r = find_root_e(z_epar, e1); - // before: - // e1r - // |... - // e1 null - // / \ / - // l1 . l2 - epar(e1r) = e; z_epar(e1r) = e; - edge[l2] = e; - // after: - // e - // / \ - // e1r l2 - // |... - // e1 - // / \ - // l1 . - } - else - { - mln_invariant(e1 == null && e2 != null); - E e2r = find_root_e(z_epar, e2); - epar(e2r) = e; z_epar(e2r) = e; - edge[l1] = e; - } - - } // end of "for every region with increasing attribute" - - - { - // Display edge tree. - - mln_ch_value(g_line_t, bool) deja_vu; - initialize(deja_vu, g_line); - data::fill(deja_vu, false); - - std::cout << "edge tree: " << std::endl; - for (L l = 1; l <= l_max; ++l) - { - std::cout << l << ": "; - E e = edge[l]; - while (! deja_vu(e)) - { - std::cout << e << " -> "; - deja_vu(e) = true; - e = epar(e); - } - std::cout << e << std::endl; - } - } - - - - } - - - -} // end of namespace mln - void usage(char* argv[]) @@ -642,8 +42,6 @@ io::pgm::load(f, argv[1]); - cplx2d::e_to_labels_t e_to_labels; - // g: weights on edges. mln_VAR(g, cplx2d::f_to_g(f) ); @@ -653,30 +51,37 @@ typedef mln_psite_(g_t) E; // <--- Type of edges. - mln_VAR(nbh_g, cplx2d::e2e()); // Neighborhood between edges. - - // w: watershed labeling on edges. typedef label_16 L; // <--- Type of labels. L l_max; - mln_VAR( w, morpho::meyer_wst(g, nbh_g, l_max) ); + mln_VAR( w, morpho::meyer_wst(g, cplx2d::e2e(), l_max) ); debug::println("w:", w); - mln_VAR( w_line, pw::value(w) == pw::cst(0) ); - mln_VAR( g_line, g | w_line ); + mln_VAR( is_w_line, pw::value(w) == pw::cst(0) ); + mln_VAR( g_line, g | is_w_line ); debug::println("g | line:", g_line); - - { - /* - // debug::println("w | line:", w | w_line); mln_VAR(w_ext, cplx2d::extend_w_edges_to_all_faces(w)); debug::println("w_ext:", w_ext); - // debug::println("w_ext | line:", w_ext | (pw::value(w_ext) == pw::cst(0))); - */ - } + + + // e -> (l1, l2) + mln_VAR( e_to_l1_l2, function_e_to_l1_l2(w_ext, cplx2d::e2p()) ); + +// { +// // Test adjacency "e -> (l1, l2)". +// L l1, l2; +// mln_piter_(g_t) e(g.domain()); +// for_all(e) +// if (w(e) == 0) +// { +// e_to_l1_l2(e, l1, l2); +// std::cout << e << "=" << l1 << '|' << l2 << " "; +// } +// std::cout << std::endl; +// } @@ -691,30 +96,18 @@ util::array<L> ls = sort_by_increasing_attributes(a, l_max); - - { - std::cout << "ls:" << std::endl; - for (unsigned i = 1; i <= l_max; ++i) - std::cout << ls[i] << "(" << a[ls[i]] << ") "; - std::cout << std::endl - << std::endl; - } - - - // { - // // Test adjacency "e -> (l1, l2)". - // L l1, l2; - // mln_piter_(g_t) e(g.domain()); - // for_all(e) - // if (w(e) == 0) // { - // e_to_labels(w, e, l1, l2); - // std::cout << e << ':' << l1 << ',' << l2 << std::endl; - // } +// std::cout << "ls:" << std::endl; +// for (unsigned i = 1; i <= l_max; ++i) +// std::cout << ls[i] << "(" << a[ls[i]] << ") "; +// std::cout << std::endl +// << std::endl; // } - compute_pseudo_tree(w, g, ls, a, - e_to_labels); + + // -> pseudo-tree + + compute_pseudo_tree(w, g, ls, a, e_to_l1_l2); } Index: theo/esiee/laurent/ismm09/cplx2d.hh --- theo/esiee/laurent/ismm09/cplx2d.hh (revision 0) +++ theo/esiee/laurent/ismm09/cplx2d.hh (revision 0) @@ -0,0 +1,148 @@ + +#include <mln/core/image/image2d.hh> +#include <mln/core/alias/neighb2d.hh> +#include <mln/make/double_neighb2d.hh> + +#include <mln/pw/all.hh> +#include <mln/core/image/image_if.hh> +#include <mln/core/routine/extend.hh> + +#include <mln/data/paste.hh> + +#include <mln/morpho/gradient.hh> + + +namespace mln +{ + + + + template <typename I, typename J> + void data__paste_values(const Image<I>& input_, Image<J>& output_) + { + const I& input = exact(input_); + J& output = exact(output_); + + mln_fwd_piter(I) pi(input.domain()); + mln_fwd_piter(J) po(output.domain()); + for_all_2(pi, po) + output(po) = input(pi); + } + + + + namespace cplx2d + { + + // Neighborhoods. + + typedef neighb< win::multiple<window2d, bool(*)(const point2d&)> > dbl_neighb2d; + + inline + bool is_row_odd(const point2d& p) + { + return p.row() % 2; + } + + // Edge to (the couple of) pixels. + const dbl_neighb2d& e2p() + { + static bool e2p_h[] = { 0, 1, 0, + 0, 0, 0, + 0, 1, 0 }; + static bool e2p_v[] = { 0, 0, 0, + 1, 0, 1, + 0, 0, 0 }; + static dbl_neighb2d nbh = make::double_neighb2d(is_row_odd, e2p_h, e2p_v); + return nbh; + } + + + // Edge to neighboring edges. + const dbl_neighb2d& e2e() + { + static bool e2e_h[] = { 0, 0, 1, 0, 0, + 0, 1, 0, 1, 0, + 0, 0, 0, 0, 0, + 0, 1, 0, 1, 0, + 0, 0, 1, 0, 0 }; + static bool e2e_v[] = { 0, 0, 0, 0, 0, + 0, 1, 0, 1, 0, + 1, 0, 0, 0, 1, + 0, 1, 0, 1, 0, + 0, 0, 0, 0, 0 }; + static dbl_neighb2d nbh = make::double_neighb2d(is_row_odd, e2e_h, e2e_v); + return nbh; + } + + + // Predicates. + + typedef fun::C<bool (*)(const mln::point2d&)> predicate_t; + + inline + bool is_pixel(const point2d& p) + { + // Original pixels. + return p.row() % 2 == 0 && p.col() % 2 == 0; + } + + inline + bool is_edge(const point2d& p) + { + // Edges between pixels. + return p.row() % 2 + p.col() % 2 == 1; + } + + inline + bool is_point(const point2d& p) + { + // Points in-between pixels. + return p.row() % 2 && p.col() % 2; + } + + + + image_if< image2d<value::int_u8>, predicate_t > + f_to_g(const image2d<value::int_u8>& f) + { + image2d<value::int_u8> f_(2 * f.nrows() - 1, 2 * f.ncols() - 1); + data::fill(f_, 0); // Useless but for display! + + data__paste_values(f, (f_ | is_pixel).rw()); + + mln_VAR(g, f_ | is_edge); + data::paste(morpho::gradient(extend(g, f_), + e2p().win()), + g); + + return g; + } + + + template <typename W> + image2d<mln_value(W)> + extend_w_edges_to_all_faces(W& w) + { + mln_VAR(w_ext, w.unmorph_()); + + // edges (1D-faces) -> pixels (2D-faces) + data::paste(morpho::dilation(extend(w_ext | is_pixel, + pw::value(w_ext)), + c4().win()), + w_ext); + + // edges (1D-faces) -> points (0D-faces) + data::paste(morpho::erosion(extend(w_ext | is_point, + pw::value(w_ext)), + c4().win()), + w_ext); + + return w_ext; + } + + + + } // end of namespace mln::cplx2d + +} // end of namespace mln Index: theo/esiee/laurent/ismm09/util.hh --- theo/esiee/laurent/ismm09/util.hh (revision 3285) +++ theo/esiee/laurent/ismm09/util.hh (working copy) @@ -1,4 +1,14 @@ +#include <mln/core/concept/function.hh> +#include <mln/core/site_set/p_array.hh> + +#include <mln/level/sort_psites.hh> + +#include <mln/morpho/tree/data.hh> +#include <mln/morpho/tree/compute_attribute_image.hh> + + + namespace mln { Index: theo/esiee/laurent/ismm09/pseudo_tree.hh --- theo/esiee/laurent/ismm09/pseudo_tree.hh (revision 0) +++ theo/esiee/laurent/ismm09/pseudo_tree.hh (revision 0) @@ -0,0 +1,449 @@ + +#include <mln/core/concept/image.hh> +#include <mln/core/site_set/p_queue.hh> +#include <mln/core/site_set/p_priority.hh> +#include <mln/data/fill.hh> +#include <mln/util/array.hh> + + + +namespace mln +{ + + + // Function-Object "e -> (l1, l2)". + + template <typename W, typename N> + struct e_to_l1_l2_t + { + const W& w; + const N& nbh; + typedef mln_value(W) L; + + e_to_l1_l2_t(const W& w, const N& nbh) + : w(w), nbh(nbh) + { + } + + template <typename E> + void operator()(const E& e, // in + L& l1, // out + L& l2 // out + ) const + { + mln_niter(N) n(nbh, e); + n.start(); + l1 = w(n); + n.next(); + l2 = w(n); + mln_invariant(l2 != l1); + if (l1 > l2) + std::swap(l1, l2); + } + }; + + template <typename W, typename N> + e_to_l1_l2_t<W, N> + function_e_to_l1_l2(const W& w, const N& nbh) + { + e_to_l1_l2_t<W, N> tmp(w, nbh); + return tmp; + } + + + + template <typename A, typename L> + util::array<L> + sort_by_increasing_attributes(const util::array<A>& a, L l_max) + { + typedef std::pair<A,L> pair_t; + std::vector<pair_t> v; + v.reserve(l_max.next()); + + v.push_back(pair_t(mln_min(A), 0)); // First elt, even after sorting. + for (L l = 1; l <= l_max; ++l) + v.push_back(pair_t(a[l], l)); + + std::sort(v.begin(), v.end()); + + util::array<L> ls(l_max.next()); + for (unsigned i = 1; i <= l_max; ++i) + ls[i] = v[i].second; + + return ls; + } + + + + // Find-Root for a region labeled with 'l'. + + template <typename L> + inline + L find_root_l(util::array<L>& lpar, L l) + { + if (lpar[l] == l) + return l; + else + return lpar[l] = find_root_l(lpar, lpar[l]); + } + + + + template <typename I> + inline + mln_psite(I) + find_root_e(I& z_epar, mln_psite(I) e) + { + if (z_epar(e) == e) + return e; + else + return z_epar(e) = find_root_e(z_epar, z_epar(e)); + } + + + + // Test emptiness of the queue of a set of regions. + + template <typename Qs, typename L> + bool test_q_emptiness(const Qs& qs, L l, util::array<L>& lpar) + { + L l_ = l; + while (lpar[l_] != l_) + { + if (! qs[l_].is_empty()) + return false; + l_ = lpar[l_]; + } + return true; + } + + + // Get smallest edge. + + template <typename Q_, + typename W, typename L, typename F, + typename E> + void + get_smallest_edge(Q_& q_, // in-out + L l, const W& w, util::array<L>& lpar, const F& e_to_l1_l2, // in + E& e, L& l1, L& l2) // out + { + typedef mln_element(Q_) Q; // q_ is an array of queues with type Q. + + // Test that, when a region has merged, its edge queue has been + // emptied. + mln_invariant(test_q_emptiness(q_, l, lpar)); + + L lr = find_root_l(lpar, l); + Q& q = q_[lr]; + + while (! q.is_empty()) + { + e = q.pop_front(); + + e_to_l1_l2(e, l1, l2); + + mln_invariant(l1 != l2); + + L l1r = find_root_l(lpar, l1), + l2r = find_root_l(lpar, l2); + + mln_invariant(l1r == lr || l2r == lr); + + if (l1r == l2r) + // 'e' is an internal edge => forget it. + continue; + + // Otherwise 'e' has been found. + return; + } + + mln_invariant(0); // We should not be here! + } + + + + + // ################################################################### + // ################################################################### + // ################################################################### + // ################################################################### + // ################################################################### + + + + template <typename W, + typename G, + typename L, typename A, + typename F> + void + compute_pseudo_tree(const W& w, + const G& g, + const util::array<L>& ls, + const A& a, + const F& e_to_l1_l2) + { + + typedef mln_value(G) T; // <--- Type of edge values. + typedef mln_psite(G) E; // <--- Type of edges. + + const L l_max = ls.nelements() - 1; + + mln_VAR( g_line, g | (pw::value(w) == 0) ); + + + // Edges -> Priority queue. + + typedef p_priority< T, p_queue<E> > Q; + util::array<Q> q(l_max.next()); + + { + L l1, l2; + + mln_piter(g_line_t) e(g_line.domain()); + for_all(e) + { + mln_invariant(w(e) == 0); + e_to_l1_l2(e, l1, l2); + q[l1].push(mln_max(T) - g(e), e); + q[l2].push(mln_max(T) - g(e), e); + } + } + + + + // Initialization. + // ----------------------------------- + + + + // Information "label l -> edge e". + + E null = E(0,0); // Impossible value. FIXME: lack of genericity. + + + util::array<E> edge(l_max.next()); + for (L l = 0; l <= l_max; ++l) + edge[l] = null; + + + util::array<L> lpar(l_max.next()); + for (L l = 0; l <= l_max; ++l) + lpar[l] = l; // Make-Set. + + + // To know if an edge is out of a given region (label l), we + // maintain the information about region merging using an + // union-find structure named "lpar". + // + // In the following "lpar[l]" is shortly denoted by lr, meaning + // l-root. + + + // Given a region R with label l and an edge e = (l1, l2) from the + // priority queue, we get know if that edge is out of the set of + // regions containing l: we shall have l1r = lr or l2r = lr. + + // Please note that an edge (l1, l2) is internal to a set of + // regions if l1r = l2r. + + + + + mln_ch_value(g_line_t, E) + epar, // Edge forest. + z_epar; // Auxiliary data: edge forest with compression and balancing. + + { + initialize(epar, g_line); + initialize(z_epar, g_line); + mln_piter(g_line_t) e(g_line.domain()); + for_all(e) + { + // Make-Set. + epar(e) = e; + z_epar(e) = e; + } + debug::println("epar (init):", epar); // epar(e) == e so we depict the edges! + } + + + + // GO GO GO !!! + + + for (unsigned i = 1; i < l_max; ++i) + { + L l = ls[i]; // Region label. + L l1, l2; + E e; + get_smallest_edge(q, // in-out + l, w, lpar, e_to_l1_l2, // in + e, l1, l2); // out + + L l1r = find_root_l(lpar, l1), + l2r = find_root_l(lpar, l2); + + // Consistency tests. + { + if (i > 1) + { + L former_l = ls[i-1]; + mln_invariant(a[l] >= a[former_l]); + } + mln_invariant(epar(e) == e); // 'e' has not been processed yet. + mln_invariant(l1 != l2); // It is a valid edge, i.e., between 2 different regions... + mln_invariant(l1r != l2r); // ...that are not already merged. + + L lr = find_root_l(lpar, l); + mln_invariant(lr == l // Either l is not deja-vu + || ((lr == l1r && lr != l2r) || // or l belongs to l1r xor l2r. + (lr == l2r && lr != l1r))); + } + + + + // aa(e) = a[l]; // FIXME: Re-activate. + + + + /* + std::cout << "l = " << l + << " e = " << e + << " (l1, l2) = (" << l1 << ", " << l2 << ") => " + << " merging R" << l1r << " and R" << l2r + << std::endl; + */ + + + // Merging both regions. + { + if (l2r < l1r) + std::swap(l1r, l2r); + mln_invariant(l2r > l1r); + lpar[l1r] = l2r; + + /* + std::cout << "q[l1r] = " << q[l1r] << std::endl; + std::cout << "q[l2r] = " << q[l2r] << std::endl; + */ + + + q[l2r].insert(q[l1r]); + q[l1r].clear(); + + + /* + std::cout << "q[l2r] = " << q[l2r] << std::endl + << std::endl; + */ + + + /* + // Displaying lpar. + { + std::cout << "lpar = "; + for (unsigned i = 1; i <= l_max; ++i) + { + L l = v[i].second; + std::cout << l << "->" << lpar[l] << " "; + } + std::cout << std::endl; + } + */ + } + + E e1 = edge[l1], + e2 = edge[l2]; + + if (e1 == null && e2 == null) + { + // New edge-component (singleton) + // Put differently: new edge-node! + edge[l1] = e; + edge[l2] = e; + // after: + // e + // / \ + // l1 l2 + } + else if (e1 != null && e2 != null) + { + // Two trees shall merge. + E e1r = find_root_e(z_epar, e1), + e2r = find_root_e(z_epar, e2); + mln_invariant(e1r != e2r); // Otherwise, there's a bug! + // before: + // e1r e2r + // |... |... + // e1 e2 + // / \ / \ + // l1 . l2 . + epar(e1r) = e; z_epar(e1r) = e; + epar(e2r) = e; z_epar(e2r) = e; + // after: + // e + // / \ + // e1r e2r + // |... |... + // e1 e2 + // / \ / \ + // l1 . l2 . + } + else if (e1 != null && e2 == null) + { + E e1r = find_root_e(z_epar, e1); + // before: + // e1r + // |... + // e1 null + // / \ / + // l1 . l2 + epar(e1r) = e; z_epar(e1r) = e; + edge[l2] = e; + // after: + // e + // / \ + // e1r l2 + // |... + // e1 + // / \ + // l1 . + } + else + { + mln_invariant(e1 == null && e2 != null); + E e2r = find_root_e(z_epar, e2); + epar(e2r) = e; z_epar(e2r) = e; + edge[l1] = e; + } + + } // end of "for every region with increasing attribute" + + + { + // Display edge tree. + + mln_ch_value(g_line_t, bool) deja_vu; + initialize(deja_vu, g_line); + data::fill(deja_vu, false); + + std::cout << "edge tree: " << std::endl; + for (L l = 1; l <= l_max; ++l) + { + std::cout << l << ": "; + E e = edge[l]; + while (! deja_vu(e)) + { + std::cout << e << " -> "; + deja_vu(e) = true; + e = epar(e); + } + std::cout << e << std::endl; + } + } + + } + +} // end of namespace mln + Index: theo/color/change_attributes.hh --- theo/color/change_attributes.hh (revision 3285) +++ theo/color/change_attributes.hh (working copy) @@ -77,6 +77,9 @@ const T* t; }; + + // Vachier's version. + template <typename T, typename I, typename M> inline mln_value(I) @@ -92,9 +95,30 @@ return a(p) = extinct_rec(t, a, mark, t.parent(p)); } + + // Modified version. + + template <typename T, typename I, typename M> + inline + mln_value(I) + extinct_rec__(const T& t, // tree + const I& a, // original attribute image + I& ea, // extincted attribute image + M& mark, + const mln_psite(I)& p) + { + mln_invariant(mark(p) == false); + mark(p) = true; + if (t.parent(p) == p || mark(t.parent(p)) == true) // Stop. + return a(t.parent(p)); // The parent attribute! + return ea(p) = extinct_rec__(t, a, ea, mark, t.parent(p)); + } + + } // end of internal + // Vachier's version. template <typename T, typename I> void @@ -128,6 +152,44 @@ + // Modified version. + + template <typename T, typename I> + void + extinct_attributes__(const T& t, // Tree. + I& a) // Attribute image. + { + typedef mln_site(I) P; + typedef mln_value(I) A; // Type of attributes. + + mln_ch_value(I, bool) mark; + initialize(mark, a); + data::fill(mark, false); + + mln_concrete(I) ea = duplicate(a); + + internal::node_pred<T> node_only; + node_only.t = &t; + + typedef p_array<P> S; + S s = level::sort_psites_increasing(a | node_only); + mln_invariant(geom::nsites(a | t.nodes()) == s.nsites()); + + mln_fwd_piter(S) p(s); + for_all(p) + { + if (mark(p) == true) + continue; + internal::extinct_rec__(t, a, ea, mark, p); + } + + data::fill(a, ea); + + // debug::println(mark | t.nodes()); + } + + + // Move down. // ----------
15 years, 10 months
1
0
0
0
r3285: Implement fastest versions of canvas::labeling
by Fabien Freling
URL:
https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox
ChangeLog: 2009-02-04 Fabien Freling <freling(a)lrde.epita.fr> Implement fastest versions of canvas::labeling. * fabien/regional_maxima.hh: New. --- labeling.hh | 199 +++++++++++++++++++++++++++++++++++++++++++++++++---- regional_maxima.hh | 171 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 357 insertions(+), 13 deletions(-) Index: trunk/milena/sandbox/fabien/regional_maxima.hh =================================================================== --- trunk/milena/sandbox/fabien/regional_maxima.hh (revision 0) +++ trunk/milena/sandbox/fabien/regional_maxima.hh (revision 3285) @@ -0,0 +1,171 @@ +// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory +// (LRDE) +// +// This file is part of the Olena Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License version 2 as published by the +// Free Software Foundation. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, +// Boston, MA 02111-1307, USA. +// +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +#ifndef MLN_LABELING_REGIONAL_MAXIMA_HH +# define MLN_LABELING_REGIONAL_MAXIMA_HH + +/// \file mln/labeling/regional_maxima.hh +/// +/// Connected component labeling of the regional maxima of an image. + +# include <mln/core/concept/image.hh> +# include <mln/core/concept/neighborhood.hh> +# include <mln/canvas/labeling.hh> +# include <mln/data/fill.hh> +# include <mln/level/sort_psites.hh> + + +namespace mln +{ + + namespace labeling + { + + /*! Connected component labeling of the regional maxima of an + * image. + * + * \param[in] input The input image. + * \param[in] nbh The connexity of the regional maxima. + * \param[out] nlabels The number of labeled regions. + * \return The label image. + * + */ + template <typename I, typename N, typename L> + mln_ch_value(I, L) + regional_maxima(const Image<I>& input, const Neighborhood<N>& nbh, + L& nlabels); + + + +# ifndef MLN_INCLUDE_ONLY + + namespace impl + { + + // Generic functor. + + template <typename I_, typename N_, typename L_> + struct regional_maxima_functor + { + typedef mln_psite(I_) P; + + // requirements from mln::canvas::labeling: + + typedef I_ I; + typedef N_ N; + typedef L_ L; + typedef p_array<P> S; + + const I& input; + const N& nbh; + S s; + + void init() { data::fill(attr, true); } + bool handles(const P&) const { return true; } + bool labels(const P& p) const { return attr(p); } + bool equiv(const P& n, const P& p) const { return input(n) == + input(p); } + void do_no_union(const P& n, const P& p) { mln_invariant(input(n) > + input(p)); + attr(p) = false; } + void init_attr(const P&) {} + void merge_attr(const P& r, const P& p) { attr(p) = attr(p) && + attr(r); } + + // end of requirements + + mln_ch_value(I, bool) attr; + + regional_maxima_functor(const I_& input, const N_& nbh) + : input(input), + nbh(nbh), + s(level::sort_psites_decreasing(input)) + { + initialize(attr, input); + } + }; + + + // Generic implementation. + + namespace generic + { + + template <typename I, typename N, typename L> + mln_ch_value(I, L) + regional_maxima(const I& input, const N& nbh, + L& nlabels) + { + trace::entering("labeling::impl::generic::regional_maxima"); + + // FIXME: abort if L is not wide enough to encode the set of + // maxima. + + typedef impl::regional_maxima_functor<I,N,L> F; + F f(exact(input), exact(nbh)); + mln_ch_value(I, L) output = canvas::labeling(input, nbh, f, nlabels); + + trace::exiting("labeling::impl::generic::regional_maxima"); + return output; + } + + } // end of namespace mln::labeling::impl::generic + + + } // end of namespace mln::labeling::impl + + + + // Facade. + + template <typename I, typename N, typename L> + mln_ch_value(I, L) + regional_maxima(const Image<I>& input_, const Neighborhood<N>& nbh_, + L& nlabels) + { + trace::entering("labeling::regional_maxima"); + + const I& input = exact(input_); + const N& nbh = exact(nbh_); + mln_precondition(input.is_valid()); + + // Calls the only (generic) impl. + mln_ch_value(I, L) output = impl::generic::regional_maxima(input, nbh, nlabels); + + trace::exiting("labeling::regional_maxima"); + return output; + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::labeling + +} // end of namespace mln + + +#endif // ! MLN_LABELING_REGIONAL_MAXIMA_HH Index: trunk/milena/sandbox/fabien/labeling.hh =================================================================== --- trunk/milena/sandbox/fabien/labeling.hh (revision 3284) +++ trunk/milena/sandbox/fabien/labeling.hh (revision 3285) @@ -201,7 +201,7 @@ - // Fastest version + // Fastest video version template <typename I> static inline @@ -214,9 +214,11 @@ return parent.element(x) = find_root(parent, parent.element(x)); } + // FIXME: Use the same functer for the generic and the fastest versions + template <typename I, typename N, typename F, typename L> mln_ch_value(I, L) - labeling_fastest(const Image<I>& input_, const Neighborhood<N>& nbh_, + labeling_fastest_video(const Image<I>& input_, const Neighborhood<N>& nbh_, F& f, L& nlabels) { trace::entering("canvas::impl::labeling"); @@ -269,7 +271,7 @@ if (f.equiv(n, p)) { // Do-Union. - P r = find_root(parent, n); + unsigned r = find_root_fastest(parent, n); if (r != p) { parent.element(r) = p; @@ -278,8 +280,7 @@ } else f.do_no_union(n, p); - } - deja_vu(p) = true; + (p) = true; } } @@ -310,6 +311,121 @@ return output; } + + + // Fastest sorted version + + template <typename I, typename N, typename F, typename L> + mln_ch_value(I, L) + labeling_fastest_sorted(const Image<I>& input_, + const Neighborhood<N>& nbh_, + S& s, F& f, L& nlabels) + { + trace::entering("canvas::impl::labeling"); + + // FIXME: Test?! + + const I& input = exact(input_); + const N& nbh = exact(nbh_); + + typedef typename F::S S; + + // Local type. + typedef mln_psite(I) P; + + // Auxiliary data. + mln_ch_value(I, bool) deja_vu; + mln_ch_value(I, P) parent; + + // Output. + mln_ch_value(I, L) output; + bool status; + + // Initialization. + { + initialize(deja_vu, input); + mln::data::fill(deja_vu, false); + + initialize(parent, input); + + initialize(output, input); + mln::data::fill(output, L(literal::zero)); + nlabels = 0; + + f.init(); // Client initialization. + } + + util::array<int> dp = offsers_wrt(input, nbh); + const unsigned n_nbhs = dp.nelements(); + + const unsigned n_points = s.elements(); + + // First Pass. + { + + for (unsigned i = 0; i < n_points; ++i) + { + unsigned p = s[i]; + if (!f.handles(p)) + continue; + + // Make-Set. + parent.element(p) = p; + f.init_attr(p); + + for (unsigned j = 0; j < n_nbhs; ++j) + { + unsigned n = p + dp[j]; + if (!deja_vu[n]) + continue; + + if (f.equiv(n, p)) + { + // Do-Union. + unsigned r = find_root_fastest(parent, n); + if (input.element(r) != input.element(p)) + { + parent.element(r) = p; + f.merge_attr(r, p); + } + } + else + f.do_no_union(n, p); + } + deja_vu.element(p) = true; + + } + + // Second Pass. + { + for (int i = n_points - 1; i >=0; --i) + { + unsigned p = s[i]; + if (!f.handles(p)) + continue; + + if (parent.element(p) == p) // if p is root + { + if (f.labels(p)) + { + if (nlabels == mln_max(L)) + { + status = false; + return output; + } + output.element(p) = ++nlabels; + } + } + else + output.element(p) = output(parent.element(p)); + } + status = true; + } + + trace::exiting("canvas::impl::labeling"); + return output; + } + } // end of namespace mln::canvas::impl @@ -319,10 +435,50 @@ namespace internal { + // Video + + template <typename I, typename N, typename F, typename L> + inline + mln_ch_value(I, L) + labeling_video(metal::false_, const Image<I>& input, + const Neighborhood<N>& nbh, F& functor, L& nlabels) + { + // FIXME:s = input.domain() + return impl::generic::labeling(input, nbh, functor, nlabels); + } + + template <typename I, typename N, typename F, typename L> + inline + mln_ch_value(I, L) + labeling_video(metal::true_, const Image<I>& input, + const Neighborhood<N>& nbh, F& functor, L& nlabels) + { + return impl::labeling_fastest_video(input, nbh, functor, nlabels); + } + template <typename I, typename N, typename F, typename L> inline mln_ch_value(I, L) - labeling(metal::false_, const Image<I>& input, + labeling_video_dispatch(const Image<I>& input, const Neighborhood<N>& nbh, + F& functor, L& nlabels) + { + enum { + test = mlc_equal(mln_trait_image_speed(I), + trait::image::speed::fastest)::value + && + mln_is_simple_neighborhood(N)::value + }; + return impl::generic::labeling_video(metal::bool_<test>(), input, nbh, + functor, nlabels); + } + + + // Sorted + + template <typename I, typename N, typename F, typename L> + inline + mln_ch_value(I, L) + labeling_sorted(metal::false_, const Image<I>& input, const Neighborhood<N>& nbh, F& functor, L& nlabels) { return impl::generic::labeling(input, nbh, functor, nlabels); @@ -331,16 +487,16 @@ template <typename I, typename N, typename F, typename L> inline mln_ch_value(I, L) - labeling(metal::true_, const Image<I>& input, + labeling_sorted(metal::true_, const Image<I>& input, const Neighborhood<N>& nbh, F& functor, L& nlabels) { - return impl::labeling_fastest(input, nbh, functor, nlabels); + return impl::labeling_fastest_sorted(input, nbh, functor, nlabels); } template <typename I, typename N, typename F, typename L> inline mln_ch_value(I, L) - labeling_dispatch(const Image<I>& input, const Neighborhood<N>& nbh, + labeling_sorted_dispatch(const Image<I>& input, const Neighborhood<N>& nbh, F& functor, L& nlabels) { enum { @@ -349,10 +505,11 @@ && mln_is_simple_neighborhood(N)::value }; - return impl::generic::labeling(metal::bool_<test>(), input, nbh, + return impl::generic::labeling_video(metal::bool_<test>(), input, nbh, functor, nlabels); } + } // end of namespace mln::canvas::internal @@ -362,20 +519,36 @@ template <typename I, typename N, typename F, typename L> inline mln_ch_value(I, L) - labeling(const Image<I>& input, const Neighborhood<N>& nbh, + labeling_video(const Image<I>& input, const Neighborhood<N>& nbh, F& functor, L& nlabels) { - trace::entering("canvas::labeling"); + trace::entering("canvas::labeling_video"); internal::labeling_tests(input, nbh, functor, nlabels); mln_ch_value(I, L) output; output = internal::labeling_dispatch(input, nbh, functor, nlabels); - trace::exiting("canvas::labeling"); + trace::exiting("canvas::labeling_video"); return output; } + template <typename I, typename N, typename F, typename L> + inline + mln_ch_value(I, L) + labeling_sorted(const Image<I>& input, const Neighborhood<N>& nbh, + F& functor, L& nlabels) + { + trace::entering("canvas::labeling_sorted"); + + internal::labeling_tests(input, nbh, functor, nlabels); + + mln_ch_value(I, L) output; + output = internal::labeling_dispatch(input, nbh, functor, nlabels); + + trace::exiting("canvas::labeling_sorted"); + return output; + } # endif // ! MLN_INCLUDE_ONLY
15 years, 10 months
1
0
0
0
r3284: Add card accu and some traits
by Edwin Carlinet
URL:
https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox
ChangeLog: 2009-02-04 Edwin Carlinet <carlinet(a)lrde.epita.fr> Add card accu and some traits. * accu.cc: Add traits and fix bugs. * accu_trait.hh: New. --- accu.cc | 155 ++++++++++++++++++++++++++++++++++++++++++++++------------ accu_trait.hh | 51 +++++++++++++++++++ 2 files changed, 175 insertions(+), 31 deletions(-) Index: trunk/milena/sandbox/edwin/accu.cc =================================================================== --- trunk/milena/sandbox/edwin/accu.cc (revision 3283) +++ trunk/milena/sandbox/edwin/accu.cc (revision 3284) @@ -1,91 +1,184 @@ -template <typename E> -struct Accumulator : public object<E> -{ - typedef mln_vtypes(E, take_with) take_with; +# include <mln/metal/equal.hh> +# include <mln/metal/if.hh> +# include <mln/metal/is_const.hh> +# include <mln/core/concept/image.hh> +# include <mln/accu/all.hh> +# include <mln/util/pix.hh> +# include <mln/make/pix.hh> +# include "accu_trait.hh" -}; +using namespace mln; + +namespace mln +{ + + namespace morpho + { namespace accu { template <typename T> - struct card : public Accumulator< card<T> > + struct card : public mln::accu::internal::base< unsigned, card<T> > { - void take(const T& elt) { ++c_; } + typedef T argument; + void init () { c_ = 0; }; + void take (const card<T>& elt) { ++c_; }; + void take (const T& elt) { ++c_; }; + void take (const mln_value(T)& v) { ++c_; }; + unsigned to_result() const { return c_; }; + operator unsigned () const { return c_; }; + bool is_valid () const { return true; }; + card () { init(); }; + + private: unsigned c_; }; -} + } // accu + } // morpho namespace impl { - template <typename I, template<typename E> class A> + template <typename I, typename A> void algebraic(const Image<I>& input, - const Accumulator< A<point2d> >& acc) + Accumulator<A>& acc) { const I& ima = exact(input); + A& accu = exact (acc); mln_piter(I) p(ima.domain()); for_all(p) - acc.take(p); + accu.take(p); } // fast implementation - template <typename I, template<typename E> class A> + template <typename I, typename A> void - leveling (const Image<I>& input, - const Accumulator< A< pix<I> > >& acc) + leveling_fast (const Image<I>& input, + Accumulator<A>& acc) { const I& ima = exact(input); + A& accu = exact (acc); mln_pixter(const I) px(ima); for_all(px) - acc.take(px); + accu.take (px.val ()); } // generic implementation - template <typename I, template<typename E> class A> + template <typename I, typename A> void leveling (const Image<I>& input, - const Accumulator< A<point2d> >& acc) + Accumulator<A>& acc) { const I& ima = exact(input); + A& accu = exact (acc); mln_piter(I) p(ima.domain()); for_all(p) - acc.take(p); + accu.take (mln::make::pix(ima, p)); } - } // impl namespace internal { template <typename I, typename A> void - leveling_dispatch(const Image<I>& input, - const Accumulator<A>& acc) + leveling_dispatch(metal::false_, + const Image<I>& input, + Accumulator<A>& acc) { + impl::leveling(input, acc); + } - //Si when_pix = use_only - // - - algebraic_dispatch(mlc_equal(mln_trait_image_speed(I), - trait::image::speed::fastest)::value, - input, - acc); + template <typename I, typename A> + inline + void + leveling_dispatch(metal::true_, + const Image<I>& input, + Accumulator<A>& acc) + { + impl::leveling_fast(input, acc); } + template <typename I, typename A> + inline + void + leveling_dispatch(const Image<I>& input, + Accumulator<A>& acc) + { + enum { + test = (mlc_equal(mln_trait_image_speed(I), + trait::image::speed::fastest)::value && + mlc_equal(mln_trait_accu_when_pix(A), + trait::accu::when_pix::use_v)::value) + }; + leveling_dispatch(metal::bool_<test>(), input, acc); } + } // internal + +} //mln + // Facade. -template <typename M, typename I> +template <typename I, typename A> void -algebraic(const Image<I>& input, const Meta_Accumulator<M>& acc) // FIXME: on préfère Meta_Accumulator ! +leveling(const Image<I>& input, + Accumulator<A>& acc) { - internal::algebraic_dispatch(input, acc); + mln::internal::leveling_dispatch(input, acc); } + + +# include <mln/accu/all.hh> +# include <mln/core/image/image2d.hh> + +# include <mln/debug/iota.hh> +# include <mln/debug/println.hh> +# include <mln/core/var.hh> +# include <mln/util/timer.hh> +int main() +{ + using namespace mln; + typedef image2d<int> I; + + I ima(1000, 1000); + mln::morpho::accu::card<util::pix<I> > acc; + + float elapsed; + mln::util::timer chrono; + + debug::iota(ima); + std::cout << "50 mean of a 1000x1000 image2d<int>" << std::endl; + + acc.init(); + chrono.start(); + for (int i = 0; i < 50; i++) + leveling(ima, acc); + elapsed = chrono.stop(); + + std::cout << "(auto) " << elapsed << "s : " << acc.to_result() << std::endl; + + acc.init(); + chrono.start(); + for (int i = 0; i < 50; i++) + mln::impl::leveling(ima, acc); + elapsed = chrono.stop(); + + std::cout << "(generic) " << elapsed << "s : " << acc.to_result() << std::endl; + + acc.init(); + chrono.start(); + for (int i = 0; i < 50; i++) + mln::impl::leveling_fast(ima, acc); + elapsed = chrono.stop(); + + std::cout << "(fast) " << elapsed << "s : " << acc.to_result() << std::endl; +} + Index: trunk/milena/sandbox/edwin/accu_trait.hh =================================================================== --- trunk/milena/sandbox/edwin/accu_trait.hh (revision 0) +++ trunk/milena/sandbox/edwin/accu_trait.hh (revision 3284) @@ -0,0 +1,51 @@ +#ifndef ACCU_TRAIT_HH_ +# define ACCU_TRAIT_HH_ + +# include <mln/trait/undef.hh> + + +# define mln_trait_accu_when_pix(A) typename trait::accu::accu_traits<A>::when_pix + + +namespace mln +{ + namespace morpho { + namespace accu + { + template <typename T> + struct card; + } + } + + namespace trait + { + namespace accu + { + + struct when_pix + { + struct use_v {}; + struct use_p {}; + struct use_pix {}; + struct use_whatever {}; + struct not_ok {}; + }; + + template <typename A> + struct accu_traits + { + typedef undef when_pix; + }; + + template <> + template <typename T> + struct accu_traits< mln::morpho::accu::card <T> > + { + typedef when_pix::use_v when_pix; + }; + } //accu + + }//trait + +} //mln +#endif /* !ACCU_TRAIT_HH_ */
15 years, 10 months
1
0
0
0
3283: Clean up ChangeLogs.
by Roland Levillain
--- ChangeLog | 12 +-- milena/ChangeLog | 242 +++++++++++++++++++++++----------------------- milena/sandbox/ChangeLog | 67 +++++++------ 3 files changed, 159 insertions(+), 162 deletions(-) diff --git a/ChangeLog b/ChangeLog index 90a0af3..d4c4716 100644 --- a/ChangeLog +++ b/ChangeLog @@ -22,16 +22,6 @@ * m4/.gitignore: New. * build-aux/.gitignore: Adjust. -2009-02-04 Frederic Bour <bour(a)lrde.epita.fr> - - [sandbox][bour] Backup of accuprops.cc. - * milena/sandbox/fred/accuprops2.cc: New. - -2009-02-04 Frederic Bour <bour(a)lrde.epita.fr> - - [sandbox][fred] Mean morphological accumulator working with. - * milena/sandbox/fred/accuprops.cc: New. - 2009-02-03 Roland Levillain <roland(a)lrde.epita.fr> Typo: s/splitted/split/. @@ -170,7 +160,7 @@ * configure.ac: Update. 2008-12-16 Guillaume Lazzara <z(a)lrde.epita.fr> - + Make use of milena/generate_dist_headers.sh. * bootstrap: update here. diff --git a/milena/ChangeLog b/milena/ChangeLog index 2818ee1..1599b96 100644 --- a/milena/ChangeLog +++ b/milena/ChangeLog @@ -114,7 +114,7 @@ * tests/unit_test/mln_io_raw_load.cc, * tests/unit_test/mln_io_raw_save.cc, * tests/io/raw/raw.cc, - * tests/io/raw/Makefile.am, + * tests/io/raw/Makefile.am, * tests/io/raw/pbm.cc, * mln/io/raw/all.hh, * mln/io/raw/load.hh, @@ -156,7 +156,7 @@ * mln/trace/exiting.hh, * mln/transform/internal/closest_point_functor.hh: add missing includes. - + * mln/debug/slices_2d.hh: remove an unused variable. 2009-02-03 Guillaume Lazzara <z(a)lrde.epita.fr> @@ -186,7 +186,7 @@ * doc/tutorial/tutorial.tex: include the right files. 2009-02-02 Guillaume Lazzara <z(a)lrde.epita.fr> - + Introduce subject_point_impl. * mln/core/point.hh: All Point proxies will inherit from that class @@ -207,7 +207,7 @@ * mln/core/internal/graph_psite_base.hh: remove a useless forward declaration. - + * mln/io/raw/all.hh: Rewrite, completely wrong... * mln/accu/compute.hh, @@ -256,7 +256,7 @@ * mln/transform/internal/closest_point_functor.hh: New. Construct an image of closest point. - + * tests/unit_test/Makefile.am, * tests/unit_test/mln_transform_internal_closest_point_functor.cc: add new unit test. @@ -341,7 +341,7 @@ 2009-02-02 Thierry Geraud <thierry.geraud(a)lrde.epita.fr> Activate fastest version of algebraic union-find. - + * mln/morpho/closing_attribute.hh (closing_attribute_dispatch): Activate for fastest images. * mln/canvas/morpho/algebraic_union_find.hh: Likewise. @@ -579,7 +579,7 @@ * Makefile.am: fix list of distributed images. * doc/tutorial/Makefile.am: include new mk files. - + * doc/tutorial/generate_dist_files.sh: new script to generate the following list of files. @@ -623,7 +623,7 @@ * doc/tutorial/figures/tuto4_genericity_and_algorithms-7.pgm, * doc/tutorial/figures/tuto4_genericity_and_algorithms-8.ppm, * doc/tutorial/figures/tuto4_genericity_and_algorithms-9.ppm: update. - + * doc/tutorial/figures/tuto4_genericity_and_algorithms-10.ppm: delete, not needed anymore. @@ -738,7 +738,7 @@ 2009-01-21 Thierry GERAUD <thierry.geraud(a)lrde.epita.fr> Add some images. - + * img/space_debris.pgm: Remove; unused. * img/small.ppm: Fix file format. * img/fly.ppm, @@ -759,7 +759,7 @@ * headers.mk: remove to_rgb.hh from distribution. * mln/convert/all.hh: remove to_rgb.hh. - + * mln/convert/from_to.hxx: add more predeclarations. * mln/convert/impl/from_value_to_value.hh: if no value concept is @@ -881,7 +881,7 @@ Add implementation of Fibonacci heap. * headers.mk: add a new header to distribution. - + * mln/util/fibonacci_heap.hh: new file. The implementation. * tests/unit_test/Makefile.am, @@ -1038,7 +1038,7 @@ 2009-01-09 Guillaume Lazzara <z(a)lrde.epita.fr> Remove a useless test in level/median. - + * tests/level/Makefile.am, * tests/level/median_.cc: remove this test. It is already tested by level/median/approx/median.cc. @@ -1055,9 +1055,9 @@ * mln/core/dpsites_piter.hh, * mln/core/neighb.hh, * mln/win/multiple_size.hh: remove empty implementation of center_at_(). - + * mln/core/image/complex_neighborhood_piter.hh: add a new line. - + * mln/core/internal/site_relative_iterator_base.hh: add default implementation of center_at_(). @@ -1130,7 +1130,7 @@ * mln/fun/meta/blue.hh, * mln/fun/meta/green.hh: Add new meta functions to use with fun_image. - + * headers.mk: Add new headers to distribution. * tests/unit_test/Makefile.am, @@ -1416,8 +1416,8 @@ * doc/tutorial/outputs/ima2d-3.txt, * doc/tutorial/samples/ima2d-3.cc, * doc/tutorial/tutorial.tex: use opt::at(ima,...) instead of ima.at() - - * doc/tutorial/outputs/ima2d-3-output.txt: remove useless file. + + * doc/tutorial/outputs/ima2d-3-output.txt: remove useless file. 2008-12-31 Guillaume Lazzara <z(a)lrde.epita.fr> @@ -1628,7 +1628,7 @@ * mln/core/image/complex_image.hh: update comments. * mln/core/image/complex_neighborhood_piter.hh: avoid a warning. - + * mln/core/internal/site_relative_iterator_base.hh: call center_at_() earlier. @@ -1735,7 +1735,7 @@ Various small fixes. - * mln/accu/count_adjacent_vertices.hh: add missing is_valid(). + * mln/accu/count_adjacent_vertices.hh: add missing is_valid(). * mln/canvas/labeling.hh: cleanup. @@ -1782,7 +1782,7 @@ * tests/unit_test/Makefile.am, * tests/unit_test/mln_geom_resize.cc: update unit tests. - * mln/accu/count_adjacent_vertices.hh: add missing is_valid(). + * mln/accu/count_adjacent_vertices.hh: add missing is_valid(). 2008-12-31 Guillaume Lazzara <z(a)lrde.epita.fr> @@ -1853,7 +1853,7 @@ 2008-12-30 Guillaume Lazzara <z(a)lrde.epita.fr> Add a call to center_at_() in - site_relative_iterator_base::center_at() (ticket #176). + site_relative_iterator_base::center_at() (ticket #176). * mln/core/dpsites_piter.hh, * mln/core/image/complex_neighborhood_piter.hh, @@ -1865,7 +1865,7 @@ 2008-12-30 Guillaume Lazzara <z(a)lrde.epita.fr> - Fix from_to dispatch. + Fix from_to dispatch. * mln/convert/from_to.hh: dispatch functions where not called at all. @@ -2590,7 +2590,7 @@ * trash/display_color_pretty.cc, * doc/benchmark/canvas.cc, * doc/examples/erosion.cc: fix doxygen warnings. - + * doc/tutorial/samples/Makefile.am: do not install sample programs. * mln/fun/l2l/relabel.hh: fix wrong guards. @@ -2878,7 +2878,7 @@ Add missing concept for bijective functions. - * mln/core/concept/function.hh: + * mln/core/concept/function.hh: Add Function_v2w2v and Function_v2w_w2v. 2008-12-15 Alexandre Abraham <abraham(a)lrde.epita.fr> @@ -2911,10 +2911,10 @@ since they are not update with the new property names. * milena/mln/core/image/bgraph_psite.hh: fix wrong include. - - * milena/mln/core/image/fi_adaptor.hh, - * milena/mln/core/image/graph_image.hh, - * milena/mln/core/image/line_graph_image.hh: move to... + + * milena/mln/core/image/fi_adaptor.hh, + * milena/mln/core/image/graph_image.hh, + * milena/mln/core/image/line_graph_image.hh: move to... * milena/trash/fi_adaptor.hh, * milena/trash/graph_image.hh, @@ -2989,7 +2989,7 @@ * tests/core/image/graph_image.cc, * tests/core/image/line_graph_image.cc: use id() instead of - element().id(). + element().id(). 2008-12-12 Guillaume Lazzara <z(a)lrde.epita.fr> @@ -3054,7 +3054,7 @@ * mln/core/image/hexa_piter.hh: update attribute name. * mln/core/internal/piter_adaptor.hh: update change_target(); - + * mln/debug/iota.spe.hh: cleanup. * mln/debug/println.spe.hh: remove wrong ifndef. @@ -3070,7 +3070,7 @@ * mln/morpho/line_gradient.hh: update with the new graph structure. * mln/subsampling/gaussian_subsampling.hh: add missing coma. - + * mln/topo/face_iter.hh, * mln/topo/internal/complex_set_iterator_base.hh, * mln/topo/internal/complex_relative_iterator_base.hh, @@ -4190,7 +4190,7 @@ Fix various tests. * headers.mk: Update distributed headers list. - + * mln/make/image.hh, * mln/make/image2d.hh, * mln/fun/v2v/convert.hh, @@ -4247,7 +4247,7 @@ * doc/tutorial/samples/fill-subimage-cfun.cc * doc/tutorial/samples/labeling-compute.cc: rename label8 to label_8 and label16 to label_16. - + * doc/tutorial/tutorial.tex: fix wrong include. * mln/core/site_set/p_graph_piter.hh: add a conversion toward the @@ -4272,7 +4272,7 @@ 2008-12-08 Guillaume Lazzara <z(a)lrde.epita.fr> - Fix build system. + Fix build system. * Makefile.am: Split and move data related to headers distribution... * headers.mk: here. @@ -4351,7 +4351,7 @@ Update unit tests. * milena/tests/unit_test/Makefile.am: Update. - + * milena/tests/unit_test/mln_convert_to_tiles.cc, * milena/tests/unit_test/mln_core_image_graph_neighborhood_piter.cc, * milena/tests/unit_test/mln_core_image_line_graph_elt_piter.cc, @@ -4656,7 +4656,7 @@ * mln/util/line_graph.hh: add graph(). - * doc/tutorial/outputs/labeling-compute-1, + * doc/tutorial/outputs/labeling-compute-1, * doc/tutorial/outputs/labeling-compute.txt: update reference output files for tutorial. @@ -4854,7 +4854,7 @@ * mln/util/internal/graph_vertex_impl.hh: rename as... * mln/util/internal/vertex_impl.hh: ... this. - + * tests/morpho/Makefile.am: disable more tests. * tests/unit_test/build_unit_test.sh: do not include mln/core/doc @@ -4933,7 +4933,7 @@ * tests/core/image/Makefile.am, * tests/convert/Makefile.am, * tests/Makefile.am: comment known non working tests. - + * tests/core/image/flat_image.cc, * tests/convert/to_p_array.cc: write test. @@ -4955,7 +4955,7 @@ * doc/examples/tuto_bis.cc (fill, gradient, dilation): Remove dedicated code; instead use - library routines. Their proper arg is nbh.win(). + library routines. Their proper arg is nbh.win(). (ima): Ensure there is no outer border. (include): Update. * mln/core/image/extended.hh: Upgrade doc style. @@ -5021,7 +5021,7 @@ * img/fly.pgm: New. 2008-11-27 Guillaume Lazzara <z(a)lrde.epita.fr> - + Add new examples. * doc/examples/erosion.cc: Apply a vertical and a horizontal erosion @@ -5040,7 +5040,7 @@ * mln/debug/colorize.hh: Pass the color type as arguments instead of passing the return type as template parameter. - + * mln/debug/draw_graph.hh: add a new signature. * mln/literal/colors.hh, @@ -5077,12 +5077,12 @@ Upgrade tutorial. * Doxyfile.in: add new path to included files. - + * tutorial/Makefile.am, * Makefile.am: update target dependencies. - + * doc.mk: add new global variables. - + * tutorial/figures/fill-subdomain-1.pbm, * tutorial/figures/fill-subdomain-2.ppm, * tutorial/figures/fill-subdomain-3.ppm, @@ -5258,7 +5258,7 @@ (zfind_root): Move from impl::generic to internal. 2008-11-27 Guillaume Lazzara <z(a)lrde.epita.fr> - + Add a missing Makefile.am * milena/tests/morpho/elementary/Makefile.am: new. @@ -5332,7 +5332,7 @@ * doc/tutorial/samples/ima2d-decl-2-blobs.cc, * doc/tutorial/samples/labeling-compute-full.cc: Use label8 instead of int_u8. - + * doc/tutorial/samples/graph-data-full.cc: Add new example. 2008-11-25 Thierry Geraud <thierry.geraud(a)lrde.epita.fr> @@ -5434,7 +5434,7 @@ * mln/morpho/tree/compute_parent.hh: New; revamp of... * sandbox/geraud/max_tree_nnodes.cc: ...this file. * tests/morpho/tree: New directory. - * tests/morpho/tree/compute_parent.cc: + * tests/morpho/tree/compute_parent.cc: * tests/morpho/tree/Makefile.am: New. * tests/morpho/Makefile.am: Update. * mln/canvas/morpho/all.hh: Upgrade doc style. @@ -5565,7 +5565,7 @@ 2008-11-20 Guillaume Lazzara <z(a)lrde.epita.fr> - + Add labeling::relabel. * mln/core/concept/function.hh: add Function_l2b and Function_l2l. @@ -5654,7 +5654,7 @@ * mln/fun/i2v/array.hh: add two from_to; - from_to(util::array, fun::i2v::array) - from_to(std::vector, fun::i2v::array) - + * mln/convert/to.hh, * doc/examples/labeling_algo.cc: cleanup. @@ -6074,7 +6074,7 @@ into... (erosion_dispatch_line): ...this new overloaded routine. (erosion_dispatch_diagonal): Remove check on kind::logic cause it - also works on this case. + also works on this case. To be consistent: * mln/accu/snake_2d.hh: Rename as... @@ -6149,7 +6149,7 @@ * tests/core/image/graph_image.cc, * tests/core/image/line_graph_image.cc: fix tests. - * mln/make/all.hh + * mln/make/all.hh * mln/make/essential.hh: uncomment inclusion of voronoi.hh. 2008-11-14 Thierry Geraud <thierry.geraud(a)lrde.epita.fr> @@ -6321,7 +6321,7 @@ * mln/arith/revert.spe.hh, * mln/arith/times.hh, * mln/arith/times.spe.hh: Cleanup comments. - + * mln/morpho/hit_or_miss.hh, * mln/display/save.hh, * mln/canvas/browsing/backdiagonal2d.hh, @@ -6373,7 +6373,7 @@ * tests/border/get.cc, * tests/border/resize_image_if.cc: Fix tests. - + 2008-11-13 Thierry Geraud <thierry.geraud(a)lrde.epita.fr> Specialize accu tranform for fastest images. @@ -7005,14 +7005,14 @@ Update use of level::transform(). - * mln/binarization/binarization.hh, - * mln/level/abs.hh, - * mln/level/saturate.hh, - * mln/level/to_enc.hh, - * tests/io/pgm/pgm16.cc, - * tests/io/pgm/pgm19.cc, - * tests/io/pgm/pgm27.cc, - * tests/value/float01.cc: Update here. + * mln/binarization/binarization.hh, + * mln/level/abs.hh, + * mln/level/saturate.hh, + * mln/level/to_enc.hh, + * tests/io/pgm/pgm16.cc, + * tests/io/pgm/pgm19.cc, + * tests/io/pgm/pgm27.cc, + * tests/value/float01.cc: Update here. * mln/level/transform.hh: Remove useless prototype. @@ -8107,7 +8107,7 @@ * doc/tutorial/samples/mln_var-3.tex: New. Add sample code. - * doc/tutorial/tutorial.tex: rewrite graph section. + * doc/tutorial/tutorial.tex: rewrite graph section. 2008-11-04 Guillaume Lazzara <z(a)lrde.epita.fr> @@ -8116,7 +8116,7 @@ * mln/debug/graph.hh: update in order to support p_vertices. * tests/core/image/graph_image.cc: Add assertions. - + * tests/core/site_set/p_vertices.cc: use fun::i2v::array. 2008-11-04 Guillaume Lazzara <z(a)lrde.epita.fr> @@ -8160,7 +8160,7 @@ * milena/tests/core/other/box_runstart_piter.cc: remove make:: prefix. - + * milena/tests/core/other/point_set_compatibility.cc: update test according last changes in p_vertices. @@ -8356,7 +8356,7 @@ * mln/io/ppm/save.hh: Update copyright. * mln/io/txt/save.hh: save an image<char> to a txt file. - + * mln/io/off/all.hh, * mln/io/txt/all.hh: new missing 'all' headers. @@ -8375,7 +8375,7 @@ * mln/logical/not.spe.hh: Write a dedicated version of not_inplace. 2008-11-03 Guillaume Lazzara <z(a)lrde.epita.fr> - + Add trace::warning. * mln/trace/warning.hh: new file. @@ -8384,7 +8384,7 @@ * mln/trace/resume.hh, * mln/trace/stop.hh: cleanup includes. - + * mln/debug/put_word.hh: use trace::warning. @@ -8873,7 +8873,7 @@ Fix return type of i2v::array::operator(). - * mln/fun/i2v/array.hh (operator() const): Return a reference instead of a copy. + * mln/fun/i2v/array.hh (operator() const): Return a reference instead of a copy. 2008-10-27 Guillaume Lazzara <z(a)lrde.epita.fr> @@ -9326,7 +9326,7 @@ Fix namespace path to update_tests(). - * mln/level/update.hh: specify full namespace path to update_tests(). + * mln/level/update.hh: specify full namespace path to update_tests(). 2008-10-22 Roland Levillain <roland(a)lrde.epita.fr> @@ -9744,11 +9744,11 @@ Add neighborhoods based on lower/higher-dimension connected n-faces. * mln/core/image/complex_neighborhoods.hh - (mln::complex_lower_dim_connected_n_face_neighborhood<D, G>): + (mln::complex_lower_dim_connected_n_face_neighborhood<D, G>): (mln::complex_higher_dim_connected_n_face_neighborhood<D, G>): New neighborhoods. Exercise them... - * tests/core/image/complex_image.cc: ...here. + * tests/core/image/complex_image.cc: ...here. 2008-10-18 Roland Levillain <roland(a)lrde.epita.fr> @@ -9856,7 +9856,7 @@ * mln/core/image/complex_neighborhoods.hh: New. Replace... * mln/core/image/complex_lower_neighborhood.hh, - * mln/core/image/complex_higher_neighborhood.hh, + * mln/core/image/complex_higher_neighborhood.hh, * mln/core/image/complex_lower_higher_neighborhood.hh: ...these files. Remove. @@ -9869,7 +9869,7 @@ * mln/core/image/complex_windows.hh: New. Replace... * mln/core/image/complex_lower_window_p.hh, - * mln/core/image/complex_higher_window_p.hh, + * mln/core/image/complex_higher_window_p.hh, * mln/core/image/complex_lower_higher_window_p.hh: ...these files. Remove. @@ -9882,7 +9882,7 @@ Factor concrete windows of complex image. * mln/core/image/complex_lower_window_p.hh, - * mln/core/image/complex_higher_window_p.hh, + * mln/core/image/complex_higher_window_p.hh, * mln/core/image/complex_lower_higher_window_p.hh: Factor using mln::internal::complex_window_p_base. @@ -9897,7 +9897,7 @@ Factor concrete neighborhoods of complex image. * mln/core/image/complex_lower_neighborhood.hh, - * mln/core/image/complex_higher_neighborhood.hh, + * mln/core/image/complex_higher_neighborhood.hh, * mln/core/image/complex_lower_higher_neighborhood.hh: Factor using mln::internal::complex_neighborhood_base. @@ -10046,10 +10046,10 @@ (mln::topo::edge(const n_face<0, D>&, const n_face<0, D>&)): New function. * mln/topo/face_data.hh - (mln::topo::internal::lower_dim_faces_data_mixin): Make + (mln::topo::internal::lower_dim_faces_data_mixin): Make mln::topo::n_face<N, D>::lower_dim_adj_faces a friend of this class. - (mln::topo::internal::higher_dim_faces_data_mixin): Make + (mln::topo::internal::higher_dim_faces_data_mixin): Make mln::topo::n_face<N, D>::higher_dim_adj_faces a friend of this class. @@ -10348,29 +10348,29 @@ Add is_valid() in the accumulator concept and move meta-accumulators in meta namespace. - - * mln/accu/count.hh, - * mln/accu/height.hh, - * mln/accu/histo.hh, - * mln/accu/max.hh, - * mln/accu/max_h.hh, - * mln/accu/mean.hh, - * mln/accu/median_alt.hh, - * mln/accu/min.hh, - * mln/accu/min_h.hh, - * mln/accu/nil.hh, - * mln/accu/p.hh, - * mln/accu/pair.hh, - * mln/accu/rank.hh, - * mln/accu/rank_bool.hh, - * mln/accu/rank_high_quant.hh, - * mln/accu/sum.hh, - * mln/accu/tuple.hh, - * mln/accu/v.hh, - * mln/accu/volume.hh: + + * mln/accu/count.hh, + * mln/accu/height.hh, + * mln/accu/histo.hh, + * mln/accu/max.hh, + * mln/accu/max_h.hh, + * mln/accu/mean.hh, + * mln/accu/median_alt.hh, + * mln/accu/min.hh, + * mln/accu/min_h.hh, + * mln/accu/nil.hh, + * mln/accu/p.hh, + * mln/accu/pair.hh, + * mln/accu/rank.hh, + * mln/accu/rank_bool.hh, + * mln/accu/rank_high_quant.hh, + * mln/accu/sum.hh, + * mln/accu/tuple.hh, + * mln/accu/v.hh, + * mln/accu/volume.hh: Add is_valid() and move meta-accumulators in meta namespace if needed. - * mln/core/concept/accumulator.hh: + * mln/core/concept/accumulator.hh: Add is_valid() static test. * tests/accu/all_accus.cc, @@ -10579,7 +10579,7 @@ * tests/timer.hh: New. Tool to bench tests. 2008-10-07 Guillaume Lazzara <z(a)lrde.epita.fr> - + Fix most of the doxygen warnings. * mln/arith/min.hh, @@ -10954,17 +10954,17 @@ Various small fixes. * mln/algebra/vec.hh: add missing header. - + * mln/core/image/obased_rle_image.hh, * mln/core/image/rle_image.hh: Use pruns. - + * mln/core/image/obased_rle_image.hh, * mln/core/image/t_image.hh: add missing init_ function. - + * mln/core/image/tr_image.hh, * tests/core/alias/point1d.cc, * tests/core/alias/point2d.cc: cleanup. - + * tests/core/image/Makefile.am: Disable known broken test such as graph related tests. @@ -11106,12 +11106,12 @@ 2008-10-03 Guillaume Lazzara <z(a)lrde.epita.fr> - Add p_edges. - - * mln/core/site_set/p_edges.hh: - The site set p_edges. + Add p_edges. + + * mln/core/site_set/p_edges.hh: + The site set p_edges. - * mln/util/internal/graph_edge_psite.hh: + * mln/util/internal/graph_edge_psite.hh: The associated psite. * tests/core/site_set/Makefile.am, @@ -11119,28 +11119,28 @@ Add a basic test. 2008-10-03 Guillaume Lazzara <z(a)lrde.epita.fr> - + Refactor graph_vertex_psite. * mln/util/internal/graph_vertex_psite.hh: Refactor this class... - * mln/util/internal/graph_psite_base.hh: - ... here. + * mln/util/internal/graph_psite_base.hh: + ... here. 2008-10-03 Guillaume Lazzara <z(a)lrde.epita.fr> - Fix util::graph<G>::is_subgraph_of(). + Fix util::graph<G>::is_subgraph_of(). - * mln/util/graph.hh: here. + * mln/util/graph.hh: here. 2008-10-03 Guillaume Lazzara <z(a)lrde.epita.fr> Add missing methods to vertex and edge. - * mln/util/internal/graph_edge.hh: - Add change_graph(). - * mln/util/internal/graph_vertex.hh: - Add invalidate(). + * mln/util/internal/graph_edge.hh: + Add change_graph(). + * mln/util/internal/graph_vertex.hh: + Add invalidate(). 2008-10-03 Guillaume Lazzara <z(a)lrde.epita.fr> @@ -11149,10 +11149,10 @@ * mln/core/site_set/p_vertices.hh: The site set p_vertices. - + * mln/util/internal/graph_vertex_psite.hh: The psite associated to p_vertices. - + * tests/core/site_set/p_vertices.cc, * tests/core/site_set/Makefile.am: Add a small test. @@ -11170,7 +11170,7 @@ * mln/util/internal/graph_vertex.hh: Remove useless const and a wrong precondition. - + 2008-10-03 Guillaume Lazzara <z(a)lrde.epita.fr> Fix missing methods in graph_base. @@ -11182,7 +11182,7 @@ Update p_graph_piter. - * mln/core/site_set/p_graph_piter.hh: + * mln/core/site_set/p_graph_piter.hh: update in order to make it work with the new graph structure. 2008-10-02 Ugo Jardonnet <ugo.jardonnet(a)lrde.epita.fr> diff --git a/milena/sandbox/ChangeLog b/milena/sandbox/ChangeLog index be9d267..b05c6f3 100644 --- a/milena/sandbox/ChangeLog +++ b/milena/sandbox/ChangeLog @@ -1,8 +1,17 @@ 2009-02-04 Fabien Freling <freling(a)lrde.epita.fr> Add my own sandbox directory to modify labeling.hh. - * .: New. - * labeling.hh: New. + * fabien/labeling.hh: New. + +2009-02-04 Frederic Bour <bour(a)lrde.epita.fr> + + Backup of accuprops.cc. + * fred/accuprops2.cc: New. + +2009-02-04 Frederic Bour <bour(a)lrde.epita.fr> + + Mean morphological accumulator working with. + * fred/accuprops.cc: New. 2009-02-03 Thierry Geraud <thierry.geraud(a)lrde.epita.fr> @@ -15,16 +24,16 @@ 2009-02-03 Edwin Carlinet <carlinet(a)lrde.epita.fr> First tries of accus with specialisation. - * accu.cc: New. - * fredwin.cc: . + * edwin/accu.cc: New. + * edwin/fredwin.cc: . 2009-02-03 Guillaume Lazzara <z(a)lrde.epita.fr> Rename io::raw as io::dump in sandbox. - * sandbox/theo/igr/irm_anat_segm.cc, - * sandbox/theo/igr/pgms2raw.cc, - * sandbox/theo/igr/raw2pgm.cc: rename here. + * theo/igr/irm_anat_segm.cc, + * theo/igr/pgms2raw.cc, + * theo/igr/raw2pgm.cc: rename here. 2009-02-03 Guillaume Lazzara <z(a)lrde.epita.fr> @@ -43,20 +52,18 @@ 2009-02-02 Edwin Carlinet <carlinet(a)lrde.epita.fr> Add dispatch functions for accumulator. - * .: New. * fredwin.cc: New. 2009-02-02 Frederic Bour <bour(a)lrde.epita.fr> - [sandbox] p2p morpher with translation, composition and flip. - * .: New. - * p2p/Makefile: New. - * p2p/compose_p2p.hh: New. - * p2p/p2p_morpher.hh: New. - * p2p/symmetry_p2p.hh: New. - * p2p/test_morph_image.cc: New. - * p2p/translate_p2p.hh: New. - * p2p: New. + p2p morpher with translation, composition and flip. + * fred/p2p/Makefile: New. + * fred/p2p/compose_p2p.hh: New. + * fred/p2p/p2p_morpher.hh: New. + * fred/p2p/symmetry_p2p.hh: New. + * fred/p2p/test_morph_image.cc: New. + * fred/p2p/translate_p2p.hh: New. + * fred/p2p: New. 2009-02-02 Thierry Geraud <thierry.geraud(a)lrde.epita.fr> @@ -211,7 +218,7 @@ 2009-01-21 Guillaume Lazzara <z(a)lrde.epita.fr> Add a new LCA implementation to Laurent's code. - + * laurent/ismm2009.cc: Use the implementation written by Alexandre Abraham for one of its previous seminar (#0821). @@ -293,7 +300,7 @@ Work on reconstruction. * garrigues/union_find/canvas/reconstruction_on_function.hh: Remove - useless escape value. + useless escape value. * garrigues/union_find/canvas/reconstruction_on_set.hh: Optimizations. * garrigues/union_find/canvas/self_dual_reconstruction.hh: . * garrigues/union_find/images/marker_to_dilate.pbm: Fix it. @@ -1791,13 +1798,13 @@ Examples : ( | == object, - = background) - - - | - | P | Here P is simple in the c4 and c8 case. - | | | + - - | + | P | Here P is simple in the c4 and c8 case. + | | | - - | - - | P | Here P is never simple. - | | | + - | - + | P | Here P is never simple. + | | | * garrigues/ocr/simple_point.cc: New. A simple test that shows all the simple points of a binary image. @@ -1961,7 +1968,7 @@ * abraham/mln/core/image/shell.hh: Fix result value. * abraham/mln/core/concept/meta_fun.hh: (mln::meta::impl) : now templated by return type - (necessary to typedef result). + (necessary to typedef result). * abraham/mln/fun/meta/red.hh: . 2008-10-27 Ugo Jardonnet <ugo.jardonnet(a)lrde.epita.fr> @@ -2085,7 +2092,7 @@ Fix an endless loop. - * scribo/demat.hh: Fix a endless loop. + * scribo/demat.hh: Fix a endless loop. 2008-10-22 Maxime van Noppen <yabo(a)lrde.epita.fr> @@ -2105,7 +2112,7 @@ Improve debug output. - * scribo/demat.hh: + * scribo/demat.hh: Use color images for debug output. Improve the way the small components are erased. @@ -2152,7 +2159,7 @@ Extract text bboxes for Scribo. * scribo/main.cc: Change usage message. - + * scribo/demat.hh: - Cleanup. - Remove too small components using level::transform. @@ -2187,7 +2194,7 @@ Get and display character bboxes. - * sandbox/scribo/demat.hh: update. + * sandbox/scribo/demat.hh: update. Does not create text bboxes yet. 2008-10-15 Guillaume Lazzara <z(a)lrde.epita.fr> -- 1.5.6.5
15 years, 10 months
1
0
0
0
r3280: Add my own sandbox directory to modify labeling.hh
by Fabien Freling
URL:
https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox
ChangeLog: 2009-02-04 Fabien Freling <freling(a)lrde.epita.fr> Add my own sandbox directory to modify labeling.hh. * .: New. * labeling.hh: New. --- labeling.hh | 387 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 387 insertions(+) Index: trunk/milena/sandbox/fabien/labeling.hh =================================================================== --- trunk/milena/sandbox/fabien/labeling.hh (revision 0) +++ trunk/milena/sandbox/fabien/labeling.hh (revision 3280) @@ -0,0 +1,387 @@ +// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory +// (LRDE) +// +// This file is part of the Olena Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License version 2 as published by the +// Free Software Foundation. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, +// Boston, MA 02111-1307, USA. +// +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +#ifndef MLN_CANVAS_LABELING_HH +# define MLN_CANVAS_LABELING_HH + +/// \file mln/canvas/labeling.hh +/// +/// Connected component labeling of the object part in a binary image. +/// +/// \todo Make the fastest version work. + +# include <mln/core/concept/image.hh> +# include <mln/data/fill.hh> +# include <mln/literal/zero.hh> +# include <mln/convert/to_upper_window.hh> + + +namespace mln +{ + + namespace canvas + { + + // General version. + template <typename I, typename N, typename F, typename L> + mln_ch_value(I, L) + labeling(const Image<I>& input, const Neighborhood<N>& nbh, + F& functor, L& nlabels); + + +# ifndef MLN_INCLUDE_ONLY + + // Tests. + + namespace internal + { + + template <typename I, typename N, typename F, typename L> + void + labeling_tests(const Image<I>& input_, const Neighborhood<N>& nbh_, + const F& f, const L& nlabels) + { + const I& input = exact(input_); + const N& nbh = exact(nbh_); + + mln_precondition(input.is_valid()); + // mln_precondition(nbh.is_valid()); + + (void) input; + (void) nbh; + (void) f; + (void) nlabels; + } + + } // end of namespace mln::canvas::internal + + + + // Implementations. + + namespace impl + { + + namespace generic + { + + template <typename I> + static inline + mln_psite(I) + find_root(I& parent, const mln_psite(I)& x) + { + if (parent(x) == x) + return x; + else + return parent(x) = find_root(parent, parent(x)); + } + + template <typename I, typename N, typename F, typename L> + mln_ch_value(I, L) + labeling(const Image<I>& input_, const Neighborhood<N>& nbh_, + F& f, L& nlabels) + { + trace::entering("canvas::impl::generic::labeling"); + + // FIXME: Test?! + + const I& input = exact(input_); + const N& nbh = exact(nbh_); + + typedef typename F::S S; + + // Local type. + typedef mln_psite(I) P; + + // Auxiliary data. + mln_ch_value(I, bool) deja_vu; + mln_ch_value(I, P) parent; + + // Output. + mln_ch_value(I, L) output; + bool status; + + // Initialization. + { + initialize(deja_vu, input); + mln::data::fill(deja_vu, false); + + initialize(parent, input); + + initialize(output, input); + mln::data::fill(output, L(literal::zero)); + nlabels = 0; + + f.init(); // Client initialization. + } + + // First Pass. + { + mln_fwd_piter(S) p(f.s); + mln_niter(N) n(nbh, p); + for_all(p) if (f.handles(p)) + { + // Make-Set. + parent(p) = p; + f.init_attr(p); + + for_all(n) + if (input.domain().has(n) && deja_vu(n)) + { + if (f.equiv(n, p)) + { + // Do-Union. + P r = find_root(parent, n); + if (r != p) + { + parent(r) = p; + f.merge_attr(r, p); + } + } + else + f.do_no_union(n, p); + } + deja_vu(p) = true; + } + } + + // Second Pass. + { + mln_bkd_piter(S) p(f.s); + for_all(p) if (f.handles(p)) + { + if (parent(p) == p) // if p is root + { + if (f.labels(p)) + { + if (nlabels == mln_max(L)) + { + status = false; + return output; + } + output(p) = ++nlabels; + } + } + else + output(p) = output(parent(p)); + } + status = true; + } + + trace::exiting("canvas::impl::generic::labeling"); + return output; + } + + } // end of namespace mln::canvas::impl::generic + + + + // Fastest version + + template <typename I> + static inline + unsigned + find_root_fastest(I& parent, unsigned x) + { + if (parent.element(x) == x) + return x; + else + return parent.element(x) = find_root(parent, parent.element(x)); + } + + template <typename I, typename N, typename F, typename L> + mln_ch_value(I, L) + labeling_fastest(const Image<I>& input_, const Neighborhood<N>& nbh_, + F& f, L& nlabels) + { + trace::entering("canvas::impl::labeling"); + + // FIXME: Test?! + + const I& input = exact(input_); + const N& nbh = exact(nbh_); + + typedef typename F::S S; + + // Local type. + typedef mln_psite(I) P; + + // Auxiliary data. + mln_ch_value(I, bool) deja_vu; + mln_ch_value(I, P) parent; + + // Output. + mln_ch_value(I, L) output; + bool status; + + // Initialization. + { + initialize(deja_vu, input); + mln::data::fill(deja_vu, false); + + initialize(parent, input); + + initialize(output, input); + mln::data::fill(output, L(literal::zero)); + nlabels = 0; + + f.init(); // Client initialization. + } + + // First Pass. + { + mln_pixter(const S) p(f.s); + mln_nixter(const S, N) n(p, nbh); + for_all(p) if (f.handles(p)) + { + // Make-Set. + parent.element(p) = p; + f.init_attr(p); + + for_all(n) + if (input.has(n) && deja_vu(n)) + { + if (f.equiv(n, p)) + { + // Do-Union. + P r = find_root(parent, n); + if (r != p) + { + parent.element(r) = p; + f.merge_attr(r, p); + } + } + else + f.do_no_union(n, p); + } + deja_vu(p) = true; + } + } + + // Second Pass. + { + mln_bkd_pixter(S) p(f.s); + for_all(p) if (f.handles(p)) + { + if (parent.element(p) == p) // if p is root + { + if (f.labels(p)) + { + if (nlabels == mln_max(L)) + { + status = false; + return output; + } + output.element(p) = ++nlabels; + } + } + else + output.element(p) = output(parent.element(p)); + } + status = true; + } + + trace::exiting("canvas::impl::labeling"); + return output; + } + + } // end of namespace mln::canvas::impl + + + + // Dispatch. + + namespace internal + { + + template <typename I, typename N, typename F, typename L> + inline + mln_ch_value(I, L) + labeling(metal::false_, const Image<I>& input, + const Neighborhood<N>& nbh, F& functor, L& nlabels) + { + return impl::generic::labeling(input, nbh, functor, nlabels); + } + + template <typename I, typename N, typename F, typename L> + inline + mln_ch_value(I, L) + labeling(metal::true_, const Image<I>& input, + const Neighborhood<N>& nbh, F& functor, L& nlabels) + { + return impl::labeling_fastest(input, nbh, functor, nlabels); + } + + template <typename I, typename N, typename F, typename L> + inline + mln_ch_value(I, L) + labeling_dispatch(const Image<I>& input, const Neighborhood<N>& nbh, + F& functor, L& nlabels) + { + enum { + test = mlc_equal(mln_trait_image_speed(I), + trait::image::speed::fastest)::value + && + mln_is_simple_neighborhood(N)::value + }; + return impl::generic::labeling(metal::bool_<test>(), input, nbh, + functor, nlabels); + } + + } // end of namespace mln::canvas::internal + + + + // Facade. + + template <typename I, typename N, typename F, typename L> + inline + mln_ch_value(I, L) + labeling(const Image<I>& input, const Neighborhood<N>& nbh, + F& functor, L& nlabels) + { + trace::entering("canvas::labeling"); + + internal::labeling_tests(input, nbh, functor, nlabels); + + mln_ch_value(I, L) output; + output = internal::labeling_dispatch(input, nbh, functor, nlabels); + + trace::exiting("canvas::labeling"); + return output; + } + + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::canvas + +} // end of namespace mln + + +#endif // ! MLN_CANVAS_LABELING_HH
15 years, 10 months
2
1
0
0
r3256: First tries of accus with specialisation
by Edwin Carlinet
URL:
https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox
ChangeLog: 2009-02-03 Edwin Carlinet <carlinet(a)lrde.epita.fr> First tries of accus with specialisation. * accu.cc: New. * fredwin.cc: . --- accu.cc | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ fredwin.cc | 96 ++++++++++++++++++++++++++++++++++++------------------------- 2 files changed, 149 insertions(+), 38 deletions(-) Index: trunk/milena/sandbox/edwin/accu.cc =================================================================== --- trunk/milena/sandbox/edwin/accu.cc (revision 0) +++ trunk/milena/sandbox/edwin/accu.cc (revision 3256) @@ -0,0 +1,91 @@ +template <typename E> +struct Accumulator : public object<E> +{ + typedef mln_vtypes(E, take_with) take_with; + + + +}; + +namespace accu +{ + template <typename T> + struct card : public Accumulator< card<T> > + { + void take(const T& elt) { ++c_; } + unsigned c_; + }; +} + + +namespace impl +{ + + template <typename I, template<typename E> class A> + void + algebraic(const Image<I>& input, + const Accumulator< A<point2d> >& acc) + { + const I& ima = exact(input); + + mln_piter(I) p(ima.domain()); + for_all(p) + acc.take(p); + } + + // fast implementation + template <typename I, template<typename E> class A> + void + leveling (const Image<I>& input, + const Accumulator< A< pix<I> > >& acc) + { + const I& ima = exact(input); + + mln_pixter(const I) px(ima); + for_all(px) + acc.take(px); + } + + // generic implementation + template <typename I, template<typename E> class A> + void + leveling (const Image<I>& input, + const Accumulator< A<point2d> >& acc) + { + const I& ima = exact(input); + + mln_piter(I) p(ima.domain()); + for_all(p) + acc.take(p); + } + + +} // impl + +namespace internal +{ + template <typename I, typename A> + void + leveling_dispatch(const Image<I>& input, + const Accumulator<A>& acc) + { + + //Si when_pix = use_only + // + + algebraic_dispatch(mlc_equal(mln_trait_image_speed(I), + trait::image::speed::fastest)::value, + input, + acc); + } + +} + +// Facade. + +template <typename M, typename I> +void +algebraic(const Image<I>& input, const Meta_Accumulator<M>& acc) // FIXME: on préfÚre Meta_Accumulator ! +{ + internal::algebraic_dispatch(input, acc); +} Index: trunk/milena/sandbox/edwin/fredwin.cc =================================================================== --- trunk/milena/sandbox/edwin/fredwin.cc (revision 3255) +++ trunk/milena/sandbox/edwin/fredwin.cc (revision 3256) @@ -1,5 +1,7 @@ +// TODO : ajouter un trait when_pix +// when_pix in {use_p template <typename E> struct Accumulator { @@ -46,15 +48,16 @@ + namespace impl { // Leveling // -------- - template <typename I, typename A> + template <typename I, typename PX> void - leveling(const Image<I>& input, const Accumulator<A>& acc) + leveling_generic(const Image<I>& input, const Accumulator<PX>& acc) { const I& ima = exact(input); // algo en resume : @@ -80,29 +83,15 @@ // spécialisation pour les images fastest - // Algebraic - // --------- - - - template <typename I, typename A> - void - generic_algebraic(const Image<I>& input, const Accumulator<A>& acc) - { - // algo en resume : - mln_piter(I) p(ima.domain()); - for_all(p) - acc.take(p); // psite - } - - template <typename I, typename A> - void - algebraic_fastest(const Image<I>& input, const Accumulator<A>& acc) - { - // algo en resume : - mln_pixter(const I) pxl(input); - for_all(pxl) - acc.take(pxl); - } + // template <typename I, typename A> +// void +// algebraic_fastest(const Image<I>& input, const Accumulator<A>& acc) +// { +// // algo en resume : +// mln_pixter(const I) pxl(input); +// for_all(pxl) +// acc.take(pxl); +// } // FIXME: pb: soit on passe du "site", soit du "pixel"... @@ -123,29 +112,60 @@ // FIXME: On veut qqch qui ressemble à : - template <typename I, typename A> +// template <typename I, typename A> +// void +// generic_algebraic_or_leveling(const Image<I>& input, const Accumulator<A>& acc) +// { +// const I& ima = exact(input); +// // algo en resume : +// mln_piter(I) p(ima.domain()); +// for_all(p) +// acc.take( FIXME ); +// } + +// template <typename I, typename A> +// void +// algebraic_or_leveling_fastest(const Image<I>& input, const Accumulator<A>& acc) +// { +// const I& ima = exact(input); +// // algo en resume : +// mln_pixter(const I) pxl(ima); +// for_all(pxl) +// acc.take( FIXME ); +// } + + + // FIXME: Mais ce n'est peut-être pas possible avec des + // Accumulator... + + // Algebraic + // --------- + + + template <typename I, template<typename E> typename A> void - generic_algebraic_or_leveling(const Image<I>& input, const Accumulator<A>& acc) + algebraic(const Image<I>& input, const Accumulator< A<point2d> >& acc) { + const I& ima = exact(input); + // algo en resume : mln_piter(I) p(ima.domain()); for_all(p) - acc.take( FIXME ); + acc.take(p); // psite } - template <typename I, typename A> + + + template <typename I, template<typename E> typename A> void - algebraic_or_leveling_fastest(const Image<I>& input, const Accumulator<A>& acc) + leveling (const Image<I>& input, const Accumulator< A< pix<I> > >& acc) { - // algo en resume : - mln_pixter(const I) pxl(input); - for_all(pxl) - acc.take( FIXME ); - } - + const I& ima = exact(input); - // FIXME: Mais ce n'est peut-être pas possible avec des - // Accumulator... + mln_pixter(const I) px(ima); + for_all(px) + acc.take(px); + } } // impl
15 years, 10 months
2
1
0
0
Re: [Olena-patches] [Olena] #11: Integrate and use oln.m4 from Olena 0.11
by Olena
#11: Integrate and use oln.m4 from Olena 0.11 ------------------------+--------------------------------------------------- Reporter: levill_r | Owner: levill_r Type: defect | Status: closed Priority: minor | Milestone: Olena 1.1 Component: Olena | Version: 1.0 Resolution: duplicate | Keywords: oln.m4 configure.ac 0.10 ------------------------+--------------------------------------------------- Changes (by levill_r): * status: new => closed * resolution: => duplicate Comment: Merge with #129. -- Ticket URL: <
https://trac.lrde.org/olena/ticket/11#comment:5
> Olena <
http://olena.lrde.epita.fr
> Olena, a generic and efficient C++ image processing library.
15 years, 10 months
1
0
0
0
← Newer
1
...
19
20
21
22
23
24
25
26
27
Older →
Jump to page:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
Results per page:
10
25
50
100
200