Commit e5430fb8 authored by Matthieu Garrigues's avatar Matthieu Garrigues
Browse files

Add another version of self dual reconstruction.


	* garrigues/union_find/self_dual_reconstruction.hh,
	* garrigues/union_find/self_dual_reconstruction.cc: Add a new version
	of self dual reconstruction.
	* garrigues/union_find/Makefile: New, Add a simple Makefile.
	* garrigues/union_find/canvas/find_root.hh,
	* garrigues/union_find/canvas/reconstruction_on_function.hh,
	* garrigues/union_find/canvas/reconstruction_on_set.hh,
	* garrigues/union_find/canvas/self_dual_reconstruction.hh: Move
	find_root implementation in find_root.hh.
	* garrigues/union_find/images/marker.pbm: Rename as...
	* garrigues/union_find/images/marker_to_erode.pbm: ...this.

git-svn-id: https://svn.lrde.epita.fr/svn/oln/trunk@3198 4aad255d-cdde-0310-9447-f3009e2ae8c0
parent 95226b1b
2009-01-23 Matthieu Garrigues <garrigues@lrde.epita.fr>
Add another version of self dual reconstruction.
* garrigues/union_find/self_dual_reconstruction.hh,
* garrigues/union_find/self_dual_reconstruction.cc: Add a new version
of self dual reconstruction.
* garrigues/union_find/Makefile: New, Add a simple Makefile.
* garrigues/union_find/canvas/find_root.hh,
* garrigues/union_find/canvas/reconstruction_on_function.hh,
* garrigues/union_find/canvas/reconstruction_on_set.hh,
* garrigues/union_find/canvas/self_dual_reconstruction.hh: Move
find_root implementation in find_root.hh.
* garrigues/union_find/images/marker.pbm: Rename as...
* garrigues/union_find/images/marker_to_erode.pbm: ...this.
2009-01-23 Thierry Geraud <thierry.geraud@lrde.epita.fr>
Add perfect fusion grid neighborhoods from 2D and 3D.
......
CFLAGS=#-O3 -DNDEBUG
all: sd on_set on_fun
sd: self_dual_reconstruction.o
g++ self_dual_reconstruction.o -o sd
on_set: reconstructions_on_set.o
g++ reconstructions_on_set.o -o on_set
on_fun: reconstructions_on_function.o
g++ reconstructions_on_function.o -o on_fun
clean:
rm -f sd on_set on_fun reconstructions_on_set.o reconstructions_on_function.o self_dual_reconstruction.o
%.o : %.cc
g++ -c -I. -I../../.. $(CFLAGS) $<
reconstructions_on_function.o: reconstructions_on_function.cc \
reconstructions_on_function.hh canvas/reconstruction_on_function.hh
reconstructions_on_set.o: reconstructions_on_set.cc \
reconstructions_on_set.hh canvas/reconstruction_on_set.hh
self_dual_reconstruction.o: self_dual_reconstruction.cc \
self_dual_reconstruction.hh canvas/self_dual_reconstruction.hh \
reconstructions_on_function.hh canvas/reconstruction_on_function.hh
// 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.
#ifndef MLN_FIND_ROOT_HH
# define MLN_FIND_ROOT_HH
namespace mln
{
namespace canvas
{
namespace morpho
{
template <typename I>
static inline
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));
}
} // end of namespace mln::canvas::morpho
} // end of namespace mln::canvas
} // end of namespace mln.
#endif // ! MLN_FIND_ROOT_HH
......@@ -42,28 +42,17 @@
# include <mln/io/pgm/save.hh>
# include <mln/io/pbm/load.hh>
# include <canvas/find_root.hh>
namespace mln
{
namespace canvas
{
namespace morpho
{
template <typename I>
static inline
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));
}
template <typename N, typename F>
inline
void
......@@ -167,79 +156,6 @@ namespace mln
trace::exiting("canvas::morpho::reconstruction_on_function");
}
/*
template <typename N, typename F>
void
reconstruction_on_function_old(const Neighborhood<N>& nbh_,
F& f)
{
trace::entering("canvas::morpho::reconstruction_on_function");
// Tests.
reconstruction_on_function_tests(nbh_, f);
const N& nbh = exact(nbh_);
// Local type.
typedef typename F::I I;
typedef typename F::S S;
typedef mln_site(I) P;
typedef mln_value(I) V;
// Auxiliary data.
mln_ch_value(I, bool) deja_vu;
mln_ch_value(I, P) parent;
// init
{
initialize(deja_vu, f.mask);
initialize(parent, f.mask);
mln::data::fill(deja_vu, false);
data::fill(f.output, f.marker);
}
// first pass
{
mln_fwd_piter(S) p(f.s);
mln_niter(N) n(nbh, p);
for_all(p)
{
// Make set.
parent(p) = p;
for_all(n) if (f.mask.domain().has(n) && deja_vu(n))
{
//do_union(n, p);
P r = find_root(parent, n);
if (r != p)
if (f.is_active(r, p))
{
parent(r) = p;
f.merge(r, p);
}
else
f.output(p) = f.mask(p);
}
deja_vu(p) = true;
}
}
// second pass
{
mln_bkd_piter(S) p(f.s);
for_all(p)
{
if (parent(p) != p) // if p is not a root.
f.output(p) = f.output(parent(p));
}
}
trace::exiting("canvas::morpho::reconstruction_on_function");
}
*/
} // end of namespace mln::canvas::morpho
} // end of namespace mln::canvas
......
......@@ -41,6 +41,8 @@
# include <mln/io/pbm/save.hh>
# include <mln/io/pbm/load.hh>
# include <canvas/find_root.hh>
namespace mln
{
......@@ -51,18 +53,6 @@ namespace mln
namespace morpho
{
template <typename I>
static inline
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));
}
template <typename N, typename F>
void
reconstruction_on_set(const Neighborhood<N>& nbh_,
......@@ -94,9 +84,9 @@ namespace mln
// first pass
{
mln_fwd_piter(I) p(f.mask.domain());
const std::vector<mln_deduce(I, site, delta)> & n_win(const_cast<N*>(&nbh)->hook_win_().std_vector());
unsigned n_size = n_win.size();
// mln_niter(N) n(nbh, p);
// const std::vector<mln_deduce(I, site, delta)> & n_win(const_cast<N*>(&nbh)->hook_win_().std_vector());
// unsigned n_size = n_win.size();
mln_niter(N) n(nbh, p);
for_all(p)
{
if (f.is_in_D(p))
......@@ -105,10 +95,11 @@ namespace mln
parent(p) = p;
f.init(p);
// for_all(n)
for(unsigned i = 0; i < n_size; i++)
{
mln_site(I) n = p + n_win[i];
for_all(n)
{
// for(unsigned i = 0; i < n_size; i++)
// {
// mln_site(I) n = p + n_win[i];
if (f.mask.domain().has(n))
{
......
......@@ -42,6 +42,8 @@
# include <mln/io/pgm/save.hh>
# include <mln/io/pbm/load.hh>
# include <canvas/find_root.hh>
namespace mln
{
......@@ -51,18 +53,6 @@ namespace mln
namespace morpho
{
template <typename I>
static inline
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));
}
template <typename N, typename F>
inline
void
......@@ -157,8 +147,8 @@ namespace mln
parent(r) = p;
f.d1_merge(r, p);
}
else
f.output(p) = f.mask(p);
else
f.output(p) = f.mask(p);
}
}
......@@ -199,8 +189,8 @@ namespace mln
parent(r) = p;
f.d2_merge(r, p);
}
else
f.output(p) = f.mask(p);
else
f.output(p) = f.mask(p);
}
}
......@@ -218,7 +208,6 @@ namespace mln
trace::exiting("canvas::morpho::self_dual_reconstruction");
}
} // end of namespace mln::canvas::morpho
} // end of namespace mln::canvas
......
......@@ -32,13 +32,14 @@
# include <mln/io/pgm/load.hh>
# include <mln/io/pgm/save.hh>
# include <mln/linear/gaussian.hh>
# include <mln/arith/diff_abs.hh>
# include <tests/timer.hh>
# include "self_dual_reconstruction.hh"
void usage(char** argv)
{
std::cerr << "Usage: " << argv[0] << " input.pgm blur" << std::endl;
std::cerr << "Usage: " << argv[0] << " input.pgm blur output" << std::endl;
exit(1);
}
......@@ -46,7 +47,7 @@ int main(int argc, char** argv)
{
using namespace mln;
if (argc < 2)
if (argc < 3)
usage(argv);
typedef image2d<value::int_u8> I;
......@@ -58,23 +59,47 @@ int main(int argc, char** argv)
I input = io::pgm::load<V>(argv[1]);
std::cout << "load: " << t << std::endl;
I output;
I output;
t.start();
output = linear::gaussian(input, atoi(argv[2]));
io::pgm::save(output, "gaussian.pgm");
std::cout << "gaussian: " << t << std::endl;
t.start();
output = linear::gaussian(input, atoi(argv[2]));
io::pgm::save(output, "gaussian.pgm");
std::cout << "gaussian: " << t << std::endl;
trace::quiet = false;
trace::quiet = false;
t.start();
output = self_dual_reconstruction(output, input, c8());
std::cout << "reconstruction: " << t << std::endl;
t.start();
output = self_dual_reconstruction_ref(output, input, c8());
std::cout << "reconstruction: " << t << std::endl;
trace::quiet = true;
trace::quiet = true;
t.start();
io::pgm::save(output, argv[3]);
std::cout << "save: " << t << std::endl;
I output_test;
t.start();
output_test = linear::gaussian(input, atoi(argv[2]));
io::pgm::save(output_test, "gaussian.pgm");
std::cout << "gaussian: " << t << std::endl;
trace::quiet = false;
t.start();
output_test = self_dual_reconstruction(output_test, input, c8());
std::cout << "reconstruction: " << t << std::endl;
trace::quiet = true;
t.start();
io::pgm::save(output_test, "sd_test.pgm");
std::cout << "save: " << t << std::endl;
io::pgm::save(arith::diff_abs(output_test, output), "diff_abs.pgm");
t.start();
io::pgm::save(output, "reconstruction.pgm");
std::cout << "save: " << t << std::endl;
}
......@@ -47,6 +47,7 @@
# include <mln/core/image/image_if.hh>
# include "canvas/self_dual_reconstruction.hh"
# include "reconstructions_on_function.hh"
namespace mln
{
......@@ -70,14 +71,12 @@ namespace mln
: marker(marker),
mask(mask),
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))
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))))
{
}
bool is_in_d1(const P& p) { return marker(p) < mask(p); }
bool is_in_d1(const P& p) { return marker(p) <= mask(p); }
bool is_in_d2(const P& p) { return marker(p) > mask(p); }
......@@ -95,8 +94,6 @@ namespace mln
output(p) = output(r);
}
void d1_escape(const P& p) { output(p) = d1_escape_value; }
bool d2_is_active(const P& r, const P& p)
{
......@@ -111,14 +108,11 @@ namespace mln
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.
......@@ -154,6 +148,58 @@ namespace mln
return output;
}
template <typename I, typename J, typename N>
mln_concrete(I)
self_dual_reconstruction_ref(const Image<I>& marker_,
const Image<J>& mask_,
const Neighborhood<N>& nbh_)
{
trace::entering("morpho::self_dual_reconstruction_ref");
const I& marker = exact(marker_);
const J& mask = exact(mask_);
const N& nbh = exact(nbh_);
mln_precondition(marker.is_valid());
mln_precondition(mask.is_valid());
mln_precondition(mask.domain() == marker.domain());
mln_concrete(I) output;
initialize(output, marker);
mln_concrete(I) by_dilation =
reconstruction_on_function_by_dilation
(marker | (pw::value(marker) < pw::value(mask)),
mask | (pw::value(marker) < pw::value(mask)),
nbh);
io::pgm::save(by_dilation, "sd_by_dilation.pgm");
mln_concrete(I) by_erosion =
reconstruction_on_function_by_erosion
(marker | (pw::value(marker) > pw::value(mask)),
mask | (pw::value(marker) > pw::value(mask)),
nbh);
io::pgm::save(by_erosion, "sd_by_erosion.pgm");
mln_piter(I) p(output.domain());
for_all(p)
{
if (marker(p) > mask(p))
output(p) = by_erosion(p);
else if (marker(p) < mask(p))
output(p) = by_dilation(p);
else
output(p) = mask(p);
}
trace::exiting("morpho::self_dual_reconstruction_ref");
return output;
}
} // end of namespace mln.
......
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