https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Add morphological top-hats and contrast.
* tests/morpho_gradient.cc: Fix doc.
* mln/geom/pmin_pmax.hh (pmin_pmax): Overload for point set.
* mln/geom/bbox.hh: Update.
* mln/morpho/includes.hh (include): Add mln/test/positive.hh
and mln/arith/plus.hh.
* mln/morpho/gradient.hh: Add commentaries.
* tests/morpho_contrast.cc: New.
* mln/morpho/contrast.hh: New.
* mln/morpho/top_hat.hh: New.
mln/geom/bbox.hh | 3 -
mln/geom/pmin_pmax.hh | 91 ++++++++++++++++++++++++++----
mln/morpho/contrast.hh | 82 +++++++++++++++++++++++++++
mln/morpho/gradient.hh | 21 +++----
mln/morpho/includes.hh | 3 +
mln/morpho/top_hat.hh | 138 +++++++++++++++++++++++++++++++++++++++++++++++
tests/morpho_contrast.cc | 61 ++++++++++++++++++++
tests/morpho_gradient.cc | 4 -
8 files changed, 373 insertions(+), 30 deletions(-)
Index: tests/morpho_gradient.cc
--- tests/morpho_gradient.cc (revision 1058)
+++ tests/morpho_gradient.cc (working copy)
@@ -25,9 +25,9 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-/*! \file tests/erosion.cc
+/*! \file tests/morpho_gradient.cc
*
- * \brief Test on mln::morpho::erosion.
+ * \brief Test on mln::morpho::gradient.
*/
#include <mln/core/image2d_b.hh>
Index: tests/morpho_contrast.cc
--- tests/morpho_contrast.cc (revision 0)
+++ tests/morpho_contrast.cc (revision 0)
@@ -0,0 +1,61 @@
+// 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/morpho_contrast.cc
+ *
+ * \brief Test on mln::morpho::contrast.
+ */
+
+#include <mln/core/image2d_b.hh>
+#include <mln/core/win/rectangle2d.hh>
+
+#include <mln/io/load_pgm.hh>
+#include <mln/io/save_pgm.hh>
+
+#include <mln/value/int_u8.hh>
+#include <mln/morpho/contrast.hh>
+#include <mln/level/saturate.hh>
+
+
+int main()
+{
+ using namespace mln;
+ using value::int_u8;
+
+ win::rectangle2d rect(5, 5);
+ border::thickness = 2;
+
+ image2d_b<int_u8>
+ lena = io::load_pgm("../img/tiny.pgm"),
+ out(lena.domain());
+
+ image2d_b<int> tmp(lena.domain());
+ morpho::contrast(lena, rect, tmp);
+
+ level::saturate(tmp, out);
+ io::save_pgm(out, "out.pgm");
+}
Index: mln/geom/pmin_pmax.hh
--- mln/geom/pmin_pmax.hh (revision 1058)
+++ mln/geom/pmin_pmax.hh (working copy)
@@ -36,6 +36,10 @@
# include <utility>
+# include <mln/core/concept/point_set.hh>
+# include <mln/core/concept/box.hh>
+
+
namespace mln
{
@@ -44,6 +48,19 @@
{
+ /// Compute the minimum and maximum points of point set \p s.
+ template <typename S>
+ std::pair<mln_point(S), mln_point(S)>
+ pmin_pmax(const Point_Set<S>& s);
+
+
+ /// Compute the minimum and maximum points, \p pmin and \p max,
+ /// of point set \p s.
+ template <typename S>
+ void
+ pmin_pmax(const Point_Set<S>& s, mln_point(S)& pmin, mln_point(S)&
pmax);
+
+
/// Compute the minimum and maximum points when browsing with
/// iterator \p p.
template <typename I>
@@ -61,40 +78,86 @@
# ifndef MLN_INCLUDE_ONLY
+
+ // Versions with point iterator.
+
template <typename I>
- std::pair<mln_point(I), mln_point(I)>
- pmin_pmax(Point_Iterator<I>& p_)
+ void
+ pmin_pmax(const Point_Iterator<I>& p_, mln_point(I)& pmin,
mln_point(I)& pmax)
{
- I& p = exact(p_);
-
- typedef mln_point(I) P;
- std::pair<P, P> tmp;
- P& pmin = tmp.first;
- P& pmax = tmp.second;
+ I p = exact(p_); // a copy of p_
// init with first point
p.start();
+ mln_precondition(p.is_valid());
pmin = pmax = p;
// update with remaining points
+ typedef mln_point(I) P;
for_all_remaining(p)
for (unsigned i = 0; i < P::dim; ++i)
if (p[i] < pmin[i])
pmin[i] = p[i];
else if (p[i] > pmax[i])
pmax[i] = p[i];
+ }
+ template <typename I>
+ std::pair<mln_point(I), mln_point(I)>
+ pmin_pmax(const Point_Iterator<I>& p)
+ {
+ typedef mln_point(I) P;
+ std::pair<P, P> tmp;
+ pmin_pmax(p, tmp.first, tmp.second); // calls the previous version
return tmp;
}
- template <typename I>
+
+ // Versions with point set.
+
+ namespace impl
+ {
+
+ // General case.
+
+ template <typename S>
void
- pmin_pmax(const Point_Iterator<I>& p, mln_point(I)& pmin,
mln_point(I)& pmax)
+ pmin_pmax_(const Point_Set<S>& s, mln_point(S)& pmin,
mln_point(S)& pmax)
{
- typedef mln_point(I) P;
- std::pair<P, P> tmp = pmin_pmax(p);
- pmin = tmp.first;
- pmax = tmp.second;
+ mln_piter(S) it(exact(s));
+ pmin_pmax(it, pmin, pmax);
+ }
+
+ // Box.
+
+ template <typename B>
+ void
+ pmin_pmax_(const Box<B>& b, mln_point(B)& pmin, mln_point(B)&
pmax)
+ {
+ pmin = exact(b).pmin();
+ pmax = exact(b).pmax();
+ }
+
+ } // end of namespace mln::geom::impl
+
+
+ template <typename S>
+ void
+ pmin_pmax(const Point_Set<S>& s, mln_point(S)& pmin, mln_point(S)&
pmax)
+ {
+ mln_precondition(exact(s).npoints() != 0);
+ impl::pmin_pmax_(exact(s), pmin, pmax);
+ }
+
+ template <typename S>
+ std::pair<mln_point(S), mln_point(S)>
+ pmin_pmax(const Point_Set<S>& s)
+ {
+ mln_precondition(exact(s).npoints() != 0);
+ typedef mln_point(S) P;
+ std::pair<P, P> tmp;
+ pmin_pmax(p_, tmp.first, tmp.second); // calls the previous version
+ return tmp;
}
# endif // ! MLN_INCLUDE_ONLY
Index: mln/geom/bbox.hh
--- mln/geom/bbox.hh (revision 1058)
+++ mln/geom/bbox.hh (working copy)
@@ -100,8 +100,7 @@
mln_precondition(pset.npoints() != 0);
typedef mln_point(S) P;
- mln_piter(S) p(pset);
- std::pair<P, P> pp = geom::pmin_pmax(p);
+ std::pair<P, P> pp = geom::pmin_pmax(pset);
box_<P> tmp(pp.first, pp.second);
// FIXME: mln_postcondition(tmp <= pset.bbox());
Index: mln/morpho/includes.hh
--- mln/morpho/includes.hh (revision 1058)
+++ mln/morpho/includes.hh (working copy)
@@ -40,11 +40,14 @@
# include <mln/accu/min.hh>
# include <mln/accu/max.hh>
+# include <mln/arith/plus.hh>
# include <mln/arith/minus.hh>
# include <mln/level/compare.hh>
# include <mln/level/fill.hh>
+# include <mln/test/positive.hh>
+
# include <mln/border/resize.hh>
# include <mln/border/fill.hh>
Index: mln/morpho/gradient.hh
--- mln/morpho/gradient.hh (revision 1058)
+++ mln/morpho/gradient.hh (working copy)
@@ -31,10 +31,11 @@
/*! \file mln/morpho/gradient.hh
*
* \brief Morphological gradient.
+ *
+ * \todo Save memory.
*/
# include <mln/morpho/includes.hh>
-# include <mln/test/positive.hh>
namespace mln
@@ -82,11 +83,10 @@
mln_precondition(output.domain() = input.domain());
mln_precondition(! win.is_empty());
+ dilation(input, win, output); // output = dilation
O temp(input.domain());
- erosion(input, win, temp);
-
- dilation(input, win, output);
- arith::minus_inplace(output, temp);
+ erosion(input, win, temp); // temp = erosion
+ arith::minus_inplace(output, temp); // now output = dilation - erosion
mln_postcondition(test::positive(output));
}
@@ -103,9 +103,8 @@
mln_precondition(! win.is_empty());
O temp(input.domain());
- erosion(input, win, temp);
-
- arith::minus(input, temp, output);
+ erosion(input, win, temp); // temp = erosion
+ arith::minus(input, temp, output); // output = input - erosion
mln_postcondition(test::positive(output));
}
@@ -121,10 +120,8 @@
mln_precondition(output.domain() = input.domain());
mln_precondition(! win.is_empty());
- O temp(input.domain());
- dilation(input, win, temp);
-
- arith::minus(temp, input, output);
+ dilation(input, win, output); // output = dilation
+ arith::minus_inplace(output, input); // now output = dilation - input
mln_postcondition(test::positive(output));
}
Index: mln/morpho/contrast.hh
--- mln/morpho/contrast.hh (revision 0)
+++ mln/morpho/contrast.hh (revision 0)
@@ -0,0 +1,82 @@
+// 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.
+
+#ifndef MLN_MORPHO_CONTRAST_HH
+# define MLN_MORPHO_CONTRAST_HH
+
+/*! \file mln/morpho/contrast.hh
+ *
+ * \brief Morphological contrast operator (based on top-hats).
+ *
+ * \todo Save memory.
+ */
+
+# include <mln/morpho/top_hat.hh>
+
+
+namespace mln
+{
+
+ namespace morpho
+ {
+
+ /*! Morphological contrast operator (based on top-hats).
+ *
+ * This operator is Id + wth_B - bth_B.
+ */
+ template <typename I, typename W, typename O>
+ void contrast(const Image<I>& input, const Window<W>& win,
+ Image<O>& output);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename I, typename W, typename O>
+ void contrast(const Image<I>& input_, const Window<W>& win_,
Image<O>& output_)
+ {
+ const I& input = exact(input_);
+ const W& win = exact(win_);
+ O& output = exact(output_);
+
+ mln_precondition(output.domain() = input.domain());
+ mln_precondition(! win.is_empty());
+
+ top_hat_white(input, win, output); // output = wth
+ arith::plus_inplace(output, input); // now output = wth + input
+ O temp(input.domain());
+ top_hat_black(input, win, temp); // temp = bth
+ arith::minus_inplace(output, temp); // now output = wth + input - bth
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::morpho
+
+} // end of namespace mln
+
+
+#endif // ! MLN_MORPHO_CONTRAST_HH
Index: mln/morpho/top_hat.hh
--- mln/morpho/top_hat.hh (revision 0)
+++ mln/morpho/top_hat.hh (revision 0)
@@ -0,0 +1,138 @@
+// 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.
+
+#ifndef MLN_MORPHO_TOP_HAT_HH
+# define MLN_MORPHO_TOP_HAT_HH
+
+/*! \file mln/morpho/top_hat.hh
+ *
+ * \brief Morphological top-hats.
+ *
+ * \todo Save memory.
+ */
+
+# include <mln/morpho/opening.hh>
+# include <mln/morpho/closing.hh>
+
+
+namespace mln
+{
+
+ namespace morpho
+ {
+
+ /*! Morphological white top-hat (for object / light objects).
+ *
+ * This operator is Id - ope_B.
+ */
+ template <typename I, typename W, typename O>
+ void top_hat_white(const Image<I>& input, const Window<W>& win,
+ Image<O>& output);
+
+
+ /*! Morphological black top-hat (for background / dark objects).
+ *
+ * This operator is clo_B - Id.
+ */
+ template <typename I, typename W, typename O>
+ void top_hat_black(const Image<I>& input, const Window<W>& win,
+ Image<O>& output);
+
+
+ /*! Morphological self-complementary top-hat.
+ *
+ * This operator is \n
+ * = top_hat_white + top_hat_black \n
+ * = (input - opening) + (closing - input) \n
+ * = closing - opening. \n
+ */
+ template <typename I, typename W, typename O>
+ void top_hat_self_complementary(const Image<I>& input, const
Window<W>& win,
+ Image<O>& output);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename I, typename W, typename O>
+ void top_hat_white(const Image<I>& input_, const Window<W>& win_,
Image<O>& output_)
+ {
+ const I& input = exact(input_);
+ const W& win = exact(win_);
+ O& output = exact(output_);
+
+ mln_precondition(output.domain() = input.domain());
+ mln_precondition(! win.is_empty());
+
+ O temp(input.domain());
+ opening(input, win, temp); // temp = opening
+ arith::minus(input, temp, output); // output = input - opening
+
+ mln_postcondition(test::positive(output));
+ }
+
+ template <typename I, typename W, typename O>
+ void top_hat_black(const Image<I>& input_, const Window<W>& win_,
Image<O>& output_)
+ {
+ const I& input = exact(input_);
+ const W& win = exact(win_);
+ O& output = exact(output_);
+
+ mln_precondition(output.domain() = input.domain());
+ mln_precondition(! win.is_empty());
+
+ closing(input, win, output); // output = closing
+ arith::minus_inplace(output, input); // now output = closing - input
+
+ mln_postcondition(test::positive(output));
+ }
+
+ template <typename I, typename W, typename O>
+ void top_hat_self_complementary(const Image<I>& input_, const
Window<W>& win_, Image<O>& output_)
+ {
+ const I& input = exact(input_);
+ const W& win = exact(win_);
+ O& output = exact(output_);
+
+ mln_precondition(output.domain() = input.domain());
+ mln_precondition(! win.is_empty());
+
+ closing(input, win, output); // output = closing
+ O temp(input.domain());
+ opening(input, win, temp); // temp = opening
+ arith::minus_inplace(output, temp); // now output = closing - opening
+
+ mln_postcondition(test::positive(output));
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::morpho
+
+} // end of namespace mln
+
+
+#endif // ! MLN_MORPHO_TOP_HAT_HH