r4305: Fix bugs in segmentation method based on mean color

URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox ChangeLog: 2009-07-16 Edwin Carlinet <carlinet@lrde.epita.fr> Fix bugs in segmentation method based on mean color. * edwin/exec/max_delta_colormean_obj.cc: The distance used to retrieve components is now based on the distance to parent and the distance to brothers. * edwin/exec/mask_fill_mean_color.cc: Fill the mask from binarisation with the mean color of the components. * edwin/exec/pgm_gradient.cc: Compute a thick gradient from the a grey scale image. Debug: * edwin/mln/morpho/tree/components_debug.hh, * edwin/mln/morpho/tree/debug.hh, * edwin/mln/morpho/tree/propagate_node_debug.hh, * edwin/exec/tree_debug.cc: Code instrumentalized for debuging. Vizualisation: * edwin/tools: New. * edwin/exec/give_me_the_curve.cc, * edwin/tools/make_the_curves.sh: Trace the plot of log files genererated by debug code. --- exec/give_me_the_curve.cc | 2 exec/mask_fill_mean_color.cc | 61 +++++ exec/max_delta_colormean_obj.cc | 53 +++- exec/pgm_gradient.cc | 42 +++ exec/tree_debug.cc | 86 +++++++ mln/morpho/tree/components_debug.hh | 384 ++++++++++++++++++++++++++++++++ mln/morpho/tree/debug.hh | 124 ++++++++++ mln/morpho/tree/propagate_node_debug.hh | 217 ++++++++++++++++++ tools/make_the_curves.sh | 15 + 9 files changed, 976 insertions(+), 8 deletions(-) Index: trunk/milena/sandbox/edwin/tools/make_the_curves.sh =================================================================== --- trunk/milena/sandbox/edwin/tools/make_the_curves.sh (revision 0) +++ trunk/milena/sandbox/edwin/tools/make_the_curves.sh (revision 4305) @@ -0,0 +1,15 @@ +#! /bin/bash + +conf="gplot.conf" + +echo 'set terminal png;' > $conf +echo 'set size 2,1' >> $conf +echo 'set xtic out rotate by 90' >> $conf +i=0 +for file in *.log; do + printf "set output \"plot_%03i.png\"\n" $i >> $conf + echo plot \"$file\" 'using 2:xticlabels(1) with lines' >> $conf + i=$((i+1)) +done + +gnuplot $conf Property changes on: trunk/milena/sandbox/edwin/tools/make_the_curves.sh ___________________________________________________________________ Added: svn:executable + * Index: trunk/milena/sandbox/edwin/exec/give_me_the_curve.cc =================================================================== --- trunk/milena/sandbox/edwin/exec/give_me_the_curve.cc (revision 4304) +++ trunk/milena/sandbox/edwin/exec/give_me_the_curve.cc (revision 4305) @@ -72,7 +72,7 @@ while (!tree.is_root(p)) { - data << a(p) << std::endl; + data << '"' << p << "\" " << a(p) << std::endl; p = tree.parent(p); } data.close(); Index: trunk/milena/sandbox/edwin/exec/mask_fill_mean_color.cc =================================================================== --- trunk/milena/sandbox/edwin/exec/mask_fill_mean_color.cc (revision 0) +++ trunk/milena/sandbox/edwin/exec/mask_fill_mean_color.cc (revision 4305) @@ -0,0 +1,61 @@ +#include <mln/core/image/image2d.hh> +#include <mln/core/alias/neighb2d.hh> + +#include <mln/value/int_u8.hh> +#include <mln/value/int_u16.hh> +#include <mln/value/rgb8.hh> + +#include <mln/io/pbm/load.hh> +#include <mln/io/ppm/load.hh> +#include <mln/io/ppm/save.hh> + +#include <mln/accu/stat/mean.hh> + +#include <mln/labeling/compute_image.hh> +#include <mln/labeling/blobs.hh> + +#include <mln/convert/to.hh> +#include <mln/data/convert.hh> + +using namespace mln; +using value::int_u16; +using value::int_u8; +using value::rgb8; + +void usage(char** argv) +{ + std::cout << "Usage: " << argv[0] << " in:mask.pgm in:source.ppm [out:colormean.ppm]" + << std::endl; + abort(); +} + +template <typename M, typename I> +void +process(const Image<M>& mask, const Image<I>& ref, const char* foutput) +{ + int_u16 nlabels; + + image2d<int_u16> labels = labeling::blobs(mask, c4(), nlabels); + + typedef mln_ch_value(I, rgb8) O; + O out = data::convert(rgb8(), labeling::compute_image(accu::meta::stat::mean (), ref, labels, nlabels)); + + io::ppm::save(out, foutput); +} + +int main(int argc, char** argv) +{ + if (argc < 3) + usage(argv); + + const char* finput = argv[1]; + const char* freference = argv[2]; + const char* foutput = (argc >= 4) ? argv[3] : "colormean.ppm"; + + image2d<bool> input; + io::pbm::load(input, finput); + + image2d<rgb8> ref; + io::ppm::load(ref, freference); + process(input, ref, foutput); +} Index: trunk/milena/sandbox/edwin/exec/pgm_gradient.cc =================================================================== --- trunk/milena/sandbox/edwin/exec/pgm_gradient.cc (revision 0) +++ trunk/milena/sandbox/edwin/exec/pgm_gradient.cc (revision 4305) @@ -0,0 +1,42 @@ +// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE) +// +// This file is part of Olena. +// +// Olena is free software: you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, version 2 of the License. +// +// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>. +// +// As a special exception, you may use this file as part of a free +// software project 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/core/alias/neighb2d.hh> +#include <mln/io/pgm/load.hh> +#include <mln/io/pgm/save.hh> + +#include <mln/morpho/elementary/gradient.hh> + + +int main(int argc, char* argv[]) +{ + using namespace mln; + using value::int_u8; + + image2d<int_u8> ima; + io::pgm::load(ima, argv[1]); + io::pgm::save(morpho::elementary::gradient(ima, c8()), argv[2]); +} Index: trunk/milena/sandbox/edwin/exec/tree_debug.cc =================================================================== --- trunk/milena/sandbox/edwin/exec/tree_debug.cc (revision 0) +++ trunk/milena/sandbox/edwin/exec/tree_debug.cc (revision 4305) @@ -0,0 +1,86 @@ +//Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE) + +// This file is part of Olena. + +// Olena is free software: you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, version 2 of the License. + +// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>. + +// As a special exception, you may use this file as part of a free +// software project 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/core/alias/neighb2d.hh> + +#include <mln/value/int_u8.hh> +#include <mln/value/rgb8.hh> + +#include <mln/morpho/tree/data.hh> +#include <mln/morpho/tree/compute_attribute_image.hh> +#include <mln/morpho/tree/propagate.hh> +#include <mln/morpho/tree/propagate_representative.hh> +#include <mln/morpho/tree/debug.hh> + +# include <mln/io/pgm/save.hh> +# include <mln/io/pgm/load.hh> + +#include <mln/accu/stat/mean.hh> + +#include <mln/data/sort_psites.hh> + +#include <map> +#include <iostream> + + +using namespace mln; +using value::int_u8; + +int main(int argc, char** argv) +{ + + if (argc < 1) + abort(); + + const char* finput = argv[1]; + + // Image loadin'. + typedef image2d<value::int_u8> I; + I input; + io::pgm::load(input, finput); + + + // Tree construction. + typedef p_array<mln_psite_(I)> S; + typedef morpho::tree::data<I, S> T; + + S s = data::sort_psites_decreasing(input); + T tree(input, s, c4()); + + typedef std::map< int_u8, unsigned > M; + + M m = morpho::tree::debug::tree_height(tree); + + std::cout << "Height:\tLeaf Count:" << std::endl; + for (M::iterator it = m.begin(); it != m.end(); ++it) + std::cout << it->first << "\t" << it->second << std::endl; + + + mln_ch_value_(I, int_u8) bro = morpho::tree::debug::tree_brother(tree); + morpho::tree::propagate_representative(tree, bro); + io::pgm::save(bro, "bro.pgm"); +} Index: trunk/milena/sandbox/edwin/exec/max_delta_colormean_obj.cc =================================================================== --- trunk/milena/sandbox/edwin/exec/max_delta_colormean_obj.cc (revision 4304) +++ trunk/milena/sandbox/edwin/exec/max_delta_colormean_obj.cc (revision 4305) @@ -31,7 +31,6 @@ #include <mln/morpho/tree/data.hh> #include <mln/morpho/tree/compute_attribute_image.hh> -#include <mln/morpho/tree/components.hh> #include <mln/morpho/tree/propagate.hh> #include <mln/morpho/tree/propagate_representative.hh> @@ -46,15 +45,26 @@ #include <mln/io/pgm/save.hh> #include <mln/io/ppm/save.hh> +#include <mln/math/max.hh> + #include <mln/math/diff_abs.hh> #include "color_distance.hh" + #include <iostream> #include <cstring> +// debug +#include <mln/morpho/tree/debug.hh> +#include <mln/morpho/tree/components.hh> + using namespace mln; using value::int_u8; +//template <typename T> +//struct mymean : public mln::accu::internal + + void usage(char** argv) { @@ -108,10 +118,16 @@ { typedef mln_ch_value(typename T::function, mln_sum(mln_value(S))) O; - O out = morpho::tree::compute_attribute_image_from(accu::stat::mean<mln_value(S)>(), - tree, source); + typedef accu::stat::mean<mln_value(S)> ACC; + typedef mln_ch_value(typename T::function, ACC) ACC_IMG; - io::ppm::save(data::convert(value::rgb8(), out), "mean.ppm"); + ACC_IMG accus; + O means = morpho::tree::compute_attribute_image_from(ACC (), + tree, + source, + &accus); + + io::ppm::save(data::convert(value::rgb8(), means), "mean.ppm"); // Compute delta image. mln_ch_value(typename T::function, int_u8) dist; @@ -120,8 +136,29 @@ mln_up_node_piter(T) n(tree); for_all(n) { - // Fixme: rewrite distance routines with vector instead of convert ? - dist(n) = dist_mean(convert::to<value::rgb8>(out(tree.parent(n))), convert::to<value::rgb8>(out(n))); + int_u8 dist_dad, dist_bro; + value::rgb8 current, mean_bro; + ACC aux = accus(tree.parent(n)); + + aux.untake(accus(n)); + + // FIXME: add untake_n_times to accumlator concept + // Note: this is an approximation to avoid the real mean computation of bros. + unsigned m = accus(tree.parent(n)).count() - accus(n).count() - aux.count(); + value::rgb8 v = exact(source)(n); + + for (unsigned i = 0; i < m; i++) + aux.untake(v); + + current = convert::to<value::rgb8>(means(n)); + mean_bro = convert::to<value::rgb8>(aux.to_result()); + + dist_dad = dist_mean(convert::to<value::rgb8>(means(tree.parent(n))), + current); + dist_bro = dist_mean(convert::to<value::rgb8>(aux.to_result()), + current); + + dist(n) = math::max(dist_bro, dist_dad); } return dist; @@ -140,7 +177,6 @@ int main(int argc, char** argv) { - if (argc < 3) usage(argv); @@ -175,6 +211,9 @@ { image2d<value::rgb8> src; io::ppm::load(src, fsource); + + // init debug + global::debug_img = duplicate(src); delta = compute_delta_mean(tree, src); } else Index: trunk/milena/sandbox/edwin/mln/morpho/tree/debug.hh =================================================================== --- trunk/milena/sandbox/edwin/mln/morpho/tree/debug.hh (revision 0) +++ trunk/milena/sandbox/edwin/mln/morpho/tree/debug.hh (revision 4305) @@ -0,0 +1,124 @@ +//Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE) + +// This file is part of Olena. + +// Olena is free software: you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, version 2 of the License. + +// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>. + +// As a special exception, you may use this file as part of a free +// software project 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 DEBUG_HH +# define DEBUG_HH + +# include <mln/core/image/image2d.hh> +# include <mln/morpho/tree/data.hh> + +# include <mln/value/rgb8.hh> +# include <mln/value/int_u8.hh> + +# include <mln/data/fill.hh> + +# include <map> + +namespace mln +{ + + namespace global + { + image2d<value::rgb8> debug_img; + } + + + namespace morpho + { + + namespace tree + { + + namespace debug + { + + + /// Count the brothers of each tree node and return the result + /// as an image. + /// + /// \param tree The component tree. + /// + /// \return The bro' count image. + /// + template <typename T> + inline + mln_ch_value(typename T::function, value::int_u8) + tree_brother(const T& tree) + { + + typedef typename T::function F; + + typedef mln_ch_value(F, value::int_u8) A; + + A out; + initialize(out, tree.f()); + + mln::data::fill(out, 0); + + { + mln_up_node_piter(T) n(tree); + for_all(n) + out(tree.parent(n))++; + } + + { + mln_dn_node_piter(T) n(tree); + for_all(n) + out(n) = out(tree.parent(n)) - 1; + } + return out; + } + + template <typename T> + inline + std::map< mln_value(T::function), unsigned> + tree_height(const T& tree) + { + std::map< mln_value(T::function), unsigned> m; + + mln_leaf_piter(T) l(tree); + for_all(l) + m[tree.f(l)]++; + + return m; + } + + } + + } + + } + +} + + + + + +# ifndef MLN_INCLUDE_ONLY + +# endif // ! MLN_INCLUDE_ONLY + +#endif // ! DEBUG_HH Index: trunk/milena/sandbox/edwin/mln/morpho/tree/components_debug.hh =================================================================== --- trunk/milena/sandbox/edwin/mln/morpho/tree/components_debug.hh (revision 0) +++ trunk/milena/sandbox/edwin/mln/morpho/tree/components_debug.hh (revision 4305) @@ -0,0 +1,384 @@ +// Copyright (C) 2007, 2008, 2009 EPITA Research and Development Laboratory +// (LRDE) +// +// This file is part of the Milena 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_TREE_COMPONENTS_HH_ +# define MLN_MORPHO_TREE_COMPONENTS_HH_ + +# include <mln/core/concept/image.hh> +# include <mln/core/concept/function.hh> +# include <mln/data/fill.hh> + +# include <mln/morpho/tree/propagate_node.hh> +# include <mln/morpho/tree/data.hh> +# include <mln/trace/entering.hh> +# include <mln/trace/exiting.hh> + +/* Debug */ +# include <mln/morpho/tree/debug.hh> +# include <mln/morpho/tree/propagate_representative.hh> +# include <mln/core/image/image2d.hh> +# include <mln/literal/colors.hh> +# include <mln/io/ppm/save.hh> +# include <iostream> +# include <fstream> +# include <sstream> +# include <unistd.h> + +/** +** \file mln/morpho/tree/components.hh +** +** Routines that permits to retrieve tree components. +** Tree components are nodes maximising the attribute. +** The code is instrumented for debugging. +*/ + + + +namespace mln { + + namespace morpho { + + namespace tree { + + /** + ** Retrieve components from the tree until all leaves belong to + ** components. + ** + ** @param tree Component tree. + ** @param attr_image Attribute image. + ** + ** @return Array of components. + */ + template <typename T, typename A> + p_array< mln_psite(A) > + get_components(const T& tree, const Image<A>& attr_image); + + /** + ** Retrieve the \p n most important components from the tree. n + ** should be lesser than the maximum number of components. If + ** not, the functions stops when there's no more components. + ** + ** @param tree Component tree. + ** @param attr_image Attribute image. + ** @param n Number of components to get. + ** + ** @return Array of components. + */ + template <typename T, typename A> + p_array< mln_psite(A) > + get_components(const T& tree, const Image<A>& attr_image, unsigned n); + + /** + ** Retrieve the most important components that check + ** predicate \p pred. + ** + ** @param tree Component tree. + ** @param attr_image Attribute image. + ** @param pred Predicate that components must check. + ** + ** @return Array of components. + */ + template <typename T, typename A, typename P2B> + p_array< mln_psite(A) > + get_components(const T& tree, const Image<A>& attr_image, const Function_v2b<P2B>& pred); + + +# ifndef MLN_INCLUDE_ONLY + + namespace internal + { + template <typename P, typename I> + struct desc_sort + { + bool operator()(const P& p1, const P& p2) const + { + return ima(p1) > ima(p2); + } + const I& ima; + + desc_sort(const I& ima) : ima(ima) {} + }; + + template <typename P, typename I> + inline + void + sort(p_array<P>& arr, const I& ima_) + { + mlc_converts_to(P, mln_psite(I))::check(); + + const I& ima = exact(ima_); + std::vector<P>& v = arr.hook_std_vector_(); + std::sort(v.begin(), v.end(), desc_sort<P,I>(ima)); + } + + template <typename A> + inline + bool + get_max(const p_array< mln_psite(A) >& arr, const A& activity, unsigned& pos) + { + while (pos < arr.nsites() && !activity(arr[pos])) + ++pos; + return (pos < arr.nsites()); + } + + + ////////////////////////// + // Predifined predicate // + ////////////////////////// + + /// Predicate used to gets components until tree leaves last. + template <typename T> + class pred_tree_leaves_last + { + public: + pred_tree_leaves_last(const T& tree) : + n_ (tree.leaves().nsites()) + { + } + + template <typename P> + bool operator() (const P& p, unsigned n, unsigned* nb_leaves) const + { + (void)p; + (void)n; + mln_assertion(nb_leaves != 0); + + return (*nb_leaves < n_); + } + + + private: + unsigned n_; + }; + + /// Predicate used to get n components. + class pred_n_components + { + public: + pred_n_components(unsigned n) : + n_(n) + { + } + + template <typename P> + bool operator() (const P& p, unsigned n, unsigned* nb_leaves) const + { + (void)p; + (void)nb_leaves; + + return (n < n_); + } + + + private: + unsigned n_; + }; + + /// Predicate used to get components that check a p2b function predicate. + template <typename P2B> + class pred_p2b + { + public: + pred_p2b(const P2B& f) : + f_ (f) + { + } + + template <typename P> + bool operator() (const P& p, unsigned n, unsigned* nb_leaves) const + { + (void)n; + (void)nb_leaves; + + return (f_(p)); + } + + + private: + const P2B& f_; + }; + + template <typename T, typename A, class P> + p_array< mln_psite(A) > + get_components(const T& tree, const A& a, const P& pred, bool uses_leaves = 0) + { + + mln_psite(A) p; + p_array< mln_psite(A) > components; + mln_ch_value(A, bool) activity; + p_array< mln_psite(A) > max_arr = tree.nodes(); + unsigned arr_pos = 0; // position in max_array + unsigned n = 0; + unsigned* nb_leaves = uses_leaves ? new unsigned(0) : 0; + + initialize(activity, a); + mln::data::fill(activity, true); + internal::sort(max_arr, a); + + unsigned cpt = 0; + + do + { + if (!internal::get_max(max_arr, activity, arr_pos)) + break; + p = max_arr[arr_pos]; + + { // debug + std::cout << "# " << cpt << " Retrieve " << p << " with attribute value: " + << a(p) << std::endl; + } + + + if (a(p) == 0) + break; + components.insert(p); + morpho::tree::propagate_node_to_descendants(p, tree, activity, false, nb_leaves); + morpho::tree::propagate_node_to_ancestors(p, tree, activity, false); + activity(p) = false; + n++; + mln_assertion(nb_leaves == 0 || *nb_leaves < mln_max(unsigned)); + + // debug + { + morpho::tree::propagate_node_to_descendants(p, tree, global::debug_img, + literal::green); + morpho::tree::propagate_node_to_ancestors(p, tree, global::debug_img, + literal::red); + + global::debug_img(p) = literal::blue; + + morpho::tree::propagate_representative(tree, global::debug_img); + + std::stringstream fn; + fn.fill('0'); + fn << "debug/log_"; + fn.width(3); + fn << std::right << cpt; + + std::ofstream out((fn.str() + ".log").c_str()); + + out << "# " << cpt << " Retrieve " << p << " with attribute value: " + << a(p) << std::endl; + + mln_psite(T) it = p; + while (!tree.is_root(it)) + { + out << "\"" << it << "\" " << a(it) << std::endl; + it = tree.parent(it); + } + out.close(); + + + io::ppm::save(global::debug_img, (fn.str() + ".ppm").c_str()); + + +// if (fork() == 0) +// { +// execlp("xv", "xv", "debug.ppm", 0); +// exit(0); +// } + //std::cout << "Press to continue: " + // << std::endl; + //std::cin.ignore(); + cpt++; + } + } + while (pred(p, n, nb_leaves)); + + if (uses_leaves) + delete nb_leaves; + return components; + } + + } // end of namespace mln::morpho::tree::internal + + + template <typename T, typename A> + p_array< mln_psite(A) > + get_components(const T& tree, const Image<A>& attr_image) + { + trace::entering("mln::morpho::tree::get_components"); + + const A& a = exact(attr_image); + mln_precondition(tree.f().domain() == a.domain()); // May be to strong. + mln_precondition(a.is_valid()); + + p_array< mln_psite(A) > components = + internal::get_components<T, A>(tree, a, internal::pred_tree_leaves_last<T>(tree), true); + + trace::exiting("mln::morpho::tree::get_components"); + return components; + } + + + template <typename T, typename A> + p_array< mln_psite(A) > + get_components(const T& tree, const Image<A>& attr_image, unsigned n) + { + trace::entering("mln::morpho::tree::get_components"); + + const A& a = exact(attr_image); + mln_precondition(tree.f().domain() == a.domain()); // May be to strong. + mln_precondition(a.is_valid()); + + p_array< mln_psite(A) > components; + + if (n > 0) + components = internal::get_components(tree, a, internal::pred_n_components(n), false); + + trace::exiting("mln::morpho::tree::get_components"); + return components; + } + + template <typename T, typename A, typename P2B> + p_array< mln_psite(A) > + get_components(const T& tree, const Image<A>& attr_image, const Function_v2b<P2B>& pred) + { + trace::entering("mln::morpho::tree::get_components"); + + const A& a = exact(attr_image); + const P2B& predicate = exact(pred); + mln_precondition(tree.f().domain() == a.domain()); // May be to strong. + mln_precondition(a.is_valid()); + + p_array< mln_psite(A) > components = + internal::get_components(tree, a, internal::pred_p2b<P2B>(predicate), false); + + trace::exiting("mln::morpho::tree::get_components"); + return components; + } + +# endif /* !MLN_INCLUDE_ONLY */ + + } // end of namespace mln::morpho::tree + + } // end of namespace mln::morpho + +} // end of namespace mln + +#endif /* !MLN_MORPHO_TREE_COMPONENTS_HH_ */ Property changes on: trunk/milena/sandbox/edwin/mln/morpho/tree/components_debug.hh ___________________________________________________________________ Added: svn:mergeinfo Index: trunk/milena/sandbox/edwin/mln/morpho/tree/propagate_node_debug.hh =================================================================== --- trunk/milena/sandbox/edwin/mln/morpho/tree/propagate_node_debug.hh (revision 0) +++ trunk/milena/sandbox/edwin/mln/morpho/tree/propagate_node_debug.hh (revision 4305) @@ -0,0 +1,217 @@ +// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE) +// +// This file is part of Olena. +// +// Olena is free software: you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, version 2 of the License. +// +// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>. +// +// As a special exception, you may use this file as part of a free +// software project 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_TREE_PROPAGATE_NODE_HH +# define MLN_MORPHO_TREE_PROPAGATE_NODE_HH + +# include <mln/core/concept/image.hh> +# include <mln/core/macros.hh> +# include <mln/morpho/tree/data.hh> + +// debug +# include <mln/morpho/tree/debug.hh> + +/// \file +/// +/// Functions to propagate node in the tree. + + +namespace mln +{ + + namespace morpho + { + + namespace tree + { + + /*! + ** Propagate a value \p v from a node \p n to its descendants. + ** + ** \param[in] n Node to propagate. + ** \param[in] t Component tree used for propagation. + ** \param[in] a_ Attribute image where values are propagated. + ** \param[in] v Value to propagate. + ** \param[out] nb_leaves Optional. Store the number of leaves in + ** the component. + */ + template <typename T, typename A> + void + propagate_node_to_descendants(mln_psite(A) n, + const T& t, + Image<A>& a_, + const mln_value(A)& v, + unsigned* nb_leaves = 0); + + /*! + ** Propagate the node's value to its descendants. + ** + ** \param[in] n Node to propagate. + ** \param[in] t Component tree used for propagation. + ** \param[in] a_ Attribute image where values are propagated. + ** \param[out] nb_leaves Optional. Store the number of leaves in + ** the component. + */ + template <typename T, typename A> + inline + void + propagate_node_to_descendants(mln_psite(A)& n, + const T& t, + Image<A>& a_, + unsigned* nb_leaves = 0); + + + /*! + ** Propagate a value \p v from a node \p n to its ancestors. + ** + ** \param[in] n Node to propagate. + ** \param[in] t Component tree used for propagation. + ** \param[in] a_ Attribute image where values are propagated. + ** \param[in] v Value to propagate. + */ + template <typename T, typename A> + void + propagate_node_to_ancestors(mln_psite(A) n, + const T& t, + Image<A>& a_, + const mln_value(A)& v); + + /*! + ** Propagate the node's value to its ancestors. + ** + ** \param[in] n Node to propagate. + ** \param[in] t Component tree used for propagation. + ** \param[in,out] a_ Attribute image where values are propagated. + */ + template <typename T, typename A> + inline + void + propagate_node_to_ancestors(mln_psite(A) n, + const T& t, + Image<A>& a_); + + +# ifndef MLN_INCLUDE_ONLY + + /* Descendants propagation */ + + template <typename T, typename A> + inline + void + propagate_node_to_descendants(mln_psite(A) n, + const T& t, + Image<A>& a_, + const mln_value(A)& v, + unsigned* nb_leaves = 0) + { + A& a = exact(a_); + mln_precondition(a.is_valid()); + mln_precondition(a.domain() == t.f().domain()); + mln_precondition(a.domain().has(n)); + + + if (!t.is_a_node(n)) // Get the representant. + n = t.parent(n); + mln_assertion(t.is_a_node(n)); + + typename T::depth1st_piter pp(t, n); + + pp.start(); // We don't set n to v. + + if (nb_leaves) + *nb_leaves += t.is_a_leaf(pp); + + for (pp.next(); pp.is_valid(); pp.next()) + { + a(pp) = v; + if (nb_leaves && t.is_a_leaf(pp)) + ++(*nb_leaves); + } + + } + + + template <typename T, typename A> + inline + void + propagate_node_to_descendants(mln_psite(A) n, + const T& t, + Image<A>& a_, + unsigned* nb_leaves = 0) + + { + A& a = exact(a_); + propagate_node_to_descendants(n, t, a, a(n), nb_leaves); + } + + + /* Ancestors propagation */ + + template <typename T, typename A> + void + propagate_node_to_ancestors(mln_psite(A) n, + const T& t, + Image<A>& a_, + const mln_value(A)& v) + { + A& a = exact(a_); + mln_precondition(a.is_valid()); + mln_precondition(a.domain() == t.f().domain()); + mln_precondition(a.domain().has(n)); + + if (!t.is_a_node(n)) // Get the representant. + n = t.parent(n); + mln_assertion(t.is_a_node(n)); + + if (t.is_root(n)) + return; + + do { + n = t.parent(n); + a(n) = v; + } while (!t.is_root(n)); + + } + + template <typename T, typename A> + inline + void + propagate_node_to_ancestors(mln_psite(A) n, + const T& t, + Image<A>& a_) + { + A& a = exact(a_); + propagate_node_to_ancestors(n, t, a, a(n)); + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::morpho::tree + + } // end of namespace mln::morpho + +} // end of namespace mln + +#endif // ! MLN_MORPHO_TREE_PROPAGATE_NODE_HH Property changes on: trunk/milena/sandbox/edwin/mln/morpho/tree/propagate_node_debug.hh ___________________________________________________________________ Added: svn:mergeinfo
participants (1)
-
Edwin Carlinet