URL:
https://svn.lrde.epita.fr/svn/oln/trunk/milena
ChangeLog:
2007-12-17 Guillaume Duhamel <guillaume.duhamel(a)lrde.epita.fr>
Review chamfer and labeling in canvas.
* mln/canvas/chamfer.hh,
* mln/canvas/labeling.hh: Review this files split declaration and
implementation, fix typo.
Tests.
* tests/chamfer.cc: Remove ...
* tests/canvas/chamfer.cc: ... replace it and modify tests.
---
mln/canvas/chamfer.hh | 29 +++++++--
mln/canvas/labeling.hh | 151 +++++++++++++++++++++++++++++++++---------------
tests/canvas/chamfer.cc | 128 ++++++++++++++++++++++++++++++++++++++++
3 files changed, 256 insertions(+), 52 deletions(-)
Index: trunk/milena/tests/chamfer.cc (deleted)
===================================================================
Index: trunk/milena/tests/canvas/chamfer.cc
===================================================================
--- trunk/milena/tests/canvas/chamfer.cc (revision 0)
+++ trunk/milena/tests/canvas/chamfer.cc (revision 1615)
@@ -0,0 +1,128 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// 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.
+
+/*! \file tests/canvas/chamfer.cc
+ *
+ * \brief Tests on mln::geom::chamfer.
+ */
+
+#include <mln/core/image2d.hh>
+#include <mln/core/sub_image.hh>
+#include <mln/core/image_if_value.hh>
+#include <mln/core/inplace.hh>
+
+#include <mln/level/fill.hh>
+#include <mln/debug/println.hh>
+#include <mln/core/w_window2d_int.hh>
+#include <mln/core/w_window2d_float.hh>
+#include <mln/core/image_if_interval.hh>
+
+#include <mln/make/win_chamfer.hh>
+#include <mln/geom/chamfer.hh>
+#include <mln/level/compare.hh>
+
+
+int main()
+{
+ using namespace mln;
+ unsigned max = 51;
+
+ image2d<bool> ima(9, 9);
+
+ {
+ level::fill(ima, false);
+ ima.at(4,4) = true;
+ const w_window2d_int& w_win = make::mk_chamfer_3x3_int<2, 0> ();
+ image2d<unsigned> out = geom::chamfer(ima, w_win, max);
+ unsigned r[9][9] =
+ {
+ {16, 14, 12, 10, 8, 10, 12, 14, 16},
+ {14, 12, 10, 8, 6, 8, 10, 12, 14},
+ {12, 10, 8, 6, 4, 6, 8, 10, 12},
+ {10, 8, 6, 4, 2, 4, 6, 8, 10},
+ { 8, 6, 4, 2, 0, 2, 4, 6, 8},
+ {10, 8, 6, 4, 2, 4, 6, 8, 10},
+ {12, 10, 8, 6, 4, 6, 8, 10, 12},
+ {14, 12, 10, 8, 6, 8, 10, 12, 14},
+ {16, 14, 12, 10, 8, 10, 12, 14, 16}
+ };
+
+ image2d<unsigned> ref (make::image2d(r));
+ mln_assertion (out == ref);
+ }
+
+ {
+ level::fill(ima, false);
+ ima.at(4,4) = true;
+ const w_window2d_int& w_win = make::mk_chamfer_3x3_int<2, 3> ();
+ image2d<unsigned> out = geom::chamfer(ima, w_win, max);
+
+ unsigned r[9][9] =
+ {
+ {12, 11, 10, 9, 8, 9, 10, 11, 12},
+ {11, 9, 8, 7, 6, 7, 8, 9, 11},
+ {10, 8, 6, 5, 4, 5, 6, 8, 10},
+ { 9, 7, 5, 3, 2, 3, 5, 7, 9},
+ { 8, 6, 4, 2, 0, 2, 4, 6, 8},
+ { 9, 7, 5, 3, 2, 3, 5, 7, 9},
+ {10, 8, 6, 5, 4, 5, 6, 8, 10},
+ {11, 9, 8, 7, 6, 7, 8, 9, 11},
+ {12, 11, 10, 9, 8, 9, 10, 11, 12}
+ };
+
+ image2d<unsigned> ref (make::image2d(r));
+ mln_assertion (out == ref);
+ }
+
+ {
+ level::fill(ima, false);
+ ima.at(4,4) = true;
+ const w_window2d_int& w_win = make::mk_chamfer_5x5_int<4, 6, 9> ();
+ image2d<unsigned> out = geom::chamfer(ima, w_win, max);
+ image2d<unsigned>::fwd_piter p(out.domain());
+ for_all(p)
+ out(p) = out(p) / 2;
+
+ unsigned r[9][9] =
+ {
+ {12, 10, 9, 8, 8, 8, 9, 10, 12},
+ {10, 9, 7, 6, 6, 6, 7, 9, 10},
+ { 9, 7, 6, 4, 4, 4, 6, 7, 9},
+ { 8, 6, 4, 3, 2, 3, 4, 6, 8},
+ { 8, 6, 4, 2, 0, 2, 4, 6, 8},
+ { 8, 6, 4, 3, 2, 3, 4, 6, 8},
+ { 9, 7, 6, 4, 4, 4, 6, 7, 9},
+ {10, 9, 7, 6, 6, 6, 7, 9, 10},
+ {12, 10, 9, 8, 8, 8, 9, 10, 12}
+ };
+
+ image2d<unsigned> ref (make::image2d(r));
+ mln_assertion (out == ref);
+
+ }
+
+}
Index: trunk/milena/mln/canvas/chamfer.hh
===================================================================
--- trunk/milena/mln/canvas/chamfer.hh (revision 1614)
+++ trunk/milena/mln/canvas/chamfer.hh (revision 1615)
@@ -38,23 +38,40 @@
namespace canvas
{
+ /*!
+ * \brief Compute chamfer distance.
+ *
+ */
template <typename F>
struct chamfer
{
- F& f;
-
typedef typename F::I I;
typedef typename F::W W;
typedef mln_point(I) point;
- chamfer(F& f)
+ F& f;
+
+ chamfer(F& f);
+
+ void run();
+ };
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template<typename F>
+ inline
+ chamfer<F>::chamfer(F& f)
: f(f)
{
run();
}
- void run()
+ template<typename F>
+ inline
+ void
+ chamfer<F>::run()
{
+
/// Init.
{
f.init();
@@ -86,9 +103,9 @@
f.output(p) = f.output(q) + q.w();
f.status = true;
}
-
}
- };
+
+# endif // ! MLN_INCLUDE_ONLY
} // end of mln::canvas
Index: trunk/milena/mln/canvas/labeling.hh
===================================================================
--- trunk/milena/mln/canvas/labeling.hh (revision 1614)
+++ trunk/milena/mln/canvas/labeling.hh (revision 1615)
@@ -71,7 +71,69 @@
bool status;
// Ctor.
- labeling(F& f)
+ labeling(F& f);
+
+ void init();
+
+ void pass_1();
+
+ void pass_2();
+
+
+ // Auxiliary methods.
+
+ void make_set(const point& p);
+
+ bool is_root(const point& p) const;
+
+ point find_root(const point& x);
+
+ void do_union(const point& n, const point& p);
+
+ };
+
+
+ template <typename F>
+ struct labeling_fastest
+ {
+ // Functor.
+ F& f;
+
+ typedef typename F::I I;
+ typedef typename F::N N;
+ typedef typename F::L L;
+
+ // Auxiliary data.
+ mln_ch_value(I, unsigned) parent;
+
+ // Output.
+ mln_ch_value(I, L) output;
+ L nlabels;
+ bool status;
+
+ // Ctor.
+ labeling_fastest(F& f);
+
+ void init();
+
+ void pass_1();
+
+ void pass_2();
+
+ // Auxiliary methods.
+
+ bool is_root(unsigned p) const;
+
+ unsigned find_root(unsigned x);
+
+ void do_union(unsigned n, unsigned p);
+
+ };
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename F>
+ labeling<F>::labeling(F& f)
: f(f)
{
trace::entering("canvas::labeling");
@@ -84,8 +146,9 @@
trace::exiting("canvas::labeling");
}
-
- void init()
+ template <typename F>
+ void
+ labeling<F>::init()
{
initialize(deja_vu, f.input);
mln::level::fill(deja_vu, false);
@@ -95,7 +158,9 @@
nlabels = 0;
}
- void pass_1()
+ template <typename F>
+ void
+ labeling<F>::pass_1()
{
mln_fwd_piter(S) p(f.s);
mln_niter(N) n(f.nbh, p);
@@ -112,7 +177,9 @@
}
}
- void pass_2()
+ template <typename F>
+ void
+ labeling<F>::pass_2()
{
mln_bkd_piter(S) p(f.s);
for_all(p) if (f.handles(p))
@@ -135,21 +202,24 @@
status = true;
}
-
- // Auxiliary methods.
-
- void make_set(const point& p)
+ template <typename F>
+ void
+ labeling<F>::make_set(const point& p)
{
parent(p) = p;
f.init_attr(p);
}
- bool is_root(const point& p) const
+ template <typename F>
+ bool
+ labeling<F>::is_root(const point& p) const
{
return parent(p) == p;
}
- point find_root(const point& x)
+ template <typename F>
+ typename labeling<F>::point
+ labeling<F>::find_root(const point& x)
{
if (parent(x) == x)
return x;
@@ -157,7 +227,9 @@
return parent(x) = find_root(parent(x));
}
- void do_union(const point& n, const point& p)
+ template <typename F>
+ void
+ labeling<F>::do_union(const point& n, const point& p)
{
point r = find_root(n);
if (r != p)
@@ -167,31 +239,8 @@
}
}
- };
-
-
-
-
template <typename F>
- struct labeling_fastest
- {
- // Functor.
- F& f;
-
- typedef typename F::I I;
- typedef typename F::N N;
- typedef typename F::L L;
-
- // Auxiliary data.
- mln_ch_value(I, unsigned) parent;
-
- // Output.
- mln_ch_value(I, L) output;
- L nlabels;
- bool status;
-
- // Ctor.
- labeling_fastest(F& f)
+ labeling_fastest<F>::labeling_fastest(F& f)
: f(f)
{
trace::entering("canvas::labeling_fastest");
@@ -204,8 +253,9 @@
trace::exiting("canvas::labeling_fastest");
}
-
- void init()
+ template <typename F>
+ void
+ labeling_fastest<F>::init()
{
initialize(parent, f.input);
for (unsigned p = 0; p < parent.ncells(); ++p)
@@ -215,7 +265,9 @@
nlabels = 0;
}
- void pass_1()
+ template <typename F>
+ void
+ labeling_fastest<F>::pass_1()
{
mln_bkd_pixter(const I) p(f.input);
@@ -234,7 +286,9 @@
}
}
- void pass_2()
+ template <typename F>
+ void
+ labeling_fastest<F>::pass_2()
{
mln_fwd_pixter(const I) p(f.input);
@@ -258,14 +312,16 @@
status = true;
}
- // Auxiliary methods.
-
- bool is_root(unsigned p) const
+ template <typename F>
+ bool
+ labeling_fastest<F>::is_root(unsigned p) const
{
return parent[p] == p;
}
- unsigned find_root(unsigned x)
+ template <typename F>
+ unsigned
+ labeling_fastest<F>::find_root(unsigned x)
{
if (parent[x] == x)
return x;
@@ -273,7 +329,9 @@
return parent[x] = find_root(parent[x]);
}
- void do_union(unsigned n, unsigned p)
+ template <typename F>
+ void
+ labeling_fastest<F>::do_union(unsigned n, unsigned p)
{
unsigned r = find_root(n);
if (r != p)
@@ -283,7 +341,8 @@
}
}
- };
+
+# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln::canvas