https://svn.lrde.epita.fr/svn/oln/trunk/milena
I've just remembered mln/labeling/level.hh existed, and probably does the
same job as the file I'm checking in. I needed it to implement Meyer's
Watershed Transfom algorithm, so I'll remove it as soon as I merge both
files.
Index: ChangeLog
from Roland Levillain <roland(a)lrde.epita.fr>
Add a computation of the level components.
* mln/morpho/level_components.hh: New.
Imported from Olena proto-1.0.
* tests/morpho/level_components.cc: New test.
* tests/morpho/Makefile.am (check_PROGRAMS): Add level_components.
(level_components_SOURCES): New.
mln/morpho/level_components.hh | 138 ++++++++++++++++++++++++++++-----------
tests/morpho/Makefile.am | 2
tests/morpho/level_components.cc | 62 +++++++++++++++++
3 files changed, 166 insertions(+), 36 deletions(-)
Index: mln/morpho/level_components.hh
--- mln/morpho/level_components.hh (revision 1680)
+++ mln/morpho/level_components.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2005 EPITA Research and Development Laboratory
+// Copyright (C) 2005, 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,62 +25,128 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-#ifndef OLENA_MORPHO_LEVEL_COMPONENTS_HH
-# define OLENA_MORPHO_LEVEL_COMPONENTS_HH
+#ifndef MLN_MORPHO_MORPHO_COMPONENTS_HH
+# define MLN_MORPHO_MORPHO_COMPONENTS_HH
+
+// FIXME: This file seems to contain the same algorithm as
+// mln/labeling/level.hh. Merge or remove to avoid duplication.
+
+// FIXME: Provide neighborhood-aware versions of these algorithms.
# include <queue>
-# include "oln/level/fill.hh"
+# include <mln/trait/value_.hh>
+# include <mln/trait/ch_value.hh>
+
+# include <mln/level/fill.hh>
+
+# include <mln/morpho/includes.hh>
+
+
+namespace mln {
+
+ namespace morpho {
+
+ /** Compute the level components of \a input.
+
+ \p DestValue is the value type of the output.
+
+ The result is an image where each level component is given a
+ value between \c mln_value(DestValue) and \c ncomps (the
+ number of level components).
+
+ \param[in] input The image whose minima are computed.
+ \param[in] win The window describing the connexity of \a input.
+ \param[out] ncomps The number of minima found by the algorithm.
+ \return The image of components
-namespace oln {
+ \pre \p DestValue is large enough to hold a number of values
+ equal to \c nminima + 1, so as to tag all the minima points
+ plus the non-minima points. */
+ template <typename DestValue, typename I, typename W>
+ mln_ch_value(I, DestValue)
+ level_components(const Image<I>& input, const Window<W>& win,
+ unsigned& ncomps);
- namespace level {
+ /// \brief Like the 3-argument version of mln::moprho::level_components,
+ /// without the out argument \c ncomps.
+ template <typename DestValue, typename I, typename W>
+ mln_ch_value(I, DestValue)
+ level_components(const Image<I>& input, const Window<W>& win);
- /// Compute the level components of \a input.
- template <typename DestValue, typename I>
- typename ch_value_type<I, DestValue>::ret
- level_components(const abstract::image_with_nbh<I>& input)
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename DestValue, typename I, typename W>
+ mln_ch_value(I, DestValue)
+ level_components(const Image<I>& input_, const Window<W>& win_,
+ unsigned& ncomps)
{
- mlc_is_a(I, abstract::scalar_valued_image)::ensure();
+ /* FIXME: Ensure the input image has scalar values. */
+
+ /* FIXME: Errors due to a too small DestValue type should be
+ reported more explicitely. Currently, we abort with messages
+ akin to this one:
+
+ Assertion failed:
+ (unsigned(i) <= mln::trait::value_< enc_ >::max()),
+ function operator=, file ../../../../milena/mln/value/int_u.hh,
+ line 243.
+
+ This is not user-friendly at all! */
- typename ch_value_type<I, DestValue>::ret labels(input.size(),
- input.nbh_get());
- typename ch_value_type<I, bool>::ret processed(input.size(),
- input.nbh_get());
+ const I& input = exact(input_);
+ const W& win = exact(win_);
+
+ mln_ch_value(I, DestValue) labels(input.domain());
+ mln_ch_value(I, bool) processed(input.domain());
level::fill (processed, false);
- DestValue cur_label = ntg_min_val(DestValue);
+ DestValue cur_label = mln_min(DestValue);
- typedef oln_type_of(I, point) point_type;
- std::queue<point_type> q;
+ typedef mln_point(I) point_type;
+ std::queue<point_type> queue;
- oln_type_of(I, piter) p(input.size());
- for_all_p (p)
- if (!processed[p])
+ mln_piter(I) p(input.domain());
+ for_all(p)
+ if (!processed(p))
{
- labels[p] = cur_label;
- processed[p] = true;
- q.push(p);
- while (!q.empty())
+ labels(p) = cur_label;
+ processed(p) = true;
+ queue.push(p);
+ while (!queue.empty())
{
- point_type s = q.front();
- q.pop();
- oln_type_of(I, niter) n(input);
- for_all_n_of_p (n, s)
- if (input.hold(n) and !processed[n] and input[n] == input[s])
+ point_type s = queue.front();
+ queue.pop();
+ mln_qiter(W) q(win, s);
+ for_all(q)
+ if (input.has(q) and !processed(q) and input(q) == input(s))
{
- labels[n] = cur_label;
- processed[n] = true;
- q.push(n);
+ labels(q) = cur_label;
+ processed(q) = true;
+ queue.push(q);
}
}
++cur_label;
}
+ // Update ncomps.
+ ncomps = cur_label;
return labels;
}
- } // end of namespace oln::level
+ template <typename DestValue, typename I, typename W>
+ mln_ch_value(I, DestValue)
+ level_components(const Image<I>& input, const Window<W>& win)
+ {
+ // Dummy value.
+ unsigned ncomps;
+ return level_components<DestValue>(input, win, ncomps);
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::morpho
-} // end of namespace oln
+} // end of namespace mln
-#endif // ! OLENA_MORPHO_LEVEL_COMPONENTS_HH
+#endif // ! MLN_MORPHO_MORPHO_COMPONENTS_HH
Index: tests/morpho/level_components.cc
--- tests/morpho/level_components.cc (revision 0)
+++ tests/morpho/level_components.cc (revision 0)
@@ -0,0 +1,62 @@
+// 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
+// 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/morpho/level_components.cc
+// /\brief Test on mln::morpho::level_components
+
+#include <iostream>
+
+#include <mln/core/image2d.hh>
+#include <mln/core/window2d.hh>
+#include <mln/core/neighb2d.hh>
+
+#include <mln/convert/to_window.hh>
+
+#include <mln/value/int_u8.hh>
+
+#include <mln/morpho/level_components.hh>
+
+#include <mln/io/pgm/load.hh>
+#include <mln/io/pgm/save.hh>
+
+#include "tests/data.hh"
+
+
+int main()
+{
+ using namespace mln;
+ using value::int_u8;
+
+ image2d<int_u8> input;
+ io::pgm::load(input, MLN_IMG_DIR "/squares.pgm");
+ unsigned ncomps;
+ // FIXME: Do we really need to use a neighborood to express a 4-c window?
+ image2d<int_u8> output =
+ morpho::level_components<int_u8>(input, convert::to_window(c4()), ncomps);
+ std::cout << "ncomps = " << ncomps << std::endl;
+ io::pgm::save(output, "out.pgm");
+}
Index: tests/morpho/Makefile.am
--- tests/morpho/Makefile.am (revision 1692)
+++ tests/morpho/Makefile.am (working copy)
@@ -11,6 +11,7 @@
gradient \
hit_or_miss \
laplacian \
+ level_components \
opening_area \
thinning
@@ -22,6 +23,7 @@
gradient_SOURCES = gradient.cc
hit_or_miss_SOURCES = hit_or_miss.cc
laplacian_SOURCES = laplacian.cc
+level_components_SOURCES = level_components.cc
opening_area_SOURCES = opening_area.cc
thinning_SOURCES = thinning.cc