URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena
ChangeLog:
2007-09-05 Simon Nivault <simon.nivault(a)lrde.epita.fr>
Add fast-gaussian
* sandbox/nivault/fast_gaussian.hh: New.
* sandbox/nivault/tests/test.cc: New.
* sandbox/nivault/tests/test: New.
* sandbox/nivault/tests: New.
fast_gaussian.hh | 288 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
tests/test | 4
tests/test.cc | 42 ++++++++
3 files changed, 334 insertions(+)
Index: trunk/milena/sandbox/nivault/tests/test
===================================================================
--- trunk/milena/sandbox/nivault/tests/test (revision 0)
+++ trunk/milena/sandbox/nivault/tests/test (revision 1069)
@@ -0,0 +1,4 @@
+#!/bin/bash
+
+g++ -I../../.. -I../.. -I.. test.cc -O1
+./a.out
Property changes on: trunk/milena/sandbox/nivault/tests/test
___________________________________________________________________
Name: svn:executable
+ *
Index: trunk/milena/sandbox/nivault/tests/test.cc
===================================================================
--- trunk/milena/sandbox/nivault/tests/test.cc (revision 0)
+++ trunk/milena/sandbox/nivault/tests/test.cc (revision 1069)
@@ -0,0 +1,42 @@
+// 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.
+
+#include <mln/core/image2d_b.hh>
+#include <mln/io/load_pgm.hh>
+#include <mln/io/save_pgm.hh>
+
+#include <fast_gaussian.hh>
+
+int main()
+{
+ mln::image2d_b<mln::value::int_u<8u> > im1 = mln::io::load_pgm("../../../img/lena.pgm");
+ mln::image2d_b<float> im2;
+
+ mln::linear::gaussian(im1, 0.2, im2);
+
+ // mln::io::save_pgm(im2, "gausslena.pgm");
+ }
Index: trunk/milena/sandbox/nivault/fast_gaussian.hh
===================================================================
--- trunk/milena/sandbox/nivault/fast_gaussian.hh (revision 0)
+++ trunk/milena/sandbox/nivault/fast_gaussian.hh (revision 1069)
@@ -0,0 +1,288 @@
+// Copyright (C) 2001, 2002, 2003, 2004 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, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301, 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_CONVOL_FAST_GAUSSIAN_FILTER_HH__
+# define OLENA_CONVOL_FAST_GAUSSIAN_FILTER_HH__
+
+#include <mln/core/concept/image.hh>
+#include <mln/level/paste.hh>
+#include <mln/geom/ncols.hh>
+
+
+namespace mln
+{
+
+ namespace linear
+ {
+
+
+ struct recursivefilter_coef_
+ {
+
+ /*!
+ ** \brief Constructor.
+ */
+ recursivefilter_coef_(float a0, float a1,
+ float b0, float b1,
+ float c0, float c1,
+ float w0, float w1,
+ float s);
+ std::vector<float> n, d, nm, dm;
+ float sumA, sumC;
+ };
+
+ recursivefilter_coef_::recursivefilter_coef_(float a0, float a1,
+ float b0, float b1,
+ float c0, float c1,
+ float w0, float w1,
+ float s)
+ {
+ n.reserve(5);
+ d.reserve(5);
+ nm.reserve(5);
+ dm.reserve(5);
+
+ b0 /= s;
+ b1 /= s;
+ w0 /= s;
+ w1 /= s;
+
+ float sin0 = sin(w0);
+ float sin1 = sin(w1);
+ float cos0 = cos(w0);
+ float cos1 = cos(w1);
+
+ sumA =
+ (2.0 * a1 * exp( b0 ) * cos0 * cos0 - a0 * sin0 * exp( 2.0 * b0 )
+ + a0 * sin0 - 2.0 * a1 * exp( b0 )) /
+ (( 2.0 * cos0 * exp( b0 ) - exp( 2.0 * b0 ) - 1 ) * sin0);
+
+ sumC =
+ (2.0 * c1 * exp( b1 ) * cos1 * cos1 - c0 * sin1 * exp( 2.0 * b1 )
+ + c0 * sin1 - 2.0 * c1 * exp( b1 ))
+ / (( 2.0 * cos1 * exp( b1 ) - exp( 2.0 * b1 ) - 1 ) * sin1);
+
+ a0 /= (sumA + sumC);
+ a1 /= (sumA + sumC);
+ c0 /= (sumA + sumC);
+ c1 /= (sumA + sumC);
+
+ n[3] =
+ exp( -b1 - 2*b0 ) * (c1 * sin1 - cos1 * c0) +
+ exp( -b0 - 2*b1 ) * (a1 * sin0 - cos0 * a0);
+ n[2] =
+ 2 * exp(-b0 - b1) * ((a0 + c0) * cos1 * cos0 -
+ cos1 * a1 * sin0 -
+ cos0 * c1 * sin1) +
+ c0 * exp(-2 * b0) + a0 * exp(-2 * b1);
+ n[1] =
+ exp(-b1) * (c1 * sin1 - (c0 + 2*a0) * cos1) +
+ exp(-b0) * (a1 * sin0 - (2*c0 + a0) * cos0);
+ n[0] =
+ a0 + c0;
+
+ d[4] = exp(-2 * b0 - 2 * b1);
+ d[3] =
+ -2 * cos0 * exp(-b0 - 2*b1) -
+ 2 * cos1 * exp(-b1 - 2*b0);
+ d[2] =
+ 4 * cos1 * cos0 * exp(-b0 - b1) +
+ exp(-2*b1) + exp(-2*b0);
+ d[1] =
+ -2*exp(-b1) * cos1 - 2 * exp(-b0) * cos0;
+
+ for (unsigned i = 1; i <= 3; ++i)
+ {
+ dm[i] = d[i];
+ nm[i] = n[i] - d[i] * n[0];
+ }
+ dm[4] = d[4];
+ nm[4] = -d[4] * n[0];
+ }
+
+
+
+ template <class WorkType, class I>
+ void
+ recursivefilter_(I& ima,
+ const recursivefilter_coef_& c,
+ const mln_point(I)& start,
+ const mln_point(I)& finish,
+ int len,
+ const mln_dpoint(I)& d)
+ {
+ std::vector<WorkType> tmp1(len);
+ std::vector<WorkType> tmp2(len);
+
+ // The fourth degree approximation implies to have a special
+ // look on the four first points we consider that there is
+ // no signal before 0 (to be discussed)
+
+ // --
+ // Causal part
+
+ tmp1[0] =
+ c.n[0]*ima(start);
+
+ tmp1[1] =
+ c.n[0]*ima(start + d)
+ + c.n[1]*ima(start)
+ - c.d[1]*tmp1[0];
+
+ tmp1[2] =
+ c.n[0]*ima(start + d + d)
+ + c.n[1]*ima(start + d)
+ + c.n[2]*ima(start)
+ - c.d[1]*tmp1[1]
+ - c.d[2]*tmp1[0];
+
+ tmp1[3] =
+ c.n[0]*ima(start + d + d + d)
+ + c.n[1]*ima(start + d + d)
+ + c.n[2]*ima(start + d)
+ + c.n[3]*ima(start)
+ - c.d[1]*tmp1[2] - c.d[2]*tmp1[1]
+ - c.d[3]*tmp1[0];
+
+ mln_point(I) current(start + d + d + d + d);
+ for (mln_coord(I) i = 4; i < len; ++i)
+ {
+ tmp1[i] =
+ c.n[0]*ima(current)
+ + c.n[1]*ima(current - d)
+ + c.n[2]*ima(current - d - d)
+ + c.n[3]*ima(current - d - d - d)
+ - c.d[1]*tmp1[i - 1] - c.d[2]*tmp1[i - 2]
+ - c.d[3]*tmp1[i - 3] - c.d[4]*tmp1[i - 4];
+ current += d;
+ }
+
+ // Non causal part
+
+ tmp2[len - 1] = 0;
+
+ tmp2[len - 2] =
+ c.nm[1]*ima(finish);
+
+ tmp2[len - 3] =
+ c.nm[1]*ima(finish - d)
+ + c.nm[2]*ima(finish)
+ - c.dm[1]*tmp2[len-2];
+
+ tmp2[len - 4] =
+ c.nm[1]*ima(finish - d - d)
+ + c.nm[2]*ima(finish - d)
+ + c.nm[3]*ima(finish)
+ - c.dm[1]*tmp2[len-3]
+ - c.dm[2]*tmp2[len-2];
+
+ current = finish - d - d - d ;
+
+ for (int i = len - 5; i >= 0; --i)
+ {
+ tmp2[i] =
+ c.nm[1]*ima(current)
+ + c.nm[2]*ima(current + d)
+ + c.nm[3]*ima(current + d + d)
+ + c.nm[4]*ima(current + d + d + d)
+ - c.dm[1]*tmp2[i+1] - c.dm[2]*tmp2[i+2]
+ - c.dm[3]*tmp2[i+3] - c.dm[4]*tmp2[i+4];
+ current -= d;
+ }
+
+ // Combine results from causal and non-causal parts.
+
+ current = start;
+ for (int i = 0; i < len; ++i)
+ {
+ ima(current) = tmp1[i] + tmp2[i];
+ current += d;
+ }
+ }
+
+
+ template <class I, class F>
+ void
+ gaussian_(Image<I>& img_, const F& coef)
+ {
+ I& img = exact(img_);
+ typedef mln_point(I) P;
+ // Apply on columns.
+
+ recursivefilter_<float>(img, coef,
+ make::point2d(0, - img.border()), // FIXME
+ make::point2d(0, geom::ncols(img) - 1 + img.border()),
+ geom::ncols(img) + 2 * img.border(),
+ make::dpoint2d(0, 1));
+ }
+
+
+ template <class I, class F, class O>
+ void
+ gaussian_common_(const Image<I>& in,
+ const F& coef,
+ float sigma,
+ Image<O>& out)
+ {
+ mln_ch_value(O, float) work_img(exact(in).domain());
+ level::paste(in, work_img);
+
+ // On tiny sigma, Derich algorithm doesn't work.
+ // It is the same thing that to convolve with a Dirac.
+ if (sigma > 0.006)
+ gaussian_(work_img, coef);
+ /* Convert the result image to the user-requested datatype.
+ FIXME: We are making an unnecessary copy in case the
+ user expects a ntg::float_s image. */
+ level::paste(work_img, out);
+ }
+
+
+
+
+ template <class I, class O>
+ void
+ gaussian(const Image<I>& in, float sigma,
+ Image<O>& out)
+ {
+ recursivefilter_coef_
+ coef(1.68f, 3.735f,
+ 1.783f, 1.723f,
+ -0.6803f, -0.2598f,
+ 0.6318f, 1.997f,
+ sigma);
+
+ gaussian_common_(in, coef, sigma, out);
+ }
+
+ }
+
+}
+
+
+
+#endif // OLENA_CONVOL_FAST_GAUSSIAN_FILTER_HH__
https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Add labeling routines.
* tests/sort_points.cc: Rename as...
* tests/level_sort_points.cc: ...this.
Augment.
* tests/labeling.cc: Rename as...
* tests/labeling_foreground.cc: ...this.
Update.
* tests/labeling_regional_maxima.cc: New.
* mln/convert/to_vec_p.hh: New.
* mln/pw/image.hh (change_value): Use fixme.
* mln/core/vec_p.hh (reserve, hook_): New.
* mln/core/vec_p_piter.hh (vec_p_bkd_piter_): Code.
* mln/level/sort_points.hh (sort_points): Rename as...
(sort_points_increasing): ...this.
(sort_points_decreasing): New.
* mln/level/fill.hh: Add & to the C function arg; that fixes
the behavior of icpc when calling fill with the literal 0.
* mln/level/labeling.hh: Remove; obsolete because of
labeling::level.
* mln/linear/sobel.hh: Add FIXME.
* mln/canvas/labeling.hh: New.
* mln/labeling/flat_zones.hh: New.
* mln/labeling/+foreground.hh: Remove.
* mln/labeling/level.hh: New.
* mln/labeling/foreground.hh: New.
* mln/labeling/regional_minima.hh: New.
* mln/labeling/base.hh: New.
* mln/labeling/regional_maxima.hh: New.
* mln/labeling/background.hh: New.
mln/canvas/labeling.hh | 157 ++++++++++++++++++++++++++++++++++++++
mln/convert/to_vec_p.hh | 71 +++++++++++++++++
mln/core/vec_p.hh | 20 ++++
mln/core/vec_p_piter.hh | 121 ++++++++++++++++++++++++++++-
mln/labeling/background.hh | 79 +++++++++++++++++++
mln/labeling/base.hh | 94 ++++++++++++++++++++++
mln/labeling/flat_zones.hh | 111 ++++++++++++++++++++++++++
mln/labeling/foreground.hh | 79 +++++++++++++++++++
mln/labeling/level.hh | 118 ++++++++++++++++++++++++++++
mln/labeling/regional_maxima.hh | 120 +++++++++++++++++++++++++++++
mln/labeling/regional_minima.hh | 120 +++++++++++++++++++++++++++++
mln/level/fill.hh | 5 -
mln/level/sort_points.hh | 110 ++++++++++++++++++++------
mln/linear/sobel.hh | 2
mln/pw/image.hh | 2
tests/labeling_foreground.cc | 45 ++--------
tests/labeling_regional_maxima.cc | 57 +++++++++++++
tests/level_sort_points.cc | 15 ++-
18 files changed, 1254 insertions(+), 72 deletions(-)
Index: tests/level_sort_points.cc
--- tests/level_sort_points.cc (revision 1067)
+++ tests/level_sort_points.cc (working copy)
@@ -47,10 +47,13 @@
image2d_b<int_u8> ima(3, 3);
debug::iota(ima);
- std::vector<point2d> vec = level::sort_points(ima);
-
- std::copy(vec.begin(), vec.end(),
- std::ostream_iterator<point2d>(std::cout, " "));
- std::cout << std::endl;
-
+ vec_p<point2d> vec;
+ {
+ vec = level::sort_points_increasing(ima);
+ std::cout << vec << std::endl;
+ }
+ {
+ vec = level::sort_points_decreasing(ima);
+ std::cout << vec << std::endl;
+ }
}
Index: tests/labeling_foreground.cc
--- tests/labeling_foreground.cc (revision 1067)
+++ tests/labeling_foreground.cc (working copy)
@@ -25,54 +25,33 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-/*! \file tests/labeling.cc
+/*! \file tests/labeling_foreground.cc
*
- * \brief Tests on mln::level::labeling.
+ * \brief Test on mln::labeling::foreground.
*/
#include <mln/core/image2d_b.hh>
#include <mln/core/neighb2d.hh>
-
#include <mln/value/int_u8.hh>
-#include <mln/value/label.hh>
-
-#include <mln/pw/value.hh>
-#include <mln/pw/cst.hh>
-#include <mln/fun/ops.hh>
+#include <mln/pw/all.hh>
#include <mln/io/load_pgm.hh>
#include <mln/io/save_pgm.hh>
-
-#include <mln/level/fill.hh>
-#include <mln/level/labeling.hh>
-#include <mln/level/to_enc.hh>
-
+#include <mln/labeling/foreground.hh>
int main()
{
using namespace mln;
using value::int_u8;
- using value::label;
- image2d_b<int_u8> lena = io::load_pgm("../img/lena.pgm");
-
- image2d_b<bool> bin(lena.domain());
- level::fill(bin, pw::value(lena) > pw::cst(127));
-
- {
- image2d_b<int_u8> lab(lena.domain());
- level::labeling(bin, c4(), lab);
- io::save_pgm(lab, "lab.pgm");
- }
-
- {
- image2d_b< label<8> > lab(lena.domain());
- level::labeling(bin, c4(), lab);
-
- image2d_b< int_u8 > out(lena.domain());
- level::to_enc(lab, out);
+ image2d_b<int_u8>
+ lena = io::load_pgm("../img/tiny.pgm"),
+ out(lena.domain());
+
+ unsigned n;
+ labeling::foreground((pw::value(lena) > pw::cst(127)) | lena.domain(),
+ c4(), out, n);
io::save_pgm(out, "out.pgm");
- }
-
+ mln_assertion(n = 14);
}
Index: tests/labeling_regional_maxima.cc
--- tests/labeling_regional_maxima.cc (revision 0)
+++ tests/labeling_regional_maxima.cc (revision 0)
@@ -0,0 +1,57 @@
+// 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/labeling_regional_maxima.cc
+ *
+ * \brief Test on mln::labeling::regional_maxima.
+ */
+
+#include <mln/core/image2d_b.hh>
+#include <mln/core/neighb2d.hh>
+#include <mln/value/int_u8.hh>
+
+#include <mln/io/load_pgm.hh>
+#include <mln/io/save_pgm.hh>
+
+#include <mln/labeling/regional_maxima.hh>
+
+
+int main()
+{
+ using namespace mln;
+ using value::int_u8;
+
+ image2d_b<int_u8>
+ lena = io::load_pgm("../img/lena.pgm"),
+ out(lena.domain());
+
+ unsigned n;
+ labeling::regional_maxima(lena, c4(), out, n);
+ mln_assertion(n = 255);
+
+ io::save_pgm(out, "out.pgm");
+}
Index: mln/convert/to_vec_p.hh
--- mln/convert/to_vec_p.hh (revision 0)
+++ mln/convert/to_vec_p.hh (revision 0)
@@ -0,0 +1,71 @@
+// 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_CONVERT_TO_VEC_P_HH
+# define MLN_CONVERT_TO_VEC_P_HH
+
+/*! \file mln/convert/to_vec_p.hh
+ *
+ * \brief Conversions to mln::vec_p.
+ */
+
+# include <mln/core/vec_p.hh>
+
+
+namespace mln
+{
+
+ namespace convert
+ {
+
+ /// Convert a point set \p pset into a vec_p (point set vector).
+ template <typename S>
+ vec_p<mln_point(S)> to_vec_p(const Point_Set<S>& pset);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename S>
+ vec_p<mln_point(S)> to_vec_p(const Point_Set<S>& pset_)
+ {
+ const S& pset = exact(pset_);
+ vec_p<mln_point(S)> v;
+ v.reserve(pset.npoints());
+ mln_fwd_piter(S) p(pset);
+ for_all(p)
+ v.append(p);
+ return v;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::convert
+
+} // end of namespace mln
+
+
+#endif // ! MLN_CONVERT_TO_VEC_P_HH
Index: mln/pw/image.hh
--- mln/pw/image.hh (revision 1067)
+++ mln/pw/image.hh (working copy)
@@ -109,7 +109,7 @@
template <typename U>
struct change_value
{
- typedef void ret;
+ typedef internal::fixme ret;
};
protected:
Index: mln/core/vec_p.hh
--- mln/core/vec_p.hh (revision 1067)
+++ mln/core/vec_p.hh (working copy)
@@ -79,6 +79,9 @@
/// Constructor from a vector \p vect.
vec_p(const std::vector<P>& vect);
+ /// Reserve \p n cells.
+ void reserve(std::size_t n);
+
/// Test is \p p belongs to this point set.
bool has(const P& p) const;
@@ -100,6 +103,9 @@
/// Return the \p i-th point.
const P& operator[](unsigned i) const;
+ /// Hook to data.
+ std::vector<P>& hook_();
+
protected:
std::vector<P> vect_;
@@ -129,6 +135,20 @@
template <typename P>
void
+ vec_p<P>::reserve(std::size_t n)
+ {
+ vect_.reserve(n);
+ }
+
+ template <typename P>
+ std::vector<P>&
+ vec_p<P>::hook_()
+ {
+ return vect_;
+ }
+
+ template <typename P>
+ void
vec_p<P>::update_bb_() const
{
bb_.init();
Index: mln/core/vec_p_piter.hh
--- mln/core/vec_p_piter.hh (revision 1067)
+++ mln/core/vec_p_piter.hh (working copy)
@@ -92,15 +92,63 @@
- // FIXME:
+ /*! \brief Backward iterator on points of a vec_p<P>.
+ *
+ */
template <typename P>
- struct vec_p_bkd_piter_ : internal::fixme
- {};
+ struct vec_p_bkd_piter_ : public Point_Iterator< vec_p_bkd_piter_<P> >
+ {
+ enum { dim = P::dim };
+
+ /// Point_Site associated type.
+ typedef P psite;
+
+ /// Point associated type.
+ typedef P point;
+
+ /// Dpoint associated type.
+ typedef mln_dpoint(P) dpoint;
+
+ /// Coordinate associated type.
+ typedef mln_coord(P) coord;
+
+ /// Coordinate associated type.
+ template <typename S>
+ vec_p_bkd_piter_(const Point_Set<S>& s);
+
+ /// Give a hook to the point address.
+ const P* pointer_() const;
+
+ /// Read-only access to the \p i-th coordinate.
+ coord operator[](unsigned i) const;
+
+ /// Test if the iterator is valid.
+ bool is_valid() const;
+
+ /// Invalidate the iterator.
+ void invalidate();
+
+ /// Start an iteration.
+ void start();
+
+ /// Go to the next point.
+ void next_();
+
+ /// Convert the iterator into a point.
+ operator P() const;
+
+ protected:
+ const std::vector<P>& vect_;
+ int i_;
+ P p_;
+ };
# ifndef MLN_INCLUDE_ONLY
+ // vec_p_fwd_piter_<P>
+
template <typename P>
template <typename S>
vec_p_fwd_piter_<P>::vec_p_fwd_piter_(const Point_Set<S>& s)
@@ -153,6 +201,7 @@
vec_p_fwd_piter_<P>::next_()
{
++i_;
+ if (is_valid())
p_ = vect_[i_];
}
@@ -163,6 +212,72 @@
return p_;
}
+
+ // vec_p_bkd_piter_<P>
+
+ template <typename P>
+ template <typename S>
+ vec_p_bkd_piter_<P>::vec_p_bkd_piter_(const Point_Set<S>& s)
+ : vect_(exact(s).vect())
+ {
+ invalidate();
+ }
+
+ template <typename P>
+ const P*
+ vec_p_bkd_piter_<P>::pointer_() const
+ {
+ return & p_;
+ }
+
+ template <typename P>
+ mln_coord(P)
+ vec_p_bkd_piter_<P>::operator[](unsigned i) const
+ {
+ mln_precondition(i < dim);
+ mln_precondition(is_valid());
+ return p_[i];
+ }
+
+ template <typename P>
+ bool
+ vec_p_bkd_piter_<P>::is_valid() const
+ {
+ return i_ >= 0;
+ }
+
+ template <typename P>
+ void
+ vec_p_bkd_piter_<P>::invalidate()
+ {
+ i_ = -1;
+ }
+
+ template <typename P>
+ void
+ vec_p_bkd_piter_<P>::start()
+ {
+ i_ = vect_.size() - 1;
+ if (is_valid())
+ p_ = vect_[i_];
+ }
+
+ template <typename P>
+ void
+ vec_p_bkd_piter_<P>::next_()
+ {
+ --i_;
+ if (is_valid())
+ p_ = vect_[i_];
+ }
+
+ template <typename P>
+ vec_p_bkd_piter_<P>::operator P() const
+ {
+ mln_precondition(is_valid());
+ return p_;
+ }
+
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln
Index: mln/level/sort_points.hh
--- mln/level/sort_points.hh (revision 1067)
+++ mln/level/sort_points.hh (working copy)
@@ -31,13 +31,14 @@
/*! \file mln/level/sort_points.hh
*
* \brief Sort_Points the contents of an image into another one.
+ *
+ * \todo Factor code + optimize.
*/
-# include <vector>
-# include <utility>
# include <algorithm>
# include <mln/core/concept/image.hh>
+# include <mln/convert/to_vec_p.hh>
# include <mln/histo/compute.hh>
@@ -55,7 +56,7 @@
* \pre \p input.has_data
*/
template <typename I>
- std::vector<mln_point(I)> sort_points(const Image<I>& input);
+ vec_p<mln_point(I)> sort_points_increasing(const Image<I>& input);
# ifndef MLN_INCLUDE_ONLY
@@ -63,6 +64,8 @@
namespace impl
{
+ // utility
+
template <typename I>
struct value_point_less_
{
@@ -82,31 +85,40 @@
};
template <typename I>
- std::vector<mln_point(I)>
- sort_points(metal::false_, // general case
- const Image<I>& input_)
+ struct value_point_greater_
{
- const I& input = exact(input_);
+ const I& ima_;
- std::vector<mln_point(I)> vec;
- vec.reserve(input.npoints());
+ value_point_greater_(const I& ima)
+ : ima_(ima)
+ {
+ }
- mln_fwd_piter(I) p(input.domain());
- for_all(p)
- vec.push_back(p);
+ bool operator()(const mln_point(I)& lhs,
+ const mln_point(I)& rhs) const
+ {
+ return ima_(lhs) > ima_(rhs) || (ima_(lhs) = ima_(rhs)
+ && lhs > rhs);
+ }
+ };
- std::sort(vec.begin(), vec.end(),
+
+ // increasing
+
+ template <typename I>
+ vec_p<mln_point(I)>
+ sort_points_increasing_(metal::false_, const I& input) // general case
+ {
+ vec_p<mln_point(I)> v = convert::to_vec_p(input.domain());
+ std::sort(v.hook_().begin(), v.hook_().end(),
value_point_less_<I>(input));
- return vec;
+ return v;
}
template <typename I>
- std::vector<mln_point(I)>
- sort_points(metal::true_, // low quantization
- const Image<I>& input_)
+ vec_p<mln_point(I)>
+ sort_points_increasing_(metal::true_, const I& input) // low quantization
{
- const I& input = exact(input_);
-
typedef mln_vset(I) S;
const S& vset = input.values();
const unsigned n = vset.nvalues();
@@ -120,12 +132,46 @@
for (unsigned i = 1; i != n; ++i)
loc[i] = loc[i-1] + h[i-1];
- /*
- MEMO. Decreasing case is:
+ // computing output data
+ std::vector<mln_point(I)> vec(input.npoints());
+ mln_fwd_piter(I) p(input.domain());
+ for_all(p)
+ vec[loc[vset.index_of(input(p))]++] = p;
+
+ vec_p<mln_point(I)> v;
+ v.hook_() = vec;
+ return v;
+ }
+
+
+ // decreasing
+
+ template <typename I>
+ vec_p<mln_point(I)>
+ sort_points_decreasing_(metal::false_, const I& input) // general case
+ {
+ vec_p<mln_point(I)> v = convert::to_vec_p(input.domain());
+ std::sort(v.hook_().begin(), v.hook_().end(),
+ value_point_greater_<I>(input));
+ return v;
+ }
+
+ template <typename I>
+ vec_p<mln_point(I)>
+ sort_points_decreasing_(metal::true_, const I& input) // low quantization
+ {
+ typedef mln_vset(I) S;
+ const S& vset = input.values();
+ const unsigned n = vset.nvalues();
+
+ // h
+ histo::data<S> h = histo::compute(input);
+
+ // preparing output data
+ std::vector<unsigned> loc(vset.nvalues());
loc[n-1] = 0;
for (unsigned i = n - 2; i != 0; --i)
loc[i] = loc[i+1] + h[i+1];
- */
// computing output data
std::vector<mln_point(I)> vec(input.npoints());
@@ -133,20 +179,32 @@
for_all(p)
vec[loc[vset.index_of(input(p))]++] = p;
- return vec;
+ vec_p<mln_point(I)> v;
+ v.hook_() = vec;
+ return v;
}
+
} // end of namespace mln::level::impl
+ // Facades.
+
template <typename I>
- std::vector<mln_point(I)>
- sort_points(const Image<I>& input)
+ vec_p<mln_point(I)>
+ sort_points_increasing(const Image<I>& input)
{
mln_precondition(exact(input).has_data());
- return impl::sort_points(mln_is_value_lowq(I)(), exact(input));
+ return impl::sort_points_increasing_(mln_is_value_lowq(I)(), exact(input));
}
+ template <typename I>
+ vec_p<mln_point(I)>
+ sort_points_decreasing(const Image<I>& input)
+ {
+ mln_precondition(exact(input).has_data());
+ return impl::sort_points_decreasing_(mln_is_value_lowq(I)(), exact(input));
+ }
# endif // ! MLN_INCLUDE_ONLY
Index: mln/level/fill.hh
--- mln/level/fill.hh (revision 1067)
+++ mln/level/fill.hh (working copy)
@@ -86,7 +86,7 @@
* \todo Take benefit from quantization when possible.
*/
template <typename I>
- void fill(Image<I>& ima, mln_value(I) (*f)(const mln_point(I)& p));
+ void fill(Image<I>& ima, mln_value(I) (*(&f))(const mln_point(I)& p));
/*! Fill the image \p ima with the values given by the array \p arr.
@@ -191,8 +191,9 @@
template <typename I>
void fill(Image<I>& ima_,
- mln_value(I) (*f)(const mln_point(I)& p))
+ mln_value(I) (*(&f))(const mln_point(I)& p))
{
+ mln_precondition(f != 0);
I& ima = exact(ima_);
mln_precondition(ima.has_data());
mln_piter(I) p(ima.domain());
Index: mln/linear/sobel.hh
--- mln/linear/sobel.hh (revision 1067)
+++ mln/linear/sobel.hh (working copy)
@@ -102,7 +102,7 @@
O temp(exact(input).domain());
sobel_v(input, temp);
// output
- arith::plus_inplace(output, temp);
+ arith::plus_inplace(output, temp); // FIXME: abs before plus!!!
level::abs_inplace(output);
}
Index: mln/canvas/labeling.hh
--- mln/canvas/labeling.hh (revision 0)
+++ mln/canvas/labeling.hh (revision 0)
@@ -0,0 +1,157 @@
+// 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_CANVAS_LABELING_HH
+# define MLN_CANVAS_LABELING_HH
+
+/*! \file mln/canvas/labeling.hh
+ *
+ * \brief Connected component labeling of the object part in a binary
+ * image.
+ */
+
+# include <mln/level/fill.hh>
+# include <mln/level/sort_points.hh>
+
+
+namespace mln
+{
+
+ namespace canvas
+ {
+
+ template <typename F>
+ struct labeling
+ {
+ F& f;
+
+ typedef typename F::I I;
+ typedef typename F::N N;
+ typedef typename F::O O;
+ typedef typename F::S S;
+ typedef mln_point(I) point;
+
+ // aux:
+ mln_ch_value(O, bool) deja_vu;
+ mln_ch_value(O, point) parent;
+
+ labeling(F& f)
+ : f(f),
+ deja_vu(f.output.domain()),
+ parent(f.output.domain())
+ {
+ run();
+ }
+
+ void run()
+ {
+ // init
+ {
+ f.nlabels = 0;
+ mln::level::fill(deja_vu, false);
+ f.init();
+ }
+ // first pass
+ {
+ mln_fwd_piter(S) p(f.s);
+ mln_niter(N) n(f.nbh, p);
+ for_all(p) if (f.handles(p))
+ {
+ make_set(p);
+ for_all(n)
+ if (f.input.has(n) && deja_vu(n))
+ if (f.equiv(n, p))
+ do_union(n, p);
+ else
+ f.do_no_union(n, p);
+ deja_vu(p) = true;
+ }
+ }
+
+ // second pass
+ {
+ mln_bkd_piter(S) p(f.s);
+ mln_niter(N) n(f.nbh, p);
+ for_all(p) if (f.handles(p))
+ {
+ if (is_root(p))
+ {
+ if (f.labels(p))
+ {
+ if (f.nlabels = mln_max(mln_value(O)))
+ {
+ f.status = false;
+ return;
+ }
+ f.output(p) = ++f.nlabels;
+ }
+ }
+ else
+ f.output(p) = f.output(parent(p));
+ }
+ f.status = true;
+ }
+
+ } // end of run()
+
+ void make_set(const point& p)
+ {
+ parent(p) = p;
+ f.init_attr(p);
+ }
+
+ bool is_root(const point& p) const
+ {
+ return parent(p) = p;
+ }
+
+ point find_root(const point& x)
+ {
+ if (parent(x) = x)
+ return x;
+ else
+ return parent(x) = find_root(parent(x));
+ }
+
+ void do_union(const point& n, const point& p)
+ {
+ point r = find_root(n);
+ if (r != p)
+ {
+ parent(r) = p;
+ f.merge_attr(r, p);
+ }
+ }
+
+ };
+
+ } // end of namespace mln::canvas
+
+} // end of namespace mln
+
+
+#endif // ! MLN_CANVAS_LABELING_HH
Index: mln/labeling/flat_zones.hh
--- mln/labeling/flat_zones.hh (revision 0)
+++ mln/labeling/flat_zones.hh (revision 0)
@@ -0,0 +1,111 @@
+// 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_LABELING_FLAT_ZONES_HH
+# define MLN_LABELING_FLAT_ZONES_HH
+
+/*! \file mln/labeling/flat_zones.hh
+ *
+ * \brief Connected component labeling of the flat zones of an image.
+ */
+
+# include <mln/labeling/base.hh>
+
+
+namespace mln
+{
+
+ namespace labeling
+ {
+
+ /*! Connected component labeling of the flat zones of an image.
+ *
+ * \param[in] input The input image.
+ * \param[in] nbh The neighborhood to consider.
+ * \param[out] output The label image.
+ * \param[out] nlabels The number of labels.
+ *
+ * \return The number of labels.
+ */
+ template <typename I, typename N, typename O>
+ bool flat_zones(const Image<I>& input, const Neighborhood<N>& nbh,
+ Image<O>& output,
+ unsigned& nlabels);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace impl
+ {
+
+ template <typename I_, typename N_, typename O_>
+ struct flat_zones_ : base_<I_,N_,O_>
+ {
+ typedef mln_point(I_) P;
+
+ // requirements from mln::canvas::labeling:
+
+ typedef mln_pset(I_) S;
+ const S& s;
+ mln_value(O) nlabels;
+ bool status;
+
+ bool equiv(const P& n, const P&) const { return input(n) = input(p); }
+
+ // end of requirements
+
+ flat_zones_(const I_& input, const N_& nbh, O_& output)
+ : base_<I_,N_,O_>(input, nbh, output),
+ s(input.domain())
+ {}
+ };
+
+ } // end of namespace mln::labeling::impl
+
+
+ // Facade.
+
+ template <typename I, typename N, typename O>
+ bool flat_zones(const Image<I>& input, const Neighborhood<N>& nbh,
+ Image<O>& output,
+ unsigned& nlabels)
+ {
+ typedef impl::flat_zones_<I,N,O> F;
+ F f(exact(input), exact(nbh), exact(output));
+ canvas::labeling<F> run(f);
+ nlabels = f.nlabels;
+ return f.status;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::labeling
+
+} // end of namespace mln
+
+
+#endif // ! MLN_LABELING_FLAT_ZONES_HH
Index: mln/labeling/level.hh
--- mln/labeling/level.hh (revision 0)
+++ mln/labeling/level.hh (revision 0)
@@ -0,0 +1,118 @@
+// 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_LABELING_LEVEL_HH
+# define MLN_LABELING_LEVEL_HH
+
+/*! \file mln/labeling/level.hh
+ *
+ * \brief Connected component labeling of the image objects at a given
+ * level.
+ */
+
+# include <mln/labeling/base.hh>
+# include <mln/level/fill.hh>
+
+
+namespace mln
+{
+
+ namespace labeling
+ {
+
+ /*! Connected component labeling of the image objects at a given
+ * level.
+ *
+ * \param[in] input The input image.
+ * \param[in] val The level to consider for the labeling.
+ * \param[in] nbh The neighborhood.
+ * \param[out] output The label image.
+ * \param[out] nlabels The number of labels.
+ *
+ * \return Succeed or not.
+ */
+ template <typename I, typename N, typename O>
+ bool level(const Image<I>& input, const mln_value(I)& val, const Neighborhood<N>& nbh,
+ Image<O>& output, unsigned& nlabels);
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace impl
+ {
+
+ template <typename I_, typename N_, typename O_>
+ struct level_ : base_<I_,N_,O_>
+ {
+ typedef mln_point(I_) P;
+
+ // requirements from mln::canvas::labeling:
+
+ typedef mln_pset(I_) S;
+ const S& s;
+
+ void init() { mln::level::fill(this->output, 0); }
+ bool handles(const P& p) const { return input(p) = val; }
+ bool equiv(const P& n, const P&) const { return input(n) = val; }
+
+ // end of requirements
+
+ const mln_value(I_)& val;
+
+ level_(const I_& input, const mln_value(I_)& val, const N_& nbh, O_& output)
+ : base_<I_,N_,O_>(input, nbh, output),
+ s(input.domain()),
+ val(val)
+ {}
+ };
+
+ } // end of namespace mln::labeling::impl
+
+
+ // Facade.
+
+ template <typename I, typename N, typename O>
+ bool level(const Image<I>& input, const mln_value(I)& val, const Neighborhood<N>& nbh,
+ Image<O>& output, unsigned& nlabels)
+ {
+ mln_precondition(exact(output).domain() = exact(input).domain());
+ typedef impl::level_<I,N,O> F;
+ F f(exact(input), val, exact(nbh), exact(output));
+ canvas::labeling<F> run(f);
+ nlabels = f.nlabels;
+ return f.status;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::labeling
+
+} // end of namespace mln
+
+
+#endif // ! MLN_LABELING_LEVEL_HH
Index: mln/labeling/foreground.hh
--- mln/labeling/foreground.hh (revision 0)
+++ mln/labeling/foreground.hh (revision 0)
@@ -0,0 +1,79 @@
+// 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_LABELING_FOREGROUND_HH
+# define MLN_LABELING_FOREGROUND_HH
+
+/*! \file mln/labeling/foreground.hh
+ *
+ * \brief Connected component labeling of the object part in a binary
+ * image.
+ */
+
+# include <mln/labeling/level.hh>
+
+
+namespace mln
+{
+
+ namespace labeling
+ {
+
+ /*! Connected component labeling of the object part in a binary
+ * image.
+ *
+ * \param[in] input The input image.
+ * \param[in] nbh The neighborhood to consider.
+ * \param[out] output The label image.
+ * \param[out] nlabels The number of labels.
+ *
+ * \return The number of labels.
+ */
+ template <typename I, typename N, typename O>
+ bool foreground(const Image<I>& input, const Neighborhood<N>& nbh,
+ Image<O>& output,
+ unsigned& nlabels);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename I, typename N, typename O>
+ bool foreground(const Image<I>& input, const Neighborhood<N>& nbh,
+ Image<O>& output,
+ unsigned& nlabels)
+ {
+ return labeling::level(input, true, nbh, output, nlabels);
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::labeling
+
+} // end of namespace mln
+
+
+#endif // ! MLN_LABELING_FOREGROUND_HH
Index: mln/labeling/regional_minima.hh
--- mln/labeling/regional_minima.hh (revision 0)
+++ mln/labeling/regional_minima.hh (revision 0)
@@ -0,0 +1,120 @@
+// 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_LABELING_REGIONAL_MINIMA_HH
+# define MLN_LABELING_REGIONAL_MINIMA_HH
+
+/*! \file mln/labeling/regional_minima.hh
+ *
+ * \brief Connected component labeling of the regional minima of an
+ * image.
+ */
+
+# include <mln/labeling/base.hh>
+# include <mln/level/sort_points.hh>
+
+
+namespace mln
+{
+
+ namespace labeling
+ {
+
+ /*! Connected component labeling of the regional minima of an
+ * image.
+ *
+ * \param[in] input The input image.
+ * \param[in] nbh The neighborhood to consider.
+ * \param[out] output The label image.
+ *
+ * \return The number of labels.
+ */
+ template <typename I, typename N, typename O>
+ bool regional_minima(const Image<I>& input, const Neighborhood<N>& nbh,
+ Image<O>& output, unsigned& nlabels);
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace impl
+ {
+
+ template <typename I_, typename N_, typename O_>
+ struct regional_minima_ : base_<I_,N_,O_>
+ {
+ typedef mln_point(I_) P;
+
+ // requirements from mln::canvas::labeling:
+
+ typedef vec_p<P> S;
+ S s;
+
+ void init() { mln::level::fill(this->output, 0);
+ level::fill(attr, true); }
+ bool labels(const P& p) const { return attr(p); }
+ bool equiv(const P& n, const P& p) const { return input(n) = input(p); }
+ void do_no_union(const P& n, const P& p) { mln_invariant(input(n) < input(p));
+ attr(p) = false; }
+ void merge_attr(const P& r, const P& p) { attr(p) = attr(p) && attr(r); }
+
+ // end of requirements
+
+ mln_ch_value(O_, bool) attr;
+
+ regional_minima_(const I_& input, const N_& nbh, O_& output)
+ : base_<I_,N_,O_>(input, nbh, output),
+ s(level::sort_points_increasing(input)),
+ attr(output.domain())
+ {
+ }
+ };
+
+ } // end of namespace mln::labeling::impl
+
+
+ // Facade.
+
+ template <typename I, typename N, typename O>
+ bool regional_minima(const Image<I>& input, const Neighborhood<N>& nbh,
+ Image<O>& output, unsigned& nlabels)
+ {
+ typedef impl::regional_minima_<I,N,O> F;
+ F f(exact(input), exact(nbh), exact(output));
+ canvas::labeling<F> run(f);
+ nlabels = f.nlabels;
+ return f.status;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::labeling
+
+} // end of namespace mln
+
+
+#endif // ! MLN_LABELING_REGIONAL_MINIMA_HH
Index: mln/labeling/base.hh
--- mln/labeling/base.hh (revision 0)
+++ mln/labeling/base.hh (revision 0)
@@ -0,0 +1,94 @@
+// 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_LABELING_BASE_HH
+# define MLN_LABELING_BASE_HH
+
+/*! \file mln/labeling/base.hh
+ *
+ * \brief Base class for labeling functors.
+ */
+
+# include <mln/core/concept/image.hh>
+# include <mln/core/concept/neighborhood.hh>
+# include <mln/canvas/labeling.hh>
+
+
+namespace mln
+{
+
+ namespace labeling
+ {
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace impl
+ {
+
+ /// Base class for labeling functors.
+ template <typename I_, typename N_, typename O_>
+ struct base_
+ {
+ typedef I_ I;
+ typedef N_ N;
+ typedef O_ O;
+ typedef mln_point(I_) P;
+
+ const I& input;
+ const N& nbh;
+ O& output;
+
+ mln_value(O_) nlabels;
+ bool status;
+
+ base_(const I_& input, const N_& nbh, O_& output)
+ : input(input),
+ nbh(nbh),
+ output(output)
+ {
+ }
+
+ // Defaults.
+
+ bool handles(const P&) const { return true; }
+ bool labels(const P&) const { return true; }
+ void init() {}
+ void do_no_union(const P&, const P&) {}
+ void init_attr(const P&) {}
+ void merge_attr(const P&, const P&) {}
+ };
+
+ } // end of namespace mln::labeling::impl
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::labeling
+
+} // end of namespace mln
+
+
+#endif // ! MLN_LABELING_BASE_HH
Index: mln/labeling/regional_maxima.hh
--- mln/labeling/regional_maxima.hh (revision 0)
+++ mln/labeling/regional_maxima.hh (revision 0)
@@ -0,0 +1,120 @@
+// 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_LABELING_REGIONAL_MAXIMA_HH
+# define MLN_LABELING_REGIONAL_MAXIMA_HH
+
+/*! \file mln/labeling/regional_maxima.hh
+ *
+ * \brief Connected component labeling of the regional maxima of an
+ * image.
+ */
+
+# include <mln/labeling/base.hh>
+# include <mln/level/sort_points.hh>
+
+
+namespace mln
+{
+
+ namespace labeling
+ {
+
+ /*! Connected component labeling of the regional maxima of an
+ * image.
+ *
+ * \param[in] input The input image.
+ * \param[in] nbh The neighborhood to consider.
+ * \param[out] output The label image.
+ *
+ * \return The number of labels.
+ */
+ template <typename I, typename N, typename O>
+ bool regional_maxima(const Image<I>& input, const Neighborhood<N>& nbh,
+ Image<O>& output, unsigned& nlabels);
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace impl
+ {
+
+ template <typename I_, typename N_, typename O_>
+ struct regional_maxima_ : base_<I_,N_,O_>
+ {
+ typedef mln_point(I_) P;
+
+ // requirements from mln::canvas::labeling:
+
+ typedef vec_p<P> S;
+ S s;
+
+ void init() { mln::level::fill(this->output, 0);
+ level::fill(attr, true); }
+ bool labels(const P& p) const { return attr(p); }
+ bool equiv(const P& n, const P& p) const { return input(n) = input(p); }
+ void do_no_union(const P& n, const P& p) { mln_invariant(input(n) > input(p));
+ attr(p) = false; }
+ void merge_attr(const P& r, const P& p) { attr(p) = attr(p) && attr(r); }
+
+ // end of requirements
+
+ mln_ch_value(O_, bool) attr;
+
+ regional_maxima_(const I_& input, const N_& nbh, O_& output)
+ : base_<I_,N_,O_>(input, nbh, output),
+ s(level::sort_points_decreasing(input)),
+ attr(output.domain())
+ {
+ }
+ };
+
+ } // end of namespace mln::labeling::impl
+
+
+ // Facade.
+
+ template <typename I, typename N, typename O>
+ bool regional_maxima(const Image<I>& input, const Neighborhood<N>& nbh,
+ Image<O>& output, unsigned& nlabels)
+ {
+ typedef impl::regional_maxima_<I,N,O> F;
+ F f(exact(input), exact(nbh), exact(output));
+ canvas::labeling<F> run(f);
+ nlabels = f.nlabels;
+ return f.status;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::labeling
+
+} // end of namespace mln
+
+
+#endif // ! MLN_LABELING_REGIONAL_MAXIMA_HH
Index: mln/labeling/background.hh
--- mln/labeling/background.hh (revision 0)
+++ mln/labeling/background.hh (revision 0)
@@ -0,0 +1,79 @@
+// 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_LABELING_BACKGROUND_HH
+# define MLN_LABELING_BACKGROUND_HH
+
+/*! \file mln/labeling/background.hh
+ *
+ * \brief Connected component labeling of the background in a binary
+ * image.
+ */
+
+# include <mln/labeling/level.hh>
+
+
+namespace mln
+{
+
+ namespace labeling
+ {
+
+ /*! Connected component labeling of the background in a binary
+ * image.
+ *
+ * \param[in] input The input image.
+ * \param[in] nbh The neighborhood to consider.
+ * \param[out] output The label image.
+ * \param[out] nlabels The number of labels.
+ *
+ * \return The number of labels.
+ */
+ template <typename I, typename N, typename O>
+ bool background(const Image<I>& input, const Neighborhood<N>& nbh,
+ Image<O>& output,
+ unsigned& nlabels);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename I, typename N, typename O>
+ bool background(const Image<I>& input, const Neighborhood<N>& nbh,
+ Image<O>& output,
+ unsigned& nlabels)
+ {
+ return labeling::level(input, false, nbh, output, nlabels);
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::labeling
+
+} // end of namespace mln
+
+
+#endif // ! MLN_LABELING_BACKGROUND_HH
https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Add room in sandbox.
* sandbox/duhamel: New.
* sandbox/levillain: New.
* sandbox/nivault: New.
* sandbox/jardonnet: New.
* sandbox/geraud: New.
* sandbox/garrigues: New.
* sandbox/cxxcompilation: Rename as...
* sandbox/ballas: ...this.
compilation_unit.rb | 56 --------------------
methods | 104 --------------------------------------
test.cc | 69 -------------------------
vaucanson_bench | 141 ----------------------------------------------------
4 files changed, 370 deletions(-)
Index: sandbox/cxxcompilation/compilation_unit.rb
--- sandbox/cxxcompilation/compilation_unit.rb (revision 1066)
+++ sandbox/cxxcompilation/compilation_unit.rb (working copy)
@@ -1,56 +0,0 @@
-#! /usr/bin/ruby
-
-#Create a compilation unit file from a .cc file
-
-#USAGE: ./compilation_unit.rb file.cc
-
-
-class CompilationUnit
- attr_reader :sourceFileName, :name, :namespaceName
-
- public
- def initialize(sourceFileName)
-
-
- @sourceFileName = sourceFileName
- @name = sourceFileName.gsub(/.cc\z/, ".unit.cc")
- @namespaceName = "__instanciator_code"
-
- if not File.exist?(@name) then
- self.createCompilationUnitFile
- end
- end
-
- def update
- createCompilationUnitFile
- end
-
- #Create UnitCompilationfile from source
- def createCompilationUnitFile
- sourceFile = File.new("#{@sourceFileName}", "r")
- destinationFile = File.new("#{@name}", "w")
-
- # Copy usefull include files into cache file.
- sourceFile.each_line do |line|
- destinationFile.puts(line) if line =~ /#include/
- end
-
- # trash namespace
- destinationFile.puts("namespace #{@namespaceName} {")
-
- # puts code line into trash namespace
- sourceFile.close
- sourceFile = File.new("#{@sourceFileName}", "r")
- sourceFile.each_line do |line|
- destinationFile.puts(line) if not (line =~ /#include/)
- end
-
- # end of namespace
- destinationFile.puts("}")
-
- sourceFile.close
- destinationFile.close
- end
-end
-
-unit = CompilationUnit.new(ARGV[0])
Index: sandbox/cxxcompilation/test.cc
--- sandbox/cxxcompilation/test.cc (revision 1066)
+++ sandbox/cxxcompilation/test.cc (working copy)
@@ -1,69 +0,0 @@
-// 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.
-
-#include <oln/core/2d/image2d.hh>
-#include <oln/core/3d/image3d.hh>
-#include <oln/core/1d/image1d.hh>
-#include <oln/level/fill.hh>
-
-
-using namespace oln;
-
-int main(void)
-{
- image1d<char> ima1d1(5);
- image1d<int> ima1d2(5);
- image1d<float> ima1d3(5);
- image1d<double> ima1d4(5);
-
- level::fill(inplace(ima1d1), 5);
- level::fill(inplace(ima1d2), 5);
- level::fill(inplace(ima1d3), 5);
- level::fill(inplace(ima1d4), 5);
-
- image2d<char> ima2d1(5, 5);
- image2d<int> ima2d2(5, 5);
- image2d<float> ima2d3(5, 5);
- image2d<double> ima2d4(5, 5);
-
- level::fill(inplace(ima2d1), 5);
- level::fill(inplace(ima2d2), 5);
- level::fill(inplace(ima2d3), 5);
- level::fill(inplace(ima2d4), 5);
-
- image3d<char> ima3d1(5, 5, 5);
- image3d<int> ima3d2(5, 5, 5);
- image3d<float> ima3d3(5, 5, 5);
- image3d<double> ima3d4(5, 5, 5);
-
- level::fill(inplace(ima3d1), 5);
- level::fill(inplace(ima3d2), 5);
- level::fill(inplace(ima3d3), 5);
- level::fill(inplace(ima3d4), 5);
-
- return 0;
-}
Index: sandbox/cxxcompilation/methods
--- sandbox/cxxcompilation/methods (revision 1066)
+++ sandbox/cxxcompilation/methods (working copy)
@@ -1,104 +0,0 @@
- -*- Outline -*-
-
-* without optimization flags
-
-** Benchmark
-
-compilation: 2.131
-execution: 18.538
-total: 22.670
-
-
-* O1
-
-** Benchmark
-compilation: 3.616
-execution: 4.893
-total: 8.509
-
-* O2
-** Benchmark
-compilation: 4.610
-execution: 3.781
-total: 8.391
-
-* 03
-compilation: 5.071
-execution: 1.567
-total: 6.638
-
-
-
-
-The next part introduces different method to speed up C++ compilation time.
-
-Test are made with union_find.cc file.
-
-* precompiled header (without optimization option)
-
-** Description
-
-Generate precompiled header (.gch) which can parsed in a faster way by g++.
-
-
-How to automize header precompilation, just make a precompilation of usefull header ?
-
-** Benchmark
-
-compilation: 3.733
-execution: 18.119
-total: 21.852
-
-* ccache (without optimization option)
-
-** Description
-
-"ccache is a compiler cache. It acts as a caching pre-processor to C/C++ compilers, using the -E compiler switch and a hash to detect when a compilation can be satisfied from cache. This often results in a 5 to 10 times speedup in common compilations." http://cache.samba.org
-
-** Benchmark
-
-* Vacauson Way (without optimization option)
-
-** Description
-
-cf: http://www.lrde.epita.fr/cgi-bin/twiki/view/Know/SpeedUpCxxCompilation
-
-
-*** total recompilation protocol of source.cc:
---> (1) compile source.cc to "ref".o (cache used for function addresse reference)
---> (2) source.cc -> source.o with -DINTERFACE_ONLY (real program)
---> (3) links source.o to "ref".o
-
-*** Protocole:
---> do (1)
---> do (2) and (3) as long as there is no linkage error, else redo (1)
-
-
-*** Problems:
-
-You must recompile the cache when you use an new algorithm/data type in your program.
---> solution: ask developper to write usefull algorithm/data types/includes at the start of the programm and uses template instantiation
-
-
-Automatization??
---> how deals with several files
---> how deals with missing .hh files
---> differenciate link error from other error
-
-***Others things:
-
-wrapper script or Makefile???
---> script used by Makefile
-
-** Benchmark
-
-*** first compilation or total recompilation is longer than a normal compilation
-
-you need to compile program two times
-
-
-*** next time when cache recompilation is not needed
-
-compilation: 0.200
-execution: 17.875
-toto: 18.075
Index: sandbox/cxxcompilation/vaucanson_bench
--- sandbox/cxxcompilation/vaucanson_bench (revision 1066)
+++ sandbox/cxxcompilation/vaucanson_bench (working copy)
@@ -1,141 +0,0 @@
- -*- Outline -*-
-
-* Summary:
-
- This files present c++ compilation benchmark with Vaucanson method.
-
-* Vaucanson method:
-
-** Files used:
-*** source.cc
-client code
-
-*** source.unit.cc
-This files contains instantiations of templated data and algorithms used by the client code.
-
-A Compilation unit copies #include directives used by source.cc
-Furthermore, it copies client source code into a trash name's (in order to instantiated templates).
-
-But other method exists to create compilation unit(cf .hcc).
-
-
-** Compilation process:
-
-*** total recompilation
-
---> (1) compile source.unit.cc to an object file (source.unit.o) (cache used to find function address reference).
-
---> (2) compile source.cc to source.o with -DINTERFACE_ONLY (or INCLUDE_ONLY, we want to compile just the interface the objects).
-
---> (3) link source.o with source.unit.o
-
-*** Protocol:
---> do (1)
---> do (2) and (3) as long as there are no linkage errors, else redo (1)
-
-
-
-
-* Benchmark:
-
-** With Olena:
-
-compile command:
-g++ -W -Wall -Werror -ansi -pedantic -Ipath/metalic -Ipath/olena -Ipath/extended
-
-dimension of image used for test: 512 * 512.
-Note: We can add optimization flag to speed up execution time.
-
-
-*******************************************************************************
-** File: oln/morpho/Rd/union_find.cc
-
-*** normal compilation:
-compilation time: 4.110
-execution time: 42.893
-total time: 47.003
-
-*** With Vaucanson method:
-
-**** total recompilation:
-
-compilation time: 6.749
---> (1) : 4.062
---> (2) : 2.524
---> (3) : 0.163
-
-execution time: 42.058
-total time: 48.807
-
-~= 2 second slower than a normal compilation
-
-**** Usual recompilation
-
-compilation time: 2.702
---> (2) : 2.542
---> (3) : 0.160
-
-execution time:42.060
-total time: 44.762
-
-*******************************************************************************
-** oln/morpho/Rd/queue_based.cc
-
-*** normal compilation:
-compilation time: 4.296
-execution time: 35.836
-total time: 40.132
-
-*** With Vaucanson method:
-
-**** total recompilation:
-
-compilation time: 7.187
---> (1) : 4.378
---> (2) : 2.636
---> (3) : 0.173
-
-execution time: 35.836
-total time: 43.023
-
-**** Usual recompilation
-
-compilation time: 2.809
---> (2) : 2.636
---> (3) : 0.173
-
-*******************************************************************************
-** test.cc
-
-(declare and fill 12 differents image types)
-
-*** normal compilation:
-compilation time: 25.585
-execution time: 0.006
-total time: 25.596
-
-*** With Vaucanson method:
-
-**** total recompilation:
-
-compilation time: 45.087
---> (1) : 25.378
---> (2) : 19.318
---> (3) : 0.391
-
-execution time: 0.006
-total time: 45.093
-
-**** Usual recompilation
-
-compilation time: 19.664
---> (2) : 19.259
---> (3) : 0.405
-
-** with morpher
-
-FIXME
-
-*** With Milena
-
-FIXME
https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Fix missing file.
* mln/value/cast.hh: New.
labeling/+foreground.hh | 106 ++++++++++++++++++++++++++++++++++++++++++++++++
value/cast.hh | 85 ++++++++++++++++++++++++++++++++++++++
2 files changed, 191 insertions(+)
Index: mln/value/cast.hh
--- mln/value/cast.hh (revision 0)
+++ mln/value/cast.hh (revision 0)
@@ -0,0 +1,85 @@
+// 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_VALUE_CAST_HH
+# define MLN_VALUE_CAST_HH
+
+/*! \file mln/value/cast.hh
+ * \brief Definition of the mln::value::cast routine.
+ */
+
+# include <mln/core/concept/value.hh>
+
+
+namespace mln
+{
+
+ namespace value
+ {
+
+
+ /// Cast a value \p src from type \c Src to type \c Dest.
+ template <typename Dest, typename Src>
+ Dest cast(const Src& src);
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace internal
+ {
+
+ template <typename S>
+ const S&
+ cast_(const S& src, ...)
+ {
+ return src;
+ }
+
+ template <typename T, typename S>
+ typename S::equiv
+ cast_(const T&, const Value<S>& src)
+ {
+ return exact(src);
+ }
+
+ } // end of namespace mln::value::internal
+
+ template <typename Dest, typename Src>
+ Dest cast(const Src& src)
+ {
+ return internal::cast_(src, src);
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::value
+
+} // end of namespace mln
+
+
+#endif // ! MLN_VALUE_CAST_HH
Index: mln/labeling/+foreground.hh
--- mln/labeling/+foreground.hh (revision 0)
+++ mln/labeling/+foreground.hh (revision 0)
@@ -0,0 +1,106 @@
+// 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_LABELING_FOREGROUND_HH
+# define MLN_LABELING_FOREGROUND_HH
+
+/*! \file mln/labeling/foreground.hh
+ *
+ * \brief Foreground a function-object onto image pixel values.
+ */
+
+# include <mln/core/concept/image.hh>
+# include <mln/core/concept/function.hh>
+
+
+namespace mln
+{
+
+ namespace labeling
+ {
+
+ /*! Foreground a function-object to the image \p input.
+ *
+ * \param[in,out] input The input image.
+ * \param[in] f The function-object.
+ *
+ * This routine runs: \n
+ * for all p of \p input, \p input(p) = \p f( \p input(p) ) \n
+ *
+ * This routine is equivalent to labeling::tranform(input, f, input)
+ * but it is faster since a single iterator is required.
+ *
+ * \todo Add versions for lowq images.
+ */
+ template <typename I, typename F>
+ void foreground(Image<I>& input, const Function_v2v<F>& f);
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace impl
+ {
+
+ template <typename I, typename F>
+ void foreground_(Image<I>& input_, const F& f)
+ {
+ I& input = exact(input_);
+ mln_piter(I) p(input.domain());
+ for_all(p)
+ input(p) = f(input(p));
+ }
+
+ template <typename I, typename F>
+ void foreground_(Fast_Image<I>& input_, const F& f)
+ {
+ I& input = exact(input_);
+ mln_pixter(I) pxl(input);
+ for_all(pxl)
+ pxl.val() = f(pxl.val());
+ }
+
+ } // end of namespace mln::labeling::impl
+
+
+ // Facade.
+
+ template <typename I, typename F>
+ void foreground(Image<I>& input, const Function_v2v<F>& f)
+ {
+ mln_precondition(exact(input).has_data());
+ impl::foreground_(exact(input), exact(f));
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::labeling
+
+} // end of namespace mln
+
+
+#endif // ! MLN_LABELING_FOREGROUND_HH
https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Augment morphology.
* mln/value/cast.hh: Rename as...
* mln/core/cast_image.hh: ...this.
Update.
* mln/core/concept/value.hh (cast): Move to and rename as...
* mln/value/cast.hh (cast_image): ...this, here.
* tests/cast_image.cc: Update.
* mln/morpho/thickening.hh: New.
* mln/morpho/laplacian.hh: New.
* mln/morpho/thick_miss.hh: New.
* mln/morpho/thin_fit.hh: New.
* mln/morpho/thinning.hh: New.
* tests/morpho_thinning.cc: New.
* tests/morpho_laplacian.cc: New.
* tests/morpho_hit_or_miss.cc: Update.
* mln/morpho/plus.hh (mln_postcondition): Remove.
* mln/morpho/minus.hh: Remove dead lines.
* mln/morpho/hit_or_miss.hh: Augment doc.
Add postconditions.
Add a FIXME.
* mln/io/save_pgm.hh: Rewrite.
* mln/arith/plus.hh (plus_cst, plus_cst_inplace): New.
* img/picasso.pgm: Invert.
img/picasso.pgm | 0
mln/arith/plus.hh | 31 ++++++++++++++
mln/core/cast_image.hh | 50 +++++++++++-------------
mln/core/concept/value.hh | 48 +----------------------
mln/io/save_pgm.hh | 72 +++++++++++++++++++++++++++++++---
mln/morpho/hit_or_miss.hh | 41 +++++++++++++++----
mln/morpho/laplacian.hh | 83 ++++++++++++++++++++++++++++++++++++++++
mln/morpho/minus.hh | 3 -
mln/morpho/plus.hh | 3 -
mln/morpho/thick_miss.hh | 79 ++++++++++++++++++++++++++++++++++++++
mln/morpho/thickening.hh | 79 ++++++++++++++++++++++++++++++++++++++
mln/morpho/thin_fit.hh | 79 ++++++++++++++++++++++++++++++++++++++
mln/morpho/thinning.hh | 91 ++++++++++++++++++++++++++++++++++++++++++++
tests/cast_image.cc | 6 +-
tests/morpho_hit_or_miss.cc | 6 +-
tests/morpho_laplacian.cc | 63 ++++++++++++++++++++++++++++++
tests/morpho_thinning.cc | 69 +++++++++++++++++++++++++++++++++
17 files changed, 705 insertions(+), 98 deletions(-)
Index: tests/cast_image.cc
--- tests/cast_image.cc (revision 1063)
+++ tests/cast_image.cc (working copy)
@@ -27,14 +27,14 @@
/*! \file tests/cast_image.cc
*
- * \brief Tests on mln::value::cast_image.
+ * \brief Tests on mln::cast_image.
*/
#include <mln/core/image2d_b.hh>
#include <mln/fun/p2b/chess.hh>
#include <mln/level/fill.hh>
#include <mln/debug/println.hh>
-#include <mln/value/cast.hh>
+#include <mln/core/cast_image.hh>
int main()
@@ -44,5 +44,5 @@
image2d_b<bool> ima(8, 8);
level::fill(ima, fun::p2b::chess);
debug::println(ima);
- debug::println( value::cast<int>(ima) );
+ debug::println( cast_image<int>(ima) );
}
Index: tests/morpho_thinning.cc
--- tests/morpho_thinning.cc (revision 0)
+++ tests/morpho_thinning.cc (revision 0)
@@ -0,0 +1,69 @@
+// 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_thinning.cc
+ *
+ * \brief Test on mln::morpho::thinning.
+ */
+
+#include <mln/core/image2d_b.hh>
+#include <mln/value/int_u8.hh>
+
+#include <mln/core/win/rectangle2d.hh>
+#include <mln/core/window2d.hh>
+
+#include <mln/io/load_pgm.hh>
+#include <mln/io/save_pgm.hh>
+
+#include <mln/morpho/thinning.hh>
+
+
+int main()
+{
+ using namespace mln;
+ using value::int_u8;
+
+ bool fg[] = { 0, 0, 0,
+ 0, 1, 0,
+ 0, 0, 0 };
+ window2d win_fg = make::window2d(fg);
+
+ bool bg[] = { 0, 0, 0,
+ 1, 0, 1,
+ 0, 0, 0 };
+ window2d win_bg = make::window2d(bg);
+
+ border::thickness = 2;
+
+ image2d_b<int_u8>
+ pic = io::load_pgm("../img/picasso.pgm"),
+ out(pic.domain());
+
+ morpho::thinning(pic, win_fg, win_bg, out);
+
+ io::save_pgm(out, "out.pgm");
+}
Index: tests/morpho_hit_or_miss.cc
--- tests/morpho_hit_or_miss.cc (revision 1063)
+++ tests/morpho_hit_or_miss.cc (working copy)
@@ -76,10 +76,10 @@
border::thickness = 2;
image2d_b<int_u8>
- lena = io::load_pgm("../img/picasso.pgm"),
- out(lena.domain());
+ pic = io::load_pgm("../img/picasso.pgm"),
+ out(pic.domain());
- morpho::hit_or_miss(lena, win_hit, win_miss, out);
+ morpho::hit_or_miss(pic, win_hit, win_miss, out);
io::save_pgm(out, "out.pgm");
}
Index: tests/morpho_laplacian.cc
--- tests/morpho_laplacian.cc (revision 0)
+++ tests/morpho_laplacian.cc (revision 0)
@@ -0,0 +1,63 @@
+// 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_laplacian.cc
+ *
+ * \brief Test on mln::morpho::laplacian.
+ */
+
+#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_u_sat.hh>
+#include <mln/core/cast_image.hh>
+#include <mln/pw/image.hh>
+#include <mln/arith/plus.hh>
+
+#include <mln/morpho/laplacian.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");
+ image2d_b<int> lap(lena.domain());
+ morpho::laplacian(lena, rect, lap);
+
+ image2d_b< value::int_u_sat<8> > out(lena.domain());
+ arith::plus_cst(lap, 128, out);
+ io::save_pgm(out, "out.pgm");
+}
Index: mln/core/cast_image.hh
--- mln/core/cast_image.hh (revision 1063)
+++ mln/core/cast_image.hh (working copy)
@@ -25,29 +25,27 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-#ifndef MLN_VALUE_CAST_HH
-# define MLN_VALUE_CAST_HH
+#ifndef MLN_CORE_CAST_IMAGE_HH
+# define MLN_CORE_CAST_IMAGE_HH
-/*! \file mln/value/cast.hh
+/*! \file mln/core/cast_image.hh
*
* \brief Definition of an image class FIXME
*/
# include <mln/core/concept/image.hh>
# include <mln/value/set.hh>
+# include <mln/value/cast.hh>
namespace mln
{
- namespace value
- {
-
/*! \brief FIXME
*
*/
template <typename T, typename I>
- struct cast_image : public mln::internal::image_base_< mln_pset(I), cast_image<T,I> >
+ struct cast_image_ : public mln::internal::image_base_< mln_pset(I), cast_image_<T,I> >
{
/// Point_Site associated type.
typedef mln_psite(I) psite;
@@ -62,14 +60,14 @@
typedef T rvalue;
/// Return type of read-write access.
- typedef void lvalue; // FIXME
+ typedef T lvalue;
/// Value set associated type.
typedef mln::value::set<T> vset;
/// Constructor.
- cast_image(const Image<I>& ima);
+ cast_image_(const Image<I>& ima);
/// Test if this image has been initialized.
@@ -84,8 +82,8 @@
/// Read-only access of pixel value at point site \p p.
T operator()(const psite& p) const;
- /// Read-write access is present but disabled.
- void operator()(const psite&);
+ /// Mutable access is only OK for reading (not writing).
+ T operator()(const psite& p);
/// Give the set of values of the image.
const vset& values() const;
@@ -104,11 +102,11 @@
template <typename T, typename I>
- cast_image<T,I>
- cast(const Image<I>& ima)
+ cast_image_<T,I>
+ cast_image(const Image<I>& ima)
{
mln_precondition(exact(ima).has_data());
- cast_image<T,I> tmp(ima);
+ cast_image_<T,I> tmp(ima);
return tmp;
}
@@ -117,59 +115,57 @@
# ifndef MLN_INCLUDE_ONLY
template <typename T, typename I>
- cast_image<T,I>::cast_image(const Image<I>& ima)
+ cast_image_<T,I>::cast_image_(const Image<I>& ima)
: ima_(exact(ima))
{
mln_precondition(exact(ima).has_data());
}
template <typename T, typename I>
- bool cast_image<T,I>::has_data() const
+ bool cast_image_<T,I>::has_data() const
{
mln_invariant(ima_.has_data());
return true;
}
template <typename T, typename I>
- bool cast_image<T,I>::owns_(const psite& p) const
+ bool cast_image_<T,I>::owns_(const psite& p) const
{
return ima_.owns_(p);
}
template <typename T, typename I>
const mln_pset(I)&
- cast_image<T,I>::domain() const
+ cast_image_<T,I>::domain() const
{
return ima_.domain();
}
template <typename T, typename I>
T
- cast_image<T,I>::operator()(const psite& p) const
+ cast_image_<T,I>::operator()(const psite& p) const
{
mln_precondition(ima_.owns_(p));
- return ima_(p);
+ return mln::value::cast<T>( ima_(p) );
}
template <typename T, typename I>
- void
- cast_image<T,I>::operator()(const psite&)
+ T
+ cast_image_<T,I>::operator()(const psite& p)
{
- mln_invariant(0); // FIXME: Turn into a compile-time error...
+ return mln::value::cast<T>( ima_(p) );
}
template <typename T, typename I>
const mln::value::set<T>&
- cast_image<T,I>::values() const
+ cast_image_<T,I>::values() const
{
return vset::the();
}
# endif // ! MLN_INCLUDE_ONLY
- } // end of namespace mln::value
-
} // end of namespace mln
-#endif // ! MLN_VALUE_CAST_HH
+#endif // ! MLN_CORE_CAST_IMAGE_HH
Index: mln/core/concept/value.hh
--- mln/core/concept/value.hh (revision 1063)
+++ mln/core/concept/value.hh (working copy)
@@ -63,17 +63,6 @@
- namespace value
- {
-
- /// Cast a value \p src from type \c Src to type \c Dest.
- template <typename Dest, typename Src>
- Dest cast(const Src& src);
-
- } // end of namespace mln::value
-
-
-
# ifndef MLN_INCLUDE_ONLY
template <typename E>
@@ -99,43 +88,12 @@
return exact(*this);
}
-
- namespace value
- {
-
- namespace internal
- {
-
- template <typename S>
- const S&
- cast_(const S& src, ...)
- {
- return src;
- }
-
- template <typename T, typename S>
- typename S::equiv
- cast_(const T&, const Value<S>& src)
- {
- return exact(src);
- }
-
- } // end of namespace mln::value::internal
-
-
- template <typename Dest, typename Src>
- Dest cast(const Src& src)
- {
- return internal::cast_(src, src);
- }
-
-
- } // end of namespace mln::value
-
-
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln
+# include <mln/value/cast.hh>
+
+
#endif // ! MLN_CORE_CONCEPT_VALUE_HH
Index: mln/morpho/thickening.hh
--- mln/morpho/thickening.hh (revision 0)
+++ mln/morpho/thickening.hh (revision 0)
@@ -0,0 +1,79 @@
+// 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_THICKENING_HH
+# define MLN_MORPHO_THICKENING_HH
+
+/*! \file mln/morpho/thickening.hh
+ *
+ * \brief Morphological thickening.
+ */
+
+# include <mln/morpho/hit_or_miss.hh>
+
+
+namespace mln
+{
+
+ namespace morpho
+ {
+
+
+ /*! Morphological thickening.
+ *
+ * This operator is THICK_B = Id + HMT_B, where B = (Bfg, Bbg).
+ */
+ template <typename I, typename Wfg, typename Wbg, typename O>
+ void thickening(const Image<I>& input,
+ const Window<Wfg>& win_fg, const Window<Wbg>& win_bg,
+ Image<O>& output);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename I, typename Wfg, typename Wbg, typename O>
+ void thickening(const Image<I>& input,
+ const Window<Wfg>& win_fg, const Window<Wbg>& win_bg,
+ Image<O>& output)
+ {
+ mln_precondition(exact(output).domain() = exact(input).domain());
+ mln_precondition(exact(win_bg).is_centered());
+ mln_precondition(set::inter(exact(win_fg), exact(win_bg)).is_empty());
+
+ O temp(exact(input).domain());
+ hit_or_miss(input, win_fg, win_bg, temp);
+ morpho::plus(input, temp, output);
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::morpho
+
+} // end of namespace mln
+
+
+#endif // ! MLN_MORPHO_THICKENING_HH
Index: mln/morpho/plus.hh
--- mln/morpho/plus.hh (revision 1063)
+++ mln/morpho/plus.hh (working copy)
@@ -85,10 +85,7 @@
{
mln_precondition(exact(rhs).domain() = exact(lhs).domain());
mln_precondition(exact(output).domain() = exact(lhs).domain());
-
impl::plus_(mln_value_kind(I)(), exact(lhs), exact(rhs), output);
-
- mln_postcondition(output <= lhs);
}
template <typename I, typename J>
Index: mln/morpho/laplacian.hh
--- mln/morpho/laplacian.hh (revision 0)
+++ mln/morpho/laplacian.hh (revision 0)
@@ -0,0 +1,83 @@
+// 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_LAPLACIAN_HH
+# define MLN_MORPHO_LAPLACIAN_HH
+
+/*! \file mln/morpho/laplacian.hh
+ *
+ * \brief Morphological laplacian.
+ *
+ * \todo Save memory.
+ */
+
+# include <mln/morpho/includes.hh>
+
+
+namespace mln
+{
+
+ namespace morpho
+ {
+
+ /*! Morphological laplacian.
+ *
+ * This operator is (d_B - Id) - (Id - e_B).
+ */
+ template <typename I, typename W, typename O>
+ void laplacian(const Image<I>& input, const Window<W>& win,
+ Image<O>& output);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename I, typename W, typename O>
+ void laplacian(const Image<I>& input, const Window<W>& win, Image<O>& output)
+ {
+ mln_precondition(exact(output).domain() = exact(input).domain());
+ mln_precondition(! exact(win).is_empty());
+
+ dilation(input, win, output); // output = dilation
+ morpho::minus_inplace(output, input); // now output = dilation - input
+
+ O temp(exact(input).domain());
+ {
+ O temp_(exact(input).domain());
+ erosion(input, win, temp_); // temp_ = erosion
+ morpho::minus(input, temp_, temp); // temp = input - erosion
+ }
+ morpho::minus_inplace(output, temp); // now output = (dilation - input) - (input - erosion)
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::morpho
+
+} // end of namespace mln
+
+
+#endif // ! MLN_MORPHO_LAPLACIAN_HH
Index: mln/morpho/minus.hh
--- mln/morpho/minus.hh (revision 1063)
+++ mln/morpho/minus.hh (working copy)
@@ -64,9 +64,7 @@
const Image<I>& lhs, const Image<J>& rhs,
Image<O>& output)
{
- // FIXME: mln_precondition(rhs <= lhs);
return logical::and_not(lhs, rhs, output);
- // FIXME: mln_postcondition(output <= lhs);
}
template <typename K, typename I, typename J, typename O>
@@ -87,7 +85,6 @@
{
mln_precondition(exact(rhs).domain() = exact(lhs).domain());
mln_precondition(exact(output).domain() = exact(lhs).domain());
-
impl::minus_(mln_value_kind(I)(), exact(lhs), exact(rhs), output);
}
Index: mln/morpho/thick_miss.hh
--- mln/morpho/thick_miss.hh (revision 0)
+++ mln/morpho/thick_miss.hh (revision 0)
@@ -0,0 +1,79 @@
+// 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_THICK_MISS_HH
+# define MLN_MORPHO_THICK_MISS_HH
+
+/*! \file mln/morpho/thick_miss.hh
+ *
+ * \brief Morphological thick-miss.
+ */
+
+# include <mln/morpho/hit_or_miss.hh>
+
+
+namespace mln
+{
+
+ namespace morpho
+ {
+
+
+ /*! Morphological thick-miss.
+ *
+ * This operator is THICK_B = Id + HMTopeBG_B, where B = (Bfg, Bbg).
+ */
+ template <typename I, typename Wfg, typename Wbg, typename O>
+ void thick_miss(const Image<I>& input,
+ const Window<Wfg>& win_fg, const Window<Wbg>& win_bg,
+ Image<O>& output);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename I, typename Wfg, typename Wbg, typename O>
+ void thick_miss(const Image<I>& input,
+ const Window<Wfg>& win_fg, const Window<Wbg>& win_bg,
+ Image<O>& output)
+ {
+ mln_precondition(exact(output).domain() = exact(input).domain());
+ mln_precondition(exact(win_miss).is_centered());
+ mln_precondition(set::inter(exact(win_fg), exact(win_bg)).is_empty());
+
+ O temp(exact(input).domain());
+ hit_or_miss_background_opening(input, win_fg, win_bg, temp);
+ morpho::plus(input, temp, output);
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::morpho
+
+} // end of namespace mln
+
+
+#endif // ! MLN_MORPHO_THICK_MISS_HH
Index: mln/morpho/thin_fit.hh
--- mln/morpho/thin_fit.hh (revision 0)
+++ mln/morpho/thin_fit.hh (revision 0)
@@ -0,0 +1,79 @@
+// 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_THIN_FIT_HH
+# define MLN_MORPHO_THIN_FIT_HH
+
+/*! \file mln/morpho/thin_fit.hh
+ *
+ * \brief Morphological thin-fit.
+ */
+
+# include <mln/morpho/hit_or_miss.hh>
+
+
+namespace mln
+{
+
+ namespace morpho
+ {
+
+
+ /*! Morphological thin-fit.
+ *
+ * This operator is THIN_B = Id - HMTope_B where B = (Bfg, Bbg).
+ */
+ template <typename I, typename Wfg, typename Wbg, typename O>
+ void thin_fit(const Image<I>& input,
+ const Window<Wfg>& win_fg, const Window<Wbg>& win_bg,
+ Image<O>& output);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename I, typename Wfg, typename Wbg, typename O>
+ void thin_fit(const Image<I>& input,
+ const Window<Wfg>& win_fg, const Window<Wbg>& win_bg,
+ Image<O>& output)
+ {
+ mln_precondition(exact(output).domain() = exact(input).domain());
+ mln_precondition(exact(win_fg).is_centered());
+ mln_precondition(set::inter(exact(win_fg), exact(win_bg)).is_empty());
+
+ O temp(exact(input).domain());
+ hit_or_miss_opening(input, win_fg, win_bg, temp);
+ morpho::minus(input, temp, output);
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::morpho
+
+} // end of namespace mln
+
+
+#endif // ! MLN_MORPHO_THIN_FIT_HH
Index: mln/morpho/thinning.hh
--- mln/morpho/thinning.hh (revision 0)
+++ mln/morpho/thinning.hh (revision 0)
@@ -0,0 +1,91 @@
+// 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_THINNING_HH
+# define MLN_MORPHO_THINNING_HH
+
+/*! \file mln/morpho/thinning.hh
+ *
+ * \brief Morphological thinning.
+ */
+
+# include <mln/morpho/hit_or_miss.hh>
+# include <mln/morpho/thickening.hh>
+
+
+namespace mln
+{
+
+ namespace morpho
+ {
+
+
+ /*! Morphological thinning.
+ *
+ * This operator is THIN_B = Id - HMT_B, where B = (Bfg, Bbg).
+ */
+ template <typename I, typename Wfg, typename Wbg, typename O>
+ void thinning(const Image<I>& input,
+ const Window<Wfg>& win_fg, const Window<Wbg>& win_bg,
+ Image<O>& output);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename I, typename Wfg, typename Wbg, typename O>
+ void thinning(const Image<I>& input,
+ const Window<Wfg>& win_fg, const Window<Wbg>& win_bg,
+ Image<O>& output)
+ {
+ mln_precondition(exact(output).domain() = exact(input).domain());
+ mln_precondition(exact(win_fg).is_centered());
+ mln_precondition(set::inter(exact(win_fg), exact(win_bg)).is_empty());
+
+ O temp(exact(input).domain());
+ hit_or_miss(input, win_fg, win_bg, temp);
+ morpho::minus(input, temp, output);
+ // FIXME: Pass postcondition!
+# ifndef NDEBUG
+ {
+ O temp(exact(input).domain());
+ complementation(input, temp);
+ O output_(exact(input).domain());
+ thickening(temp, win_bg, win_fg, output_);
+ complementation_inplace(output_);
+ mln_postcondition(output_ = output);
+ }
+# endif // ! NDEBUG
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::morpho
+
+} // end of namespace mln
+
+
+#endif // ! MLN_MORPHO_THINNING_HH
Index: mln/morpho/hit_or_miss.hh
--- mln/morpho/hit_or_miss.hh (revision 1063)
+++ mln/morpho/hit_or_miss.hh (working copy)
@@ -61,7 +61,7 @@
/*! Morphological hit-or-miss opening.
*
- * This operator is d_(-Bh) o HMT_(Bh,Bm).
+ * This operator is HMTope_(Bh,Bm) = d_(-Bh) o HMT_(Bh,Bm).
*/
template <typename I, typename Wh, typename Wm, typename O>
void hit_or_miss_opening(const Image<I>& input,
@@ -70,7 +70,7 @@
/*! Morphological hit-or-miss opening of the background.
*
- * This operator is FIXME.
+ * This operator is HMTopeBG = HMTope_(Bm,Bh) o C = d_(-Bm) o HMT_(Bh,Bm).
*/
template <typename I, typename Wh, typename Wm, typename O>
void hit_or_miss_background_opening(const Image<I>& input,
@@ -79,7 +79,7 @@
/*! Morphological hit-or-miss closing.
*
- * This operator is FIXME.
+ * This operator is C o HMTope o C.
*/
template <typename I, typename Wh, typename Wm, typename O>
void hit_or_miss_closing(const Image<I>& input,
@@ -88,7 +88,7 @@
/*! Morphological hit-or-miss closing of the background.
*
- * This operator is FIXME.
+ * This operator is C o HMTopeBG o C.
*/
template <typename I, typename Wh, typename Wm, typename O>
void hit_or_miss_background_closing(const Image<I>& input,
@@ -150,7 +150,8 @@
erosion(input, win_hit, ero_fg);
dilation(input, win_miss, dil_bg);
level::fill(output,
- fun::p2v::ternary(pw::value(input) = pw::value(ero_fg) && pw::value(dil_bg) < pw::value(input),
+ fun::p2v::ternary(pw::value(input) = pw::value(ero_fg)
+ && pw::value(dil_bg) < pw::value(input),
pw::value(input) - pw::value(dil_bg),
pw::cst(V::zero)));
}
@@ -160,12 +161,13 @@
erosion(input, win_miss, ero_bg);
dilation(input, win_hit, dil_fg);
level::fill(output,
- fun::p2v::ternary(pw::value(input) = pw::value(dil_fg) && pw::value(ero_bg) > pw::value(input),
+ fun::p2v::ternary(pw::value(input) = pw::value(dil_fg)
+ && pw::value(ero_bg) > pw::value(input),
pw::value(ero_bg) - pw::value(input),
pw::cst(V::zero)));
}
else
- level::fill(output, pw::cst(V::zero));
+ level::fill(output, V::zero);
}
else // Unconstrained: UHMT.
{
@@ -201,6 +203,7 @@
O temp(exact(input).domain());
hit_or_miss(input, win_hit, win_miss, temp);
dilation(temp, geom::sym(win_hit), output);
+ // FIXME: Postcondition.
}
template <typename I, typename Wh, typename Wm, typename O>
@@ -209,7 +212,18 @@
Image<O>& output)
{
impl::hit_or_miss_preconditions_(input, win_hit, win_miss, output);
- hit_or_miss_opening(input, win_miss, win_hit, output);
+ O temp(exact(input).domain());
+ complementation(input, temp);
+ hit_or_miss_opening(temp, win_miss, win_hit, output);
+# ifndef NDEBUG
+ {
+ O temp(exact(input).domain());
+ hit_or_miss(input, win_hit, win_miss, temp);
+ O output_(exact(input).domain());
+ dilation(temp, geom::sym(win_miss), output_);
+ mln_postcondition(output_ = output);
+ }
+# endif // ! NDEBUG
}
template <typename I, typename Wh, typename Wm, typename O>
@@ -222,6 +236,7 @@
complementation(input, temp);
hit_or_miss_opening(temp, win_hit, win_miss, output);
complementation_inplace(output);
+ // FIXME: Postcondition.
}
template <typename I, typename Wh, typename Wm, typename O>
@@ -231,6 +246,16 @@
{
impl::hit_or_miss_preconditions_(input, win_hit, win_miss, output);
hit_or_miss_closing(input, win_miss, win_hit, output);
+# ifndef NDEBUG
+ {
+ O temp(exact(input).domain());
+ complementation(input, temp);
+ O output_(exact(input).domain());
+ hit_or_miss_background_opening(temp, win_hit, win_miss, output_);
+ complementation_inplace(output_);
+ mln_postcondition(output_ = output);
+ }
+# endif // ! NDEBUG
}
# endif // ! MLN_INCLUDE_ONLY
Index: mln/io/save_pgm.hh
--- mln/io/save_pgm.hh (revision 1063)
+++ mln/io/save_pgm.hh (working copy)
@@ -32,20 +32,37 @@
# include <iostream>
# include <fstream>
-# include <mln/core/image2d_b.hh>
# include <mln/geom/size2d.hh>
-# include <mln/value/int_u8.hh>
+# include <mln/metal/equal.hh>
+# include <mln/metal/bexpr.hh>
namespace mln
{
+ // Fwd decl.
+ namespace value {
+ template <unsigned> class int_u;
+ template <unsigned> class int_u_sat;
+ }
+
+
namespace io
{
- void save_pgm(const image2d_b<value::int_u8>& ima, const std::string& filename)
+ template <typename I>
+ void save_pgm(const Image<I>& ima, const std::string& filename);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace impl
+ {
+
+ template <typename I>
+ void save_pgm_header_(const I& ima, const std::string& filename,
+ std::ofstream& file)
{
- std::ofstream file(filename.c_str());
if (! file)
{
std::cerr << "error: cannot open file '" << filename
@@ -53,14 +70,22 @@
abort();
}
file << "P5" << std::endl;
- file << "# olena" << std::endl;
+ file << "# milena" << std::endl;
file << geom::ncols(ima) << ' ' << geom::nrows(ima) << std::endl;
file << "255" << std::endl;
+ }
+
+ template <typename I>
+ void save_pgm_(const Fast_Image<I>& ima_, const std::string& filename)
+ {
+ const I& ima = exact(ima_);
+ std::ofstream file(filename.c_str());
+ save_pgm_header_(ima, filename, file);
const int
min_row = geom::min_row(ima),
max_row = geom::max_row(ima);
point2d p;
- if (sizeof(value::int_u8) = 1)
+ if (sizeof(mln_value(I)) = 1)
{
p.col() = geom::min_col(ima);
size_t len = geom::ncols(ima);
@@ -82,6 +107,41 @@
}
}
+ template <typename I>
+ void save_pgm_(const Image<I>& ima_, const std::string& filename)
+ {
+ const I& ima = exact(ima_);
+ std::ofstream file(filename.c_str());
+ save_pgm_header_(ima, filename, file);
+ const int
+ min_row = geom::min_row(ima),
+ max_row = geom::max_row(ima),
+ min_col = geom::min_col(ima),
+ max_col = geom::max_col(ima);
+ point2d p;
+ for (p.row() = min_row; p.row() <= max_row; ++p.row())
+ for (p.col() = min_col; p.col() <= max_col; ++p.col())
+ {
+ unsigned char c = ima(p);
+ file.write((char*)(&c), 1);
+ }
+ }
+
+ } // end of namespace mln::io::impl
+
+
+ template <typename I>
+ void save_pgm(const Image<I>& ima, const std::string& filename)
+ {
+ mln::metal::or_<
+ mln::metal::equal<mln_value(I), value::int_u<8> >,
+ mln::metal::equal<mln_value(I), value::int_u_sat<8> >
+ >::check();
+ impl::save_pgm_(exact(ima), filename);
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
} // end of namespace mln::io
} // end of namespace mln
Index: mln/arith/plus.hh
--- mln/arith/plus.hh (revision 1063)
+++ mln/arith/plus.hh (working copy)
@@ -31,10 +31,15 @@
/*! \file mln/arith/plus.hh
*
* \brief Point-wise addition between images.
+ *
+ * \todo Speedup versions with cst.
*/
# include <mln/core/concept/image.hh>
+# include <mln/pw/cst.hh>
+# include <mln/pw/image.hh>
+
namespace mln
{
@@ -54,6 +59,18 @@
void plus(const Image<L>& lhs, const Image<R>& rhs, Image<O>& output);
+ /*! Point-wise addition of the value \p val to image \p input.
+ *
+ * \param[in] input The image.
+ * \param[in] val The value.
+ * \param[out] output The result image.
+ *
+ * \pre \p output.domain = \p input.domain
+ */
+ template <typename I, typename V, typename O>
+ void plus_cst(const Image<I>& input, const V& val, Image<O>& output);
+
+
/*! Point-wise addition of image \p rhs in image \p lhs.
*
* \param[in] lhs First operand image (subject to addition).
@@ -127,6 +144,13 @@
impl::plus_(exact(lhs), exact(rhs), exact(output));
}
+ template <typename I, typename V, typename O>
+ void plus_cst(const Image<I>& input, const V& val, Image<O>& output)
+ {
+ mln_precondition(exact(output).domain() = exact(input).domain());
+ plus(input, pw::cst(val) | exact(input).domain(), output); // Calls the previous version.
+ }
+
template <typename L, typename R>
void plus_inplace(Image<L>& lhs, const Image<R>& rhs)
{
@@ -134,6 +158,13 @@
impl::plus_inplace_(exact(lhs), exact(rhs));
}
+ template <typename I, typename V>
+ void plus_cst_inplace(Image<I>& input, const V& val)
+ {
+ mln_precondition(exact(input).has_data());
+ plus_inplace(input, pw::cst(val) | exact(input).domain()); // Calls the previous version.
+ }
+
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln::arith
Index: img/picasso.pgm
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Add hit-or-miss and p2v ternary+elif functions.
* tests/morpho_hit_or_miss.cc: New.
* mln/fun/p2v/elifs.hh: New.
* mln/fun/p2v/ternary.hh: New.
* mln/morpho/min.hh: New.
* mln/morpho/hit_or_miss.hh: New.
* mln/arith/min.hh: New.
* mln/value/int_u_sat.hh: New.
* img/picasso.pgm: New.
* mln/arith/revert.hh: Fix.
* mln/morpho/includes.hh: Update.
img/picasso.pgm | 0
mln/arith/min.hh | 147 ++++++++++++++++++++++++++
mln/arith/revert.hh | 2
mln/fun/p2v/elifs.hh | 84 +++++++++++++++
mln/fun/p2v/ternary.hh | 117 +++++++++++++++++++++
mln/morpho/hit_or_miss.hh | 243 ++++++++++++++++++++++++++++++++++++++++++++
mln/morpho/includes.hh | 4
mln/morpho/min.hh | 121 +++++++++++++++++++++
mln/value/int_u_sat.hh | 191 ++++++++++++++++++++++++++++++++++
tests/morpho_hit_or_miss.cc | 85 +++++++++++++++
10 files changed, 992 insertions(+), 2 deletions(-)
Index: tests/morpho_hit_or_miss.cc
--- tests/morpho_hit_or_miss.cc (revision 0)
+++ tests/morpho_hit_or_miss.cc (revision 0)
@@ -0,0 +1,85 @@
+// 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_hit_or_miss.cc
+ *
+ * \brief Test on mln::morpho::hit_or_miss.
+ */
+
+#include <mln/core/image2d_b.hh>
+#include <mln/value/int_u8.hh>
+
+#include <mln/core/win/rectangle2d.hh>
+#include <mln/core/window2d.hh>
+#include <mln/geom/shift.hh>
+#include <mln/set/diff.hh>
+
+#include <mln/io/load_pgm.hh>
+#include <mln/io/save_pgm.hh>
+#include <mln/level/fill.hh>
+#include <mln/level/stretch.hh>
+
+#include <mln/morpho/hit_or_miss.hh>
+
+
+int main()
+{
+ using namespace mln;
+ using value::int_u8;
+
+ window2d win_hit = geom::shift(win::rectangle2d(3, 3),
+ make::dpoint2d(+1, +1));
+ window2d win_miss = set::diff(win::rectangle2d(5, 5), win_hit);
+
+ {
+ bool hit[] = { 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 1, 1, 1,
+ 0, 0, 1, 1, 1,
+ 0, 0, 1, 1, 1 };
+ window2d win_hit_ = make::window2d(hit);
+ mln_precondition(win_hit_ = win_hit);
+
+ bool miss[] = { 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1,
+ 1, 1, 0, 0, 0,
+ 1, 1, 0, 0, 0,
+ 1, 1, 0, 0, 0 };
+ window2d win_miss_ = make::window2d(miss);
+ mln_precondition(win_miss_ = win_miss);
+ }
+
+ border::thickness = 2;
+
+ image2d_b<int_u8>
+ lena = io::load_pgm("../img/picasso.pgm"),
+ out(lena.domain());
+
+ morpho::hit_or_miss(lena, win_hit, win_miss, out);
+
+ io::save_pgm(out, "out.pgm");
+}
Index: mln/fun/p2v/elifs.hh
--- mln/fun/p2v/elifs.hh (revision 0)
+++ mln/fun/p2v/elifs.hh (revision 0)
@@ -0,0 +1,84 @@
+// 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_FUN_P2V_ELIFS_HH
+# define MLN_FUN_P2V_ELIFS_HH
+
+/*! \file mln/fun/p2v/elifs.hh
+ *
+ * \brief FIXME.
+ */
+
+# include <mln/fun/p2v/ternary.hh>
+
+
+namespace mln
+{
+
+ namespace fun
+ {
+
+ namespace p2v
+ {
+
+ template <typename T1, typename N1,
+ typename T2, typename N2,
+ typename O>
+ ternary_<T1, N1,
+ ternary_<T2, N2, O> >
+ elifs(const Function_p2b<T1>& f_if_1, const Function_p2v<N1>& f_then_1,
+ const Function_p2b<T2>& f_if_2, const Function_p2v<N2>& f_then_2,
+ const Function_p2v<O>& f_otherwise);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename T1, typename N1,
+ typename T2, typename N2,
+ typename O>
+ ternary_<T1, N1,
+ ternary_<T2, N2, O> >
+ elifs(const Function_p2b<T1>& f_if_1, const Function_p2v<N1>& f_then_1,
+ const Function_p2b<T2>& f_if_2, const Function_p2v<N2>& f_then_2,
+ const Function_p2v<O>& f_otherwise)
+ {
+ typedef ternary_<T2, N2, O> T2_N2_O;
+ T2_N2_O f_otherwise_1(f_if_2, f_then_2, f_otherwise);
+ ternary_<T1, N1, T2_N2_O> tmp(f_if_1, f_then_1, f_otherwise_1);
+ return tmp;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::fun::p2v
+
+ } // end of namespace mln::fun
+
+} // end of namespace mln
+
+
+#endif // ! MLN_FUN_P2V_ELIFS_HH
Index: mln/fun/p2v/ternary.hh
--- mln/fun/p2v/ternary.hh (revision 0)
+++ mln/fun/p2v/ternary.hh (revision 0)
@@ -0,0 +1,117 @@
+// 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_FUN_P2V_TERNARY_HH
+# define MLN_FUN_P2V_TERNARY_HH
+
+/*! \file mln/fun/p2v/ternary.hh
+ *
+ * \brief FIXME.
+ */
+
+# include <mln/fun/internal/selector.hh>
+
+
+namespace mln
+{
+
+ namespace fun
+ {
+
+ namespace p2v
+ {
+
+ template <typename P, typename T, typename F>
+ struct ternary_
+ : fun::internal::selector_p2_<mln_result(T), ternary_<P,T,F> >::ret
+ {
+ typedef mln_result(T) result;
+
+ ternary_(const Function_p2b<P>& f_pred,
+ const Function_p2v<T>& f_true,
+ const Function_p2v<F>& f_false);
+
+ template <typename Pt>
+ result operator()(const Pt& p) const;
+
+ protected:
+ const P f_pred_;
+ const T f_true_;
+ const F f_false_;
+ };
+
+
+ template <typename P, typename T, typename F>
+ ternary_<P, T, F>
+ ternary(const Function_p2b<P>& f_pred,
+ const Function_p2v<T>& f_true,
+ const Function_p2v<F>& f_false);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename P, typename T, typename F>
+ ternary_<P,T,F>::ternary_(const Function_p2b<P>& f_pred,
+ const Function_p2v<T>& f_true,
+ const Function_p2v<F>& f_false)
+ : f_pred_(exact(f_pred)),
+ f_true_(exact(f_true)),
+ f_false_(exact(f_false))
+ {
+ }
+
+ template <typename P, typename T, typename F>
+ template <typename Pt>
+ mln_result(T)
+ ternary_<P,T,F>::operator()(const Pt& p) const
+ {
+ return f_pred_(p) ? f_true_(p) : f_false_(p);
+ }
+
+
+ template <typename P, typename T, typename F>
+ ternary_<P, T, F>
+ ternary(const Function_p2b<P>& f_pred,
+ const Function_p2v<T>& f_true,
+ const Function_p2v<F>& f_false)
+ {
+ ternary_<P, T, F> tmp(exact(f_pred),
+ exact(f_true),
+ exact(f_false));
+ return tmp;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::fun::p2v
+
+ } // end of namespace mln::fun
+
+} // end of namespace mln
+
+
+#endif // ! MLN_FUN_P2V_TERNARY_HH
Index: mln/morpho/min.hh
--- mln/morpho/min.hh (revision 0)
+++ mln/morpho/min.hh (revision 0)
@@ -0,0 +1,121 @@
+// 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_MIN_HH
+# define MLN_MORPHO_MIN_HH
+
+# include <mln/level/compare.hh>
+# include <mln/logical/and.hh>
+# include <mln/arith/min.hh>
+
+
+namespace mln
+{
+
+ namespace morpho
+ {
+
+ /*! Morphological min: either a logical "and" (if morpho on sets)
+ * or an arithmetical min (if morpho on functions).
+ */
+ template <typename I, typename J, typename O>
+ void min(const Image<I>& lhs, const Image<J>& rhs,
+ Image<O>& output);
+
+ /*! Morphological min, inplace version: either a logical "and" (if
+ * morpho on sets) or an arithmetical min (if morpho on
+ * functions).
+ */
+ template <typename I, typename J>
+ void min_inplace(Image<I>& lhs, const Image<J>& rhs);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace impl
+ {
+
+ template <typename I, typename J, typename O>
+ void min_(value::binary_kind, // binary => morphology on sets
+ const Image<I>& lhs, const Image<J>& rhs,
+ Image<O>& output)
+ {
+ return logical::and_(lhs, rhs, output);
+ }
+
+ template <typename K, typename I, typename J, typename O>
+ void min_(K, // otherwise => morphology on functions
+ const Image<I>& lhs, const Image<J>& rhs,
+ Image<O>& output)
+ {
+ return arith::min(lhs, rhs, output);
+ }
+
+ // in place
+
+ template <typename I, typename J>
+ void min_inplace_(value::binary_kind, // binary => morphology on sets
+ Image<I>& lhs, const Image<J>& rhs)
+ {
+ return logical::and_inplace(lhs, rhs);
+ }
+
+ template <typename K, typename I, typename J>
+ void min_inplace_(K, // otherwise => morphology on functions
+ Image<I>& lhs, const Image<J>& rhs)
+ {
+ return arith::min_inplace(lhs, rhs);
+ }
+
+ } // end of namespace mln::morpho::impl
+
+
+ // Facades.
+
+ template <typename I, typename J, typename O>
+ void min(const Image<I>& lhs, const Image<J>& rhs, Image<O>& output)
+ {
+ mln_precondition(exact(rhs).domain() = exact(lhs).domain());
+ mln_precondition(exact(output).domain() = exact(lhs).domain());
+ impl::min_(mln_value_kind(I)(), exact(lhs), exact(rhs), output);
+ }
+
+ template <typename I, typename J>
+ void min_inplace(Image<I>& lhs, const Image<J>& rhs)
+ {
+ mln_precondition(exact(rhs).domain() = exact(lhs).domain());
+ impl::min_inplace_(mln_value_kind(I)(), exact(lhs), exact(rhs));
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::morpho
+
+} // end of namespace mln
+
+
+#endif // ! MLN_MORPHO_MIN_HH
Index: mln/morpho/includes.hh
--- mln/morpho/includes.hh (revision 1062)
+++ mln/morpho/includes.hh (working copy)
@@ -49,13 +49,15 @@
# include <mln/border/fill.hh>
# include <mln/geom/sym.hh>
+# include <mln/set/inter.hh>
# include <mln/morpho/dilation.hh>
# include <mln/morpho/erosion.hh>
+# include <mln/morpho/min.hh>
+# include <mln/morpho/complementation.hh>
# include <mln/morpho/minus.hh>
# include <mln/morpho/plus.hh>
-# include <mln/morpho/complementation.hh>
#endif // ! MLN_MORPHO_INCLUDES_HH
Index: mln/morpho/hit_or_miss.hh
--- mln/morpho/hit_or_miss.hh (revision 0)
+++ mln/morpho/hit_or_miss.hh (revision 0)
@@ -0,0 +1,243 @@
+// 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_HIT_OR_MISS_HH
+# define MLN_MORPHO_HIT_OR_MISS_HH
+
+/*! \file mln/morpho/hit_or_miss.hh
+ *
+ * \brief Morphological hit-or-miss.
+ *
+ * \todo Save memory.
+ */
+
+# include <mln/morpho/includes.hh>
+# include <mln/pw/all.hh>
+# include <mln/fun/p2v/ternary.hh>
+
+
+namespace mln
+{
+
+ namespace morpho
+ {
+
+
+ bool constrained_hit_or_miss = true;
+
+
+ /*! Morphological hit-or-miss.
+ *
+ * This operator is HMT_(Bh,Bm) = e_Bh /\ (e_Bm o C).
+ */
+ template <typename I, typename Wh, typename Wm, typename O>
+ void hit_or_miss(const Image<I>& input,
+ const Window<Wh>& win_hit, const Window<Wm>& win_miss,
+ Image<O>& output);
+
+ /*! Morphological hit-or-miss opening.
+ *
+ * This operator is d_(-Bh) o HMT_(Bh,Bm).
+ */
+ template <typename I, typename Wh, typename Wm, typename O>
+ void hit_or_miss_opening(const Image<I>& input,
+ const Window<Wh>& win_hit, const Window<Wm>& win_miss,
+ Image<O>& output);
+
+ /*! Morphological hit-or-miss opening of the background.
+ *
+ * This operator is FIXME.
+ */
+ template <typename I, typename Wh, typename Wm, typename O>
+ void hit_or_miss_background_opening(const Image<I>& input,
+ const Window<Wh>& win_hit, const Window<Wm>& win_miss,
+ Image<O>& output);
+
+ /*! Morphological hit-or-miss closing.
+ *
+ * This operator is FIXME.
+ */
+ template <typename I, typename Wh, typename Wm, typename O>
+ void hit_or_miss_closing(const Image<I>& input,
+ const Window<Wh>& win_hit, const Window<Wm>& win_miss,
+ Image<O>& output);
+
+ /*! Morphological hit-or-miss closing of the background.
+ *
+ * This operator is FIXME.
+ */
+ template <typename I, typename Wh, typename Wm, typename O>
+ void hit_or_miss_background_closing(const Image<I>& input,
+ const Window<Wh>& win_hit, const Window<Wm>& win_miss,
+ Image<O>& output);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace impl
+ {
+
+ // Preconditions.
+
+ template <typename I, typename Wh, typename Wm, typename O>
+ void hit_or_miss_preconditions_(const Image<I>& input,
+ const Window<Wh>& win_hit, const Window<Wm>& win_miss,
+ Image<O>& output)
+ {
+ mln_precondition(exact(output).domain() = exact(input).domain());
+ mln_precondition(set::inter(exact(win_hit), exact(win_miss)).is_empty());
+ }
+
+ // On sets.
+
+ template <typename I, typename Wh, typename Wm, typename O>
+ void hit_or_miss_(value::binary_kind, // binary => morphology on sets
+ const Image<I>& input,
+ const Window<Wh>& win_hit, const Window<Wm>& win_miss,
+ Image<O>& output)
+ {
+ erosion(input, win_hit, output); // output = ero(input)_hit
+
+ O temp_1(exact(input).domain());
+ complementation(input, temp_1); // temp1 = C(input)
+
+ O temp_2(exact(input).domain());
+ erosion(temp_1, win_miss, temp_2); // temp_2 = ero(C(input))_miss
+
+ logical::and_inplace(output, temp_2); // output = ero(input)_hit /\ ero(C(input))_miss
+ }
+
+ // On functions.
+
+ template <typename K,
+ typename I, typename Wh, typename Wm, typename O>
+ void hit_or_miss_(K, // otherwise => morphology on functions
+ const Image<I>& input,
+ const Window<Wh>& win_hit, const Window<Wm>& win_miss,
+ Image<O>& output)
+ {
+ typedef mln_value(O) V;
+
+ if (constrained_hit_or_miss) // CHMT.
+ {
+ if (exact(win_hit).is_centered())
+ {
+ O ero_fg(exact(input).domain()), dil_bg(exact(input).domain());
+ erosion(input, win_hit, ero_fg);
+ dilation(input, win_miss, dil_bg);
+ level::fill(output,
+ fun::p2v::ternary(pw::value(input) = pw::value(ero_fg) && pw::value(dil_bg) < pw::value(input),
+ pw::value(input) - pw::value(dil_bg),
+ pw::cst(V::zero)));
+ }
+ else if (exact(win_miss).is_centered())
+ {
+ O ero_bg(exact(input).domain()), dil_fg(exact(input).domain());
+ erosion(input, win_miss, ero_bg);
+ dilation(input, win_hit, dil_fg);
+ level::fill(output,
+ fun::p2v::ternary(pw::value(input) = pw::value(dil_fg) && pw::value(ero_bg) > pw::value(input),
+ pw::value(ero_bg) - pw::value(input),
+ pw::cst(V::zero)));
+ }
+ else
+ level::fill(output, pw::cst(V::zero));
+ }
+ else // Unconstrained: UHMT.
+ {
+ O ero(exact(input).domain()), dil(exact(input).domain());
+ erosion(input, win_hit, ero);
+ dilation(input, win_miss, dil);
+ level::fill(output,
+ fun::p2v::ternary(pw::value(dil) < pw::value(ero),
+ pw::value(ero) - pw::value(dil),
+ pw::cst(V::zero)));
+ }
+ }
+
+ } // end of mln::morpho::impl
+
+
+ template <typename I, typename Wh, typename Wm, typename O>
+ void hit_or_miss(const Image<I>& input,
+ const Window<Wh>& win_hit, const Window<Wm>& win_miss,
+ Image<O>& output)
+ {
+ impl::hit_or_miss_preconditions_(input, win_hit, win_miss, output);
+ impl::hit_or_miss_(mln_value_kind(I)(), input, win_hit, win_miss, output);
+ }
+
+ template <typename I, typename Wh, typename Wm, typename O>
+ void hit_or_miss_opening(const Image<I>& input,
+ const Window<Wh>& win_hit, const Window<Wm>& win_miss,
+ Image<O>& output)
+ {
+ impl::hit_or_miss_preconditions_(input, win_hit, win_miss, output);
+
+ O temp(exact(input).domain());
+ hit_or_miss(input, win_hit, win_miss, temp);
+ dilation(temp, geom::sym(win_hit), output);
+ }
+
+ template <typename I, typename Wh, typename Wm, typename O>
+ void hit_or_miss_background_opening(const Image<I>& input,
+ const Window<Wh>& win_hit, const Window<Wm>& win_miss,
+ Image<O>& output)
+ {
+ impl::hit_or_miss_preconditions_(input, win_hit, win_miss, output);
+ hit_or_miss_opening(input, win_miss, win_hit, output);
+ }
+
+ template <typename I, typename Wh, typename Wm, typename O>
+ void hit_or_miss_closing(const Image<I>& input,
+ const Window<Wh>& win_hit, const Window<Wm>& win_miss,
+ Image<O>& output)
+ {
+ impl::hit_or_miss_preconditions_(input, win_hit, win_miss, output);
+ I temp(input.domain());
+ complementation(input, temp);
+ hit_or_miss_opening(temp, win_hit, win_miss, output);
+ complementation_inplace(output);
+ }
+
+ template <typename I, typename Wh, typename Wm, typename O>
+ void hit_or_miss_background_closing(const Image<I>& input,
+ const Window<Wh>& win_hit, const Window<Wm>& win_miss,
+ Image<O>& output)
+ {
+ impl::hit_or_miss_preconditions_(input, win_hit, win_miss, output);
+ hit_or_miss_closing(input, win_miss, win_hit, output);
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::morpho
+
+} // end of namespace mln
+
+
+#endif // ! MLN_MORPHO_HIT_OR_MISS_HH
Index: mln/arith/min.hh
--- mln/arith/min.hh (revision 0)
+++ mln/arith/min.hh (revision 0)
@@ -0,0 +1,147 @@
+// 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_ARITH_MIN_HH
+# define MLN_ARITH_MIN_HH
+
+/*! \file mln/arith/min.hh
+ *
+ * \brief Point-wise min between images.
+ */
+
+# include <mln/core/concept/image.hh>
+
+
+namespace mln
+{
+
+ namespace arith
+ {
+
+ /*! Point-wise min of images \p lhs and \p rhs.
+ *
+ * \param[in] lhs First operand image.
+ * \param[in] rhs Second operand image.
+ * \param[out] output The result image.
+ *
+ * \pre \p output.domain = \p lhs.domain = \p rhs.domain
+ */
+ template <typename L, typename R, typename O>
+ void min(const Image<L>& lhs, const Image<R>& rhs, Image<O>& output);
+
+
+ /*! Point-wise min of image \p lhs in image \p rhs.
+ *
+ * \param[in,out] lhs First operand image.
+ * \param[in] rhs Second operand image.
+ *
+ * This substraction performs: \n
+ * for all p of rhs.domain \n
+ * if rhs(p) < lhs(p) \n
+ * lhs(p) = rhs(p)
+ *
+ * \pre \p rhs.domain <= \p lhs.domain
+ */
+ template <typename L, typename R>
+ void min_inplace(Image<L>& lhs, const Image<R>& rhs);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace impl
+ {
+
+ template <typename L, typename R, typename O>
+ void min_(const Image<L>& lhs_, const Image<R>& rhs_, Image<O>& output_)
+ {
+ const L& lhs = exact(lhs_);
+ const R& rhs = exact(rhs_);
+ O& output = exact(output_);
+ mln_piter(L) p(lhs.domain());
+ for_all(p)
+ output(p) = lhs(p) < rhs(p) ? lhs(p) : rhs(p);
+ }
+
+ template <typename L, typename R, typename O>
+ void min_(const Fast_Image<L>& lhs, const Fast_Image<R>& rhs, Fast_Image<O>& output)
+ {
+ mln_pixter(const L) lp(exact(lhs));
+ mln_pixter(const R) rp(exact(rhs));
+ mln_pixter(O) op(exact(output));
+ for_all_3(lp, rp, op)
+ op.val() = lp.val() < rp.val() ? lp.val() : rp.val();
+ }
+
+ template <typename L, typename R>
+ void min_inplace_(Image<L>& lhs_, const Image<R>& rhs_)
+ {
+ L& lhs = exact(lhs_);
+ const R& rhs = exact(rhs_);
+ mln_piter(R) p(rhs.domain());
+ for_all(p)
+ if (rhs(p) < lhs(p))
+ lhs(p) = rhs(p);
+ }
+
+ template <typename L, typename R>
+ void min_inplace_(Fast_Image<L>& lhs, const Fast_Image<R>& rhs)
+ {
+ mln_pixter(L) lp(exact(lhs));
+ mln_pixter(const R) rp(exact(rhs));
+ for_all_2(rp, lp)
+ if (rp.val() < lp.val())
+ lp.val() = rp.val();
+ }
+
+ } // end of namespace mln::arith::impl
+
+
+ // Facades.
+
+ template <typename L, typename R, typename O>
+ void min(const Image<L>& lhs, const Image<R>& rhs, Image<O>& output)
+ {
+ mln_precondition(exact(rhs).domain() = exact(lhs).domain());
+ mln_precondition(exact(output).domain() = exact(lhs).domain());
+ impl::min_(exact(lhs), exact(rhs), exact(output));
+ }
+
+ template <typename L, typename R>
+ void min_inplace(Image<L>& lhs, const Image<R>& rhs)
+ {
+ mln_precondition(exact(rhs).domain() <= exact(lhs).domain());
+ impl::min_inplace_(exact(lhs), exact(rhs));
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::arith
+
+} // end of namespace mln
+
+
+#endif // ! MLN_ARITH_MIN_HH
Index: mln/arith/revert.hh
--- mln/arith/revert.hh (revision 1062)
+++ mln/arith/revert.hh (working copy)
@@ -95,7 +95,7 @@
mln_pixter(const I) ip(exact(input));
mln_pixter(O) op(exact(output));
for_all_2(ip, op)
- op.val() = mln_min(V) + (mln_max(V) - op.val());
+ op.val() = mln_min(V) + (mln_max(V) - ip.val());
}
} // end of namespace mln::arith::impl
Index: mln/value/int_u_sat.hh
--- mln/value/int_u_sat.hh (revision 0)
+++ mln/value/int_u_sat.hh (revision 0)
@@ -0,0 +1,191 @@
+// 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_VALUE_INT_U_SAT_HH
+# define MLN_VALUE_INT_U_SAT_HH
+
+/*! \file mln/value/int_u_sat.hh
+ *
+ * \brief Define a generic class for unsigned integers with saturation
+ * behavior.
+ */
+
+# include <mln/metal/math.hh>
+# include <mln/value/internal/value_like.hh>
+# include <mln/value/internal/encoding.hh>
+# include <mln/value/props.hh>
+# include <mln/debug/format.hh>
+
+
+namespace mln
+{
+
+ namespace value
+ {
+
+
+ /*! \brief Unsigned integer value class with saturation behavior.
+ *
+ * The parameter is \c n the number of encoding bits.
+ */
+ template <unsigned n>
+ struct int_u_sat
+ : public internal::value_like_< typename internal::encoding_unsigned_<n>::ret,
+ int_u_sat<n> >
+ {
+ protected:
+ typedef internal::value_like_< typename internal::encoding_unsigned_<n>::ret,
+ int_u_sat<n> > super;
+
+ public:
+
+ /// Encoding associated type.
+ typedef typename super::enc enc;
+
+ /// Constructor without argument.
+ int_u_sat();
+
+ /// Constructor from an integer.
+ int_u_sat(int i);
+
+ /// Assignment from an integer.
+ int_u_sat<n>& operator=(int i);
+
+ /// Zero value.
+ static const int_u_sat<n> zero;
+
+ /// Unit value.
+ static const int_u_sat<n> one;
+
+ /// Self addition.
+ int_u_sat<n>& operator+=(int i);
+
+ /// Self subtraction.
+ int_u_sat<n>& operator-=(int i);
+ };
+
+
+ // Safety.
+ template <> struct int_u_sat<0>;
+ template <> struct int_u_sat<1>;
+
+
+
+ template <unsigned n>
+ struct props< int_u_sat<n> >
+ {
+ static const std::size_t card_ = metal::pow<2, n>::value;
+ static const int_u_sat<n> min() { return 0; }
+ static const int_u_sat<n> max() { return card_ - 1; }
+ static const unsigned nbits = n;
+ typedef data_kind kind;
+ typedef float sum;
+ };
+
+
+
+ /*! \brief Print a saturated unsigned integer \p i into the output
+ * stream \p ostr.
+ *
+ * \param[in,out] ostr An output stream.
+ * \param[in] i A saturated unsigned integer.
+ *
+ * \return The modified output stream \p ostr.
+ */
+ template <unsigned n>
+ std::ostream& operator<<(std::ostream& ostr, const int_u_sat<n>& i);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <unsigned n>
+ int_u_sat<n>::int_u_sat()
+ {
+ }
+
+ template <unsigned n>
+ int_u_sat<n>::int_u_sat(int i)
+ {
+ if (i < 0)
+ this->v_ = enc(0);
+ else if (i > mln_max(enc))
+ this->v_ = mln_max(enc);
+ else
+ this->v_ = enc(i);
+ }
+
+ template <unsigned n>
+ int_u_sat<n>&
+ int_u_sat<n>::operator=(int i)
+ {
+ if (i < 0)
+ this->v_ = enc(0);
+ else if (i > mln_max(enc))
+ this->v_ = mln_max(enc);
+ else
+ this->v_ = enc(i);
+ return *this;
+ }
+
+ template <unsigned n>
+ int_u_sat<n>&
+ int_u_sat<n>::operator+=(int i)
+ {
+ int v = int(this->v_) + i;
+ *this = v;
+ return *this;
+ }
+
+ template <unsigned n>
+ int_u_sat<n>&
+ int_u_sat<n>::operator-=(int i)
+ {
+ int v = int(this->v_) - i;
+ *this = v;
+ return *this;
+ }
+
+ template <unsigned n>
+ const int_u_sat<n> int_u_sat<n>::zero = 0;
+
+ template <unsigned n>
+ const int_u_sat<n> int_u_sat<n>::one = 1;
+
+ template <unsigned n>
+ std::ostream& operator<<(std::ostream& ostr, const int_u_sat<n>& i)
+ {
+ return ostr << debug::format(i.to_equiv());
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::value
+
+} // end of namespace mln
+
+
+#endif // ! MLN_VALUE_INT_U_SAT_HH
Index: img/picasso.pgm
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: img/picasso.pgm
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Make operations on windows more explicit.
* mln/convert/to_std_set.hh: New.
* mln/geom/sym.hh: New.
* mln/geom/shift.hh: New.
* mln/set: New directory.
* mln/set/inter.hh: New.
* mln/set/diff.hh: New.
* mln/set/union.hh: New.
* mln/set/sym_diff.hh: New.
* mln/convert/to_image.hh: Typo.
* mln/convert/to_window.hh (to_window): New overload.
* mln/convert/to_dpoint.hh: Typo.
* mln/core/w_window.hh (sym_): Rename as...
(sym): ...this and update.
* mln/core/window.hh: Likewise.
(operator-): Remove the unary version.
(operator+, operator-): Remove; now handle by...
* mln/geom/shift.hh (shift): ...this.
* mln/core/concept/weighted_window.hh: Update.
(operator-): Remove.
* mln/core/concept/window.hh: Likewise.
* mln/core/concept/doc/weighted_window.hh,
* mln/core/concept/doc/window.hh,
* mln/core/win/vline2d.hh,
* mln/core/win/hline2d.hh,
* mln/core/win/rectangle2d.hh,
* mln/morpho/includes.hh,
* mln/morpho/closing.hh,
* mln/morpho/opening.hh,
* mln/level/was.median.hh,
* mln/level/median.hh,
* mln/level/fast_median.hh,
* tests/rectangle2d.cc: Update.
* mln/core/concept/value.hh: Fix warning.
mln/convert/to_dpoint.hh | 2
mln/convert/to_image.hh | 2
mln/convert/to_std_set.hh | 75 ++++++++++++++++++++++++++++
mln/convert/to_window.hh | 19 +++++++
mln/core/concept/doc/weighted_window.hh | 4 -
mln/core/concept/doc/window.hh | 4 -
mln/core/concept/value.hh | 2
mln/core/concept/weighted_window.hh | 10 ---
mln/core/concept/window.hh | 24 ++-------
mln/core/w_window.hh | 14 +++--
mln/core/win/hline2d.hh | 6 +-
mln/core/win/rectangle2d.hh | 6 +-
mln/core/win/vline2d.hh | 6 +-
mln/core/window.hh | 70 +++-----------------------
mln/geom/shift.hh | 73 ++++++++++++++++++++++++++++
mln/geom/sym.hh | 68 ++++++++++++++++++++++++++
mln/level/fast_median.hh | 14 +++--
mln/level/median.hh | 14 +++--
mln/level/was.median.hh | 12 ++--
mln/morpho/closing.hh | 2
mln/morpho/includes.hh | 2
mln/morpho/opening.hh | 2
mln/set/diff.hh | 80 ++++++++++++++++++++++++++++++
mln/set/inter.hh | 83 ++++++++++++++++++++++++++++++++
mln/set/sym_diff.hh | 79 ++++++++++++++++++++++++++++++
mln/set/union.hh | 82 +++++++++++++++++++++++++++++++
tests/rectangle2d.cc | 3 -
27 files changed, 630 insertions(+), 128 deletions(-)
Index: tests/rectangle2d.cc
--- tests/rectangle2d.cc (revision 1061)
+++ tests/rectangle2d.cc (working copy)
@@ -31,6 +31,7 @@
*/
#include <mln/core/win/rectangle2d.hh>
+#include <mln/geom/sym.hh>
@@ -43,7 +44,7 @@
mln_assertion(rec.is_centered());
mln_assertion(rec.is_symmetric());
- mln_assertion(rec = -rec);
+ mln_assertion(rec = geom::sym(rec));
mln_assertion(rec.ndpoints() = h * w);
}
Index: mln/convert/to_image.hh
--- mln/convert/to_image.hh (revision 1061)
+++ mln/convert/to_image.hh (working copy)
@@ -30,7 +30,7 @@
/*! \file mln/convert/to_image.hh
*
- * \brief Convertions to mln::Image.
+ * \brief Conversions to mln::Image.
*/
# include <mln/core/image2d_b.hh>
Index: mln/convert/to_std_set.hh
--- mln/convert/to_std_set.hh (revision 0)
+++ mln/convert/to_std_set.hh (revision 0)
@@ -0,0 +1,75 @@
+// 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_CONVERT_TO_STD_SET_HH
+# define MLN_CONVERT_TO_STD_SET_HH
+
+/*! \file mln/convert/to_std_set.hh
+ *
+ * \brief Conversions to std::set.
+ */
+
+# include <set>
+# include <algorithm>
+# include <iterator>
+
+# include <mln/core/window.hh>
+
+
+namespace mln
+{
+
+ namespace convert
+ {
+
+ /// Convert a window \p win into a std::set of delta-points.
+ template <typename W>
+ std::set<mln_dpoint(W)> to_std_set(const Window<W>& win);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename W>
+ std::set<mln_dpoint(W)> to_std_set(const Window<W>& win)
+ {
+ typedef mln_dpoint(W) D;
+ typedef mln_point(D) P;
+ std::set<D> s;
+ mln_qiter(W) q(exact(win), P::zero);
+ for_all(q)
+ s.insert(q - P::zero);
+ return s;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::convert
+
+} // end of namespace mln
+
+
+#endif // ! MLN_CONVERT_TO_STD_SET_HH
Index: mln/convert/to_window.hh
--- mln/convert/to_window.hh (revision 1061)
+++ mln/convert/to_window.hh (working copy)
@@ -33,10 +33,14 @@
* \brief Conversions to mln::window.
*/
+# include <set>
+
+# include <mln/core/concept/dpoint.hh>
# include <mln/core/concept/neighborhood.hh>
# include <mln/core/window.hh>
# include <mln/pw/image.hh>
# include <mln/pw/cst.hh>
+# include <mln/metal/is_a.hh>
namespace mln
@@ -57,6 +61,10 @@
template <typename S, typename F>
window<mln_dpoint(S)> to_window(const Point_Set<S>& pset);
+ /// Convert an std::set \p s of delta-points into a window.
+ template <typename D>
+ window<D> to_window(const std::set<D>& s);
+
# ifndef MLN_INCLUDE_ONLY
@@ -95,6 +103,17 @@
return to_window(pw::cst(true) | pset);
}
+ template <typename D>
+ window<D> to_window(const std::set<D>& s)
+ {
+ mln::metal::is_a<D, Dpoint>::check();
+ window<D> win;
+ for (typename std::set<D>::const_iterator i = s.begin();
+ i != s.end(); ++i)
+ win.insert(*i);
+ return win;
+ }
+
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln::convert
Index: mln/convert/to_dpoint.hh
--- mln/convert/to_dpoint.hh (revision 1061)
+++ mln/convert/to_dpoint.hh (working copy)
@@ -30,7 +30,7 @@
/*! \file mln/convert/to_dpoint.hh
*
- * \brief Convertions to mln::Dpoint.
+ * \brief Conversions to mln::Dpoint.
*/
# include <mln/core/concept/generalized_point.hh>
Index: mln/geom/sym.hh
--- mln/geom/sym.hh (revision 0)
+++ mln/geom/sym.hh (revision 0)
@@ -0,0 +1,68 @@
+// 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_GEOM_SYM_HH
+# define MLN_GEOM_SYM_HH
+
+/*! \file mln/geom/sym.hh
+ *
+ * \brief Give the symmetrical object.
+ */
+
+# include <mln/core/concept/window.hh>
+
+
+
+namespace mln
+{
+
+ namespace geom
+ {
+
+ /*! \brief Give the symmetrical window of \p win.
+ */
+ template <typename W>
+ W sym(const Window<W>& win);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename W>
+ W sym(const Window<W>& win)
+ {
+ W tmp = exact(win);
+ return tmp.sym();
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::geom
+
+} // end of namespace mln
+
+
+#endif // ! MLN_GEOM_SYM_HH
Index: mln/geom/shift.hh
--- mln/geom/shift.hh (revision 0)
+++ mln/geom/shift.hh (revision 0)
@@ -0,0 +1,73 @@
+// 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_GEOM_SHIFT_HH
+# define MLN_GEOM_SHIFT_HH
+
+/*! \file mln/geom/shift.hh
+ *
+ * \brief Shift.
+ */
+
+# include <mln/core/window.hh>
+
+
+
+namespace mln
+{
+
+ namespace geom
+ {
+
+ /// Shift a window \p win with a delta-point \p dp.
+ template <typename W>
+ window<mln_dpoint(W)>
+ shift(const Window<W>& win, const mln_dpoint(W)& dp);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename W>
+ window<mln_dpoint(W)>
+ shift(const Window<W>& win, const mln_dpoint(W)& dp)
+ {
+ typedef mln_point(W) P;
+ window<mln_dpoint(W)> tmp;
+ mln_qiter(W) q(win, P::zero);
+ for_all(q)
+ tmp.insert(convert::to_dpoint(q) + dp);
+ return tmp;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::geom
+
+} // end of namespace mln
+
+
+#endif // ! MLN_GEOM_SHIFT_HH
Index: mln/core/w_window.hh
--- mln/core/w_window.hh (revision 1061)
+++ mln/core/w_window.hh (working copy)
@@ -104,8 +104,8 @@
const mln::window<D>& win() const;
- /// Give the symmetrical w_window.
- w_window<D,W> sym_() const;
+ /// Apply a central symmetry to the target window.
+ w_window<D,W>& sym();
protected:
@@ -252,11 +252,13 @@
}
template <typename D, typename W>
- w_window<D,W>
- w_window<D,W>::sym_() const
+ w_window<D,W>&
+ w_window<D,W>::sym()
{
- w_window<D,W> tmp(*this);
- tmp.win_ = - this->win_;
+ w_window<D,W> tmp;
+ for (unsigned i = 0; i < this->ndpoints(); ++i)
+ tmp.insert(this->w(i), this->dp(i));
+ *this = tmp;
return *this;
}
Index: mln/core/window.hh
--- mln/core/window.hh (revision 1061)
+++ mln/core/window.hh (working copy)
@@ -40,6 +40,7 @@
# include <mln/core/box.hh>
# include <mln/convert/to_dpoint.hh>
+# include <mln/geom/sym.hh>
namespace mln
@@ -87,8 +88,8 @@
/// Insert a delta-point \p dp.
window<D>& insert(const D& dp);
- /// Give the symmetrical window.
- window<D> sym_() const;
+ /// Apply a central symmetry to the target window.
+ window<D>& sym();
protected:
@@ -96,24 +97,6 @@
};
- // FIXME: Move both ops below to mln/core/concept/window.hh
-
- /// Shift a window \p win with a delta-point \p dp.
- template <typename W>
- window<mln_dpoint(W)> operator+(const Window<W>& win,
- const mln_dpoint(W)& dp);
-
- /// Shift a window \p win with the delta-point (-\p dp).
- template <typename W>
- window<mln_dpoint(W)> operator-(const Window<W>& win,
- const mln_dpoint(W)& dp);
-
- /// Substract \p rhs from \p lhs.
- // FIXME: Give details!
- template <typename Wl, typename Wr>
- window<mln_dpoint(Wl)> operator-(const Window<Wl>& lhs,
- const Window<Wr>& rhs);
-
# ifndef MLN_INCLUDE_ONLY
@@ -128,7 +111,7 @@
template <typename D>
bool window<D>::is_symmetric() const
{
- return this->sym_() = *this;
+ return geom::sym(*this) = *this;
}
template <typename D>
@@ -141,52 +124,15 @@
}
template <typename D>
- window<D>
- window<D>::sym_() const
+ window<D>&
+ window<D>::sym()
{
window<D> tmp;
const unsigned n = this->ndpoints();
for (unsigned i = 0; i < n; ++i)
tmp.insert(- this->dp(i));
- return tmp;
- }
-
-
- // operators
-
- template <typename W>
- window<mln_dpoint(W)> operator+(const Window<W>& win,
- const mln_dpoint(W)& dp)
- {
- typedef mln_point(W) P;
- window<mln_dpoint(W)> tmp;
- mln_qiter(W) q(win, P::zero);
- for_all(q)
- tmp.insert(convert::to_dpoint(q) + dp);
- return tmp;
- }
-
- template <typename W>
- window<mln_dpoint(W)> operator-(const Window<W>& win,
- const mln_dpoint(W)& dp)
- {
- return win + (-dp);
- }
-
- template <typename W, typename Wr>
- window<mln_dpoint(W)> operator-(const Window<W>& lhs,
- const Window<Wr>& rhs)
- {
- typedef mln_point(W) P;
- window<mln_dpoint(W)> tmp;
- mln_qiter(W) q(lhs, P::zero);
- for_all(q)
- {
- mln_dpoint(W) dp = convert::to_dpoint(q);
- if (! exact(rhs).has(dp))
- tmp.insert(dp);
- }
- return tmp;
+ *this = tmp;
+ return *this;
}
# endif // ! MLN_INCLUDE_ONLY
Index: mln/core/concept/weighted_window.hh
--- mln/core/concept/weighted_window.hh (revision 1061)
+++ mln/core/concept/weighted_window.hh (working copy)
@@ -58,7 +58,7 @@
typedef weight;
typedef window;
- E sym_() const;
+ E& sym();
*/
/// Test if the weighted window is empty; final method.
@@ -107,19 +107,13 @@
typedef mln_fwd_qiter(E) fwd_qiter;
typedef mln_bkd_qiter(E) bkd_qiter;
- E (E::*m1)() const = & E::sym_;
+ E& (E::*m1)() = & E::sym;
m1 = 0;
const window& (E::*m2)() const = & E::win;
m2 = 0;
}
- template <typename W>
- W operator-(const Weighted_Window<W>& rhs)
- {
- return exact(rhs).sym_();
- }
-
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln
Index: mln/core/concept/window.hh
--- mln/core/concept/window.hh (revision 1061)
+++ mln/core/concept/window.hh (working copy)
@@ -39,6 +39,7 @@
namespace mln
{
+
/*! \brief Base class for implementation classes that are windows.
*
* \see mln::doc::Window for a complete documentation of this class
@@ -61,7 +62,7 @@
unsigned delta() const;
- E sym_() const;
+ E& sym();
*/
protected:
@@ -69,22 +70,17 @@
};
- /*! \brief Compute the symmetrical window of \p rhs.
- *
- * \relates mln::Window
- */
- template <typename W>
- W operator-(const Window<W>& rhs);
-
-
/*! \brief Equality comparison between windows \p lhs and \p rhs.
*
* \relates mln::Window
+ *
+ * \todo Move into mln/set/compare.hh and delegate to replace this special impl.
*/
template <typename Wl, typename Wr>
bool operator=(const Window<Wl>& lhs, const Window<Wr>& rhs);
+
# ifndef MLN_INCLUDE_ONLY
template <typename E>
@@ -105,14 +101,8 @@
m3 = 0;
unsigned (E::*m4)() const = & E::delta;
m4 = 0;
- E (E::*m_)() const = & E::sym_;
- m_ = 0;
- }
-
- template <typename W>
- W operator-(const Window<W>& rhs)
- {
- return exact(rhs).sym_();
+ E& (E::*m5)() = & E::sym;
+ m5 = 0;
}
template <typename Wl, typename Wr>
Index: mln/core/concept/doc/weighted_window.hh
--- mln/core/concept/doc/weighted_window.hh (revision 1061)
+++ mln/core/concept/doc/weighted_window.hh (working copy)
@@ -89,9 +89,9 @@
*/
const window& win() const;
- /*! \brief Give the symmetrical weighted_window.
+ /*! \brief Apply a central symmetry to the target weighted window.
*/
- E sym_() const;
+ E& sym();
};
} // end of namespace mln::doc
Index: mln/core/concept/doc/window.hh
--- mln/core/concept/doc/window.hh (revision 1061)
+++ mln/core/concept/doc/window.hh (working copy)
@@ -81,9 +81,9 @@
*/
unsigned delta() const;
- /*! \brief Give the symmetrical window.
+ /*! \brief Apply a central symmetry to the target window.
*/
- E sym_() const;
+ E& sym();
};
} // end of namespace mln::doc
Index: mln/core/concept/value.hh
--- mln/core/concept/value.hh (revision 1061)
+++ mln/core/concept/value.hh (working copy)
@@ -115,7 +115,7 @@
template <typename T, typename S>
typename S::equiv
- cast_(const T& dummy, const Value<S>& src)
+ cast_(const T&, const Value<S>& src)
{
return exact(src);
}
Index: mln/core/win/vline2d.hh
--- mln/core/win/vline2d.hh (revision 1061)
+++ mln/core/win/vline2d.hh (working copy)
@@ -108,8 +108,8 @@
*/
unsigned delta() const;
- /// Get the symmetrical window.
- vline2d sym_() const;
+ /// Apply a central symmetry to the target window.
+ vline2d& sym();
protected:
unsigned length_;
@@ -161,7 +161,7 @@
return length_ / 2;
}
- vline2d vline2d::sym_() const
+ vline2d& vline2d::sym()
{
return *this;
}
Index: mln/core/win/hline2d.hh
--- mln/core/win/hline2d.hh (revision 1061)
+++ mln/core/win/hline2d.hh (working copy)
@@ -106,8 +106,8 @@
*/
unsigned delta() const;
- /// Get the symmetrical window.
- hline2d sym_() const;
+ /// Apply a central symmetry to the target window.
+ hline2d& sym();
protected:
unsigned length_;
@@ -159,7 +159,7 @@
return length_ / 2;
}
- hline2d hline2d::sym_() const
+ hline2d& hline2d::sym()
{
return *this;
}
Index: mln/core/win/rectangle2d.hh
--- mln/core/win/rectangle2d.hh (revision 1061)
+++ mln/core/win/rectangle2d.hh (working copy)
@@ -111,8 +111,8 @@
*/
unsigned delta() const;
- /// Get the symmetrical window.
- rectangle2d sym_() const;
+ /// Apply a central symmetry to the target window.
+ rectangle2d& sym();
protected:
unsigned height_, width_;
@@ -171,7 +171,7 @@
return width_ > height_ ? width_ / 2 : height_ / 2;
}
- rectangle2d rectangle2d::sym_() const
+ rectangle2d& rectangle2d::sym()
{
return *this;
}
Index: mln/set/inter.hh
--- mln/set/inter.hh (revision 0)
+++ mln/set/inter.hh (revision 0)
@@ -0,0 +1,83 @@
+// 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_SET_INTER_HH
+# define MLN_SET_INTER_HH
+
+/*! \file mln/set/inter.hh
+ *
+ * \brief Several routines to compute the intersection between a
+ * couple of sets.
+ */
+
+# include <mln/convert/to_std_set.hh>
+# include <mln/convert/to_window.hh>
+# include <mln/metal/equal.hh>
+
+
+
+namespace mln
+{
+
+ namespace set
+ {
+
+ /*! \brief Intersection between a couple of windows.
+ *
+ * \relates mln::Window
+ */
+ template <typename Wl, typename Wr>
+ window<mln_dpoint(Wl)>
+ inter(const Window<Wl>& lhs, const Window<Wr>& rhs);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename Wl, typename Wr>
+ window<mln_dpoint(Wl)>
+ inter(const Window<Wl>& lhs, const Window<Wr>& rhs)
+ {
+ mln::metal::equal<mln_dpoint(Wl), mln_dpoint(Wr)>::check();
+ typedef mln_dpoint(Wl) D;
+ std::set<D>
+ sl = convert::to_std_set(lhs),
+ sr = convert::to_std_set(rhs),
+ s;
+ std::set_intersection(sl.begin(), sl.end(),
+ sr.begin(), sr.end(),
+ std::inserter(s, s.begin()));
+ return convert::to_window(s);
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::set
+
+} // end of namespace mln
+
+
+#endif // ! MLN_SET_INTER_HH
Index: mln/set/diff.hh
--- mln/set/diff.hh (revision 0)
+++ mln/set/diff.hh (revision 0)
@@ -0,0 +1,80 @@
+// 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_SET_DIFF_HH
+# define MLN_SET_DIFF_HH
+
+/*! \file mln/set/diff.hh
+ *
+ * \brief Set theoretic difference (non-symmetrical) of a couple of
+ * sets.
+ */
+
+# include <mln/convert/to_std_set.hh>
+# include <mln/convert/to_window.hh>
+# include <mln/metal/equal.hh>
+
+
+
+namespace mln
+{
+
+ namespace set
+ {
+
+ /// Set theoretic difference of \p lhs and \p rhs.
+ template <typename Wl, typename Wr>
+ window<mln_dpoint(Wl)>
+ diff(const Window<Wl>& lhs, const Window<Wr>& rhs);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename Wl, typename Wr>
+ window<mln_dpoint(Wl)>
+ diff(const Window<Wl>& lhs, const Window<Wr>& rhs)
+ {
+ mln::metal::equal<mln_dpoint(Wl), mln_dpoint(Wr)>::check();
+ typedef mln_dpoint(Wl) D;
+ std::set<D>
+ sl = convert::to_std_set(lhs),
+ sr = convert::to_std_set(rhs),
+ s;
+ std::set_difference(sl.begin(), sl.end(),
+ sr.begin(), sr.end(),
+ std::inserter(s, s.begin()));
+ return convert::to_window(s);
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::set
+
+} // end of namespace mln
+
+
+#endif // ! MLN_SET_DIFF_HH
Index: mln/set/union.hh
--- mln/set/union.hh (revision 0)
+++ mln/set/union.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_SET_UNION_HH
+# define MLN_SET_UNION_HH
+
+/*! \file mln/set/union.hh
+ *
+ * \brief Several routines to compute the union of a couple of sets.
+ */
+
+# include <mln/convert/to_std_set.hh>
+# include <mln/convert/to_window.hh>
+# include <mln/metal/equal.hh>
+
+
+
+namespace mln
+{
+
+ namespace set
+ {
+
+ /*! \brief Union of a couple of windows.
+ *
+ * \relates mln::Window
+ */
+ template <typename Wl, typename Wr>
+ window<mln_dpoint(Wl)>
+ union(const Window<Wl>& lhs, const Window<Wr>& rhs);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename Wl, typename Wr>
+ window<mln_dpoint(Wl)>
+ union(const Window<Wl>& lhs, const Window<Wr>& rhs)
+ {
+ mln::metal::equal<mln_dpoint(Wl), mln_dpoint(Wr)>::check();
+ typedef mln_dpoint(Wl) D;
+ std::set<D>
+ sl = convert::to_std_set(lhs),
+ sr = convert::to_std_set(rhs),
+ s;
+ std::set_union(sl.begin(), sl.end(),
+ sr.begin(), sr.end(),
+ std::inserter(s, s.begin()));
+ return convert::to_window(s);
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::set
+
+} // end of namespace mln
+
+
+#endif // ! MLN_SET_UNION_HH
Index: mln/set/sym_diff.hh
--- mln/set/sym_diff.hh (revision 0)
+++ mln/set/sym_diff.hh (revision 0)
@@ -0,0 +1,79 @@
+// 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_SET_SYM_DIFF_HH
+# define MLN_SET_SYM_DIFF_HH
+
+/*! \file mln/set/sym_diff.hh
+ *
+ * \brief Set theoretic symmetrical difference of a couple of sets.
+ */
+
+# include <mln/convert/to_std_set.hh>
+# include <mln/convert/to_window.hh>
+# include <mln/metal/equal.hh>
+
+
+
+namespace mln
+{
+
+ namespace set
+ {
+
+ /// Set theoretic symmetrical difference of \p lhs and \p rhs.
+ template <typename Wl, typename Wr>
+ window<mln_dpoint(Wl)>
+ sym_diff(const Window<Wl>& lhs, const Window<Wr>& rhs);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename Wl, typename Wr>
+ window<mln_dpoint(Wl)>
+ sym_diff(const Window<Wl>& lhs, const Window<Wr>& rhs)
+ {
+ mln::metal::equal<mln_dpoint(Wl), mln_dpoint(Wr)>::check();
+ typedef mln_dpoint(Wl) D;
+ std::set<D>
+ sl = convert::to_std_set(lhs),
+ sr = convert::to_std_set(rhs),
+ s;
+ std::set_symmetric_difference(sl.begin(), sl.end(),
+ sr.begin(), sr.end(),
+ std::inserter(s, s.begin()));
+ return convert::to_window(s);
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::set
+
+} // end of namespace mln
+
+
+#endif // ! MLN_SET_SYM_DIFF_HH
Index: mln/morpho/includes.hh
--- mln/morpho/includes.hh (revision 1061)
+++ mln/morpho/includes.hh (working copy)
@@ -48,6 +48,8 @@
# include <mln/border/resize.hh>
# include <mln/border/fill.hh>
+# include <mln/geom/sym.hh>
+
# include <mln/morpho/dilation.hh>
# include <mln/morpho/erosion.hh>
Index: mln/morpho/closing.hh
--- mln/morpho/closing.hh (revision 1061)
+++ mln/morpho/closing.hh (working copy)
@@ -64,7 +64,7 @@
O temp(input.domain());
dilation(input, win, temp);
- erosion(temp, -win, output);
+ erosion(temp, geom::sym(win), output);
mln_postcondition(output >= input);
}
Index: mln/morpho/opening.hh
--- mln/morpho/opening.hh (revision 1061)
+++ mln/morpho/opening.hh (working copy)
@@ -64,7 +64,7 @@
O temp(input.domain());
erosion(input, win, temp);
- dilation(temp, -win, output);
+ dilation(temp, geom::sym(win), output);
mln_postcondition(output <= input);
}
Index: mln/level/was.median.hh
--- mln/level/was.median.hh (revision 1061)
+++ mln/level/was.median.hh (working copy)
@@ -59,12 +59,12 @@
min_col = geom::min_col(input), max_col = geom::max_col(input);
window2d
- win_fwd_plus = win - (win + left),
- win_fwd_minus = (win + left) - win,
- win_bkd_plus = win - (win + right),
- win_bkd_minus = (win + right) - win,
- win_bot = win - (win + up),
- win_top = (win + up) - win;
+ win_fwd_plus = set::diff(win, geom::shift(win, left)),
+ win_fwd_minus = set::diff(geom::shift(win, left), win),
+ win_bkd_plus = set::diff(win, geom::shift(win, right)),
+ win_bkd_minus = set::diff(geom::shift(win, right), win),
+ win_bot = set::diff(win, geom::shift(win, up)),
+ win_top = set::diff(geom::shift(win, up), win);
point2d p;
mln_qiter(W)
Index: mln/level/median.hh
--- mln/level/median.hh (revision 1061)
+++ mln/level/median.hh (working copy)
@@ -38,11 +38,14 @@
# include <mln/core/window2d.hh>
# include <mln/core/win/hline2d.hh>
-
# include <mln/core/t_image.hh>
+
# include <mln/accu/median.hh>
# include <mln/canvas/sbrowsing.hh>
+# include <mln/geom/shift.hh>
+# include <mln/set/diff.hh>
+
namespace mln
{
@@ -98,9 +101,12 @@
// aux data
med(input.values()),
p(),
- win_fp(win - (win + left)), win_fm((win + left) - win),
- win_bp(win - (win + right)), win_bm((win + right) - win),
- win_dp(win - (win + up)), win_dm((win + up) - win),
+ win_fp(set::diff(win, geom::shift(win, left))),
+ win_fm(set::diff(geom::shift(win, left), win)),
+ win_bp(set::diff(win, geom::shift(win, right))),
+ win_bm(set::diff(geom::shift(win, right), win)),
+ win_dp(set::diff(win, geom::shift(win, up))),
+ win_dm(set::diff(geom::shift(win, up), win)),
q_fp(win_fp, p), q_fm(win_fm, p),
q_bp(win_bp, p), q_bm(win_bm, p),
q_dp(win_dp, p), q_dm(win_dm, p)
Index: mln/level/fast_median.hh
--- mln/level/fast_median.hh (revision 1061)
+++ mln/level/fast_median.hh (working copy)
@@ -36,6 +36,8 @@
# include <mln/core/concept/image.hh>
# include <mln/core/window2d.hh>
# include <mln/accu/median.hh>
+# include <mln/geom/shift.hh>
+# include <mln/set/diff.hh>
namespace mln
@@ -77,12 +79,12 @@
min_col = geom::min_col(input), max_col = geom::max_col(input);
window2d
- win_fwd_plus = win - (win + left),
- win_fwd_minus = (win + left) - win,
- win_bkd_plus = win - (win + right),
- win_bkd_minus = (win + right) - win,
- win_bot = win - (win + up),
- win_top = (win + up) - win;
+ win_fwd_plus = set::diff(win, geom::shift(win, left)),
+ win_fwd_minus = set::diff(geom::shift(win, left), win),
+ win_bkd_plus = set::diff(win, geom::shift(win, right)),
+ win_bkd_minus = set::diff(geom::shift(win, right), win),
+ win_bot = set::diff(win, geom::shift(win, up)),
+ win_top = set::diff(geom::shift(win, up), win);
accu::median<mln_vset(I)> med(input.values());
https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Add morphological complementation.
* tests/morpho_contrast.cc: Augment.
* mln/core/concept/value.hh (cast): New.
* mln/fun/v2v/saturate.hh: Update.
* mln/morpho/minus.hh: Move assertions.
* mln/logical/and.hh,
* mln/logical/and_not.hh,
* mln/logical/or.hh: Fix doc.
* mln/value/int_s.hh (operator=): New.
* mln/value/int_u.hh: Likewise.
* mln/morpho/complementation.hh: New.
* mln/morpho/includes.hh: Update.
* mln/arith/revert.hh: New.
* mln/logical/not.hh: New.
mln/arith/revert.hh | 127 ++++++++++++++++++++++++++++++++++++++++++
mln/core/concept/value.hh | 46 +++++++++++++++
mln/fun/v2v/saturate.hh | 10 +--
mln/logical/and.hh | 2
mln/logical/and_not.hh | 2
mln/logical/not.hh | 120 +++++++++++++++++++++++++++++++++++++++
mln/logical/or.hh | 2
mln/morpho/complementation.hh | 105 ++++++++++++++++++++++++++++++++++
mln/morpho/includes.hh | 1
mln/morpho/minus.hh | 7 --
mln/value/int_s.hh | 13 ++++
mln/value/int_u.hh | 13 ++++
tests/morpho_contrast.cc | 22 ++++++-
13 files changed, 455 insertions(+), 15 deletions(-)
Index: tests/morpho_contrast.cc
--- tests/morpho_contrast.cc (revision 1060)
+++ tests/morpho_contrast.cc (working copy)
@@ -37,7 +37,11 @@
#include <mln/io/save_pgm.hh>
#include <mln/value/int_u8.hh>
+#include <mln/value/int_s.hh>
+
#include <mln/morpho/contrast.hh>
+
+#include <mln/level/fill.hh>
#include <mln/level/saturate.hh>
@@ -53,9 +57,23 @@
lena = io::load_pgm("../img/tiny.pgm"),
out(lena.domain());
- image2d_b<int> tmp(lena.domain());
- morpho::contrast(lena, rect, tmp);
+ image2d_b< value::int_s<10> >
+ in(lena.domain()),
+ tmp(lena.domain());
+
+ level::fill(in, lena);
+ morpho::contrast(in, rect, tmp);
level::saturate(tmp, out);
io::save_pgm(out, "out.pgm");
+
+ {
+ // self-duality test:
+ morpho::complementation_inplace(in);
+ image2d_b< value::int_s<10> > tmp_(lena.domain());
+ morpho::contrast(in, rect, tmp_);
+ morpho::complementation_inplace(tmp_);
+ mln_assertion(tmp_ = tmp);
+ }
+
}
Index: mln/core/concept/value.hh
--- mln/core/concept/value.hh (revision 1060)
+++ mln/core/concept/value.hh (working copy)
@@ -62,6 +62,18 @@
};
+
+ namespace value
+ {
+
+ /// Cast a value \p src from type \c Src to type \c Dest.
+ template <typename Dest, typename Src>
+ Dest cast(const Src& src);
+
+ } // end of namespace mln::value
+
+
+
# ifndef MLN_INCLUDE_ONLY
template <typename E>
@@ -87,6 +99,40 @@
return exact(*this);
}
+
+ namespace value
+ {
+
+ namespace internal
+ {
+
+ template <typename S>
+ const S&
+ cast_(const S& src, ...)
+ {
+ return src;
+ }
+
+ template <typename T, typename S>
+ typename S::equiv
+ cast_(const T& dummy, const Value<S>& src)
+ {
+ return exact(src);
+ }
+
+ } // end of namespace mln::value::internal
+
+
+ template <typename Dest, typename Src>
+ Dest cast(const Src& src)
+ {
+ return internal::cast_(src, src);
+ }
+
+
+ } // end of namespace mln::value
+
+
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln
Index: mln/fun/v2v/saturate.hh
--- mln/fun/v2v/saturate.hh (revision 1060)
+++ mln/fun/v2v/saturate.hh (working copy)
@@ -57,7 +57,7 @@
typedef V result;
template <typename W>
- V operator()(const W& v) const;
+ V operator()(const W& w) const;
protected:
V min_, max_;
@@ -84,13 +84,13 @@
template <typename V>
template <typename W>
V
- saturate<V>::operator()(const W& v) const
+ saturate<V>::operator()(const W& w) const
{
- if (v < min_)
+ if (w < min_)
return min_;
- if (v > max_)
+ if (w > max_)
return max_;
- return v;
+ return mln::value::cast<V>(w);
}
# endif // ! MLN_INCLUDE_ONLY
Index: mln/morpho/includes.hh
--- mln/morpho/includes.hh (revision 1060)
+++ mln/morpho/includes.hh (working copy)
@@ -53,6 +53,7 @@
# include <mln/morpho/minus.hh>
# include <mln/morpho/plus.hh>
+# include <mln/morpho/complementation.hh>
#endif // ! MLN_MORPHO_INCLUDES_HH
Index: mln/morpho/minus.hh
--- mln/morpho/minus.hh (revision 1060)
+++ mln/morpho/minus.hh (working copy)
@@ -64,7 +64,9 @@
const Image<I>& lhs, const Image<J>& rhs,
Image<O>& output)
{
+ // FIXME: mln_precondition(rhs <= lhs);
return logical::and_not(lhs, rhs, output);
+ // FIXME: mln_postcondition(output <= lhs);
}
template <typename K, typename I, typename J, typename O>
@@ -85,19 +87,14 @@
{
mln_precondition(exact(rhs).domain() = exact(lhs).domain());
mln_precondition(exact(output).domain() = exact(lhs).domain());
- mln_precondition(rhs <= lhs);
impl::minus_(mln_value_kind(I)(), exact(lhs), exact(rhs), output);
-
- mln_postcondition(output <= lhs);
}
template <typename I, typename J>
void minus_inplace(Image<I>& lhs, const Image<J>& rhs)
{
mln_precondition(exact(rhs).domain() = exact(lhs).domain());
- mln_precondition(rhs <= lhs);
-
morpho::minus(lhs, rhs, lhs); // Calls the previous version.
}
Index: mln/morpho/complementation.hh
--- mln/morpho/complementation.hh (revision 0)
+++ mln/morpho/complementation.hh (revision 0)
@@ -0,0 +1,105 @@
+// 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_COMPLEMENTATION_HH
+# define MLN_MORPHO_COMPLEMENTATION_HH
+
+# include <mln/level/compare.hh>
+# include <mln/logical/not.hh>
+# include <mln/arith/revert.hh>
+
+
+namespace mln
+{
+
+ namespace morpho
+ {
+
+ /*! Morphological complementation: either a logical "not" (if
+ * morpho on sets) or an arithmetical complementation (if morpho
+ * on functions).
+ */
+ template <typename I, typename O>
+ void complementation(const Image<I>& input, Image<O>& output);
+
+
+ /*! Morphological complementation, inplace version: either a
+ * logical "not" (if morpho on sets) or an arithmetical
+ * complementation (if morpho on functions).
+ */
+ template <typename I>
+ void complementation_inplace(Image<I>& input);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace impl
+ {
+
+ template <typename I, typename O>
+ void complementation_(value::binary_kind, // binary => morphology on sets
+ const Image<I>& input,
+ Image<O>& output)
+ {
+ return logical::not_(input, output);
+ }
+
+ template <typename K, typename I, typename O>
+ void complementation_(K, // otherwise => morphology on functions
+ const Image<I>& input,
+ Image<O>& output)
+ {
+ return arith::revert(input, output);
+ }
+
+ } // end of namespace mln::morpho::impl
+
+
+ // Facades.
+
+ template <typename I, typename O>
+ void complementation(const Image<I>& input, Image<O>& output)
+ {
+ mln_precondition(exact(output).domain() = exact(input).domain());
+ impl::complementation_(mln_value_kind(I)(), exact(input), output);
+ }
+
+ template <typename I>
+ void complementation_inplace(Image<I>& input)
+ {
+ mln_precondition(exact(input).has_data());
+ morpho::complementation(input, input); // Calls the previous version.
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::morpho
+
+} // end of namespace mln
+
+
+#endif // ! MLN_MORPHO_COMPLEMENTATION_HH
Index: mln/arith/revert.hh
--- mln/arith/revert.hh (revision 0)
+++ mln/arith/revert.hh (revision 0)
@@ -0,0 +1,127 @@
+// 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_ARITH_REVERT_HH
+# define MLN_ARITH_REVERT_HH
+
+/*! \file mln/arith/revert.hh
+ *
+ * \brief Point-wise revert (min -> max and max -> min) of images.
+ *
+ * \todo Add static assertion and save one iterator in in-place version.
+ */
+
+# include <mln/core/concept/image.hh>
+# include <mln/value/props.hh>
+
+// FIXME: Rely instead on mln/fun/v2v/revert.hh.
+// FIXME: Revert on int value 0 does not give 0 (since min != - max; idem for float etc.)
+
+
+
+namespace mln
+{
+
+ namespace arith
+ {
+
+ /*! Point-wise reversion of image \p input.
+ *
+ * \param[in] input the input image.
+ * \param[out] output The result image.
+ *
+ * \pre \p output.domain = \p input.domain
+ */
+ template <typename I, typename O>
+ void revert(const Image<I>& input, Image<O>& output);
+
+
+ /*! Point-wise in-place reversion of image \p input.
+ *
+ * \param[in,out] input The target image.
+ *
+ * It performs: \n
+ * for all p of input.domain \n
+ * input(p) = min + (max - input(p))
+ */
+ template <typename I>
+ void revert_inplace(Image<I>& input);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace impl
+ {
+
+ template <typename I, typename O>
+ void revert_(const Image<I>& input_, Image<O>& output_)
+ {
+ const I& input = exact(input_);
+ O& output = exact(output_);
+ typedef mln_value(I) V;
+ mln_piter(I) p(input.domain());
+ for_all(p)
+ output(p) = mln_min(V) + (mln_max(V) - input(p));
+ }
+
+ template <typename I, typename O>
+ void revert_(const Fast_Image<I>& input, Fast_Image<O>& output)
+ {
+ typedef mln_value(I) V;
+ mln_pixter(const I) ip(exact(input));
+ mln_pixter(O) op(exact(output));
+ for_all_2(ip, op)
+ op.val() = mln_min(V) + (mln_max(V) - op.val());
+ }
+
+ } // end of namespace mln::arith::impl
+
+
+ // Facades.
+
+ template <typename I, typename O>
+ void revert(const Image<I>& input, Image<O>& output)
+ {
+ mln_precondition(exact(output).domain() = exact(input).domain());
+ impl::revert_(exact(input), exact(output));
+ }
+
+ template <typename I>
+ void revert_inplace(Image<I>& input)
+ {
+ mln_precondition(exact(input).has_data());
+ impl::revert_(exact(input), exact(input));
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::arith
+
+} // end of namespace mln
+
+
+#endif // ! MLN_ARITH_REVERT_HH
Index: mln/logical/and.hh
--- mln/logical/and.hh (revision 1060)
+++ mln/logical/and.hh (working copy)
@@ -61,7 +61,7 @@
* \param[in] lhs First operand image.
* \param[in,out] rhs Second operand image.
*
- * This addition performs: \n
+ * It performs: \n
* for all p of rhs.domain \n
* lhs(p) = lhs(p) and rhs(p)
*
Index: mln/logical/and_not.hh
--- mln/logical/and_not.hh (revision 1060)
+++ mln/logical/and_not.hh (working copy)
@@ -61,7 +61,7 @@
* \param[in] lhs First operand image.
* \param[in,out] rhs Second operand image.
*
- * This addition performs: \n
+ * It performs: \n
* for all p of rhs.domain \n
* lhs(p) = lhs(p) and not rhs(p)
*
Index: mln/logical/or.hh
--- mln/logical/or.hh (revision 1060)
+++ mln/logical/or.hh (working copy)
@@ -61,7 +61,7 @@
* \param[in] lhs First operand image.
* \param[in,out] rhs Second operand image.
*
- * This addition performs: \n
+ * It performs: \n
* for all p of rhs.domain \n
* lhs(p) = lhs(p) or rhs(p)
*
Index: mln/logical/not.hh
--- mln/logical/not.hh (revision 0)
+++ mln/logical/not.hh (revision 0)
@@ -0,0 +1,120 @@
+// 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_LOGICAL_NOT_HH
+# define MLN_LOGICAL_NOT_HH
+
+/*! \file mln/logical/not.hh
+ *
+ * \brief Point-wise "logical not" of a binary image.
+ *
+ * \todo Add static assertion and save one iterator in in-place version.
+ */
+
+# include <mln/core/concept/image.hh>
+
+
+namespace mln
+{
+
+ namespace logical
+ {
+
+ /*! Point-wise "logical not" of image \p input.
+ *
+ * \param[in] input the input image.
+ * \param[out] output The result image.
+ *
+ * \pre \p output.domain = \p input.domain
+ */
+ template <typename I, typename O>
+ void not_(const Image<I>& input, Image<O>& output);
+
+
+ /*! Point-wise in-place "logical not" of image \p input.
+ *
+ * \param[in,out] input The target image.
+ *
+ * It performs: \n
+ * for all p of input.domain \n
+ * input(p) = not input(p)
+ */
+ template <typename I>
+ void not_inplace(Image<I>& input);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace impl
+ {
+
+ template <typename I, typename O>
+ void not__(const Image<I>& input_, Image<O>& output_)
+ {
+ const I& input = exact(input_);
+ O& output = exact(output_);
+ mln_piter(I) p(input.domain());
+ for_all(p)
+ output(p) = ! input(p);
+ }
+
+ template <typename I, typename O>
+ void not__(const Fast_Image<I>& input, Fast_Image<O>& output)
+ {
+ mln_pixter(const I) ip(exact(input));
+ mln_pixter(O) op(exact(output));
+ for_all_2(ip, op)
+ op.val() = ! ip.val();
+ }
+
+ } // end of namespace mln::logical::impl
+
+
+ // Facades.
+
+ template <typename I, typename O>
+ void not_(const Image<I>& input, Image<O>& output)
+ {
+ mln_precondition(exact(output).domain() = exact(input).domain());
+ impl::not__(exact(input), exact(output));
+ }
+
+ template <typename I>
+ void not_inplace(Image<I>& input)
+ {
+ mln_precondition(exact(input).has_data());
+ impl::not__(exact(input), exact(input));
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::logical
+
+} // end of namespace mln
+
+
+#endif // ! MLN_LOGICAL_NOT_HH
Index: mln/value/int_s.hh
--- mln/value/int_s.hh (revision 1060)
+++ mln/value/int_s.hh (working copy)
@@ -71,6 +71,9 @@
/// Constructor from an integer.
int_s(int i);
+ /// Assignment from an integer.
+ int_s<n>& operator=(int i);
+
/// Negation.
int_s<n> operator-() const;
@@ -135,6 +138,16 @@
}
template <unsigned n>
+ int_s<n>&
+ int_s<n>::operator=(int i)
+ {
+ mln_precondition(i >= mln_min(enc));
+ mln_precondition(i <= mln_max(enc));
+ this->v_ = i;
+ return *this;
+ }
+
+ template <unsigned n>
int_s<n>
int_s<n>::operator-() const
{
Index: mln/value/int_u.hh
--- mln/value/int_u.hh (revision 1060)
+++ mln/value/int_u.hh (working copy)
@@ -71,6 +71,9 @@
/// Constructor from an integer.
int_u(int i);
+ /// Assignment from an integer.
+ int_u<n>& operator=(int i);
+
/// Zero value.
static const int_u<n> zero;
@@ -132,6 +135,16 @@
template <unsigned n>
int_u<n>&
+ int_u<n>::operator=(int i)
+ {
+ mln_precondition(i >= 0);
+ mln_precondition(i <= mln_max(enc));
+ this->v_ = i;
+ return *this;
+ }
+
+ template <unsigned n>
+ int_u<n>&
int_u<n>::operator+=(int i)
{
mln_precondition(long(this->v_) + i >= 0);
https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Add morphology plus and minus.
* tests/erosion.cc: Rename as...
* tests/morpho_erosion.cc: ...this.
* mln/geom/pmin_pmax.hh: Fix.
* mln/morpho/plus.hh: New.
* mln/morpho/minus.hh: New.
* mln/logical: New.
* mln/logical/and.hh: New.
* mln/logical/and_not.hh: New.
* mln/logical/or.hh: New.
* mln/morpho/includes.hh,
* mln/morpho/gradient.hh,
* mln/morpho/contrast.hh,
* mln/morpho/top_hat.hh: Update.
mln/geom/pmin_pmax.hh | 4 -
mln/logical/and.hh | 127 ++++++++++++++++++++++++++++++++++++++++++++++++
mln/logical/and_not.hh | 127 ++++++++++++++++++++++++++++++++++++++++++++++++
mln/logical/or.hh | 127 ++++++++++++++++++++++++++++++++++++++++++++++++
mln/morpho/contrast.hh | 4 -
mln/morpho/gradient.hh | 6 +-
mln/morpho/includes.hh | 5 -
mln/morpho/minus.hh | 111 +++++++++++++++++++++++++++++++++++++++++
mln/morpho/plus.hh | 108 ++++++++++++++++++++++++++++++++++++++++
mln/morpho/top_hat.hh | 6 +-
tests/morpho_erosion.cc | 2
11 files changed, 613 insertions(+), 14 deletions(-)
Index: tests/morpho_erosion.cc
--- tests/morpho_erosion.cc (revision 1059)
+++ tests/morpho_erosion.cc (working copy)
@@ -25,7 +25,7 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-/*! \file tests/erosion.cc
+/*! \file tests/morpho_erosion.cc
*
* \brief Test on mln::morpho::erosion.
*/
Index: mln/geom/pmin_pmax.hh
--- mln/geom/pmin_pmax.hh (revision 1059)
+++ mln/geom/pmin_pmax.hh (working copy)
@@ -108,7 +108,7 @@
{
typedef mln_point(I) P;
std::pair<P, P> tmp;
- pmin_pmax(p, tmp.first, tmp.second); // calls the previous version
+ pmin_pmax(p, tmp.first, tmp.second); // Calls the previous version.
return tmp;
}
@@ -156,7 +156,7 @@
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
+ pmin_pmax(s, tmp.first, tmp.second); // Calls the previous version.
return tmp;
}
Index: mln/morpho/plus.hh
--- mln/morpho/plus.hh (revision 0)
+++ mln/morpho/plus.hh (revision 0)
@@ -0,0 +1,108 @@
+// 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_PLUS_HH
+# define MLN_MORPHO_PLUS_HH
+
+# include <mln/level/compare.hh>
+# include <mln/logical/or.hh>
+# include <mln/arith/plus.hh>
+
+
+namespace mln
+{
+
+ namespace morpho
+ {
+
+ /*! Morphological plus: either a "logical or" (if morpho on sets)
+ * or an "arithmetical plus" (if morpho on functions).
+ */
+ template <typename I, typename J, typename O>
+ void plus(const Image<I>& lhs, const Image<J>& rhs,
+ Image<O>& output);
+
+ /*! Morphological plus, inplace version: either a "logical or" (if
+ * morpho on sets) or an "arithmetical plus" (if morpho on
+ * functions).
+ */
+ template <typename I, typename J>
+ void plus_inplace(Image<I>& lhs, const Image<J>& rhs);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace impl
+ {
+
+ template <typename I, typename J, typename O>
+ void plus_(value::binary_kind, // binary => morphology on sets
+ const Image<I>& lhs, const Image<J>& rhs,
+ Image<O>& output)
+ {
+ return logical::or_(lhs, rhs, output);
+ }
+
+ template <typename K, typename I, typename J, typename O>
+ void plus_(K, // otherwise => morphology on functions
+ const Image<I>& lhs, const Image<J>& rhs,
+ Image<O>& output)
+ {
+ return arith::plus(lhs, rhs, output);
+ }
+
+ } // end of namespace mln::morpho::impl
+
+
+ // Facades.
+
+ template <typename I, typename J, typename O>
+ void plus(const Image<I>& lhs, const Image<J>& rhs, Image<O>& output)
+ {
+ mln_precondition(exact(rhs).domain() = exact(lhs).domain());
+ mln_precondition(exact(output).domain() = exact(lhs).domain());
+
+ impl::plus_(mln_value_kind(I)(), exact(lhs), exact(rhs), output);
+
+ mln_postcondition(output <= lhs);
+ }
+
+ template <typename I, typename J>
+ void plus_inplace(Image<I>& lhs, const Image<J>& rhs)
+ {
+ mln_precondition(exact(rhs).domain() = exact(lhs).domain());
+ morpho::plus(lhs, rhs, lhs); // Calls the previous version.
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::morpho
+
+} // end of namespace mln
+
+
+#endif // ! MLN_MORPHO_PLUS_HH
Index: mln/morpho/includes.hh
--- mln/morpho/includes.hh (revision 1059)
+++ mln/morpho/includes.hh (working copy)
@@ -40,9 +40,6 @@
# 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>
@@ -54,6 +51,8 @@
# include <mln/morpho/dilation.hh>
# include <mln/morpho/erosion.hh>
+# include <mln/morpho/minus.hh>
+# include <mln/morpho/plus.hh>
#endif // ! MLN_MORPHO_INCLUDES_HH
Index: mln/morpho/minus.hh
--- mln/morpho/minus.hh (revision 0)
+++ mln/morpho/minus.hh (revision 0)
@@ -0,0 +1,111 @@
+// 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_MINUS_HH
+# define MLN_MORPHO_MINUS_HH
+
+# include <mln/level/compare.hh>
+# include <mln/logical/and_not.hh>
+# include <mln/arith/minus.hh>
+
+
+namespace mln
+{
+
+ namespace morpho
+ {
+
+ /*! Morphological minus: either a logical "and not" (if morpho on
+ * sets) or an arithmetical minus (if morpho on functions).
+ */
+ template <typename I, typename J, typename O>
+ void minus(const Image<I>& lhs, const Image<J>& rhs,
+ Image<O>& output);
+
+ /*! Morphological minus, inplace version: either a logical "and
+ * not" (if morpho on sets) or an arithmetical minus (if morpho
+ * on functions).
+ */
+ template <typename I, typename J>
+ void minus_inplace(Image<I>& lhs, const Image<J>& rhs);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace impl
+ {
+
+ template <typename I, typename J, typename O>
+ void minus_(value::binary_kind, // binary => morphology on sets
+ const Image<I>& lhs, const Image<J>& rhs,
+ Image<O>& output)
+ {
+ return logical::and_not(lhs, rhs, output);
+ }
+
+ template <typename K, typename I, typename J, typename O>
+ void minus_(K, // otherwise => morphology on functions
+ const Image<I>& lhs, const Image<J>& rhs,
+ Image<O>& output)
+ {
+ return arith::minus(lhs, rhs, output);
+ }
+
+ } // end of namespace mln::morpho::impl
+
+
+ // Facades.
+
+ template <typename I, typename J, typename O>
+ void minus(const Image<I>& lhs, const Image<J>& rhs, Image<O>& output)
+ {
+ mln_precondition(exact(rhs).domain() = exact(lhs).domain());
+ mln_precondition(exact(output).domain() = exact(lhs).domain());
+ mln_precondition(rhs <= lhs);
+
+ impl::minus_(mln_value_kind(I)(), exact(lhs), exact(rhs), output);
+
+ mln_postcondition(output <= lhs);
+ }
+
+ template <typename I, typename J>
+ void minus_inplace(Image<I>& lhs, const Image<J>& rhs)
+ {
+ mln_precondition(exact(rhs).domain() = exact(lhs).domain());
+ mln_precondition(rhs <= lhs);
+
+ morpho::minus(lhs, rhs, lhs); // Calls the previous version.
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::morpho
+
+} // end of namespace mln
+
+
+#endif // ! MLN_MORPHO_MINUS_HH
Index: mln/morpho/gradient.hh
--- mln/morpho/gradient.hh (revision 1059)
+++ mln/morpho/gradient.hh (working copy)
@@ -86,7 +86,7 @@
dilation(input, win, output); // output = dilation
O temp(input.domain());
erosion(input, win, temp); // temp = erosion
- arith::minus_inplace(output, temp); // now output = dilation - erosion
+ morpho::minus_inplace(output, temp); // now output = dilation - erosion
mln_postcondition(test::positive(output));
}
@@ -104,7 +104,7 @@
O temp(input.domain());
erosion(input, win, temp); // temp = erosion
- arith::minus(input, temp, output); // output = input - erosion
+ morpho::minus(input, temp, output); // output = input - erosion
mln_postcondition(test::positive(output));
}
@@ -121,7 +121,7 @@
mln_precondition(! win.is_empty());
dilation(input, win, output); // output = dilation
- arith::minus_inplace(output, input); // now output = dilation - input
+ morpho::minus_inplace(output, input); // now output = dilation - input
mln_postcondition(test::positive(output));
}
Index: mln/morpho/contrast.hh
--- mln/morpho/contrast.hh (revision 1059)
+++ mln/morpho/contrast.hh (working copy)
@@ -66,10 +66,10 @@
mln_precondition(! win.is_empty());
top_hat_white(input, win, output); // output = wth
- arith::plus_inplace(output, input); // now output = wth + input
+ morpho::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
+ morpho::minus_inplace(output, temp); // now output = wth + input - bth
}
# endif // ! MLN_INCLUDE_ONLY
Index: mln/morpho/top_hat.hh
--- mln/morpho/top_hat.hh (revision 1059)
+++ mln/morpho/top_hat.hh (working copy)
@@ -89,7 +89,7 @@
O temp(input.domain());
opening(input, win, temp); // temp = opening
- arith::minus(input, temp, output); // output = input - opening
+ morpho::minus(input, temp, output); // output = input - opening
mln_postcondition(test::positive(output));
}
@@ -105,7 +105,7 @@
mln_precondition(! win.is_empty());
closing(input, win, output); // output = closing
- arith::minus_inplace(output, input); // now output = closing - input
+ morpho::minus_inplace(output, input); // now output = closing - input
mln_postcondition(test::positive(output));
}
@@ -123,7 +123,7 @@
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
+ morpho::minus_inplace(output, temp); // now output = closing - opening
mln_postcondition(test::positive(output));
}
Index: mln/logical/and.hh
--- mln/logical/and.hh (revision 0)
+++ mln/logical/and.hh (revision 0)
@@ -0,0 +1,127 @@
+// 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_LOGICAL_AND_HH
+# define MLN_LOGICAL_AND_HH
+
+/*! \file mln/logical/and.hh
+ *
+ * \brief Point-wise "logical and" between binary images.
+ *
+ * \todo Add static assertion and save one iterator in in-place version.
+ */
+
+# include <mln/core/concept/image.hh>
+
+
+namespace mln
+{
+
+ namespace logical
+ {
+
+ /*! Point-wise "logical and" between images \p lhs and \p rhs.
+ *
+ * \param[in] lhs First operand image.
+ * \param[in] rhs Second operand image.
+ * \param[out] output The result image.
+ *
+ * \pre \p output.domain = \p lhs.domain = \p rhs.domain
+ */
+ template <typename L, typename R, typename O>
+ void and_(const Image<L>& lhs, const Image<R>& rhs, Image<O>& output);
+
+
+ /*! Point-wise in-place "logical and" of image \p rhs in image \p lhs.
+ *
+ * \param[in] lhs First operand image.
+ * \param[in,out] rhs Second operand image.
+ *
+ * This addition performs: \n
+ * for all p of rhs.domain \n
+ * lhs(p) = lhs(p) and rhs(p)
+ *
+ * \pre \p rhs.domain <= \p lhs.domain
+ */
+ template <typename L, typename R>
+ void and_inplace(Image<L>& lhs, const Image<R>& rhs);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace impl
+ {
+
+ template <typename L, typename R, typename O>
+ void and__(const Image<L>& lhs_, const Image<R>& rhs_, Image<O>& output_)
+ {
+ const L& lhs = exact(lhs_);
+ const R& rhs = exact(rhs_);
+ O& output = exact(output_);
+ mln_piter(L) p(lhs.domain());
+ for_all(p)
+ output(p) = lhs(p) && rhs(p);
+ }
+
+ template <typename L, typename R, typename O>
+ void and__(const Fast_Image<L>& lhs, const Fast_Image<R>& rhs, Fast_Image<O>& output)
+ {
+ mln_pixter(const L) lp(exact(lhs));
+ mln_pixter(const R) rp(exact(rhs));
+ mln_pixter(O) op(exact(output));
+ for_all_3(lp, rp, op)
+ op.val() = lp.val() && rp.val();
+ }
+
+ } // end of namespace mln::logical::impl
+
+
+ // Facades.
+
+ template <typename L, typename R, typename O>
+ void and_(const Image<L>& lhs, const Image<R>& rhs, Image<O>& output)
+ {
+ mln_precondition(exact(rhs).domain() = exact(lhs).domain());
+ mln_precondition(exact(output).domain() = exact(lhs).domain());
+ impl::and__(exact(lhs), exact(rhs), exact(output));
+ }
+
+ template <typename L, typename R>
+ void and_inplace(Image<L>& lhs, const Image<R>& rhs)
+ {
+ mln_precondition(exact(rhs).domain() <= exact(lhs).domain());
+ impl::and__(exact(lhs), exact(rhs), exact(lhs));
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::logical
+
+} // end of namespace mln
+
+
+#endif // ! MLN_LOGICAL_AND_HH
Index: mln/logical/and_not.hh
--- mln/logical/and_not.hh (revision 0)
+++ mln/logical/and_not.hh (revision 0)
@@ -0,0 +1,127 @@
+// 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_LOGICAL_AND_NOT_HH
+# define MLN_LOGICAL_AND_NOT_HH
+
+/*! \file mln/logical/and_not.hh
+ *
+ * \brief Point-wise logical "and not" between binary images.
+ *
+ * \todo Add static assertion and save one iterator in in-place version.
+ */
+
+# include <mln/core/concept/image.hh>
+
+
+namespace mln
+{
+
+ namespace logical
+ {
+
+ /*! Point-wise logical "and not" between images \p lhs and \p rhs.
+ *
+ * \param[in] lhs First operand image.
+ * \param[in] rhs Second operand image.
+ * \param[out] output The result image.
+ *
+ * \pre \p output.domain = \p lhs.domain = \p rhs.domain
+ */
+ template <typename L, typename R, typename O>
+ void and_not(const Image<L>& lhs, const Image<R>& rhs, Image<O>& output);
+
+
+ /*! Point-wise in-place logical "and not" of image \p rhs in image \p lhs.
+ *
+ * \param[in] lhs First operand image.
+ * \param[in,out] rhs Second operand image.
+ *
+ * This addition performs: \n
+ * for all p of rhs.domain \n
+ * lhs(p) = lhs(p) and not rhs(p)
+ *
+ * \pre \p rhs.domain <= \p lhs.domain
+ */
+ template <typename L, typename R>
+ void and_not_inplace(Image<L>& lhs, const Image<R>& rhs);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace impl
+ {
+
+ template <typename L, typename R, typename O>
+ void and_not_(const Image<L>& lhs_, const Image<R>& rhs_, Image<O>& output_)
+ {
+ const L& lhs = exact(lhs_);
+ const R& rhs = exact(rhs_);
+ O& output = exact(output_);
+ mln_piter(L) p(lhs.domain());
+ for_all(p)
+ output(p) = lhs(p) && ! rhs(p);
+ }
+
+ template <typename L, typename R, typename O>
+ void and_not_(const Fast_Image<L>& lhs, const Fast_Image<R>& rhs, Fast_Image<O>& output)
+ {
+ mln_pixter(const L) lp(exact(lhs));
+ mln_pixter(const R) rp(exact(rhs));
+ mln_pixter(O) op(exact(output));
+ for_all_3(lp, rp, op)
+ op.val() = lp.val() && ! rp.val();
+ }
+
+ } // end of namespace mln::logical::impl
+
+
+ // Facades.
+
+ template <typename L, typename R, typename O>
+ void and_not(const Image<L>& lhs, const Image<R>& rhs, Image<O>& output)
+ {
+ mln_precondition(exact(rhs).domain() = exact(lhs).domain());
+ mln_precondition(exact(output).domain() = exact(lhs).domain());
+ impl::and_not_(exact(lhs), exact(rhs), exact(output));
+ }
+
+ template <typename L, typename R>
+ void and_not_inplace(Image<L>& lhs, const Image<R>& rhs)
+ {
+ mln_precondition(exact(rhs).domain() <= exact(lhs).domain());
+ impl::and_not_(exact(lhs), exact(rhs), exact(lhs));
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::logical
+
+} // end of namespace mln
+
+
+#endif // ! MLN_LOGICAL_AND_NOT_HH
Index: mln/logical/or.hh
--- mln/logical/or.hh (revision 0)
+++ mln/logical/or.hh (revision 0)
@@ -0,0 +1,127 @@
+// 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_LOGICAL_OR_HH
+# define MLN_LOGICAL_OR_HH
+
+/*! \file mln/logical/or.hh
+ *
+ * \brief Point-wise "logical or" between binary images.
+ *
+ * \todo Add static assertion and save one iterator in in-place version.
+ */
+
+# include <mln/core/concept/image.hh>
+
+
+namespace mln
+{
+
+ namespace logical
+ {
+
+ /*! Point-wise "logical or" between images \p lhs and \p rhs.
+ *
+ * \param[in] lhs First operand image.
+ * \param[in] rhs Second operand image.
+ * \param[out] output The result image.
+ *
+ * \pre \p output.domain = \p lhs.domain = \p rhs.domain
+ */
+ template <typename L, typename R, typename O>
+ void or_(const Image<L>& lhs, const Image<R>& rhs, Image<O>& output);
+
+
+ /*! Point-wise in-place "logical or" of image \p rhs in image \p lhs.
+ *
+ * \param[in] lhs First operand image.
+ * \param[in,out] rhs Second operand image.
+ *
+ * This addition performs: \n
+ * for all p of rhs.domain \n
+ * lhs(p) = lhs(p) or rhs(p)
+ *
+ * \pre \p rhs.domain <= \p lhs.domain
+ */
+ template <typename L, typename R>
+ void or_inplace(Image<L>& lhs, const Image<R>& rhs);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace impl
+ {
+
+ template <typename L, typename R, typename O>
+ void or__(const Image<L>& lhs_, const Image<R>& rhs_, Image<O>& output_)
+ {
+ const L& lhs = exact(lhs_);
+ const R& rhs = exact(rhs_);
+ O& output = exact(output_);
+ mln_piter(L) p(lhs.domain());
+ for_all(p)
+ output(p) = lhs(p) || rhs(p);
+ }
+
+ template <typename L, typename R, typename O>
+ void or__(const Fast_Image<L>& lhs, const Fast_Image<R>& rhs, Fast_Image<O>& output)
+ {
+ mln_pixter(const L) lp(exact(lhs));
+ mln_pixter(const R) rp(exact(rhs));
+ mln_pixter(O) op(exact(output));
+ for_all_3(lp, rp, op)
+ op.val() = lp.val() || rp.val();
+ }
+
+ } // end of namespace mln::logical::impl
+
+
+ // Facades.
+
+ template <typename L, typename R, typename O>
+ void or_(const Image<L>& lhs, const Image<R>& rhs, Image<O>& output)
+ {
+ mln_precondition(exact(rhs).domain() = exact(lhs).domain());
+ mln_precondition(exact(output).domain() = exact(lhs).domain());
+ impl::or__(exact(lhs), exact(rhs), exact(output));
+ }
+
+ template <typename L, typename R>
+ void or_inplace(Image<L>& lhs, const Image<R>& rhs)
+ {
+ mln_precondition(exact(rhs).domain() <= exact(lhs).domain());
+ impl::or__(exact(lhs), exact(rhs), exact(lhs));
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::logical
+
+} // end of namespace mln
+
+
+#endif // ! MLN_LOGICAL_OR_HH