https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Update segmentation code.
* theo/color/segment.cc: Rename as...
* theo/color/segment_rgb_edges.cc: ...this.
Update.
* theo/color/segment_debase.cc: Rename as...
* theo/color/segment_gl_pixels.cc: ...this.
Update.
* theo/color/segment.hh (filter): Add change_kind.
* theo/color/change_attributes.hh
(extinct_attributes, move_down_attributes): Use echo.
(fuse_down_attributes): Use echo.
change_attributes.hh | 94 +++++++++++++++++++++++++++++++++++++--------------
segment.hh | 27 +++++++++++++-
segment_gl_pixels.cc | 32 ++++++++++++-----
segment_rgb_edges.cc | 66 ++++++++++++++++++++---------------
4 files changed, 154 insertions(+), 65 deletions(-)
Index: theo/color/segment.hh
--- theo/color/segment.hh (revision 3312)
+++ theo/color/segment.hh (working copy)
@@ -329,8 +329,11 @@
mln_concrete(F)
filter(const F& f, // a "gradient" of color image
const N& nbh,
+
const A& a_, // an attribute
+ unsigned change_kind,
bool do_extinction,
+
unsigned n_objects,
bool echo = false)
{
@@ -350,8 +353,25 @@
debug::println("a = ", a);
}
+ switch (change_kind)
+ {
+ case 0:
+ break;
+ case 1:
+ std::cout << "move down attributes" << std::endl;
+ move_down_attributes(t, a, echo);
+ break;
+ case 2:
+ std::cout << "fuse up attributes" << std::endl;
+ fuse_down_attributes(t, a, echo);
+ break;
+ }
+
if (do_extinction)
- extinct_attributes(t, a);
+ {
+ std::cout << "do extinction" << std::endl;
+ extinct_attributes(t, a, echo);
+ }
if (echo)
debug::println("a' =", a | t.nodes());
@@ -362,10 +382,13 @@
less, lambda, // output
echo);
- if (do_extinction == false)
+ if (do_extinction == false && change_kind == 0)
+ {
+ std::cout << "testing filter result v. classical method" <<
std::endl;
test_filter(a_, lambda, f, g, nbh,
n_objects, less,
echo);
+ }
return g;
}
Index: theo/color/segment_rgb_edges.cc
--- theo/color/segment_rgb_edges.cc (revision 3312)
+++ theo/color/segment_rgb_edges.cc (working copy)
@@ -22,10 +22,11 @@
#include <mln/morpho/dilation.hh>
#include <mln/morpho/erosion.hh>
#include <mln/morpho/meyer_wst.hh>
-
+#include <mln/labeling/compute.hh>
#include <mln/accu/count.hh>
#include <mln/accu/volume.hh>
+#include <mln/accu/mean.hh>
#include "sum_pix.hh"
@@ -241,8 +242,9 @@
void usage(char* argv[])
{
- std::cerr << "usage: " << argv[0] << " input.ppm n
extinction output.ppm echo" << std::endl;
+ std::cerr << "usage: " << argv[0] << " input.ppm n
change extinction echo output.ppm" << std::endl;
std::cerr << " n >= 2" << std::endl;
+ std::cerr << " change = 0 (none), 1 (move-down), or 2 (fuse-up)"
<< std::endl;
std::cerr << " extinction = 0 (none) or 1 (effective)" <<
std::endl;
std::cerr << " echo = 0 (mute) or 1 (verbose)" << std::endl;
abort();
@@ -256,12 +258,10 @@
using value::int_u8;
using value::rgb8;
- if (argc != 6)
+ if (argc != 7)
usage(argv);
- {
-
// Color version.
// --------------
@@ -269,9 +269,17 @@
image2d<rgb8> input;
io::ppm::load(input, argv[1]);
+
unsigned n_objects = atoi(argv[2]);
- bool do_extinction = atoi(argv[3]);
+ int change_kind = atoi(argv[3]);
+ if (change_kind < 0 || change_kind > 2)
+ usage(argv);
+
+ int do_extinction = atoi(argv[4]);
+ if (do_extinction != 0 && do_extinction != 1)
+ usage(argv);
+
bool echo = atoi(argv[5]);
@@ -295,7 +303,8 @@
accu::blen_pix<I> a_;
f_t g = filter(f, e2e(),
- a_, do_extinction,
+ a_,
+ change_kind, do_extinction,
n_objects,
echo);
@@ -324,7 +333,7 @@
}
image2d<L> w_all = w.unmorph_();
- {
+
// edges -> squares
mln_VAR(w_squares, w_all | is_square);
data::paste(morpho::dilation(extend(w_squares, pw::value(w_all)),
@@ -335,38 +344,37 @@
data::paste(morpho::erosion(extend(w_points, pw::value(w_all)),
c4().win()),
w_all);
- }
- io::pgm::save( level::transform(w_all, convert::to_fun(L_to_int_u8)),
- "temp_w_all.pgm" );
- }
-// {
-// // Gray-level version.
+ // Outputing.
+ // ----------
-// image2d<int_u8> f_;
-// io::pgm::load(f_, argv[1]);
-// unsigned n_objects = atoi(argv[2]);
+ typedef algebra::vec<3,float> vec3f;
-// mln_VAR(f, f_ | is_edge);
-// typedef f_t I;
+ util::array<vec3f> m_3f = labeling::compute(accu::mean<rgb8>(),
+ input,
+ full2image(w_all),
+ nbasins);
+ m_3f[0] = vec3f::zero;
-// typedef p_array<point2d> S;
-// S s = level::sort_psites_decreasing(f);
+ util::array<rgb8> m;
+ convert::from_to(m_3f, m);
-// typedef morpho::tree::data<I,S> tree_t;
-// tree_t t(f, s, e2e());
+ io::ppm::save( level::transform(w_all,
+ convert::to< fun::i2v::array<rgb8> >(m) ),
+ argv[6] );
-// accu::count< util::pix<I> > a_;
-// mln_VAR(a, compute_attribute_on_nodes(a_, t));
-// f_t g = filter(a, t, e2e(), n_objects);
+// debug::println("input_", input_);
+// debug::println("w_squares", w_squares);
-// unsigned nbasins;
-// debug::println("wst =", morpho::meyer_wst(g, e2e(), nbasins));
-// }
+// FIXME: The code below does not work!
+// util::array<vec3f> m_3f = labeling::compute(accu::mean<rgb8>(),
+// input_,
+// w_squares,
+// nbasins);
}
Index: theo/color/change_attributes.hh
--- theo/color/change_attributes.hh (revision 3312)
+++ theo/color/change_attributes.hh (working copy)
@@ -96,25 +96,6 @@
}
- // Modified version.
-
- template <typename T, typename I, typename M>
- inline
- mln_value(I)
- extinct_rec__(const T& t, // tree
- const I& a, // original attribute image
- I& ea, // extincted attribute image
- M& mark,
- const mln_psite(I)& p)
- {
- mln_invariant(mark(p) == false);
- mark(p) = true;
- if (t.parent(p) == p || mark(t.parent(p)) == true) // Stop.
- return a(t.parent(p)); // The parent attribute!
- return ea(p) = extinct_rec__(t, a, ea, mark, t.parent(p));
- }
-
-
} // end of internal
@@ -123,8 +104,15 @@
template <typename T, typename I>
void
extinct_attributes(const T& t, // Tree.
- I& a) // Attribute image.
+ I& a, // Attribute image.
+ bool echo = false)
+ {
+ if (echo)
{
+ std::cout << "before:" << std::endl;
+ display_tree_attributes(t, a);
+ }
+
typedef mln_site(I) P;
typedef mln_value(I) A; // Type of attributes.
@@ -148,15 +136,47 @@
}
// debug::println(mark | t.nodes());
+
+ if (echo)
+ {
+ std::cout << "after:" << std::endl;
+ display_tree_attributes(t, a);
+ }
}
+ /*
// Modified version.
+ //
+ // The extinction moves down the parent attribute. With the 1st
+ // experiments, that does not work. Yet, it is better to first modify
+ // the attributes (move down the parent values) the classically extinct.
+
+ namespace internal
+ {
+
+ template <typename T, typename I, typename M>
+ inline
+ mln_value(I)
+ extinct_rec__(const T& t, // tree
+ const I& a, // original attribute image
+ I& ea, // extincted attribute image
+ M& mark,
+ const mln_psite(I)& p)
+ {
+ mln_invariant(mark(p) == false);
+ mark(p) = true;
+ if (t.parent(p) == p || mark(t.parent(p)) == true) // Stop.
+ return a(t.parent(p)); // The parent attribute!
+ return ea(p) = extinct_rec__(t, a, ea, mark, t.parent(p));
+ }
+
+ } // end of internal
template <typename T, typename I>
void
- extinct_attributes__(const T& t, // Tree.
+ extinct_attributes_new(const T& t, // Tree.
I& a) // Attribute image.
{
typedef mln_site(I) P;
@@ -188,23 +208,36 @@
// debug::println(mark | t.nodes());
}
+ */
// Move down.
// ----------
- template <typename A, typename T>
+ template <typename T, typename A>
inline
void
- move_down_attributes(A& a, const T& t)
+ move_down_attributes(const T& t, A& a, bool echo = false)
+ {
+ if (echo)
{
+ std::cout << "before:" << std::endl;
+ display_tree_attributes(t, a);
+ }
typedef typename T::nodes_t N;
mln_fwd_piter(N) n(t.nodes());
for_all(n)
a(n) = a(t.parent(n));
+ // Test.
for_all(n)
mln_invariant(a(n) <= a(t.parent(n)));
+
+ if (echo)
+ {
+ std::cout << "after:" << std::endl;
+ display_tree_attributes(t, a);
+ }
}
@@ -213,11 +246,16 @@
// Fuse down.
// ----------
- template <typename A, typename T>
+ template <typename T, typename A>
inline
void
- fuse_down_attributes(A& a, const T& t)
+ fuse_down_attributes(const T& t, A& a, bool echo = false)
{
+ if (echo)
+ {
+ std::cout << "before:" << std::endl;
+ display_tree_attributes(t, a);
+ }
typedef typename T::nodes_t N;
mln_fwd_piter(N) n(t.nodes());
for_all(n)
@@ -225,6 +263,12 @@
for_all(n)
mln_invariant(a(n) <= a(t.parent(n)));
+
+ if (echo)
+ {
+ std::cout << "after:" << std::endl;
+ display_tree_attributes(t, a);
+ }
}
Index: theo/color/segment_gl_pixels.cc
--- theo/color/segment_gl_pixels.cc (revision 3312)
+++ theo/color/segment_gl_pixels.cc (working copy)
@@ -17,8 +17,7 @@
#include <mln/morpho/elementary/gradient.hh>
#include <mln/morpho/meyer_wst.hh>
-#include <mln/accu/volume.hh>
-#include "sum_pix.hh"
+#include <mln/accu/height.hh>
#include "segment.hh"
@@ -28,8 +27,10 @@
void usage(char* argv[])
{
- std::cerr << "usage: " << argv[0] << " input.pgm n
extinction output.ppm echo" << std::endl;
+ std::cerr << "usage: " << argv[0] << " input.pgm n
change extinction echo output.ppm" << std::endl;
+ std::cerr << "gray-level version on pixels (without edges)" <<
std::endl;
std::cerr << " n >= 2" << std::endl;
+ std::cerr << " change = 0 (none), 1 (move-down), or 2 (fuse)" <<
std::endl;
std::cerr << " extinction = 0 (none) or 1 (effective)" <<
std::endl;
std::cerr << " echo = 0 (mute) or 1 (verbose)" << std::endl;
abort();
@@ -45,20 +46,29 @@
using value::rgb8;
- if (argc != 6)
+ if (argc != 7)
usage(argv);
// Gray-level debase version.
// --------------------------
+
typedef image2d<int_u8> I;
I input;
io::pgm::load(input, argv[1]);
unsigned n_objects = atoi(argv[2]);
- bool do_extinction = atoi(argv[3]);
+
+ int change_kind = atoi(argv[3]);
+ if (change_kind < 0 || change_kind > 2)
+ usage(argv);
+
+ int do_extinction = atoi(argv[4]);
+ if (do_extinction != 0 && do_extinction != 1)
+ usage(argv);
+
bool echo = atoi(argv[5]);
@@ -69,7 +79,6 @@
// Changing input into 'f'.
I f = morpho::elementary::gradient(input, c4());
- io::pgm::save(f, "temp_f.pgm");
// // granulometry:
@@ -79,10 +88,15 @@
// accu::count< util::pix<I> > a_;
// accu::sum_pix< util::pix<I> > a_;
- accu::volume<I> a_;
+ // accu::volume<I> a_;
+ accu::height<I> a_;
+
+ // It seems that both extinction and changing attributes only
+ // properly works for the 'height' attribute.
I g = filter(f, c4(),
- a_, do_extinction,
+ a_,
+ change_kind, do_extinction,
n_objects,
echo);
@@ -99,5 +113,5 @@
image2d<rgb8> output = level::convert(rgb8(), input);
data::fill((output | (pw::value(w) == 0)).rw(), literal::red);
- io::ppm::save(output, argv[4]);
+ io::ppm::save(output, argv[6]);
}