From: Maxime van Noppen <yabo@lrde.epita.fr> To: olena-patches@lrde.epita.fr Subject: r2758: Big cleanup URL: https://svn.lrde.epita.fr/svn/oln/branches/cleanup-2008/milena/sandbox ChangeLog: 2008-11-01 Maxime van Noppen <yabo@lrde.epita.fr> Big cleanup. * max_tree.hh: Factorize code in generic methods. * v2.cc: Comment and clean code. --- max_tree.hh | 218 +++++++++++++++++++++++++----------------------------------- v2.cc | 111 +++++++++++++++++++++++------- 2 files changed, 177 insertions(+), 152 deletions(-) Index: branches/cleanup-2008/milena/sandbox/classif/max_tree.hh =================================================================== --- branches/cleanup-2008/milena/sandbox/classif/max_tree.hh (revision 2757) +++ branches/cleanup-2008/milena/sandbox/classif/max_tree.hh (revision 2758) @@ -37,21 +37,16 @@ mln_ch_value(I, point) new_parent; mln_ch_value(I, point) zpar; - // image of volumes - image3d<unsigned> vol; - image3d<unsigned> nb_represent; - image3d<double> density; - //tags image3d<bool> is_active; - image3d< algebra::vec<3, double> > mean_color; max_tree_(const I& f, const N& nbh) - : f(f), nbh(nbh), vol(f.domain()), nb_represent(f.domain()), density(f.domain()), - is_active(f.domain()), mean_color(f.domain()), new_parent(f.domain()) + : f(f), nbh(nbh), is_active(f.domain()), new_parent(f.domain()) { run(); level::fill(is_active, true); + + new_parent = parent; } void run() @@ -94,11 +89,11 @@ point active_parent(const point& p) { - if(is_root(p)) - return p; - point node = parent(p); - while (not is_active(node)) - node = parent(node); + point node = new_parent(p); + + while (not is_active(node) && not is_root(node)) + node = new_parent(node); + return node; } @@ -108,163 +103,169 @@ zpar(p) = p; } - void area() + image3d<unsigned> compute_nb_represent() { - image2d<value::int_u16> area(f.domain()); - level::fill(area, 1); - mln_fwd_piter(S) p(s); - for_all(p) - { - if (parent(p) == p) - continue; - area(parent(p)) += area(p); - } - debug::println(area); - } + image3d<unsigned> nb_represent(f.domain()); - void volume() - { - level::fill(vol, 0); level::fill(nb_represent, 0); - - { mln_fwd_piter(S) p(s); for_all(p) { - vol(p) += 1; nb_represent(p) += f(p); - if (not is_root(p)) - { nb_represent(parent(p)) += nb_represent(p); - vol(parent(p)) += vol(p); } - density(parent(p)) = (nb_represent(parent(p)) - nb_represent(p)) / (double) (vol(parent(p)) - vol(p)); - } - } - - { - mln_fwd_piter(S) p(s); - for_all(p) - { - std::cerr << " Color " << p << std::endl - << " vol = " << vol(p) << " vertices" << std::endl - << " nb_represent = " << nb_represent(p) << std::endl - << " f = " << f(p) << std::endl - << " density = " << density(p) << " representant / vertices " << std::endl << std::endl; - } - } + return nb_represent; } - void density_fusion(float ratio) + image3d<unsigned> compute_volume() { - assert(ratio < 1); + image3d<unsigned> volume(f.domain()); + level::fill(volume, 0); mln_fwd_piter(S) p(s); - for_all(p) - { - if (density(active_parent(p)) > (1 - ratio) * density(p) && - density(active_parent(p)) < (1 + ratio) * density(p)) - is_active(p) = false; - } - } - - void density_closing(float lambda) - { - assert(ratio < 1); - mln_fwd_piter(S) p(s); for_all(p) { - if (density(p) < lambda) - is_active(p) = false; + volume(p) += 1; + if (not is_root(p)) + volume(parent(p)) += volume(p); } + + return volume; } - void compute_mean_color() + image3d< algebra::vec<3, double> > compute_mean_color() { - level::fill(mean_color, make::vec(0, 0, 0)); + image3d< algebra::vec<3, double> > mean_color(f.domain()); + + update_parents(); mln_fwd_piter(S) p(s); for_all(p) mean_color(p) = make::vec(p[0], p[1], p[2]); for_all(p) - mean_color(parent(p)) = (mean_color(parent(p)) + mean_color(p)) / 2.; + mean_color(new_parent(p)) = (mean_color(new_parent(p)) + mean_color(p)) / 2.; - for_all(p) - if (mean_color(p)[0] < 10 && mean_color(p)[1] < 10 && mean_color(p)[2] < 10) - std::cerr << "Warning " << p << " == " << mean_color(p) << std::endl; + return mean_color; } - // Cut components with less represents than lambda - void volume_fusion(int lambda) + template<typename X> + void lumberjack(const X& ima, const mln_value(X)& lambda) { + unsigned progress = 0; + unsigned step = s.nsites() / 100; + mln_fwd_piter(S) p(s); + for_all(p) { - if (vol(p) < lambda) + if (ima(p) < lambda) is_active(p) = false; + + ++progress; + if (progress % step == 0) + { + std::cout << "." << std::flush; + progress = 0; } } - void nb_represent_fusion(int lambda) + std::cout << std::endl; + } + + template<typename X> + void nuclear_fusion(const X& ima, const mln_value(X)& lambda) { + unsigned progress = 0; + unsigned step = s.nsites() / 100; + + update_parents(); + mln_fwd_piter(S) p(s); for_all(p) { - if (nb_represent(p) < lambda) + if (fabs(1 - ima(new_parent(p)) / ima(p)) < lambda) is_active(p) = false; + + ++progress; + if (progress % step == 0) + { + std::cout << "." << std::flush; + progress = 0; } } + std::cout << std::endl; + } + void color_fusion(int lambda) { + unsigned progress = 0; + unsigned step = s.nsites() / 100; + + update_parents(); + mln_fwd_piter(S) p(s); for_all(p) { - if (parent(p)[0] - p[0] < lambda && - parent(p)[1] - p[1] < lambda && - parent(p)[2] - p[2] < lambda) + if (new_parent(p)[0] - p[0] < lambda && + new_parent(p)[1] - p[1] < lambda && + new_parent(p)[2] - p[2] < lambda) is_active(p) = false; - } - } - point active_parent(const point& p) + ++progress; + if (progress % step == 0) { - point node = parent(p); - - while (not is_active(node) && not is_root(node)) - node = parent(node); - - return node; + std::cout << "." << std::flush; + progress = 0; + } + } + std::cout << std::endl; } void update_parents() { + unsigned progress = 0; + unsigned step = s.nsites() / 100; + + std::cout << "Update parents"; + mln_fwd_piter(S) p(s); for_all(p) + { new_parent(p) = active_parent(p); + + ++progress; + if (progress % step == 0) + { + std::cout << "." << std::flush; + progress = 0; + } + } + std::cout << std::endl; } template < typename J > - void to_ppm(const J& ima, const std::string& file, unsigned f) + void to_ppm(const J& ima, const std::string& file, unsigned f, + const image3d< algebra::vec<3, double> >& mean_color) { + update_parents(); + J out(ima.domain()); level::fill(out, value::rgb8(0, 0, 0)); mln_piter(J) p(ima.domain()); for_all(p) { - point3d p3 = point3d(ima(p).red() / f, ima(p).green() / f, ima(p).blue() / f); - point3d node = new_parent(p3); + point3d node = new_parent(point3d(ima(p).red() / f, ima(p).green() / f, ima(p).blue() / f)); out(p) = value::rgb8(static_cast<unsigned char>(mean_color(node)[0] * f), static_cast<unsigned char>(mean_color(node)[1] * f), static_cast<unsigned char>(mean_color(node)[2] * f)); - //out(p) = value::rgb8(mean_color(node)[0] * f, mean_color(node)[1] * f, mean_color(node)[2] * f); } io::ppm::save(out, file); @@ -272,41 +273,9 @@ unsigned number_of_nodes() { - p_array<point> node; - - mln_fwd_piter(S) p(s); - for_all(p) - if (is_node(p)) - node.insert(p); - - std::cout << s.nsites() << std::endl; - std::cout << parent.domain().nsites() << std::endl; - std::cout << node.nsites() << std::endl; - return s.nsites(); } - void print_class_info() - { - int nb_class = 0; - - mln_fwd_piter(S) p(s); - - //std::cout.width(5); - std::cout.precision(2); - - std::cout << "Color\t\tId\t\tdensity\t\tvolume\t\tnb_represent" << std::endl; - - for_all(p) - { - if (is_active(p)) - { - std::cout << mean_color(p) << "\t\t" << nb_class << "\t\t" << density(p) << "\t\t" << vol(p) << "\t\t" << nb_represent(p) << std::endl; - ++nb_class; - } - } - } - bool is_root(const point& p) const { return parent(p) == p; @@ -334,7 +303,6 @@ zpar(r) = p; } } - }; Index: branches/cleanup-2008/milena/sandbox/classif/v2.cc =================================================================== --- branches/cleanup-2008/milena/sandbox/classif/v2.cc (revision 2757) +++ branches/cleanup-2008/milena/sandbox/classif/v2.cc (revision 2758) @@ -38,45 +38,100 @@ return histo; } +template <typename I> +image3d< double > +compute_density(const I& weight, const I& volume) +{ + image3d< double > density(volume.domain()); + + mln_piter(I) p(volume.domain()); + for_all(p) + density(p) = weight(p) / volume(p); + + return density; +} + template <typename I, typename J, typename N> unsigned -compute_max_tree(const I& ima, const J& histo, const N& nbh, - const unsigned f, float lambda, float ratio) +process_max_tree(const I& ima, const J& histo, const N& nbh, + double density_lambda, unsigned volume_lambda, + unsigned nb_represent_lambda, unsigned color_lambda, + unsigned div_factor) { max_tree_<J,N> run(histo, nbh); - run.volume(); + // FIXME: write a compute() method with functor argument + image3d<unsigned> nb_represent = run.compute_nb_represent(); + image3d<unsigned> volume = run.compute_volume(); + image3d< algebra::vec<3, double> > mean_color = run.compute_mean_color(); + image3d<double> density = compute_density(nb_represent, volume); - std::cout << "step 1 - nb_represent fusion" << std::endl; - //run.nb_represent_fusion(lambda); - std::cout << "step 2 - volume fusion" << std::endl; - //run.volume_fusion(lambda); - std::cout << "step 3 - color fusion" << std::endl; - //run.color_fusion(lambda); - std::cout << "step 3 - density fusion" << std::endl; - //run.density_fusion(ratio); + // Density closing + if (density_lambda > 0.00001) + { + std::cout << "Density cutting" << std::endl; + run.nuclear_fusion(density, density_lambda); + } - std::cout << "step Update parents" << std::endl; - run.update_parents(); + // Volume cutting + if (volume_lambda != 0) + { + std::cout << "Volume cutting" << std::endl; + run.lumberjack(volume, volume_lambda); + } + + // Represent cutting + if (nb_represent_lambda != 0) + { + std::cout << "nb_represent cutting" << std::endl; + run.lumberjack(nb_represent, nb_represent_lambda); + } + + // Color fusion + if (color_lambda != 0) + { + std::cout << "Color fusion" << std::endl; + run.color_fusion(color_lambda); // FIXME: factorize the code with a functor + } - std::cout << "step Compute mean color" << std::endl; + // Compute mean color of active nodes + std::cout << "Compute mean color" << std::endl; run.compute_mean_color(); - std::cout << "step Print class info" << std::endl; - run.print_class_info(); + // Print informations on the filtered max tree + { + int nb_class = 0; + + mln_piter(image3d<unsigned>) p(nb_represent.domain()); + + std::cerr.precision(2); + + std::cerr << "Color\t\tId\t\tdensity\t\tvolume\t\tnb_represent" << std::endl; + + for_all(p) + if (run.is_active(p)) + { + std::cerr << mean_color(p) << "\t\t" << nb_class << "\t\t" << density(p) << "\t\t" << volume(p) << "\t\t" << nb_represent(p) << std::endl; + ++nb_class; + } - std::cout << "step Output image" << std::endl; - run.to_ppm(ima, "out.ppm", f); + std::cout << "Number of classes : " << nb_class << std::endl; + } + + + // Write the image w.r.t. the max tree + run.to_ppm(ima, "out.ppm", div_factor, mean_color); } bool usage(int argc, char ** argv) { - if (argc != 5) + if (argc != 7) { - std::cout << "usage: " << argv[0] << " image div_factor lambda ratio" << std::endl; + std::cout << "usage: " << argv[0] << " image div_factor density_lambda volume_lambda nb_represent_lambda color_lambda" << std::endl; return false; } + return true; } @@ -86,10 +141,14 @@ return 1; image2d<value::rgb8> ima; + ima = io::ppm::load<value::rgb8>(argv[1]); - const int div_factor = atoi(argv[2]); - const float lambda = atof(argv[3]); - const float ratio = atof(argv[4]); + + int div_factor = atoi(argv[2]); + float density_lambda = atof(argv[3]); + unsigned volume_lambda = atoi(argv[4]); + unsigned nb_represent_lambda = atoi(argv[5]); + unsigned color_lambda = atoi(argv[6]); //make histo image3d<unsigned> histo = fill_histo(ima, div_factor); @@ -98,8 +157,6 @@ accu::mean<unsigned, unsigned, unsigned> mean; image2d<unsigned> phisto = proj(histo, mean); - //debug::println(phisto); - - // Compute max_tree - compute_max_tree(ima, histo, c6(), div_factor, lambda, ratio); + // Process max_tree + process_max_tree(ima, histo, c6(), density_lambda, volume_lambda, nb_represent_lambda, color_lambda, div_factor); }
participants (1)
-
Maxime van Noppen