URL:
https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox
ChangeLog:
2008-12-15 Matthieu Garrigues <garrigues(a)lrde.epita.fr>
Finalize reconstructions.
Add the concept of "escape value".
* garrigues/union_find/canvas/reconstruction_on_function.hh: .
* garrigues/union_find/canvas/self_dual_reconstruction.hh: .
* garrigues/union_find/reconstructions_on_function.hh: .
* garrigues/union_find/leveling.cc: Rename as...
* garrigues/union_find/self_dual_reconstruction.cc: ...this.
* garrigues/union_find/self_dual_reconstruction.hh: .
---
canvas/reconstruction_on_function.hh | 4 +-
canvas/self_dual_reconstruction.hh | 13 ++++---
reconstructions_on_function.hh | 30 ++++++++++++----
self_dual_reconstruction.cc | 62 +++++++++++++++++++++++++++++++++++
self_dual_reconstruction.hh | 51 ++++++++++++++++++----------
5 files changed, 126 insertions(+), 34 deletions(-)
Index: trunk/milena/sandbox/garrigues/union_find/leveling.cc (deleted)
===================================================================
Index: trunk/milena/sandbox/garrigues/union_find/reconstructions_on_function.hh
===================================================================
--- trunk/milena/sandbox/garrigues/union_find/reconstructions_on_function.hh (revision
3050)
+++ trunk/milena/sandbox/garrigues/union_find/reconstructions_on_function.hh (revision
3051)
@@ -55,27 +55,32 @@
typedef I_ I;
typedef J_ J;
typedef mln_site(I) P;
+ typedef mln_value(I) V;
typedef p_array<mln_psite(I)> S;
reconstruction_on_function_by_dilation_t (const I& marker, const J& mask,
mln_concrete(I)& output)
: marker(marker),
mask(mask),
output(output),
- s(level::sort_psites_decreasing(mask))
+ s(level::sort_psites_decreasing(mask)),
+ escape_value(mln_max(V))
{
}
- bool is_active(const P& p) { return output(p) <= mask(p); }
+ bool is_active(const P& r, const P& p) { return output(r) <= mask(p); }
+ void escape(const P& p) { output(p) = escape_value; }
void merge(const P& r, const P& p)
{
if (output(r) > output(p))
output(p) = output(r);
}
+
const I& marker; // F
const J& mask; // G
mln_concrete(I)& output; // O
S s;
+ const V escape_value;
};
@@ -85,23 +90,31 @@
typedef I_ I;
typedef J_ J;
typedef mln_site(I) P;
+ typedef mln_value(I) V;
typedef p_array<mln_psite(I)> S;
reconstruction_on_function_by_erosion_t (const I& marker, const J& mask,
mln_concrete(I)& output)
: marker(marker),
mask(mask),
output(output),
- s(level::sort_psites_increasing(marker))
+ s(level::sort_psites_increasing(mask)),
+ escape_value(mln_min(V))
{
}
- bool is_active(const P& p) { return mask(p) <= output(p); }
- void merge(const P& r, const P& p) { output(p) = math::min(output(p),
output(r)); }
+ bool is_active(const P& r, const P& p) { return output(r) >= mask(p); }
+ void escape(const P& p) { output(p) = escape_value; }
+ void merge(const P& r, const P& p)
+ {
+ if (output(r) < output(p))
+ output(p) = output(r);
+ }
const I& marker; // F
const J& mask; // G
mln_concrete(I)& output; // O
S s;
+ const V escape_value;
};
@@ -131,8 +144,8 @@
F f(marker, mask, output);
canvas::morpho::reconstruction_on_function(nbh, f);
-// mln_postcondition(marker <= output);
-// mln_postcondition(output <= mask);
+ mln_postcondition(marker <= output);
+ mln_postcondition(output <= mask);
trace::exiting("morpho::reconstruction_on_function_by_dilation");
return output;
@@ -163,7 +176,8 @@
F f(marker, mask, output);
canvas::morpho::reconstruction_on_function(nbh, f);
- mln_postcondition(marker >= output && output >= mask);
+ mln_postcondition(marker >= output);
+ mln_postcondition(output >= mask);
trace::exiting("morpho::reconstruction_on_function_by_erosion");
return output;
Index: trunk/milena/sandbox/garrigues/union_find/self_dual_reconstruction.cc
===================================================================
--- trunk/milena/sandbox/garrigues/union_find/self_dual_reconstruction.cc (revision 0)
+++ trunk/milena/sandbox/garrigues/union_find/self_dual_reconstruction.cc (revision 3051)
@@ -0,0 +1,62 @@
+// Copyright (C) 2007, 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
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+# include <mln/core/alias/neighb2d.hh>
+# include <mln/core/image/image2d.hh>
+# include <mln/value/int_u8.hh>
+# include <mln/io/pgm/load.hh>
+# include <mln/io/pgm/save.hh>
+# include <mln/linear/gaussian.hh>
+
+# include "self_dual_reconstruction.hh"
+
+void usage(char** argv)
+{
+ std::cerr << "Usage: " << argv[0] << " input.pgm
blur" << std::endl;
+ exit(1);
+}
+
+int main(int argc, char** argv)
+{
+ using namespace mln;
+
+ if (argc < 2)
+ usage(argv);
+
+ typedef image2d<value::int_u8> I;
+ typedef mln_value_(I) V;
+
+ I input = io::pgm::load<V>(argv[1]);
+ I output;
+
+ output = linear::gaussian(input, atoi(argv[2]));
+ io::pgm::save(output, "gaussian.pgm");
+
+ output = self_dual_reconstruction(output, input, c8());
+ io::pgm::save(output, "reconstruction.pgm");
+}
Index: trunk/milena/sandbox/garrigues/union_find/canvas/reconstruction_on_function.hh
===================================================================
---
trunk/milena/sandbox/garrigues/union_find/canvas/reconstruction_on_function.hh (revision
3050)
+++
trunk/milena/sandbox/garrigues/union_find/canvas/reconstruction_on_function.hh (revision
3051)
@@ -147,7 +147,7 @@
f.merge(r, p);
}
else
- f.output(p) = mln_max(V);
+ f.escape(p);
}
deja_vu(p) = true;
@@ -161,7 +161,7 @@
{
if (parent(p) == p) // if p is a root.
{
- if (f.output(p) == mln_max(V))
+ if (f.output(p) == f.escape_value)
f.output(p) = f.mask(p);
}
else
Index: trunk/milena/sandbox/garrigues/union_find/canvas/self_dual_reconstruction.hh
===================================================================
--- trunk/milena/sandbox/garrigues/union_find/canvas/self_dual_reconstruction.hh (revision
3050)
+++ trunk/milena/sandbox/garrigues/union_find/canvas/self_dual_reconstruction.hh (revision
3051)
@@ -144,6 +144,7 @@
for_all(n) if (f.mask.domain().has(n) && deja_vu(n))
{
+ mln_assertion(f.is_in_d1(n));
//do_union(n, p);
P r = find_root(parent, n);
if (r != p)
@@ -153,13 +154,15 @@
f.d1_merge(r, p);
}
else
- f.output(p) = mln_max(V);
+ f.d1_escape(p);
}
deja_vu(p) = true;
}
}
+ mln::level::fill(deja_vu, false);
+
// Body of D2.
{
mln_fwd_piter(S) p(f.d2_s);
@@ -171,6 +174,7 @@
for_all(n) if (f.mask.domain().has(n) && deja_vu(n))
{
+ mln_assertion(f.is_in_d2(n));
//do_union(n, p);
P r = find_root(parent, n);
if (r != p)
@@ -180,8 +184,7 @@
f.d2_merge(r, p);
}
else
- f.output(p) = mln_max(V);
-
+ f.d2_escape(p);
}
deja_vu(p) = true;
@@ -197,7 +200,7 @@
{
if (parent(p) == p) // if p is a root.
{
- if (f.output(p) == mln_max(V))
+ if (f.output(p) == f.d1_escape_value)
f.output(p) = f.mask(p);
}
else
@@ -211,7 +214,7 @@
{
if (parent(p) == p) // if p is a root.
{
- if (f.output(p) == mln_max(V))
+ if (f.output(p) == f.d2_escape_value)
f.output(p) = f.mask(p);
}
else
Index: trunk/milena/sandbox/garrigues/union_find/self_dual_reconstruction.hh
===================================================================
--- trunk/milena/sandbox/garrigues/union_find/self_dual_reconstruction.hh (revision 3050)
+++ trunk/milena/sandbox/garrigues/union_find/self_dual_reconstruction.hh (revision 3051)
@@ -55,55 +55,68 @@
template <typename I_, typename J_>
struct self_dual_reconstruction_t
{
- // d1 : marker(p) < mask(p)
- // d2 : marker(p) > mask(p)
+ // d1 : marker(p) < mask(p) -> dilation
+ // d2 : marker(p) > mask(p) -> erosion
typedef I_ I;
typedef J_ J;
typedef mln_site(I) P;
+ typedef mln_value(I) V;
typedef p_array<mln_psite(I)> S;
self_dual_reconstruction_t (const I& marker, const J& mask,
mln_concrete(I)& output)
: marker(marker),
mask(mask),
- output(output)
- // d1_s(level::sort_psites_increasing(mask | (pw::value(marker) >
pw::value(mask)))),
- // d2_s(level::sort_psites_decreasing(mask | (pw::value(marker) >
pw::value(mask))))
- {
- S d1, d2;
- mln_piter(I) p(mask.domain());
- for_all(p)
- {
- if (is_in_d1(p))
- d1_s.append(p);
- else
- if (is_in_d2(p))
- d2_s.append(p);
+ output(output),
+ d1_s(level::sort_psites_decreasing(mask | (pw::value(marker) < pw::value(mask)))),
+ d2_s(level::sort_psites_increasing(mask | (pw::value(marker) > pw::value(mask)))),
+ d1_escape_value(mln_max(V)),
+ d2_escape_value(mln_min(V))
+ {
}
+ bool is_in_d1(const P& p) { return marker(p) < mask(p); }
+ bool is_in_d2(const P& p) { return marker(p) > mask(p); }
+
+
+
+ bool d1_is_active(const P& r, const P& p)
+ {
+ mln_assertion(is_in_d1(r) && is_in_d1(p));
+ return output(r) <= mask(p);
}
- bool is_in_d1(const P& p) { return marker(p) < mask(p); }
- bool d1_is_active(const P& r, const P& p) { return output(r) <= mask(p);
}
void d1_merge(const P& r, const P& p)
{
+ mln_assertion(is_in_d1(r) && is_in_d1(p));
if (output(r) > output(p))
output(p) = output(r);
}
- bool is_in_d2(const P& p) { return marker(p) > mask(p); }
- bool d2_is_active(const P& r, const P& p) { return output(r) <= mask(p);
}
+ void d1_escape(const P& p) { output(p) = d1_escape_value; }
+
+
+ bool d2_is_active(const P& r, const P& p)
+ {
+ mln_assertion(is_in_d2(r) && is_in_d2(p));
+ return output(r) >= mask(p);
+ }
+
void d2_merge(const P& r, const P& p)
{
+ mln_assertion(is_in_d2(r) && is_in_d2(p));
if (output(r) < output(p))
output(p) = output(r);
}
+ void d2_escape(const P& p) { output(p) = d2_escape_value; }
+
const I& marker; // F
const J& mask; // G
mln_concrete(I)& output; // O
S d1_s, d2_s;
+ const V d1_escape_value, d2_escape_value;
};
} // end of namespace mln::impl.