milena r3435: Clean and separate connected (leveling/algebraic) filters

URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena ChangeLog: 2009-02-28 Edwin Carlinet <carlinet@lrde.epita.fr> Clean and separate connected (leveling/algebraic) filters. * mln/canvas/morpho/attribute_filter.hh: Move algebraic/leveling facade from attribute filter and change dispatch. * mln/canvas/morpho/connected_filter.hh: Remove. * mln/morpho/algebraic_filter.hh: Facade for algebraic filter. * mln/morpho/closing: New. * mln/morpho/leveling_filter.hh: Facade for leveling filter. * mln/morpho/opening: New. * sandbox/edwin/tree/propagate.hh * sandbox/edwin/tree/tree.cc: Correct some bugs. * tests/canvas/morpho/attribute_filter.cc: Test file for attribute filters. * tests/canvas/morpho/connected_filter.cc: Remove. --- mln/canvas/morpho/attribute_filter.hh | 461 ++++++++++++++++++++++++++++++++ mln/morpho/algebraic_filter.hh | 71 ++++ mln/morpho/leveling_filter.hh | 69 ++++ sandbox/edwin/tree/propagate.hh | 4 sandbox/edwin/tree/tree.cc | 17 - tests/canvas/morpho/attribute_filter.cc | 108 +++++++ 6 files changed, 721 insertions(+), 9 deletions(-) Index: trunk/milena/tests/canvas/morpho/connected_filter.cc (deleted) =================================================================== Index: trunk/milena/tests/canvas/morpho/attribute_filter.cc =================================================================== --- trunk/milena/tests/canvas/morpho/attribute_filter.cc (revision 0) +++ trunk/milena/tests/canvas/morpho/attribute_filter.cc (revision 3435) @@ -0,0 +1,108 @@ +// Copyright (C) 2007, 2008, 2009 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. + +#include <mln/core/image/image2d.hh> +#include <mln/io/pgm/all.hh> +#include <mln/util/timer.hh> +#include <mln/core/alias/neighb2d.hh> +#include <mln/morpho/attribute/volume.hh> +#include <mln/morpho/attribute/card.hh> +#include <mln/morpho/leveling_filter.hh> +#include <mln/morpho/algebraic_filter.hh> + +#include "tests/data.hh" + +int main(int argc, char** argv) +{ + using namespace mln; + using value::int_u8; + + if (argc != 2) + { + std::cout << "Usage: ./connected_filter lambda" << std::endl; + return 0; + } + + typedef mln::image2d<int_u8> I; + I lena; + + float elapsed; + mln::util::timer chrono; + mln::morpho::attribute::volume<I> c; + mln::morpho::attribute::card<I> c2; + int lambda = atoi(argv[1]); + + mln::io::pgm::load(lena, MLN_IMG_DIR "/lena.pgm"); + I out; + + std::cout << "Test with card attribute:" << std::endl; + chrono.start(); + out = mln::canvas::morpho::attribute_filter(lena, c4(), c2, lambda, true); + elapsed = chrono.stop(); + std::cout << "(Full auto) " << elapsed << "s" << std::endl; + mln::io::pgm::save(out, "alg_auto.pgm"); + + chrono.start(); + out = mln::morpho::algebraic_filter(lena, c4(), c2, lambda, true); + elapsed = chrono.stop(); + std::cout << "(Algebraic Auto) " << elapsed << "s" << std::endl; + mln::io::pgm::save(out, "alg_algebraic.pgm"); + + chrono.start(); + out = mln::canvas::morpho::internal::attribute_filter_dispatch(metal::false_(), lena, c4(), c2, lambda, true); + elapsed = chrono.stop(); + std::cout << "(Force Slow) " << elapsed << "s" << std::endl; + mln::io::pgm::save(out, "alg_slow.pgm"); + + // Try force algebraic dispatch with wrong accu (volume). + // mln::morpho::algebraic_filter(lena, c4(), c, lambda, true); + + std::cout << "Test with volume attribute:" << std::endl; + chrono.start(); + out = mln::canvas::morpho::attribute_filter(lena, c4(), c, lambda, true); + elapsed = chrono.stop(); + std::cout << "(Full auto) " << elapsed << "s" << std::endl; + mln::io::pgm::save(out, "lev_auto.pgm"); + + chrono.start(); + out = mln::morpho::leveling_filter(lena, c4(), c, lambda, true); + elapsed = chrono.stop(); + std::cout << "(Leveling Auto) " << elapsed << "s" << std::endl; + mln::io::pgm::save(out, "lev_leveling.pgm"); + + chrono.start(); + out = mln::canvas::morpho::internal::attribute_filter_dispatch(metal::false_(), lena, c4(), c, lambda, true); + elapsed = chrono.stop(); + std::cout << "(Force Slow) " << elapsed << "s" << std::endl; + mln::io::pgm::save(out, "lev_slow.pgm"); + + // Try force leveling dispatch with wrong accu (card). + // mln::morpho::leveling_filter(lena, c4(), c2, lambda, true); + + +} Index: trunk/milena/mln/morpho/leveling_filter.hh =================================================================== --- trunk/milena/mln/morpho/leveling_filter.hh (revision 0) +++ trunk/milena/mln/morpho/leveling_filter.hh (revision 3435) @@ -0,0 +1,69 @@ +// Copyright (C) 2007, 2008, 2009 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_MORPHO_LEVELING_FILTER_HH_ +# define MLN_MORPHO_LEVELING_FILTER_HH_ + +/// \file mln/morpho/leveling_filter.hh +/// +/// Leveling filter calls attribute canvas. + +# include <mln/core/concept/image.hh> +# include <mln/core/concept/neighborhood.hh> +# include <mln/core/concept/accumulator.hh> + +# include <mln/trait/accumulators.hh> + +# include <mln/level/sort_psites.hh> +# include <mln/level/sort_offsets.hh> + +# include <mln/canvas/morpho/attribute_filter.hh> + +namespace mln { + namespace morpho { + + template <typename I, typename N, typename A> + mln_concrete(I) + leveling_filter(const Image<I>& input, + const Neighborhood<N>& nbh, + const Accumulator<A>& a, + const typename A::result& lambda, + bool increasing) + { + mlc_or(mlc_equal(mln_trait_accumulator_when_pix(A), + trait::accumulator::when_pix::use_pix), + mlc_equal(mln_trait_accumulator_when_pix(A), + trait::accumulator::when_pix::use_v))::check(); + + return canvas::morpho::internal::attribute_filter_dispatch(input, nbh, a, lambda, increasing); + } + } // end of namespace mln::morpho +} // end of namespace mln + + +#endif /* !MLN_MORPHO_LEVELING_FILTER_HH_ */ Index: trunk/milena/mln/morpho/algebraic_filter.hh =================================================================== --- trunk/milena/mln/morpho/algebraic_filter.hh (revision 0) +++ trunk/milena/mln/morpho/algebraic_filter.hh (revision 3435) @@ -0,0 +1,71 @@ +// Copyright (C) 2007, 2008, 2009 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_MORPHO_ALGEBRAIC_FILTER_HH_ +# define MLN_MORPHO_ALGEBRAIC_FILTER_HH_ + +/// \file mln/morpho/leveling_filter.hh +/// +/// Leveling filter calls attribute canvas. + + +# include <mln/core/concept/image.hh> +# include <mln/core/concept/neighborhood.hh> +# include <mln/core/concept/accumulator.hh> + +# include <mln/trait/accumulators.hh> + +# include <mln/level/sort_psites.hh> +# include <mln/level/sort_offsets.hh> + +# include <mln/canvas/morpho/attribute_filter.hh> + +namespace mln { + namespace morpho { + + template <typename I, typename N, typename A> + mln_concrete(I) + algebraic_filter(const Image<I>& input, + const Neighborhood<N>& nbh, + const Accumulator<A>& a, + const typename A::result& lambda, + bool increasing) + { + mlc_or(mlc_equal(mln_trait_accumulator_when_pix(A), + trait::accumulator::when_pix::use_none), + mlc_equal(mln_trait_accumulator_when_pix(A), + trait::accumulator::when_pix::use_p))::check(); + + return canvas::morpho::internal::attribute_filter_dispatch(input, nbh, a, lambda, increasing); + } + + } // end of namespace mln::morpho +} // end of namespace mln + + + +#endif /* !MLN_MORPHO_ALGEBRAIC_FILTER_HH_ */ Index: trunk/milena/mln/canvas/morpho/connected_filter.hh (deleted) =================================================================== Index: trunk/milena/mln/canvas/morpho/attribute_filter.hh =================================================================== --- trunk/milena/mln/canvas/morpho/attribute_filter.hh (revision 0) +++ trunk/milena/mln/canvas/morpho/attribute_filter.hh (revision 3435) @@ -0,0 +1,461 @@ +// Copyright (C) 2007, 2008, 2009 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_MORPHO_ATTRIBUTE_FILTER_HH +# define MLN_CANVAS_MORPHO_ATTRIBUTE_FILTER_HH + +/// \file mln/canvas/morpho/attribute_filter.hh +/// +/// Connected filters dispatch (algebraic & leveling filters). + + +# include <mln/core/concept/image.hh> +# include <mln/core/concept/neighborhood.hh> +# include <mln/core/concept/accumulator.hh> + +# include <mln/trait/accumulators.hh> + +# include <mln/util/pix.hh> + +# include <mln/data/fill.hh> + +namespace mln { + namespace canvas { + namespace morpho { + + // Facade Fwd Declaration + template <typename I, typename N, typename A> + mln_concrete(I) + attribute_filter(const Image<I>& input, const Neighborhood<N>& nbh, + const Accumulator<A>& a, const typename A::result& lambda, + bool increasing); + + template <typename I, typename N, typename A> + mln_concrete(I) + algebraic_filter(const Image<I>& input, const Neighborhood<N>& nbh, + const Accumulator<A>& a, const typename A::result& lambda, + bool increasing); + +# ifndef MLN_INCLUDE_ONLY + + namespace impl { + + template <typename A, typename I> + void take_as_init_fastest (trait::accumulator::when_pix::use_none, A& accu, + const I& input, const unsigned p) + { + (void)input; + (void)p; + accu.take_as_init (); + } + + template <typename A, typename I, typename P> + void take_as_init (trait::accumulator::when_pix::use_p, A& accu, + const I& input, const P& p) + { + (void)input; + accu.take_as_init (p); + } + + template <typename A, typename I, typename P> + void take_as_init (trait::accumulator::when_pix::use_none, A& accu, + const I& input, const P& p) + { + (void)input; + accu.take_as_init (p); + } + + template <typename A, typename I, typename P> + void take_as_init (trait::accumulator::when_pix::use_pix, A& accu, + const I& input, const P& p) + { + accu.take_as_init (make::pix(input, p)); + } + + template <typename A, typename I, typename P> + void take_as_init (trait::accumulator::when_pix::use_v, A& accu, + const I& input, const P& p) + { + accu.take_as_init (make::pix(input, p)); + } + + template <typename A, typename I> + void take_as_init_fastest (trait::accumulator::when_pix::use_v, A& accu, + const I& input, const unsigned p) + { + accu.take_as_init (input.element (p)); + } + + + template <typename A, typename I, typename P> + void take_as_init (A& accu, const I& input, const P& p) + { + take_as_init (mln_trait_accumulator_when_pix(A)(), accu, input, p); + } + + template <typename A, typename I, typename P> + void take_as_init_fastest (A& accu, const I& input, const P& p) + { + take_as_init_fastest (mln_trait_accumulator_when_pix(A)(), accu, input, p); + } + + + namespace generic { + + + //////////////////////// + /// Generic version. /// + //////////////////////// + + + 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 S, typename A> + mln_concrete(I) + attribute_filter (const Image<I>& input_, + const Neighborhood<N>& nbh_, + const Site_Set<S>& s_, + const Accumulator<A>& a_, + const typename A::result& lambda) + { + trace::entering("canvas::morpho::impl::generic::attribute_filter"); + // FIXME: Test?! + + const I& input = exact(input_); + const N& nbh = exact(nbh_); + const S& s = exact(s_); + (void)a_; // To avoid warning at compilation + + mln_concrete(I) output; + initialize(output, input); + + // Local type. + typedef mln_psite(I) P; + + + // Auxiliary data. + mln_ch_value(I, bool) deja_vu; + mln_ch_value(I, bool) activity; + mln_ch_value(I, P) parent; + mln_ch_value(I, A) data; + + // Initialization. + { + initialize(deja_vu, input); + data::fill(deja_vu, false); + initialize(activity, input); + data::fill(activity, true); + initialize(parent, input); + initialize(data, input); + //a.init(); // init required. + } + + // First pass. + { + mln_fwd_piter(S) p(s); // s required. + mln_niter(N) n(nbh, p); + + for_all(p) + { + // Make set. + { + parent(p) = p; + + // Check accumulator trait to handle argument type (Pix or Site). + take_as_init (data(p), input, p); + } + + for_all(n) + if (input.domain().has(n) && deja_vu(n)) + { + //do_union(n, p); + P r = find_root(parent, n); + if (r != p) + { + if (input(r) == input(p) || (activity(r) && (data(r) < lambda))) // Equiv(r, p) + // Either a flat zone or the component of r is still growing. + { + /* FIXME: Same remark as above concerning the + initialization of data(p); instead of + + data(p).take(data(r)); + + we should (or could) have + + unite_data(p, r); + + so as to keep the generic aspect of this canvas + (as long as the set of acceptable types for the + template parameter A is not bound). */ + + data(p).take(data(r)); + parent(r) = p; + if (activity(r) == false) + activity(p) = false; + } + else + { + activity(p) = false; + } + } + } + deja_vu(p) = true; + } + } + + // Second pass. + { + mln_bkd_piter(S) p(s); + for_all(p) + if (parent(p) == p) // p is root. + output(p) = input(p); + else + output(p) = output(parent(p)); + } + + trace::exiting("canvas::morpho::impl::generic::attribute_filter"); + return output; + } + + } // end of namespace mln::canvas::morpho::impl::generic + + + //////////////////////// + /// Fastest version. /// + //////////////////////// + + template <typename I> + inline + unsigned + find_root_fastest(I& parent, unsigned x) + { + if (parent.element(x) == x) + return x; + else + return parent.element(x) = find_root_fastest(parent, parent.element(x)); + } + + template <typename I, typename N, typename A> + mln_concrete(I) + attribute_filter_fastest(const Image<I>& input_, + const Neighborhood<N>& nbh_, + const util::array<unsigned>& s, + const Accumulator<A>& a_, + const typename A::result& lambda) + { + trace::entering("canvas::morpho::impl::attribute_filter_fastest"); + // FIXME: Tests? + + const I& input = exact(input_); + const N& nbh = exact(nbh_); + (void)a_; + + mln_concrete(I) output; + initialize(output, input); + + // Local type. + typedef mln_psite(I) P; + + // Auxiliary data. + mln_ch_value(I, bool) deja_vu; + mln_ch_value(I, bool) activity; + mln_ch_value(I, unsigned) parent; + mln_ch_value(I, A) data; + + // Initialization. + { + initialize(deja_vu, input); + data::fill(deja_vu, false); + initialize(activity, input); + data::fill(activity, true); + initialize(parent, input); + data::fill(parent, 0); + initialize(data, input); + } + + util::array<int> dp = offsets_wrt(input, nbh); + const unsigned n_nbhs = dp.nelements(); + const unsigned n_points = s.nelements(); + + // First pass. + { + for (unsigned i = 0; i < n_points; ++i) + { + unsigned p = s[i]; // An offset. + + // Make set. + parent.element(p) = p; + + // Check accumulator trait to handle argument type (Value or None). + take_as_init_fastest (data.element(p), input, p); + + for (unsigned j = 0; j < n_nbhs; ++j) + { + unsigned n = p + dp[j]; + if (!deja_vu.element(n)) + continue; + + unsigned r = find_root_fastest(parent, n); + if (r != p) + { + if (input.element(r) == input.element(p) + || (activity.element(r) + && (data.element(r) < lambda))) + { + data.element(p).take(data.element(r)); + parent.element(r) = p; + if (activity.element(r) == false) + activity.element(p) = false; + } + else + activity.element(p) = false; + } + } + + deja_vu.element(p) = true; + } + } + + + // Second pass. + { + for (int i = n_points - 1; i >= 0 ; --i) + { + unsigned p = s[i]; + if (parent.element(p) == p) // p is root. + output.element(p) = input.element(p); + else + output.element(p) = output.element(parent.element(p)); + } + } + + trace::exiting("canvas::morpho::impl::attribute_filter_fastest"); + return output; + } + } // end of namespace mln::canvas::morpho::impl + + + + + // Dispatch. + + + namespace internal + { + // Dispatch to generic. + template <typename I, typename N, typename A> + inline + mln_concrete(I) + attribute_filter_dispatch(metal::false_, + const Image<I>& input, + const Neighborhood<N>& nbh, + const Accumulator<A>& a, + const typename A::result& lambda, + bool increasing) + { + p_array<mln_psite(I)> s = increasing ? + level::sort_psites_increasing(input) : + level::sort_psites_decreasing(input); + + return impl::generic::attribute_filter(input, nbh, s, a, lambda); + } + + // Dispatch to fastest. + template <typename I, typename N, typename A> + inline + mln_concrete(I) + attribute_filter_dispatch(metal::true_, + const Image<I>& input, + const Neighborhood<N>& nbh, + const Accumulator<A>& a, + const typename A::result& lambda, + bool increasing) + { + util::array<unsigned> s = + increasing ? + level::sort_offsets_increasing(input) : + level::sort_offsets_decreasing(input); + + return impl::attribute_filter_fastest(input, nbh, s, a, lambda); + } + + + + template <typename I, typename N, typename A> + inline + mln_concrete(I) + attribute_filter_dispatch(const Image<I>& input, + const Neighborhood<N>& nbh, + const Accumulator<A>& a, + const typename A::result& lambda, + bool increasing) + { + enum { + test = (mlc_equal(mln_trait_image_speed(I), + trait::image::speed::fastest)::value && + mln_is_simple_neighborhood(N)::value && + (mlc_equal(mln_trait_accumulator_when_pix(A), + trait::accumulator::when_pix::use_none)::value || + mlc_equal(mln_trait_accumulator_when_pix(A), + trait::accumulator::when_pix::use_v)::value)) + }; + return attribute_filter_dispatch(metal::bool_<test>(), input, nbh, a, lambda, increasing); + } + } // end of namespace mln::canvas::morpho::internal + + +# endif // ! MLN_INCLUDE_ONLY + + // Facade. + + template <typename I, typename N, typename A> + mln_concrete(I) + attribute_filter(const Image<I>& input, + const Neighborhood<N>& nbh, + const Accumulator<A>& a, + const typename A::result& lambda, + bool increasing) + { + return internal::attribute_filter_dispatch(input, nbh, a, lambda, increasing); + } + + } // end of namespace mln::canvas::morpho + } // end of namespace mln::canvas +} // end of namespace mln + + +#endif // ! MLN_CANVAS_MORPHO_ATTRIBUTE_FILTER_HH Index: trunk/milena/sandbox/edwin/tree/propagate.hh =================================================================== --- trunk/milena/sandbox/edwin/tree/propagate.hh (revision 3434) +++ trunk/milena/sandbox/edwin/tree/propagate.hh (revision 3435) @@ -60,9 +60,9 @@ void back_propagate_subbranch(const T& t, A& a, mln_value(A) v) { - mln_fwd_piter(T) p(t.domain()); + mln_bkd_piter(T) p(t.domain()); for_all(p) - if (t.is_a_node(p) && a(t.parent(p)) == v) + if (a(t.parent(p)) == v) { mln_assertion(t.is_a_node(t.parent(p))); a(p) = a(t.parent(p)); Index: trunk/milena/sandbox/edwin/tree/tree.cc =================================================================== --- trunk/milena/sandbox/edwin/tree/tree.cc (revision 3434) +++ trunk/milena/sandbox/edwin/tree/tree.cc (revision 3435) @@ -44,8 +44,8 @@ if (echo) io::pbm::save(aa, "before.pbm"); if (echo > 1) debug::println("aa (before)", aa); - //back_propagate_subbranch(t, aa, true); - //if (echo > 1) debug::println("aa (After subbranch propagation)", aa); + back_propagate_subbranch(t, aa, true); + if (echo > 1) debug::println("aa (After subbranch propagation)", aa); back_propagate_level(t, aa); if (echo > 1) debug::println("aa (Final)", aa); @@ -62,7 +62,7 @@ template <typename I, typename A> inline void -create_tree_and_compute(I& f_, A a_, float lambda = mln_min(float), float lambda2 = mln_max(float)) +create_tree_and_compute(Image<I>& f_, Accumulator<A> a_, float lambda, float lambda2 = mln_max(float)) { using namespace mln; using value::int_u8; @@ -84,13 +84,14 @@ debug::println("a | nodes", a | t.nodes()); } - image2d<bool> b = duplicate((pw::value(a) < pw::cst(lambda1) && pw::value(a) < pw::cst(lambda2)) | a.domain()); + std::cout << lambda; + image2d<bool> b = duplicate((pw::cst(lambda) < pw::value(a) && pw::value(a) < pw::cst(lambda2)) | a.domain()); sample(t, b, echo); } void usage(char* argv[]) { - std::cerr << "usage: " << argv[0] << " input.pgm echo lambda" << std::endl; + std::cerr << "usage: " << argv[0] << " input.pgm echo lambda1 lamda2" << std::endl; std::cerr << "\techo:\t0 (none)" << std::endl << "\t\t1 (img output)" << std::endl << "\t\t2 (debug)" << std::endl; @@ -104,10 +105,12 @@ mln_VAR(nbh, c4()); - if (argc != 4) + if (argc < 4) usage(argv); echo = std::atoi(argv[2]); + float lambda1 = atof(argv[3]); + float lambda2 = (argc == 5) ? atof(argv[4]) : mln_max(float); typedef image2d<int_u8> I; @@ -139,6 +142,6 @@ //create_tree_and_compute(img, morpho::attribute::volume<I2>()); // - create_tree_and_compute(f, morpho::attribute::card<I>(), std::atof(argv[3])); + create_tree_and_compute(f, morpho::attribute::coccupation<I>(), lambda1, lambda2); }
participants (1)
-
Edwin Carlinet