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