Commit 4ec694d9 authored by Thierry Geraud's avatar Thierry Geraud
Browse files

Augment Laurent's ISMM code.

	* laurent/playing_with_attributes.cc: Augment.
	* laurent/ismm2009.cc: Memorize as...
	* laurent/ismm2009.v2.cc: ...this new file.
	* laurent/ismm2009.cc: Augment.


git-svn-id: https://svn.lrde.epita.fr/svn/oln/trunk@3173 4aad255d-cdde-0310-9447-f3009e2ae8c0
parent 01ca7d23
2009-01-20 Thierry Geraud <thierry.geraud@lrde.epita.fr>
Augment Laurent's ISMM code.
* laurent/playing_with_attributes.cc: Augment.
* laurent/ismm2009.cc: Memorize as...
* laurent/ismm2009.v2.cc: ...this new file.
* laurent/ismm2009.cc: Augment.
2009-01-19 Thierry Geraud <thierry.geraud@lrde.epita.fr>
Augment code for Laurent.
......
#include "ismm2009.hh"
#include <mln/value/int_u8.hh>
#include <mln/io/pgm/load.hh>
#include <mln/io/pgm/save.hh>
#include <mln/value/label_8.hh>
#include <mln/value/label_16.hh>
#include <mln/io/pgm/load.hh>
#include <mln/util/ord_pair.hh>
#include <mln/debug/println.hh>
#include <mln/core/routine/duplicate.hh>
......@@ -18,14 +21,9 @@
/*
TO-DO list:
-----------
- having a heap for every lr (support merge)
- handling adjacency on the fly (instead of having an image)
*/
......@@ -266,18 +264,18 @@ namespace mln
typename N_e2e,
typename L >
mln_ch_value(G, L)
f_to_wst_unique_g(F& f, // On pixels.
G& g, // On edges.
const N_e2p& e2p,
const N_e2e& e2e,
L& n_basins,
bool echo)
compute_wst_g_from_f(F& f, // On pixels.
G& g, // On edges.
const N_e2p& e2p,
const N_e2e& e2e,
L& n_basins,
bool echo)
{
data::paste(morpho::gradient(extend(g, f),
e2p.win()),
g);
// FIXME: Here, we want a unique value per edge!
# ifdef MAKE_UNIQUE
if (echo)
debug::println("g (before):", g);
......@@ -311,6 +309,9 @@ namespace mln
}
}
# endif // MAKE_UNIQUE
mln_VAR( wst_g,
morpho::meyer_wst(g, e2e, n_basins) );
......@@ -333,8 +334,9 @@ namespace mln
void usage(char* argv[])
{
std::cerr << "usage: " << argv[0] << " input.pgm" << std::endl;
std::cerr << "Laurent ISMM 2009 scheme." << std::endl;
std::cerr << "usage: " << argv[0] << " input.pgm echo output.pgm" << std::endl;
std::cerr << "Laurent ISMM 2009 scheme with saliency map as output." << std::endl;
std::cerr << " echo = 0 or 1." << std::endl;
abort();
}
......@@ -347,14 +349,20 @@ int main(int argc, char* argv[])
using value::int_u8;
using value::label_16;
bool echo = true;
if (argc != 2)
if (argc != 4)
usage(argv);
image2d<int_u8> raw_f;
io::pgm::load(raw_f, argv[1]);
bool echo;
{
int echo_ = std::atoi(argv[2]);
if (echo_ != 0 && echo_ != 1)
usage(argv);
echo = bool(echo_);
}
typedef image2d<int_u8> Complex;
typedef mln_pset_(Complex) full_D;
......@@ -372,15 +380,9 @@ int main(int argc, char* argv[])
L n_basins;
mln_VAR( wst_g,
f_to_wst_g(f, g, e2p(), e2e(), n_basins) );
/*
UNIQUE:
mln_VAR( wst_g,
f_to_wst_unique_g(f, g, e2p(), e2e(), n_basins, echo) );
*/
compute_wst_g_from_f(f, g, e2p(), e2e(), n_basins, echo) );
if (echo)
......@@ -501,11 +503,12 @@ int main(int argc, char* argv[])
std::vector<pair_t> v = sort_attributes(a, n_basins); // Sort regions.
// Optional code (for testing purpose): change attributes
// so that they are all different.
// Maybe activate to test purpose:
/*
# ifdef MAKE_UNIQUE
make_unique_attribute(a, v, n_basins, echo);
*/
# endif
// Display attributes.
......@@ -796,11 +799,11 @@ int main(int argc, char* argv[])
// +---------------------------------------------------------------+
{
// Dealing with the watershed line.
// Dealing with the watershed line.
mln_VAR(aa_line, aa | is_line);
mln_VAR(aa_line, aa | is_line);
{
{
// First, processing the 1D-faces (edges) of the watershed line.
......@@ -886,16 +889,26 @@ int main(int argc, char* argv[])
}
if (echo)
debug::println("aa | basins", aa_basins);
debug::println("aa | basins:", aa_basins);
}
if (echo)
debug::println("aa:", aa);
// Output is salency map.
{
image2d<int_u8> output(f_.domain());
data::fill(output, 0);
data::paste(aa_line, output);
io::pgm::save(output, argv[3]);
}
} // end of main
......
This diff is collapsed.
......@@ -13,6 +13,10 @@
#include <mln/morpho/tree/compute_attribute_image.hh>
#include <mln/labeling/regional_minima.hh>
#include <mln/core/site_set/p_array.hh>
#include <mln/level/sort_psites.hh>
#include <mln/geom/nsites.hh>
#include <mln/accu/count.hh>
......@@ -26,6 +30,200 @@ void usage(char* argv[])
namespace mln
{
template <typename T>
struct node_pred : Function_p2b< node_pred<T> >
{
typedef bool result;
template <typename P>
bool operator()(const P& p) const
{
return t->is_a_node(p);
}
const T* t;
};
template <typename T, typename I>
void depict_tree_attributes(const T& t, // Tree.
const I& a) // Attribute image.
{
typedef mln_site(I) P;
mln_ch_value(I, bool) deja_vu;
initialize(deja_vu, a);
data::fill(deja_vu, false);
typedef typename T::nodes_t nodes_t;
mln_fwd_piter(nodes_t) p(t.nodes());
for_all(p)
{
if (deja_vu(p))
continue;
P e = p;
do
{
std::cout << a(e) << ':' << e << " -> ";
deja_vu(e) = true;
e = t.parent(e);
}
while (! deja_vu(e));
std::cout << a(e) << ':' << e << std::endl;
}
std::cout << std::endl;
}
template <typename T, typename I>
mln_concrete(I)
change_tree_attributes(const T& t, // Tree.
const I& a, // Attribute image.
bool echo = false)
{
typedef mln_site(I) P;
typedef mln_value(I) A; // Type of attributes.
// Test that attributes increase with parenthood.
mln_fwd_piter(T) p(t.domain());
for_all(p)
if (t.is_a_non_root_node(p))
{
mln_assertion(t.is_a_node(t.parent(p)));
mln_invariant(a(t.parent(p)) >= a(p));
}
if (echo)
depict_tree_attributes(t, a);
node_pred<T> node_only;
node_only.t = &t;
typedef p_array<P> S;
S s = level::sort_psites_increasing(a | node_only);
mln_invariant(geom::nsites(a | t.nodes()) == s.nsites());
mln_ch_value(I, bool) mark;
initialize(mark, a);
data::fill(mark, false);
// Modify attributes.
mln_concrete(I) aa;
initialize(aa, a);
data::fill(aa, 0);
{
P e, par_e;
A v;
bool found;
mln_fwd_piter(S) p(s);
// Initialization.
for_all(p)
{
if (mark(p) == true)
continue;
// First, fetch the attribute value v from p;
e = p;
found = false;
while (mark(e) == false && e != t.parent(e))
{
par_e = t.parent(e);
if (mark(par_e) == true)
{
v = a(e);
found = true;
break;
}
e = par_e;
};
if (! found && e == t.parent(e))
{
// e is a root node; we get its value:
v = a(e);
if (echo)
std::cout << "from p = " << p
<< " to root e = " << e
<< " v = " << v
<< std::endl;
// we set aa from p to the root node
e = p;
do
{
aa(e) = v;
mln_invariant(mark(e) == false);
mark(e) = true;
e = t.parent(e);
}
while (e != t.parent(e));
// handle the root node 'e':
aa(e) = v;
mln_invariant(mark(e) == false);
mark(e) = true;
mln_invariant(a(e) == v);
}
else if (found)
{
e = p;
P last_e = P(0,0);
while (mark(e) == false)
{
aa(e) = v;
mark(e) = true;
last_e = e;
e = t.parent(e);
};
if (echo)
{
if (last_e == p)
std::cout << "p = " << p
<< " par(e) = " << par_e
<< " so keep v = " << v
<< std::endl;
else
std::cout << "from p = " << p
<< " to e = " << last_e
<< " with par(e) = " << par_e
<< " v = " << v
<< std::endl;
}
}
}
if (echo)
depict_tree_attributes(t, aa);
} // end of Modify attributes.
return aa;
}
} // mln
template <typename I, typename N, typename L>
void do_it(const I& g, const N& nbh, L& n_labels)
{
......@@ -34,7 +232,7 @@ void do_it(const I& g, const N& nbh, L& n_labels)
// regional minima
mln_ch_value(I,L) regmin = labeling::regional_minima(g, nbh, n_labels);
debug::println("regmin(g):", regmin);
// debug::println("regmin(g):", regmin);
// watershed
......@@ -42,7 +240,7 @@ void do_it(const I& g, const N& nbh, L& n_labels)
L n_basins;
mln_ch_value(I,L) w = morpho::meyer_wst(g, nbh, n_basins);
mln_invariant(n_basins == n_labels);
debug::println("w(g):", w);
// debug::println("w(g):", w);
{
......@@ -55,12 +253,28 @@ void do_it(const I& g, const N& nbh, L& n_labels)
accu::count< util::pix<I> > a_; // Kind of attribute.
mln_ch_value(I,unsigned) a = morpho::tree::compute_attribute_image(a_, t);
debug::println("a:", a);
debug::println("a | nodes:", a | t.nodes());
mln_ch_value(I,unsigned) aa = change_tree_attributes(t, a);
debug::println("aa | nodes:", aa | t.nodes());
// Back-propagation from nodes to components.
{
mln_fwd_piter(tree_t) p(t.domain());
for_all(p)
if (! t.is_a_node(p))
{
mln_assertion(t.is_a_node(t.parent(p)));
aa(p) = aa(t.parent(p));
}
}
debug::println("a | w line:", a | (pw::value(w) == pw::cst(0)));
debug::println("a | w basins:", a | (pw::value(w) != pw::cst(0)));
debug::println("aa | w line:", aa | (pw::value(w) == pw::cst(0)));
// debug::println("a | w basins:", a | (pw::value(w) != pw::cst(0)));
// debug::println("a | regmin:", a | (pw::value(regmin) != pw::cst(0)));
debug::println("a | regmin:", a | (pw::value(regmin) != pw::cst(0)));
}
} // end of do_it
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment