https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Fetch Ugo's code to prepare merging it with 1st steps.
* jardonnet/n_cmpt/n_cmpt5.hh: Fix typo.
Copy to...
* geraud/tufa_2008/n_cmpt.cc: ...this new file.
Cleanup code.
Fix typos.
(main): New.
geraud/tufa_2008/n_cmpt.cc | 190 ++++++++++++++++++++++++--------------------
jardonnet/n_cmpt/n_cmpt5.hh | 2
2 files changed, 105 insertions(+), 87 deletions(-)
Index: jardonnet/n_cmpt/n_cmpt5.hh
--- jardonnet/n_cmpt/n_cmpt5.hh (revision 3044)
+++ jardonnet/n_cmpt/n_cmpt5.hh (working copy)
@@ -96,7 +96,7 @@
// number of minima
unsigned cmpts = label;
if (lambda > cmpts)
- std::cout << "warning : lambda value is to hight." <<
std::endl;
+ std::cout << "Warning: lambda value is too high!" <<
std::endl;
std::cout << cmpts << std::endl;
Index: geraud/tufa_2008/n_cmpt.cc
--- geraud/tufa_2008/n_cmpt.cc (revision 3043)
+++ geraud/tufa_2008/n_cmpt.cc (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2008 EPITA Research and Development Laboratory
+// Copyright (C) 2008 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
@@ -25,78 +25,68 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-#ifndef MLN_N_CMPT3_HH
-# define MLN_N_CMPT3_HH
-
-# include <mln/labeling/regional_minima.hh>
+#include <mln/core/image/image2d.hh>
# include <mln/core/alias/neighb2d.hh>
-# include <mln/util/set.hh>
+
+#include <mln/value/int_u8.hh>
+#include <mln/value/int_u16.hh>
+#include <mln/io/pgm/load.hh>
# include <mln/debug/println.hh>
# include <mln/debug/iota.hh>
-# include <mln/accu/volume.hh>
+#include <mln/labeling/regional_minima.hh>
+#include <mln/level/fill.hh>
+
# include <mln/morpho/tree/data.hh>
# include <mln/morpho/tree/compute_attribute_image.hh>
-namespace mln
-{
-
- namespace n_cmpt
- {
+#include <mln/accu/volume.hh>
+#include <mln/accu/count.hh>
- template < typename I >
- void n_cmpt5(const I& (((((((ima))))))));
-# ifndef MLN_INCLUDE_ONLY
+namespace mln
+{
template <typename I>
inline
- mln_psite(I)
- find_root(I& parent,
- const mln_psite(I)& x)
+ mln_psite(I) find_root__(I& parent, const mln_psite(I)& x)
{
if (parent(x) == x)
return x;
else
- return parent(x) = find_root(parent, parent(x));
+ return parent(x) = find_root__(parent, parent(x));
}
- template < typename I, typename N>
- I
- n_cmpt3(const I& ima, const N& nbh,
- unsigned lambda)
- {
- std::cout << "/ima/" << std::endl;
- debug::println(ima);
- // compute volume image
- //---------------------
+ template <typename A, typename I, typename N>
+ mln_concrete(I)
+ n_cmpt(A a, const I& f, const N& nbh, unsigned lambda)
+ {
+ // Compute attribute image.
+ //-------------------------
typedef p_array<mln_psite(I)> S;
- typedef mln_ch_value(I,unsigned) V;
- typedef accu::volume<I> A;
+ typedef mln_ch_value(I, mln_result(A)) Attr;
- S sp = level::sort_psites_decreasing(ima);
- morpho::tree::data<I,S> t(ima, sp, nbh);
- V volume = morpho::tree::compute_attribute_image(A(), t);
- sp = level::sort_psites_increasing(volume);
- std::cout << "/volume/" << std::endl;
- debug::println(volume);
+ S s = level::sort_psites_decreasing(f);
+ morpho::tree::data<I,S> t(f, s, nbh);
+ Attr attr = morpho::tree::compute_attribute_image(a, t);
+ s = level::sort_psites_increasing(attr);
+ debug::println("attr =", attr);
- // get /volume/ regional minima
- //-----------------------------
+ // Compute regional minima of attribute image.
+ //--------------------------------------------
unsigned label;
- mln_ch_value(I, unsigned) min_v = labeling::regional_minima(volume, nbh, label);
- std::cout << "/volume/ regional minima" << std::endl;
- debug::println(min_v);
+ mln_ch_value(I, unsigned) min_v = labeling::regional_minima(attr, nbh, label);
+ debug::println("regmin =", min_v);
// number of minima
unsigned cmpts = label;
if (lambda > cmpts)
- std::cout << "warning : lambda value is to hight." <<
std::endl;
+ std::cout << "Warning: lambda value is too high!" <<
std::endl;
std::cout << cmpts << std::endl;
@@ -106,23 +96,21 @@
// init fused image
mln_ch_value(I, bool) fused;
- initialize(fused, volume);
+ initialize(fused, attr);
mln::level::fill(fused, false);
// prepare union find
- typedef mln_psite(V) P;
-
- //data
- mln_ch_value(V, accu::volume<V>) data(volume.domain());
+ typedef mln_psite(I) P;
//deja_vu
- mln_ch_value(V, bool) deja_vu(volume.domain());
- mln::level::fill(deja_vu, false);
+ mln_ch_value(I, bool) deja_vu;
+ initialize(deja_vu, f);
+ level::fill(deja_vu, false);
//parent
- mln_ch_value(V, P) parent(volume.domain());
+ mln_ch_value(I, P) parent(attr.domain());
{
- mln_fwd_piter(S) p(sp);
+ mln_fwd_piter(S) p(s);
for_all(p)
{
parent(p) = p;
@@ -133,32 +121,30 @@
}
}
- // UNION FIND ON VOLUME
- mln_fwd_piter(S) p(sp);
+ // UNION FIND ON ATTR
+ mln_fwd_piter(S) p(s);
mln_niter(N) n(nbh, p);
for_all(p)
{
- std::cout << p << std::endl;
- //if (volume(p) > lambda)
- // goto step2;
+ // std::cout << p << std::endl;
for_all(n)
{
- if (volume.domain().has(n) && deja_vu(n))
+ if (attr.domain().has(n) && deja_vu(n))
{
- //do_union(n, p);
- P r = find_root(parent, n);
+ P r = find_root__(parent, n);
if (r != p)
{
- std::cout << "neighb: " << n << std::endl;
- std::cout << "v(r): " << volume(r) << "
v(p): " << volume(p) << " f(p): " << fused(p) <<
std::endl;
+ // std::cout << "neighb: " << n << std::endl;
+ // std::cout << "v(r): " << attr(r) << " v(p):
"
+ // << attr(p) << " f(p): " << fused(p)
<< std::endl;
- //if (volume(r) != volume(p)) // r and p have different volumes
+ //if (attr(r) != attr(p)) // r and p have different attrs
// This check was wrong.
// you just fused with a minima.
- // then you fuse with a neighbor already fused that has the same volume as
you
+ // then you fuse with a neighbor already fused that has the same attr as you
// a) 1 50 1
// 2 2 2
- // we don't have ( volume(r) == volume(p) ) => not fused(r)
+ // we don't have ( attr(r) == attr(p) ) => not fused(r)
// even if r and p are not minima
// problem :
@@ -166,39 +152,44 @@
// - when fusing cmpts (a) : same level, both fused. DEC
// One cmpt less if
- if (fused(r) && min_v(p) == 0) // p is not a minima
- if (fused(p)) // p already belong to a cmpt (fused for an another n)
- if (cmpts >= lambda) // union is still allowed
+
+// if (fused(r) && min_v(p) == 0) // p is not a minima
+// if (fused(p)) // p already belong to a cmpt (fused for an another n)
+// if (cmpts >= lambda) // union is still allowed
+
+ if (fused(r) && min_v(p) == 0 // p is not a minima
+ && fused(p) // p already belong to a cmpt (fused for an another n)
+ && cmpts >= lambda) // union is still allowed
{
- cmpts--;
- std::cout << "dec" << std::endl;
+ --cmpts;
+ // std::cout << "dec" << std::endl;
}
- mln_invariant(fused(r) || volume(r) == volume(p));
+ mln_invariant(fused(r) || attr(r) == attr(p));
// Union made if
if (cmpts >= lambda || // union is still allowed or
- not fused(r) || // r not fused or
- not fused(p) || // p not fused or
+ ! fused(r) || // r not fused or
+ ! fused(p) || // p not fused or
min_v(p) != 0) // p is a minima
{
- std::cout << "fuse" << p << n <<
std::endl;
+ // std::cout << "fusing " << p << " with "
<< n << std::endl;
parent(r) = p;
// This test is mandatory. Sometimes (--_) points are fused
- // tought none of these points belongs to a component (attached
+ // tough none of these points belongs to a component (attached
// to a local minima). In this case fused(p) must not be true
// since it can be fused again without removing a component.
- // looking if r is fused should be enought.
+ // looking if r is fused should be enough.
// This test force minima to be initialized fused.
if (fused(r))
fused(p) = true;
// If I try to fuse with something never fused I am on a plateau.
- // not fused(r) => ( volume(r) == volume(p) )
- mln_invariant(fused(r) || volume(r) == volume(p));
- // fused(r) and ( volume(r) == volume(p) ) happen on minima plateau.
+ // not fused(r) => ( attr(r) == attr(p) )
+ mln_invariant(fused(r) || attr(r) == attr(p));
+ // fused(r) and ( attr(r) == attr(p) ) happen on minima plateau.
// fused(n) = true; // useless ? probably yes because when we
// want to know that we really fuse component, we look at
@@ -206,7 +197,8 @@
// fused(n) is not an invariant: --_. And it is ok (I think).
// We don't have to retro-propagate fused.
- std::cerr << "volume " << volume(p) << "
- " << cmpts << std::endl;
+
+ // std::cout << "attr " << attr(p) << " - "
<< cmpts << std::endl;
//debug::println(fused);
}
}
@@ -215,16 +207,17 @@
deja_vu(p) = true;
}
- mln_ch_value(I,value::int_u<16>) iota(ima.domain());
+ mln_ch_value(I,value::int_u<16>) iota(f.domain());
debug::iota(iota);
std::cout << std::endl;
std::cout << "cmpts : " << cmpts << std::endl;
// second pass
- I output(ima.domain());
+ mln_concrete(I) output;
+ initialize(output, f);
{
- mln_bkd_piter(S) p(sp);
+ mln_bkd_piter(S) p(s);
for_all(p)
if (parent(p) == p) // p is root.
output(p) = iota(p);
@@ -235,11 +228,36 @@
return output;
}
- } // end of namespace n_cmpt
+} // end of namespace mln
-# endif // ! MLN_INCLUDE_ONLY
-} // end of namespace mln
-#endif /* MLN_N_CMPT3_HH */
+void usage(char* argv[])
+{
+ std::cerr << "usage: " << argv[0] << " input.pgm
n" << std::endl;
+ std::cerr << "n: expected number of basins" << std::endl;
+ std::abort();
+}
+
+
+int main(int argc, char* argv[])
+{
+ using namespace mln;
+ using value::int_u8;
+
+ if (argc != 3)
+ usage(argv);
+ typedef image2d<int_u8> I;
+ I f;
+ io::pgm::load(f, argv[1]);
+ debug::println("f =", f);
+
+ unsigned n = std::atoi(argv[2]);
+
+ accu::count< util::pix<I> > acc;
+ // accu::volume<I> acc;
+
+ image2d<int_u8> g = n_cmpt(acc, f, c4(), n + 1);
+ debug::println(g);
+}