Commit 66f4ade1 authored by Thierry Geraud's avatar Thierry Geraud
Browse files

Augment morpho and add saturation for int-like types.

	* mln/arith/minus.hh (minus_inplace): New.
	* mln/arith/plus.hh (plus_inplace): New.
	* mln/fun/v2v/saturate.hh: New.
	* mln/level/abs.hh: New.
	* mln/level/saturate.hh: New.
	* mln/linear/sobel.hh: Update.
	* mln/math/round.hh (round_): Rename as...
	(round): ...this.
	* tests/convolve.cc,
	* tests/line_convolve.cc,
	* tests/sobel.cc: Update.

	* mln/linear/line_convolve.hh,
	* mln/linear/line_x2_convolve.hh,
	* mln/make/w_window_line.hh: Unconst array literals to help
	g++-2.95.

	* mln/core/concept/function.hh (Function_v2b): New.
	* mln/core/macros.hh (mln_value_): New.
	* mln/fun/ops.hh (l_, r_, f_): Add const.
	(mln_decl_binary_expr_): Use 'Out' part of fun type name.
	(mln_decl_unary_expr_): Likewise.
	New overload for "v2v -> v2b" operators.
	* mln/fun/v2v/id.hh: New.
	* mln/level/assign.hh,
	* mln/level/fill.hh: Add todo.
	* mln/morpho/erosion.hh: Update.

	* mln/morpho/includes.hh,
	* mln/morpho/closing.hh,
	* mln/morpho/dilation.hh
	* mln/morpho/gradient.hh
	* mln/morpho/opening.hh: New.
	* mln/test: New directory.
	* mln/test/positive.hh,
	* mln/test/predicate.hh,
	* tests/morpho_gradient.cc: New.


git-svn-id: https://svn.lrde.epita.fr/svn/oln/trunk@1056 4aad255d-cdde-0310-9447-f3009e2ae8c0
parent 2e66d4d3
2007-08-27 Thierry Geraud <thierry.geraud@lrde.epita.fr>
Augment morpho and add saturation for int-like types.
* mln/arith/minus.hh (minus_inplace): New.
* mln/arith/plus.hh (plus_inplace): New.
* mln/fun/v2v/saturate.hh: New.
* mln/level/abs.hh: New.
* mln/level/saturate.hh: New.
* mln/linear/sobel.hh: Update.
* mln/math/round.hh (round_): Rename as...
(round): ...this.
* tests/convolve.cc,
* tests/line_convolve.cc,
* tests/sobel.cc: Update.
* mln/linear/line_convolve.hh,
* mln/linear/line_x2_convolve.hh,
* mln/make/w_window_line.hh: Unconst array literals to help
g++-2.95.
* mln/core/concept/function.hh (Function_v2b): New.
* mln/core/macros.hh (mln_value_): New.
* mln/fun/ops.hh (l_, r_, f_): Add const.
(mln_decl_binary_expr_): Use 'Out' part of fun type name.
(mln_decl_unary_expr_): Likewise.
New overload for "v2v -> v2b" operators.
* mln/fun/v2v/id.hh: New.
* mln/level/assign.hh,
* mln/level/fill.hh: Add todo.
* mln/morpho/erosion.hh: Update.
* mln/morpho/includes.hh,
* mln/morpho/closing.hh,
* mln/morpho/dilation.hh
* mln/morpho/gradient.hh
* mln/morpho/opening.hh: New.
* mln/test: New directory.
* mln/test/positive.hh,
* mln/test/predicate.hh,
* tests/morpho_gradient.cc: New.
2007-08-27 Thierry Geraud <thierry.geraud@lrde.epita.fr>
Augment tools for linear filtering; add sobel.
......
......@@ -54,22 +54,84 @@ namespace mln
void minus(const Image<L>& lhs, const Image<R>& rhs, Image<O>& output);
/*! Point-wise substraction of image \p lhs in image \p rhs.
*
* \param[in,out] lhs First operand image (subject to substraction).
* \param[in] rhs Second operand image (to be substracted to \p lhs).
*
* This substraction performs: \n
* for all p of rhs.domain \n
* lhs(p) -= rhs(p)
*
* \pre \p rhs.domain <= \p lhs.domain
*/
template <typename L, typename R>
void minus_inplace(Image<L>& lhs, const Image<R>& rhs);
# ifndef MLN_INCLUDE_ONLY
template <typename L, typename R, typename O>
void minus(const Image<L>& lhs_, const Image<R>& rhs_, Image<O>& output_)
namespace impl
{
const L& lhs = exact(lhs_);
const R& rhs = exact(rhs_);
O& output = exact(output_);
mln_precondition(rhs.domain() == lhs.domain());
mln_precondition(output.domain() == lhs.domain());
template <typename L, typename R, typename O>
void minus_(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 minus_(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();
}
template <typename L, typename R>
void minus_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)
lhs(p) -= rhs(p);
}
template <typename L, typename R>
void minus_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)
lp.val() -= rp.val();
}
} // end of namespace mln::arith::impl
// Facades.
mln_piter(I) p(output.domain());
for_all(p)
output(p) = lhs(p) - rhs(p);
template <typename L, typename R, typename O>
void minus(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::minus_(exact(lhs), exact(rhs), exact(output));
}
template <typename L, typename R>
void minus_inplace(Image<L>& lhs, const Image<R>& rhs)
{
mln_precondition(exact(rhs).domain() <= exact(lhs).domain());
impl::minus_inplace_(exact(lhs), exact(rhs));
}
# endif // ! MLN_INCLUDE_ONLY
......
......@@ -54,6 +54,20 @@ namespace mln
void plus(const Image<L>& lhs, const Image<R>& rhs, Image<O>& output);
/*! Point-wise addition of image \p rhs in image \p lhs.
*
* \param[in] lhs First operand image (subject to addition).
* \param[in,out] rhs Second operand image (to be added to \p lhs).
*
* This addition performs: \n
* for all p of rhs.domain \n
* lhs(p) += rhs(p)
*
* \pre \p rhs.domain <= \p lhs.domain
*/
template <typename L, typename R>
void plus_inplace(Image<L>& lhs, const Image<R>& rhs);
# ifndef MLN_INCLUDE_ONLY
......@@ -81,10 +95,29 @@ namespace mln
op.val() = lp.val() + rp.val();
}
template <typename L, typename R>
void plus_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)
lhs(p) += rhs(p);
}
template <typename L, typename R>
void plus_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)
lp.val() += rp.val();
}
} // end of namespace mln::arith::impl
// Facade.
// Facades.
template <typename L, typename R, typename O>
void plus(const Image<L>& lhs, const Image<R>& rhs, Image<O>& output)
......@@ -94,6 +127,13 @@ namespace mln
impl::plus_(exact(lhs), exact(rhs), exact(output));
}
template <typename L, typename R>
void plus_inplace(Image<L>& lhs, const Image<R>& rhs)
{
mln_precondition(exact(rhs).domain() <= exact(lhs).domain());
impl::plus_inplace_(exact(lhs), exact(rhs));
}
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln::arith
......
......@@ -53,6 +53,7 @@ namespace mln
*/
protected:
Function();
Function(const Function&);
};
......@@ -65,6 +66,7 @@ namespace mln
{
protected:
Function_v2v();
Function_v2v(const Function_v2v&);
};
......@@ -77,6 +79,7 @@ namespace mln
{
protected:
Function_i2v();
Function_i2v(const Function_i2v&);
};
......@@ -85,10 +88,25 @@ namespace mln
/// Base class for implementation of function-objects from point to
/// value.
template <typename E>
struct Function_p2v : public Function_v2v<E>
struct Function_p2v : public virtual Function_v2v<E>
{
protected:
Function_p2v();
Function_p2v(const Function_p2v&);
};
// Value -> bool.
/// Base class for implementation of function-objects from value to
/// bool.
template <typename E>
struct Function_v2b : public virtual Function_v2v<E>
{
typedef bool result;
protected:
Function_v2b();
Function_v2b(const Function_v2b&);
};
......@@ -97,11 +115,13 @@ namespace mln
/// Base class for implementation of function-objects from point to
/// bool.
template <typename E>
struct Function_p2b : public Function_p2v<E>
struct Function_p2b : public Function_p2v<E>,
public Function_v2b<E>
{
typedef bool result;
protected:
Function_p2b();
Function_p2b(const Function_p2b&);
};
......@@ -114,6 +134,7 @@ namespace mln
{
protected:
Function_p2p();
Function_p2p(const Function_p2p&);
};
......@@ -126,26 +147,71 @@ namespace mln
typedef mln_result(E) result;
}
template <typename E>
Function<E>::Function(const Function<E>&)
{
}
template <typename E>
Function_v2v<E>::Function_v2v()
{
}
template <typename E>
Function_v2v<E>::Function_v2v(const Function_v2v<E>&)
{
}
template <typename E>
Function_i2v<E>::Function_i2v()
{
}
template <typename E>
Function_i2v<E>::Function_i2v(const Function_i2v<E>&)
{
}
template <typename E>
Function_p2v<E>::Function_p2v()
{
}
template <typename E>
Function_p2v<E>::Function_p2v(const Function_p2v<E>&)
{
}
template <typename E>
Function_v2b<E>::Function_v2b()
{
}
template <typename E>
Function_v2b<E>::Function_v2b(const Function_v2b<E>&)
{
}
template <typename E>
Function_p2b<E>::Function_p2b()
{
}
template <typename E>
Function_p2b<E>::Function_p2b(const Function_p2b<E>&)
{
}
template <typename E>
Function_p2p<E>::Function_p2p()
{
}
template <typename E>
Function_p2p<E>::Function_p2p(const Function_p2p<E>&)
{
}
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln
......
......@@ -148,6 +148,7 @@
/// Shortcut to access the value type associated to T.
# define mln_value(T) typename T::value
# define mln_value_(T) T::value
/// Shortcut to the kind of values for an image with type \c I.
# define mln_value_kind(I) typename mln::value::props< mln_value(I) >::kind
......
......@@ -51,11 +51,13 @@ namespace mln
// Function_v2v
// |
// + -- Function_i2v
// |
// + -- Function_p2v
// |
// + -- Function_p2b
// + ---------------------- Function_v2b
// | |
// + -- Function_i2v |
// | |
// + -- Function_p2v |
// | |
// + -- Function_p2b -- +
// |
// + -- Function_p2p
......@@ -69,9 +71,9 @@ namespace mln
template <int arg, int res, typename E> struct helper_selector_;
// no b2* type => v2v type
// b2* => v2v type, except for v2b
template <typename E>
struct helper_selector_< b_, b_, E > { typedef Function_v2v<E> ret; };
struct helper_selector_< b_, b_, E > { typedef Function_v2b<E> ret; };
template <typename E>
struct helper_selector_< b_, i_, E > { typedef Function_v2v<E> ret; };
template <typename E>
......@@ -79,7 +81,7 @@ namespace mln
template <typename E>
struct helper_selector_< b_, v_, E > { typedef Function_v2v<E> ret; };
// i2* => only i2v type
// i2* => i2v type
template <typename E>
struct helper_selector_< i_, b_, E > { typedef Function_i2v<E> ret; };
template <typename E>
......@@ -99,9 +101,9 @@ namespace mln
template <typename E>
struct helper_selector_< p_, v_, E > { typedef Function_p2v<E> ret; };
// v2* => only v2v type
// v2* => v2v type, except for v2b
template <typename E>
struct helper_selector_< v_, b_, E > { typedef Function_v2v<E> ret; };
struct helper_selector_< v_, b_, E > { typedef Function_v2b<E> ret; };
template <typename E>
struct helper_selector_< v_, i_, E > { typedef Function_v2v<E> ret; };
template <typename E>
......
......@@ -34,6 +34,7 @@
*/
# include <mln/core/concept/function.hh>
# include <mln/fun/internal/selector.hh>
......@@ -43,11 +44,12 @@
{ \
\
template <typename L, typename R> \
struct Name##_expr_ : public Function_##Out < Name##_expr_<L,R> > \
struct Name##_##Out##_expr_ \
: public Function_##Out < Name##_##Out##_expr_<L,R> > \
{ \
typedef mln_result(L) result; \
\
Name##_expr_(const L& l, const R& r) \
Name##_##Out##_expr_(const L& l, const R& r) \
: l_(l), r_(r) \
{ \
} \
......@@ -59,64 +61,66 @@
} \
\
protected: \
L l_; \
R r_; \
const L l_; \
const R r_; \
}; \
\
} \
\
template <typename L, typename R> \
fun::Name##_expr_<L,R> \
fun::Name##_##Out##_expr_<L,R> \
operator Symbol (const Function_##In<L>& lhs, const Function_##In<R>& rhs) \
{ \
fun::Name##_expr_<L,R> tmp(exact(lhs), exact(rhs)); \
fun::Name##_##Out##_expr_<L,R> tmp(exact(lhs), exact(rhs)); \
return tmp; \
} \
\
struct dummy
# define mln_decl_unary_expr_(In, Out, Name, Symbol) \
\
namespace fun \
{ \
\
template <typename F> \
struct Name##_expr_ : public Function_##Out< Name##_expr_<F> > \
{ \
typedef mln_result(F) result; \
\
Name##_expr_(const F& f) \
: f_(f) \
{ \
} \
\
template <typename P> \
result operator()(const P& p) const \
{ \
return Symbol f_(p); \
} \
\
protected: \
F f_; \
}; \
\
} \
\
template <typename F> \
fun::Name##_expr_<F> \
operator Symbol (const Function_##In<F>& f) \
{ \
fun::Name##_expr_<F> tmp(exact(f)); \
return tmp; \
} \
\
# define mln_decl_unary_expr_(In, Out, Name, Symbol) \
\
namespace fun \
{ \
\
template <typename F> \
struct Name##_##Out##_expr_ \
: public Function_##Out< Name##_##Out##_expr_<F> > \
{ \
typedef mln_result(F) result; \
\
Name##_##Out##_expr_(const F& f) \
: f_(f) \
{ \
} \
\
template <typename P> \
result operator()(const P& p) const \
{ \
return Symbol f_(p); \
} \
\
protected: \
const F f_; \
}; \
\
} \
\
template <typename F> \
fun::Name##_##Out##_expr_<F> \
operator Symbol (const Function_##In<F>& f) \
{ \
fun::Name##_##Out##_expr_<F> tmp(exact(f)); \
return tmp; \
} \
\
struct dummy
namespace mln
{
// -> p2v
mln_decl_binary_expr_(p2v, p2b, equal, ==);
mln_decl_binary_expr_(p2v, p2b, not_equal, !=);
......@@ -141,6 +145,22 @@ namespace mln
mln_decl_unary_expr_(p2v, p2v, uplus, +);
mln_decl_unary_expr_(p2v, p2v, uminus, -);
// -> v2b
mln_decl_binary_expr_(v2v, v2b, equal, ==);
mln_decl_binary_expr_(v2v, v2b, not_equal, !=);
mln_decl_binary_expr_(v2v, v2b, less, <);
mln_decl_binary_expr_(v2v, v2b, less_or_equal, <=);
mln_decl_binary_expr_(v2v, v2b, greater_or_equal, >=);
mln_decl_binary_expr_(v2v, v2b, greater, >);
mln_decl_binary_expr_(v2b, v2b, and, &&);
mln_decl_binary_expr_(v2b, v2b, or, ||);
mln_decl_binary_expr_(v2b, v2b, xor, ^);
mln_decl_unary_expr_(v2b, v2b, not, !);
} // end of namespace mln
......
// 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_V2V_ID_HH
# define MLN_FUN_V2V_ID_HH
/*! \file mln/fun/id.hh
*
* \brief FIXME.
*/
# include <mln/fun/internal/selector.hh>
namespace mln
{
namespace fun
{
namespace v2v
{
// FIXME: Doc!
template <typename T>
struct id
: fun::internal::selector_<T, T, id<T> >::ret
{
typedef T result;
T operator()(const T& t) const;
};
# ifndef MLN_INCLUDE_ONLY
template <typename T>
T
id<T>::operator()(const T& t) const
{
return t;
}