
ChangeLog: 2009-04-19 Edwin Carlinet <carlinet@lrde.epita.fr> Process line: WST from color image using tree component. (BUG). * edwin/rush/exo2/wst_from_tree.cc: Process line. * edwin/tree/components.hh: Fix bug related to research of n components method. --- rush/exo2/Makefile | 7 - rush/exo2/wst_from_tree.cc | 235 +++++++++++++++++++++++++++++++++++++++++++++ tree/components.hh | 12 +- 3 files changed, 247 insertions(+), 7 deletions(-) Index: trunk/milena/sandbox/edwin/tree/components.hh =================================================================== --- trunk/milena/sandbox/edwin/tree/components.hh (revision 3687) +++ trunk/milena/sandbox/edwin/tree/components.hh (revision 3688) @@ -222,7 +222,7 @@ 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 arr_pos; //position in max_array unsigned n = 0; unsigned* nb_leaves = uses_leaves ? new unsigned(0) : 0; @@ -237,11 +237,13 @@ p = max_arr[arr_pos]; if (a(p) == 0) break; + //std::cout << p << " " << a(p) << std::endl; 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; - mln_assertion(nb_leaves == 0 || *nb_leaves <= n); + n++; + mln_assertion(nb_leaves == 0 || *nb_leaves < mln_max(unsigned)); } while (pred(p, n, nb_leaves)); @@ -281,8 +283,10 @@ mln_precondition(tree.f().domain() == a.domain()); mln_precondition(a.is_valid()); - p_array< mln_psite(A) > components = - internal::get_components(tree, a, internal::pred_n_components(n), false); + 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; Index: trunk/milena/sandbox/edwin/rush/exo2/wst_from_tree.cc =================================================================== --- trunk/milena/sandbox/edwin/rush/exo2/wst_from_tree.cc (revision 0) +++ trunk/milena/sandbox/edwin/rush/exo2/wst_from_tree.cc (revision 3688) @@ -0,0 +1,235 @@ +// 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. + +/* core */ +#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/value/label_16.hh> + +/* io */ +#include <mln/io/ppm/load.hh> +#include <mln/io/ppm/save.hh> + +/* Gradient */ +#include "color_internal_gradient.hh" + +/* Labeling */ +#include <mln/level/convert.hh> +#include "color_labeling_mean.hh" + +/* WST */ +#include <mln/morpho/watershed/all.hh> +#include <mln/morpho/elementary/dilation.hh> + +/* Tree computation */ +#include <mln/level/sort_psites.hh> +#include <mln/morpho/tree/data.hh> +#include "../../tree/propagate.hh" +#include "../../tree/components.hh" + +#include <mln/morpho/tree/compute_attribute_image.hh> +#include <mln/morpho/attribute/sharpness.hh> + +/* pw */ +#include <mln/core/concept/function.hh> +#include <mln/fun/p2v/ternary.hh> +#include <mln/pw/all.hh> + +//std +#include <iostream> +#include <string> + +#include <mln/level/stretch.hh> +#include <mln/io/pgm/save.hh> + +namespace mln +{ + // Sharpness Attribute -> Height Attribute + template <typename P2V> + struct height_wrapper_ : Function_p2v< height_wrapper_<P2V> > + { + typedef unsigned result; + + height_wrapper_(const Function_p2v<P2V>& f) : + f_ (exact(f)) + { + mlc_is_a(mln_result(P2V), Accumulator)::check(); + } + + template <typename P> + unsigned operator() (const P& p) const + { + return f_(p).height(); + } + + private: + const P2V& f_; + }; + + // meta + template <typename P2V> + inline + height_wrapper_<P2V> + height_wrapper(const Function_p2v<P2V>& f) + { + return height_wrapper_<P2V>(f); + } +} + + + + + +void usage(char** argv) +{ + std::cout << "Usage: " << argv[0] << " input.ppm height [-o1 | -o2 | -o3]" + << std::endl + << "-o1\tSuperpose WS on input image (out: superpose.ppm)" << std::endl + << "-o2\tCount number of basins" << std::endl + << "-o3\tReplace basin by its mean color on the input (out: mean.ppm)" + << std::endl; + abort(); +} + + +int main(int argc, char** argv) +{ + using namespace mln; + using value::int_u8; + using value::int_u16; + using value::rgb8; + + if (argc < 3) + usage(argv); + + int output_ = 0; + int lambda_h = std::atoi(argv[2]); + + if (argc == 4) + if (std::string(argv[3]) == "-o1") + output_ = 1; + else if (std::string(argv[3]) == "-o2") + output_ = 2; + else if (std::string(argv[3]) == "-o3") + output_ = 3; + else + usage(argv); + + + + // Load color image. + typedef image2d<rgb8> I_; + + I_ input_; + io::ppm::load(input_, argv[1]); + + /***************************/ + /* Preprocessing (gradient)*/ + /***************************/ + typedef image2d<int_u8> I; + + I input = color_internal_gradient(input_); + + /***************************/ + /* Component tree creation */ + /***************************/ + typedef p_array<point2d> S; + typedef morpho::tree::data<I,S> tree_t; + + S s = level::sort_psites_decreasing(input); + tree_t t(input, s, c4()); + + + /******************************/ + /* Compute Attribute On Image */ + /******************************/ + typedef mln_ch_value_(I, double) A; + A a; + { + typedef morpho::attribute::sharpness<I> sharp_t; + typedef mln_ch_value_(I, sharp_t) B; + + // Attribute Pruning + B a_img; + a = morpho::tree::compute_attribute_image(sharp_t (), t, &a_img); + + // Component filtering + a = duplicate((fun::p2v::ternary(height_wrapper(pw::value(a_img)) > pw::cst(lambda_h), + pw::value(a), + pw::cst(0.0))) | a.domain()); + } + + /************************************************/ + /* Retrieve Components (Maximising the criteria)*/ + /************************************************/ + A component_img; + { + p_array< mln_psite_(A) > obj_array; + I output = level::stretch(int_u8(), a); //adapt to 0-255 + io::pgm::save(output, "components.pgm"); + + obj_array = morpho::tree::get_components(t, a); + std::cout << obj_array.nsites() << std::endl; + + component_img = morpho::tree::propagate_components(a, t, obj_array, 1); + + // debug + //I output = level::stretch(int_u8(), component_img); //adapt to 0-255 + //io::pgm::save(output, "components.pgm"); + + } + + + /************************************************/ + /* WATERSHED */ + /************************************************/ + typedef image2d<int_u16> WST; + int_u16 n_basins = 0; + WST wst = morpho::watershed::flooding(component_img, c4(), n_basins); + + if (!output_ || output_ == 1) + { + I_ out = morpho::watershed::superpose(input_, wst); + io::ppm::save(out, "superpose.pgm"); + } + if (!output_ || output_ == 2) + std::cout << "Number of basins: " << n_basins << std::endl; + + if (!output_ || output_ == 3) + { + typedef image2d<value::label_16> L; + L lab = level::convert(value::label_16(), + morpho::elementary::dilation(wst, c8())); + I_ out = color_labeling_mean(input_, lab, n_basins); + io::ppm::save(out, "mean.pgm"); + } +} Index: trunk/milena/sandbox/edwin/rush/exo2/Makefile =================================================================== --- trunk/milena/sandbox/edwin/rush/exo2/Makefile (revision 3687) +++ trunk/milena/sandbox/edwin/rush/exo2/Makefile (revision 3688) @@ -13,8 +13,10 @@ SRC= OUT_IMG=superpose.pgm mean.pgm gradient.pgm closing.pgm +BIN=wst_from_closing wst_from_tree -all: wst_from_closing + +all: $(BIN) %: %.cc $(CXX) $(CXXFLAGS) $< -o $@ @@ -22,8 +24,7 @@ clean: rm -f $(OUT_IMG) - rm -f wst_from_closing - + rm -f $(BIN) %.o: %.cc $(CXX) $(CXXFLAGS) -c $< \ No newline at end of file