From: Maxime van Noppen <yabo(a)lrde.epita.fr>
To: olena-patches(a)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(a)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);
}