Index: ChangeLog
from Damien Thivolle <damien(a)lrde.epita.fr>
* oln/morpho/reconstruction.hh: Remove a comment.
* oln/morpho/hit_or_miss.hh: New. Hit or miss implementation.
* oln/arith/ops.hh: Add comment to make it compile with g++-3.4.
* oln/arith/min.hh: Add a template parameter.
* oln/arith/max.hh: Add a template parameter.
arith/max.hh | 38 +++++----
arith/min.hh | 38 +++++----
arith/ops.hh | 24 +++---
morpho/hit_or_miss.hh | 186 +++++++++++++++++++++++++++++++++++++++++++++++
morpho/reconstruction.hh | 2
5 files changed, 244 insertions(+), 44 deletions(-)
Index: oln/morpho/reconstruction.hh
--- oln/morpho/reconstruction.hh (revision 164)
+++ oln/morpho/reconstruction.hh (working copy)
@@ -45,8 +45,6 @@
# include <oln/utils/clone.hh>
-// FIXME: ADD TESTS !!!!
-
namespace oln {
Index: oln/morpho/hit_or_miss.hh
--- oln/morpho/hit_or_miss.hh (revision 0)
+++ oln/morpho/hit_or_miss.hh (revision 0)
@@ -0,0 +1,186 @@
+// Copyright (C) 2001, 2003, 2004, 2005 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, 59 Temple Place - Suite 330, 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 OLENA_MORPHO_HIT_OR_MISS_HH
+# define OLENA_MORPHO_HIT_OR_MISS_HH
+
+# include <oln/core/gen/image_with_nbh.hh>
+# include <oln/morpho/erosion.hh>
+# include <oln/morpho/dilation.hh>
+# include <oln/arith/min.hh>
+# include <oln/utils/invert.hh>
+
+namespace oln {
+
+ namespace tag {
+
+ // No tags yet
+
+ } // end of namespace oln::morpho::tag
+
+
+ namespace morpho {
+ template <typename I, typename W1, typename W2> struct hit_or_miss_ret;
+ } // end of namespace oln::morpho
+
+ // super_type
+
+ template <typename I, typename W1, typename W2>
+ struct set_super_type< morpho::hit_or_miss_ret<I, W1, W2> >
+ {
+ typedef oln_type_of(I, concrete) output_type;
+
+ typedef morpho::hit_or_miss_ret<I, W1, W2> self_type;
+ typedef abstract::image_unary_operator<output_type, I, self_type > ret;
+ };
+
+ namespace morpho {
+
+ // Reconstruction as a 'classical' procedure returning an image (do not
+ // use it; prefer morpho::hit_or_miss).
+
+ namespace proc {
+
+ // FIXME: ...
+
+ } // end of namespace oln::morpho::proc
+
+
+ template <typename I, typename W1, typename W2>
+ struct hit_or_miss_ret :
+ // FIXME: oln_super_of_
+ public oln::internal::get_super_type< hit_or_miss_ret<I, W1, W2>
>::ret
+ {
+ typedef hit_or_miss_ret<I, W1, W2> self_type;
+ typedef typename oln::internal::get_super_type<self_type>::ret super_type;
+ const W1& win1;
+ const W2& win2;
+
+ hit_or_miss_ret(const abstract::image<I>& input,
+ const abstract::regular_window<oln_type_of(I, grid), W1> win1,
+ const abstract::regular_window<oln_type_of(I, grid), W2> win2) :
+ super_type(input),
+ win1(win1.exact()),
+ win2(win2.exact())
+ {
+ }
+
+ };
+
+
+ namespace impl {
+
+ template <typename I, typename W1, typename W2>
+ struct generic_hit_or_miss : public hit_or_miss_ret<I, W1, W2>
+ {
+ typedef hit_or_miss_ret<I, W1, W2> super_type;
+
+ generic_hit_or_miss(const abstract::image<I>& input,
+ const abstract::regular_window<oln_type_of(I, grid), W1> win1,
+ const abstract::regular_window<oln_type_of(I, grid), W2> win2) :
+ super_type(input, win1, win2)
+ {
+ }
+
+ void impl_run()
+ {
+ this->output = arith::min(erosion(this->input, this->win1),
+ erosion(utils::invert(this->input),
+ this->win2));
+ }
+ };
+
+ template <typename I, typename W1, typename W2>
+ hit_or_miss_ret<I, W1, W2>
+ hit_or_miss(const abstract::image<I>& input,
+ const abstract::regular_window<oln_type_of(I, grid), W1> win1,
+ const abstract::regular_window<oln_type_of(I, grid), W2> win2)
+ {
+ generic_hit_or_miss<I, W1, W2> tmp(input, win1, win2);
+ tmp.run();
+ return tmp;
+ }
+
+ } //end of namespace impl
+
+ template <typename I, typename W1, typename W2>
+ hit_or_miss_ret<I, W1, W2>
+ hit_or_miss(const abstract::image<I>& input,
+ const abstract::regular_window<oln_type_of(I, grid), W1> win1,
+ const abstract::regular_window<oln_type_of(I, grid), W2> win2)
+ {
+ // FIXME: win1 inter win2 must be empty
+ return impl::hit_or_miss(input.exact(), win1.exact(), win2.exact());
+ }
+
+
+ template<class I, class W1, class W2>
+ dilation_ret<hit_or_miss_ret<I, W1, W2>, W1>
+ hit_or_miss_opening(const abstract::image<I>& input,
+ const abstract::regular_window<oln_type_of(I, grid), W1> win1,
+ const abstract::regular_window<oln_type_of(I, grid), W2> win2)
+ {
+ return dilation(hit_or_miss(input, win1, win2), -win1);
+ }
+
+ template<class I, class W1, class W2>
+ dilation_ret<hit_or_miss_ret<I, W2, W1>, W2>
+ hit_or_miss_opening_bg(const abstract::image<I>& input,
+ const abstract::regular_window<oln_type_of(I, grid), W1> win1,
+ const abstract::regular_window<oln_type_of(I, grid), W2> win2)
+ {
+ return hit_or_miss_opening(input, win2, win1);
+ }
+
+ template<class I, class W1, class W2>
+
utils::image_inverted<dilation_ret<hit_or_miss_ret<utils::image_inverted<I>,
+ W1, W2>, W1> > // !!!
+ hit_or_miss_closing(const abstract::image<I>& input,
+ const abstract::regular_window<oln_type_of(I, grid), W1> win1,
+ const abstract::regular_window<oln_type_of(I, grid), W2> win2)
+ {
+ return utils::invert(hit_or_miss_opening(utils::invert(input),
+ win1, win2));
+ }
+
+ template<class I, class W1, class W2>
+
utils::image_inverted<dilation_ret<hit_or_miss_ret<utils::image_inverted<I>,
+ W2, W1>, W2> > // !!!
+ hit_or_miss_closing_bg(const abstract::image<I>& input,
+ const abstract::regular_window<oln_type_of(I, grid), W1> win1,
+ const abstract::regular_window<oln_type_of(I, grid), W2> win2)
+ {
+ return hit_or_miss_closing(input, win2, win1);
+ }
+
+
+
+ } // end of namespace morpho
+
+} // end of namespace oln
+
+#endif // ! OLENA_MORPHO_HIT_OR_MISS_HH
Index: oln/arith/ops.hh
--- oln/arith/ops.hh (revision 164)
+++ oln/arith/ops.hh (working copy)
@@ -131,18 +131,18 @@
-template <typename I, typename F>
-void operator + (const oln::abstract::image<I>&,
- const oln::pw::abstract::function<F>&)
-{
- struct OLENA_ERROR__args_are_not_compatible();
-}
-template <typename F, typename I>
-void operator + (const oln::pw::abstract::function<F>&,
- const oln::abstract::image<I>&)
-{
- struct OLENA_ERROR__args_are_not_compatible();
-}
+// template <typename I, typename F>
+// void operator + (const oln::abstract::image<I>&,
+// const oln::pw::abstract::function<F>&)
+// {
+// struct OLENA_ERROR__args_are_not_compatible();
+// }
+// template <typename F, typename I>
+// void operator + (const oln::pw::abstract::function<F>&,
+// const oln::abstract::image<I>&)
+// {
+// struct OLENA_ERROR__args_are_not_compatible();
+// }
// FIXME: to be continued...
Index: oln/arith/min.hh
--- oln/arith/min.hh (revision 164)
+++ oln/arith/min.hh (working copy)
@@ -38,38 +38,45 @@
namespace arith {
// fwd decl
namespace impl {
- template <typename I> struct min_type;
+ template <typename I1, typename I2> struct min_type;
}
}
// super_type
- template <typename I>
- struct set_super_type< arith::impl::min_type<I> >
+ template <typename I1, typename I2>
+ struct set_super_type< arith::impl::min_type<I1, I2> >
{
- typedef abstract::image_binary_operator<I, I, I, arith::impl::min_type<I>
> ret;
+ typedef oln_type_of(I1, concrete) output_type;
+ typedef arith::impl::min_type<I1, I2> self_type;
+ typedef abstract::image_binary_operator<output_type, I1, I2, self_type> ret;
};
namespace arith {
namespace impl {
- template <class I>
- struct min_type : public abstract::image_binary_operator<I, I, I,
min_type<I> >
+ template <typename I1, typename I2>
+ struct min_type :
+ // FIXME: oln_super_of_
+ public oln::internal::get_super_type< min_type<I1,I2> >::ret
{
- typedef abstract::image_binary_operator<I, I, I, min_type<I> > super_type;
+ typedef typename oln::internal::get_super_type< min_type<I1,I2> >::ret
+ super_type;
+ typedef oln_type_of(I1, concrete) output_type;
- min_type(const abstract::image<I>& input1,
- const abstract::image<I>& input2) :
+ min_type(const abstract::image<I1>& input1,
+ const abstract::image<I2>& input2) :
super_type(input1.exact(), input2.exact())
{}
void impl_run()
{
precondition(this->input1.size() == this->input2.size());
- I output(this->input1.size());
- oln_type_of(I, fwd_piter) p(this->input1.size());
+ output_type output(this->input1.size());
+ oln_type_of(I1, fwd_piter) p(this->input1.size());
+
for_all_p (p)
output[p] = ntg::min(this->input1[p].value(), this->input2[p].value());
@@ -80,11 +87,12 @@
}
- template <typename I>
- impl::min_type<I> min(const abstract::image<I>& input1,
- const abstract::image<I>& input2)
+ template <typename I1, typename I2>
+ impl::min_type<I1, I2> min(const abstract::image<I1>& input1,
+ const abstract::image<I2>& input2)
{
- impl::min_type<I> tmp(input1, input2);
+ mlc::eq<oln_type_of(I1, grid), oln_type_of(I2, grid)>::ensure();
+ impl::min_type<I1, I2> tmp(input1, input2);
tmp.run();
return tmp;
}
Index: oln/arith/max.hh
--- oln/arith/max.hh (revision 164)
+++ oln/arith/max.hh (working copy)
@@ -38,38 +38,45 @@
namespace arith {
// fwd decl
namespace impl {
- template <typename I> struct max_type;
+ template <typename I1, typename I2> struct max_type;
}
}
// super_type
- template <typename I>
- struct set_super_type< arith::impl::max_type<I> >
+ template <typename I1, typename I2>
+ struct set_super_type< arith::impl::max_type<I1, I2> >
{
- typedef abstract::image_binary_operator<I, I, I, arith::impl::max_type<I>
> ret;
+ typedef oln_type_of(I1, concrete) output_type;
+ typedef arith::impl::max_type<I1, I2> self_type;
+ typedef abstract::image_binary_operator<output_type, I1, I2, self_type> ret;
};
namespace arith {
namespace impl {
- template <class I>
- struct max_type : public abstract::image_binary_operator<I, I, I,
max_type<I> >
+ template <typename I1, typename I2>
+ struct max_type :
+ // FIXME: oln_super_of_
+ public oln::internal::get_super_type< max_type<I1,I2> >::ret
{
- typedef abstract::image_binary_operator<I, I, I, max_type<I> > super_type;
+ typedef typename oln::internal::get_super_type< max_type<I1,I2> >::ret
+ super_type;
+ typedef oln_type_of(I1, concrete) output_type;
- max_type(const abstract::image<I>& input1,
- const abstract::image<I>& input2) :
+ max_type(const abstract::image<I1>& input1,
+ const abstract::image<I2>& input2) :
super_type(input1.exact(), input2.exact())
{}
void impl_run()
{
precondition(this->input1.size() == this->input2.size());
- I output(this->input1.size());
- oln_type_of(I, fwd_piter) p(this->input1.size());
+ output_type output(this->input1.size());
+ oln_type_of(I1, fwd_piter) p(this->input1.size());
+
for_all_p (p)
output[p] = ntg::max(this->input1[p].value(), this->input2[p].value());
@@ -80,11 +87,12 @@
}
- template <typename I>
- impl::max_type<I> max(const abstract::image<I>& input1,
- const abstract::image<I>& input2)
+ template <typename I1, typename I2>
+ impl::max_type<I1, I2> max(const abstract::image<I1>& input1,
+ const abstract::image<I2>& input2)
{
- impl::max_type<I> tmp(input1, input2);
+ mlc::eq<oln_type_of(I1, grid), oln_type_of(I2, grid)>::ensure();
+ impl::max_type<I1, I2> tmp(input1, input2);
tmp.run();
return tmp;
}