https://svn.lrde.epita.fr/svn/oln/prototypes/proto-1.0
ChangeLog | 15 ++++
img/Makefile.am | 14 +++-
img/squares-lc.pgm | 5 +
oln/makefile.src | 1
oln/morpho/lower_completion.hh | 124 ++++++++++++++++++++++++++++++++++++
tests/morpho/tests/lower_completion | 25 +++++++
6 files changed, 182 insertions(+), 2 deletions(-)
Index: olena/ChangeLog
from Roland Levillain <roland(a)lrde.epita.fr>
Add lower completion.
* oln/morpho/lower_completion.hh: New file
* oln/makefile.src (OLN_DEP): Add morpho/lower_completion.hh.
* olena/img/squares.pgm, olena/img/squares-lc.pgm: New images.
* img/Makefile.am (SOURCE_IMGS): Add $(srcdir)/16x16.pbm,
$(srcdir)/16x16.pbm.gz, $(srcdir)/16x16.pgm,
$(srcdir)/16x16.pgm.gz, $(srcdir)/16x16.ppm,
$(srcdir)/16x16.ppm.gz, $(srcdir)/marker.pbm, $(srcdir)/mask.pbm,
$(srcdir)/object.pbm, $(srcdir)/squares-lc.pgm,
$(srcdir)/squares.pgm:
* tests/morpho/tests/lower_completion: New test.
Index: olena/tests/morpho/tests/lower_completion
--- olena/tests/morpho/tests/lower_completion (revision 0)
+++ olena/tests/morpho/tests/lower_completion (revision 0)
@@ -0,0 +1,25 @@
+ // -*- C++ -*-
+#include "data.hh"
+#include "ntg/int.hh"
+#include "oln/core/2d/image2d.hh"
+#include "oln/core/gen/image_with_nbh.hh"
+#include "oln/io/read_image.hh"
+#include "oln/io/write_image.hh"
+#include "oln/morpho/lower_completion.hh"
+#include "oln/ops/cmp.hh"
+
+using namespace oln;
+
+bool check()
+{
+ image2d<ntg::int_u8> raw_input;
+ raw_input = io::read(rdata("squares.pgm"));
+
+ typedef image_with_nbh<image2d<ntg::int_u8>, neighborhood2d> image_type;
+ image_type input = join(raw_input, neighb_c4());
+ image_type output = morpho::lower_completion<ntg::int_u8>(input);
+
+ image2d<ntg::int_u8> ref_output;
+ ref_output = io::read(rdata("squares-lc.pgm"));
+ return !(output == ref_output);
+}
Index: olena/oln/makefile.src
--- olena/oln/makefile.src (revision 194)
+++ olena/oln/makefile.src (working copy)
@@ -160,6 +160,7 @@
morpho/erosion.hh \
morpho/geodesic_dilation.hh \
morpho/geodesic_erosion.hh \
+ morpho/lower_completion.hh \
morpho/opening.hh \
morpho/reconstruction_by_dilation.hh \
morpho/reconstruction_by_erosion.hh \
Index: olena/oln/morpho/lower_completion.hh
--- olena/oln/morpho/lower_completion.hh (revision 0)
+++ olena/oln/morpho/lower_completion.hh (revision 0)
@@ -0,0 +1,124 @@
+// Copyright (C) 2005 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, 59 Temple Place - Suite 330, 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 OLENA_MORPHO_LOWER_COMPLETION_HH
+# define OLENA_MORPHO_LOWER_COMPLETION_HH
+
+# include <queue>
+
+# include "oln/level/fill.hh"
+
+namespace oln {
+
+ namespace morpho {
+
+ // FIXME: INPUT should be a scalar image.
+ template <typename DestValue, typename I>
+ typename ch_value_type<I, DestValue>::ret
+ lower_completion(const abstract::image_with_nbh<I>& input)
+ {
+ typedef oln_type_of(I, point) point_type;
+
+ /*------------------------------------------.
+ | Distance map to the closest lower point. |
+ `------------------------------------------*/
+
+ typedef std::queue<point_type> queue_type;
+ queue_type q;
+ typename ch_value_type<I, bool>::ret processed(input.size());
+ level::fill (processed, false);
+
+ typename ch_value_type<I, unsigned>::ret distance(input.size());
+ unsigned cur_dist = 1;
+
+ oln_type_of(I, fwd_piter) p(input.size());
+ for_all_p (p)
+ {
+ distance[p] = 0;
+ oln_type_of(I, niter) n(input);
+ for_all_n_of_p (n, p)
+ if (input.hold(n) && input[n] < input[p])
+ {
+ q.push(p);
+ processed[p] = true;
+ }
+ }
+
+ typedef oln_pt_type_of(point_type, grid) grid_type;
+ typedef oln_grd_type_of(grid_type, dimvalue) dimvalue_type;
+ const unsigned dim = dimvalue_type::val;
+ // Fictitious point, used as a separator between ranges of
+ // points in the queue.
+ point_type fictitious;
+ for (unsigned i = 0; i < dim; ++i)
+ fictitious.nth (i) = -1;
+ q.push(fictitious);
+
+ while (!q.empty())
+ {
+ point_type p = q.front();
+ q.pop();
+ if (p == fictitious)
+ {
+ if (!q.empty())
+ {
+ q.push(fictitious);
+ ++cur_dist;
+ }
+ }
+ else
+ {
+ distance[p] = cur_dist;
+ oln_type_of(I, niter) n(input);
+ for_all_n_of_p (n, p)
+ if (input.hold(n) && input[n] == input[p] && !processed[n])
+ {
+ q.push(n);
+ processed[n] = true;
+ }
+ }
+ }
+
+ /*-------------------.
+ | Lower completion. |
+ `-------------------*/
+
+ typename ch_value_type<I, DestValue>::ret output(input.size());
+ for_all_p (p)
+ if (distance[p] == ntg_zero_val(DestValue))
+ output[p] = cur_dist * input[p].value();
+ else
+ output[p] = cur_dist * input[p].value() + distance[p].value() - 1;
+
+ return output;
+ }
+
+ } // end of namespace oln::morpho
+
+} // end of namespace oln
+
+#endif // ! OLENA_MORPHO_LOWER_COMPLETION_HH
Index: olena/img/Makefile.am
--- olena/img/Makefile.am (revision 194)
+++ olena/img/Makefile.am (working copy)
@@ -1,4 +1,10 @@
SOURCE_IMGS = \
+ $(srcdir)/16x16.pbm \
+ $(srcdir)/16x16.pbm.gz \
+ $(srcdir)/16x16.pgm \
+ $(srcdir)/16x16.pgm.gz \
+ $(srcdir)/16x16.ppm \
+ $(srcdir)/16x16.ppm.gz \
$(srcdir)/chien.pbm \
$(srcdir)/chien.pbm.gz \
$(srcdir)/lena.pbm \
@@ -6,7 +12,11 @@
$(srcdir)/lena.pgm \
$(srcdir)/lena.pgm.gz \
$(srcdir)/lena.ppm \
- $(srcdir)/lena.ppm.gz
+ $(srcdir)/lena.ppm.gz \
+ $(srcdir)/marker.pbm \
+ $(srcdir)/mask.pbm \
+ $(srcdir)/object.pbm \
+ $(srcdir)/squares-lc.pgm \
+ $(srcdir)/squares.pgm
dist_pkgdata_DATA = $(SOURCE_IMGS)
-