Commit f5d52c2f authored by Thierry Geraud's avatar Thierry Geraud
Browse files

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.


git-svn-id: https://svn.lrde.epita.fr/svn/oln/trunk@1063 4aad255d-cdde-0310-9447-f3009e2ae8c0
parent e04278fb
2007-08-31 Thierry Geraud <thierry.geraud@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.
2007-08-30 Thierry Geraud <thierry.geraud@lrde.epita.fr>
Make operations on windows more explicit.
......
// 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
......@@ -95,7 +95,7 @@ namespace mln
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
......
// 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
// 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
// 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)
{