Index: ChangeLog
from Damien Thivolle <damien(a)lrde.epita.fr>
* oln/core/gen/regular_window.hh: Add splitting methods.
* oln/morpho/reconstruction.hh: New. Add generic facade for the
reconstruction.
* oln/morpho/reconstruction_by_erosion.inctrash: Remove.
* oln/morpho/reconstruction_by_dilation.hh: New. Return of the generic
reconstructions by dilation.
* oln/morpho/splitse.trash: Remove.
* oln/morpho/reconstruction_by_erosion.hh: New. Return of the generic
reconstructions by erosion.
* oln/morpho/reconstruction_by_dilation.inctrash: Remove.
* oln/canvas: New.
* oln/canvas/reconstruction.hh: New. Add hybrid and sequential
reconstruction canvas.
* oln/canvas/backandforth.hh: New. Contains generic back and forth
canvas: both classical and until_convergence versions.
canvas/backandforth.hh | 198 +++++++++++++++++++++++++
canvas/reconstruction.hh | 224 +++++++++++++++++++++++++++++
core/gen/regular_window.hh | 108 +++++++++++++
morpho/reconstruction.hh | 136 +++++++++++++++++
morpho/reconstruction_by_dilation.hh | 151 +++++++++++++++++++
morpho/reconstruction_by_dilation.inctrash | 142 ------------------
morpho/reconstruction_by_erosion.hh | 150 +++++++++++++++++++
morpho/reconstruction_by_erosion.inctrash | 141 ------------------
morpho/splitse.trash | 209 ---------------------------
9 files changed, 962 insertions(+), 497 deletions(-)
Index: oln/core/gen/regular_window.hh
--- oln/core/gen/regular_window.hh (revision 183)
+++ oln/core/gen/regular_window.hh (working copy)
@@ -33,7 +33,7 @@
# include <iterator>
# include <vector>
# include <set>
-
+
# include <mlc/contract.hh>
# include <oln/core/abstract/grid.hh>
# include <oln/core/abstract/dpoint.hh>
@@ -53,7 +53,7 @@
// props
template <typename G, typename E>
- struct set_props< category::window, abstract::regular_window<G, E> >
+ struct set_props< category::window, abstract::regular_window<G, E> >
{
typedef G grid_type;
typedef oln_grd_type_of(G, dpoint) dpoint_type;
@@ -61,9 +61,9 @@
typedef regular_fwd_qiter<G,E> fwd_iter_type;
// typedef regular_fwd_dpiter<G> fwd_dpiter_type; // FIXME: later...
};
-
+
namespace abstract
{
@@ -72,7 +72,7 @@
{
public:
-
+
typedef regular_window<G, E> self_type;
typedef oln_grd_type_of(G, coord) coord_type;
@@ -121,6 +121,101 @@
return this->dp_;
}
+
+ self_type get_fwd_win() const
+ {
+ self_type out;
+
+ for (unsigned i = 0; i < this->card(); ++i)
+ {
+ const dpoint_type& dp = dp_[i];
+
+ for (unsigned n = 0; n < dim; ++n)
+ if (dp.nth(n) < 0)
+ {
+ out.add(dp);
+ break;
+ }
+ else if (dp.nth(n) > 0)
+ break;
+ }
+ return out;
+ }
+
+
+ self_type get_fwd_win_p() // abstract::window<W>& win)
+ {
+ self_type out;
+
+
+ for (unsigned i = 0; i < this->card(); ++i)
+ {
+ const dpoint_type& dp = dp_[i];
+
+ unsigned n;
+ for (n = 0; n < dim; ++n)
+ if (dp.nth(n) < 0)
+ {
+ out.add(dp);
+ break;
+ }
+ else if (dp.nth(n) > 0)
+ break;
+
+ // All p.nth(n) are 0.
+ if (n == dim)
+ out.add(dp);
+
+ }
+ return out;
+ }
+
+
+ self_type get_bkd_win()
+ {
+ self_type out;
+
+ for (unsigned i = 0; i < card(); ++i)
+ {
+ const dpoint_type& dp = dp_[i];
+
+ for (unsigned n = 0; n < dim; ++n)
+ if (dp.nth(n) > 0)
+ {
+ out.add(dp);
+ break;
+ }
+ else if (dp.nth(n) < 0)
+ break;
+ }
+ return out;
+ }
+
+
+ self_type get_bkd_win_p()
+ {
+ self_type out;
+
+ for (unsigned i = 0; i < card(); ++i)
+ {
+ const dpoint_type& dp = win.get_dp()[i];
+
+ unsigned n;
+ for (n = 0; n < dim; ++n)
+ if (dp.nth(n) > 0)
+ {
+ out.add(dp);
+ break;
+ }
+ else if (dp.nth(n) < 0)
+ break;
+ // All p.nth(n) are 0.
+ if (n == dim)
+ out.add(dp);
+ }
+ return out;
+ }
+
protected:
regular_window() :
@@ -153,8 +248,11 @@
this->delta_update_(dp);
}
+
+
+
private:
-
+
std::set<dpoint_type, fwd_less_dpoint> dpset_;
std::vector<dpoint_type> dp_;
coord_type delta_;
Index: oln/morpho/reconstruction.hh
--- oln/morpho/reconstruction.hh (revision 0)
+++ oln/morpho/reconstruction.hh (revision 0)
@@ -0,0 +1,136 @@
+// Copyright (C) 2001, 2002, 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 filek 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_RECONSTRUCTION_HH
+# define OLENA_MORPHO_RECONSTRUCTION_HH
+
+# include <oln/morpho/reconstruction_by_dilation.hh>
+# include <oln/morpho/reconstruction_by_erosion.hh>
+
+namespace oln {
+
+
+ namespace morpho {
+
+
+ namespace impl {
+
+ // Generic implementation of reconstruction (routine).
+
+ template<typename Op, typename A, typename I1, typename I2>
+ oln_type_of(I1, concrete)
+ reconstruction_(const abstract::image_with_nbh<I1>& marker,
+ const abstract::image<I2>& mask)
+ {
+ reconstruction<Op, A, I1, I2> tmp(marker, mask);
+ // tmp.entering(); FIXME: something like that ?
+ tmp.run();
+ // tmp.exiting(); FIXME: something like that ?
+ return tmp.get_output();
+ }
+
+ } // end of namespace impl
+
+ /// Generic reconstruction (facade).
+
+ template<typename Op, typename I1, typename I2, typename A>
+ oln_type_of(I1, concrete)
+ reconstruction(const tag::oper<Op>& oper_,
+ const abstract::image_with_nbh<I1>& marker,
+ const abstract::image<I2>& mask,
+ const tag::algo<A>& algo_)
+ {
+ mlc::eq<oln_type_of(I1, grid), oln_type_of(I2, grid)>::ensure();
+ precondition(marker.size() == mask.size());
+
+ entering("morpho::reconstruction");
+
+ oln_type_of(I1, concrete) output("output");
+// output = impl::reconstruction_(oper_, marker.exact(), mask.exact(), algo_);
+
+ exiting("morpho::reconstruction");
+ return output;
+
+ }
+
+ // by dilation
+
+ template<typename I1, typename I2, typename A>
+ oln_type_of(I1, concrete)
+ reconstruction_by_dilation(const abstract::image_with_nbh<I1>& marker,
+ const abstract::image<I2>& mask,
+ const tag::algo<A>& algo_)
+ {
+ mlc::eq<oln_type_of(I1, grid), oln_type_of(I2, grid)>::ensure();
+ precondition(marker.size() == mask.size());
+
+ return reconstruction(tag::by_dilation_type(), marker, mask, algo_);
+ }
+
+ template<typename I1, typename I2>
+ oln_type_of(I1, concrete)
+ reconstruction_by_dilation(const abstract::image_with_nbh<I1>& marker,
+ const abstract::image<I2>& mask)
+ {
+ mlc::eq<oln_type_of(I1, grid), oln_type_of(I2, grid)>::ensure();
+ precondition(marker.size() == mask.size());
+
+ return reconstruction(tag::by_dilation_type(), marker,
+ mask, tag::hybrid_type());
+ }
+
+ // by erosion
+
+ template<typename I1, typename I2, typename A>
+ oln_type_of(I1, concrete)
+ reconstruction_by_erosion(const abstract::image_with_nbh<I1>& marker,
+ const abstract::image<I2>& mask,
+ const tag::algo<A>& algo_)
+ {
+ mlc::eq<oln_type_of(I1, grid), oln_type_of(I2, grid)>::ensure();
+ precondition(marker.size() == mask.size());
+
+ return reconstruction(tag::by_erosion_type(), marker, mask, algo_);
+ }
+
+ template<typename I1, typename I2>
+ oln_type_of(I1, concrete)
+ reconstruction_by_erosion(const abstract::image_with_nbh<I1>& marker,
+ const abstract::image<I2>& mask)
+ {
+ mlc::eq<oln_type_of(I1, grid), oln_type_of(I2, grid)>::ensure();
+ precondition(marker.size() == mask.size());
+
+ return reconstruction(tag::by_erosion_type(), marker,
+ mask, tag::hybrid_type());
+ }
+
+ } // end of namespace oln::morpho
+
+} // end of namespace oln
+
+#endif // ! OLENA_MORPHO_RECONSTRUCTION_HH
Index: oln/morpho/reconstruction_by_erosion.inctrash
--- oln/morpho/reconstruction_by_erosion.inctrash (revision 183)
+++ oln/morpho/reconstruction_by_erosion.inctrash (working copy)
@@ -1,141 +0,0 @@
-// Copyright (C) 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 filek 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.
-
-namespace oln {
-
- namespace morpho {
-
- namespace impl {
-
- // Sequential version
-
- template<typename I1, typename I2>
- struct generic_reconstruction <tag::by_erosion, tag::sequential, I1, I2>
- : public generic_reconstruction_canvas<I1, I2, tag::sequential,
- generic_reconstruction<tag::by_erosion, tag::sequential, I1, I2> >
- {
- typedef generic_reconstruction<tag::by_erosion,
- tag::sequential, I1,I2> self_type;
- typedef generic_reconstruction_canvas<I1, I2, tag::sequential,
- self_type> super_type;
-
- generic_reconstruction(const abstract::image_with_nbh<I1>& marker,
- const abstract::image<I2>& mask) :
- super_type(marker, mask)
- {
- }
-
-
- void impl_bkd_loop_body()
- {
- this->output[this->bkd_p] = ntg::max(morpho::min(this->output,
- this->bkd_p,
- this->win_minus),
- this->mask[this->bkd_p].value());
- }
-
- void impl_fwd_loop_body()
- {
- this->output[this->fwd_p] = ntg::max(morpho::min(this->output,
- this->fwd_p,
- this->win_plus),
- this->mask[this->fwd_p].value());
- }
-
- void impl_preconditions()
- {
- precondition(level::is_greater_or_equal(this->marker, this->mask));
- }
-
- };
-
- // Hybrid version
-
- template<typename I1, typename I2>
- struct generic_reconstruction <tag::by_erosion, tag::hybrid, I1, I2>
- : public generic_reconstruction_canvas<I1, I2, tag::hybrid,
- generic_reconstruction<tag::by_erosion, tag::hybrid, I1, I2> >
- {
- typedef generic_reconstruction<tag::by_erosion,
- tag::hybrid, I1,I2> self_type;
- typedef generic_reconstruction_canvas<I1, I2, tag::hybrid,
- self_type> super_type;
-
- generic_reconstruction(const abstract::image_with_nbh<I1>& marker,
- const abstract::image<I2>& mask) :
- super_type(marker, mask)
- {
- }
-
-
-
- void impl_bkd_loop_body()
- {
- this->output[this->bkd_p] = ntg::max(morpho::min(this->work,
- this->bkd_p,
- this->win_minus),
- this->mask[this->bkd_p].value());
- }
-
- void impl_fwd_loop_body()
- {
- this->output[this->fwd_p] = ntg::max(morpho::min(this->work,
- this->fwd_p,
- this->win_plus),
- this->mask[this->fwd_p].value());
- }
-
- void impl_fifo_loop_body()
- {
- if ((this->output[this->q] > this->output[this->p]) &&
- (this->mask[this->q] != this->output[this->q]))
- {
- this->output[this->q] = ntg::min(this->output[this->p].value(),
- this->mask[this->q].value());
- this->fifo.push(this->q);
- }
- }
-
- bool impl_exist_init()
- {
- return this->output.hold(this->q) &&
- (this->output[this->q] > this->output[this->bkd_p]) &&
- (this->output[this->q] > this->mask[this->q]);
- }
-
- void impl_preconditions()
- {
- precondition(level::is_greater_or_equal(this->marker, this->mask));
- }
-
- };
-
- }
-
- }
-
-}
Index: oln/morpho/reconstruction_by_dilation.hh
--- oln/morpho/reconstruction_by_dilation.hh (revision 0)
+++ oln/morpho/reconstruction_by_dilation.hh (revision 0)
@@ -0,0 +1,151 @@
+// Copyright (C) 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 filek 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_RECONSTRUCTION_BY_DILATION_HH
+# define OLENA_MORPHO_RECONSTRUCTION_BY_DILATION_HH
+
+# include <oln/canvas/reconstruction.hh>
+# include <oln/morpho/tags.hh>
+
+namespace oln {
+
+ namespace morpho {
+
+ namespace impl {
+
+ // Sequential version
+ template<typename I1, typename I2>
+ struct reconstruction <tag::by_dilation_type, tag::sequential_type, I1, I2>
+ : public canvas::sequential_reconstruction<I1, I2,
+ reconstruction<tag::by_dilation_type, tag::sequential_type, I1, I2> >
+ {
+ typedef reconstruction<tag::by_dilation_type,
+ tag::sequential_type, I1,I2> self_type;
+ typedef canvas::sequential_reconstruction<I1, I2, self_type> super_type;
+
+ reconstruction(const abstract::image_with_nbh<I1>& marker,
+ const abstract::image<I2>& mask) :
+ super_type(marker, mask)
+ {
+ }
+
+
+ void impl_bkd_loop_body()
+ {
+ this->output[this->bkd_p] = ntg::min(morpho::max(this->output,
+ this->bkd_p,
+ this->win_minus),
+ this->mask[this->bkd_p]);
+ }
+
+ void impl_fwd_loop_body()
+ {
+ this->output[this->fwd_p] = ntg::min(morpho::max(this->output,
+ this->fwd_p,
+ this->win_plus),
+ this->mask[this->fwd_p]);
+ }
+
+ // FIXME: unused...
+ void impl_preconditions()
+ {
+ precondition(level::is_greater_or_equal(this->mask, this->marker));
+ }
+
+ };
+
+
+ // Hybrid version
+
+ template<typename I1, typename I2>
+ struct reconstruction <tag::by_dilation_type, tag::hybrid_type, I1, I2>
+ : public canvas::hybrid_reconstruction<I1, I2,
+ reconstruction<tag::by_dilation_type, tag::hybrid_type, I1, I2> >
+ {
+ typedef reconstruction<tag::by_dilation_type,
+ tag::hybrid_type, I1,I2> self_type;
+ typedef canvas::hybrid_reconstruction<I1, I2,
+ self_type> super_type;
+
+ reconstruction(const abstract::image_with_nbh<I1>& marker,
+ const abstract::image<I2>& mask) :
+ super_type(marker, mask)
+ {
+ }
+
+
+
+ void impl_bkd_loop_body()
+ {
+ this->output[this->bkd_p] = ntg::min(morpho::max(this->work,
+ this->bkd_p,
+ this->win_minus),
+ this->mask[this->bkd_p]);
+ }
+
+ void impl_fwd_loop_body()
+ {
+ this->output[this->fwd_p] = ntg::min(morpho::max(this->work,
+ this->fwd_p,
+ this->win_plus),
+ this->mask[this->fwd_p]);
+ }
+
+ void impl_fifo_loop_body()
+ {
+ if ((this->output[this->q] < this->output[this->p]) &&
+ (this->mask[this->q] != this->output[this->q]))
+ {
+ this->output[this->q] = ntg::min(this->output[this->p],
+ this->mask[this->q]);
+ this->fifo.push(this->q);
+ }
+ }
+
+ bool impl_exist_init()
+ {
+ return this->output.hold(this->q) &&
+ (this->output[this->q] < this->output[this->bkd_p]) &&
+ (this->output[this->q] < this->mask[this->q]);
+ }
+
+ //FIXME: unused...
+ void impl_preconditions()
+ {
+ precondition(level::is_greater_or_equal(this->mask, this->marker));
+ }
+
+ };
+
+ }
+
+ }
+
+}
+
+
+#endif // ! OLENA_MORPHO_RECONSTRUCTION_BY_DILATION_HH
Index: oln/morpho/splitse.trash
--- oln/morpho/splitse.trash (revision 183)
+++ oln/morpho/splitse.trash (working copy)
@@ -1,209 +0,0 @@
-// Copyright (C) 2001, 2002, 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_SPLITSE_HH
-# define OLENA_MORPHO_SPLITSE_HH
-
-# include <oln/basics.hh>
-
-# include <oln/core/1d/size1d.hh>
-# include <oln/core/2d/size2d.hh>
-# include <oln/core/3d/size3d.hh>
-
-# include <oln/core/abstract/window.hh>
-# include <oln/core/abstract/window.hh>
-
-
-namespace oln {
- namespace morpho {
-
- template <class S>
- struct dim_traits
- {
- };
-
- template <>
- struct dim_traits<size1d>
- {
- enum {dim = 1};
- };
-
- template <>
- struct dim_traits<size2d>
- {
- enum {dim = 2};
- };
-
- template <>
- struct dim_traits<size3d>
- {
- enum {dim = 3};
- };
-
- /*!
- ** \brief Get a sub part of a window.
- **
- ** \param E Exact type of the window.
- **
- ** \arg win The window.
- **
- ** A point p take part of the new window if it exists
- ** a i that belongs to [[0..dim-1]] like p(i) < 0 and for all j
- ** that belongs to [[0..i-1]] p(j) = 0.
- **
- */
-
-
- template<class W>
- W
- get_plus_win_only(const W& win) // FIXME: abstract::window<W>& win)
- {
- W out;
- for (unsigned i = 0; i < win.card(); ++i)
- {
- const oln_wn_type_of(W, dpoint)& dp = win.get_dp()[i];
- unsigned n;
- for (n = 0; n < dim_traits<oln_wn_type_of(W, size)>::dim; ++n)
- if (dp.nth(n) < 0) {
- out.add(dp);
- break;
- } else if (dp.nth(n) > 0) {
- break;
- }
- }
- return out;
- }
-
- /*!
- ** \brief Get a sub part of a window.
- **
- ** \param W Exact type of the window.
- **
- ** \arg win The window.
- **
- ** A point p take part of the new window if it exists
- ** a i that belongs to [[0..dim-1]] like p(i) < 0 and for all j
- ** that belongs to [[0..i-1]] p(j) = 0 or if for all i that
- ** belongs to [[0..dim-1]] p(i) = 0.
- **
- */
- template<class W>
- W
- get_plus_win_p(const W& win) // abstract::window<W>& win)
- {
- W out;
- for (unsigned i = 0; i < win.card(); ++i)
- {
- const oln_wn_type_of(W, dpoint)& dp = win.get_dp()[i];
- unsigned n;
- for (n = 0; n < dim_traits<oln_wn_type_of(W, size)>::dim; ++n)
- if (dp.nth(n) < 0) {
- out.add(dp);
- break;
- } else if (dp.nth(n) > 0) {
- break;
- }
- // All p.nth(n) are 0.
- if (n == dim_traits<oln_wn_type_of(W, size)>::dim)
- out.add(dp);
- }
- return out;
- }
-
- /*!
- ** \brief Get a sub part of a window.
- **
- ** \param W Exact type of the window.
- **
- ** \arg win The window.
- **
- ** A point p take part of the new window if it exists
- ** a i that belongs to [[0..dim-1]] like p(i) > 0 and for all j
- ** that belongs to [[0..i-1]] p(j) = 0.
- **
- */
- template<class W>
- W
- get_minus_win_only(const W& win) // abstract::window<W>& win)
- {
- W out;
- for (unsigned i = 0; i < win.card(); ++i)
- {
- const oln_wn_type_of(W, dpoint)& dp = win.get_dp()[i];
- unsigned n;
- for (n = 0; n < dim_traits<oln_wn_type_of(W, size)>::dim; ++n)
- if (dp.nth(n) > 0) {
- out.add(dp);
- break;
- } else if (dp.nth(n) < 0) {
- break;
- }
- }
- return out;
- }
-
- /*!
- ** \brief Get a sub part of a window.
- **
- ** \param W Exact type of the window.
- **
- ** \arg win The window.
- **
- ** A point p take part of the new window if it exists
- ** a i that belongs to [[0..dim-1]] like p(i) > 0 and for all j
- ** that belongs to [[0..i-1]] p(j) = 0 or if for all i that
- ** belongs to [[0..dim-1]] p(i) = 0.
- **
- */
- template<class W>
- W
- get_minus_win_p(const W& win) // abstract::window<W>& win)
- {
- W out;
- for (unsigned i = 0; i < win.card(); ++i)
- {
- const oln_wn_type_of(W, dpoint)& dp = win.get_dp()[i];
- unsigned n;
- for (n = 0; n < dim_traits<oln_wn_type_of(W, size)>::dim; ++n)
- if (dp.nth(n) > 0) {
- out.add(dp);
- break;
- } else if (dp.nth(n) < 0) {
- break;
- }
- // All p.nth(n) are 0.
- if (n == dim_traits<oln_wn_type_of(W, size)>::dim)
- out.add(dp);
- }
- return out;
- }
-
- } // end of namespace oln::morpho
-
-} // end of namespace oln
-
-#endif // ! OLENA_MORPHO_SPLITSE_HH
Index: oln/morpho/reconstruction_by_erosion.hh
--- oln/morpho/reconstruction_by_erosion.hh (revision 0)
+++ oln/morpho/reconstruction_by_erosion.hh (revision 0)
@@ -0,0 +1,150 @@
+// Copyright (C) 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 filek 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_RECONSTRUCTION_BY_EROSION_HH
+# define OLENA_MORPHO_RECONSTRUCTION_BY_EROSION_HH
+
+# include <oln/canvas/reconstruction.hh>
+# include <oln/morpho/tags.hh>
+
+namespace oln {
+
+ namespace morpho {
+
+ namespace impl {
+
+ // Sequential version
+
+ template<typename I1, typename I2>
+ struct reconstruction <tag::by_erosion_type, tag::sequential_type, I1, I2>
+ : public canvas::sequential_reconstruction<I1, I2,
+ reconstruction<tag::by_erosion_type,
+ tag::sequential_type, I1, I2> >
+ {
+ typedef reconstruction<tag::by_erosion_type,
+ tag::sequential_type, I1, I2> self_type;
+ typedef canvas::sequential_reconstruction<I1, I2, self_type> super_type;
+
+ reconstruction(const abstract::image_with_nbh<I1>& marker,
+ const abstract::image<I2>& mask) :
+ super_type(marker, mask)
+ {
+ }
+
+
+ void impl_bkd_loop_body()
+ {
+ this->output[this->bkd_p] = ntg::max(morpho::min(this->output,
+ this->bkd_p,
+ this->win_minus),
+ this->mask[this->bkd_p]);
+ }
+
+ void impl_fwd_loop_body()
+ {
+ this->output[this->fwd_p] = ntg::max(morpho::min(this->output,
+ this->fwd_p,
+ this->win_plus),
+ this->mask[this->fwd_p]);
+ }
+
+ // FIXME: unused...
+ void impl_preconditions()
+ {
+ precondition(level::is_greater_or_equal(this->marker, this->mask));
+ }
+
+ };
+
+ // Hybrid version
+
+ template<typename I1, typename I2>
+ struct reconstruction <tag::by_erosion_type, tag::hybrid_type, I1, I2>
+ : public canvas::hybrid_reconstruction<I1, I2,
+ reconstruction<tag::by_erosion_type, tag::hybrid_type, I1, I2> >
+ {
+ typedef reconstruction<tag::by_erosion_type,
+ tag::hybrid_type, I1,I2> self_type;
+ typedef canvas::hybrid_reconstruction<I1, I2,
+ self_type> super_type;
+
+ reconstruction(const abstract::image_with_nbh<I1>& marker,
+ const abstract::image<I2>& mask) :
+ super_type(marker, mask)
+ {
+ }
+
+ void impl_bkd_loop_body()
+ {
+ this->output[this->bkd_p] = ntg::max(morpho::min(this->work,
+ this->bkd_p,
+ this->win_minus),
+ this->mask[this->bkd_p]);
+ }
+
+ void impl_fwd_loop_body()
+ {
+ this->output[this->fwd_p] = ntg::max(morpho::min(this->work,
+ this->fwd_p,
+ this->win_plus),
+ this->mask[this->fwd_p]);
+ }
+
+ void impl_fifo_loop_body()
+ {
+ if ((this->output[this->q] > this->output[this->p]) &&
+ (this->mask[this->q] != this->output[this->q]))
+ {
+ this->output[this->q] = ntg::min(this->output[this->p],
+ this->mask[this->q]);
+ this->fifo.push(this->q);
+ }
+ }
+
+ bool impl_exist_init()
+ {
+ return this->output.hold(this->q) &&
+ (this->output[this->q] > this->output[this->bkd_p]) &&
+ (this->output[this->q] > this->mask[this->q]);
+ }
+
+ // FIXME: unused...
+ void impl_preconditions()
+ {
+ precondition(level::is_greater_or_equal(this->marker, this->mask));
+ }
+
+ };
+
+ }
+
+ }
+
+}
+
+
+#endif // ! OLENA_MORPHO_RECONSTRUCTION_BY_EROSION_HH
Index: oln/morpho/reconstruction_by_dilation.inctrash
--- oln/morpho/reconstruction_by_dilation.inctrash (revision 183)
+++ oln/morpho/reconstruction_by_dilation.inctrash (working copy)
@@ -1,142 +0,0 @@
-// Copyright (C) 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 filek 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.
-
-namespace oln {
-
- namespace morpho {
-
- namespace impl {
-
- // Sequential version
-
- template<typename I1, typename I2>
- struct generic_reconstruction <tag::by_dilation, tag::sequential, I1, I2>
- : public generic_reconstruction_canvas<I1, I2, tag::sequential,
- generic_reconstruction<tag::by_dilation, tag::sequential, I1, I2> >
- {
- typedef generic_reconstruction<tag::by_dilation,
- tag::sequential, I1,I2> self_type;
- typedef generic_reconstruction_canvas<I1, I2, tag::sequential,
- self_type> super_type;
-
- generic_reconstruction(const abstract::image_with_nbh<I1>& marker,
- const abstract::image<I2>& mask) :
- super_type(marker, mask)
- {
- }
-
-
- void impl_bkd_loop_body()
- {
- this->output[this->bkd_p] = ntg::min(morpho::max(this->output,
- this->bkd_p,
- this->win_minus),
- this->mask[this->bkd_p].value());
- }
-
- void impl_fwd_loop_body()
- {
- this->output[this->fwd_p] = ntg::min(morpho::max(this->output,
- this->fwd_p,
- this->win_plus),
- this->mask[this->fwd_p].value());
- }
-
- void impl_preconditions()
- {
- precondition(level::is_greater_or_equal(this->mask, this->marker));
- }
-
- };
-
-
- // Hybrid version
-
- template<typename I1, typename I2>
- struct generic_reconstruction <tag::by_dilation, tag::hybrid, I1, I2>
- : public generic_reconstruction_canvas<I1, I2, tag::hybrid,
- generic_reconstruction<tag::by_dilation, tag::hybrid, I1, I2> >
- {
- typedef generic_reconstruction<tag::by_dilation,
- tag::hybrid, I1,I2> self_type;
- typedef generic_reconstruction_canvas<I1, I2, tag::hybrid,
- self_type> super_type;
-
- generic_reconstruction(const abstract::image_with_nbh<I1>& marker,
- const abstract::image<I2>& mask) :
- super_type(marker, mask)
- {
- }
-
-
-
- void impl_bkd_loop_body()
- {
- this->output[this->bkd_p] = ntg::min(morpho::max(this->work,
- this->bkd_p,
- this->win_minus),
- this->mask[this->bkd_p].value());
- }
-
- void impl_fwd_loop_body()
- {
- this->output[this->fwd_p] = ntg::min(morpho::max(this->work,
- this->fwd_p,
- this->win_plus),
- this->mask[this->fwd_p].value());
- }
-
- void impl_fifo_loop_body()
- {
- if ((this->output[this->q] < this->output[this->p]) &&
- (this->mask[this->q] != this->output[this->q]))
- {
- this->output[this->q] = ntg::min(this->output[this->p].value(),
- this->mask[this->q].value());
- this->fifo.push(this->q);
- }
- }
-
- bool impl_exist_init()
- {
- return this->output.hold(this->q) &&
- (this->output[this->q] < this->output[this->bkd_p]) &&
- (this->output[this->q] < this->mask[this->q]);
- }
-
- void impl_preconditions()
- {
- precondition(level::is_greater_or_equal(this->mask, this->marker));
- }
-
- };
-
- }
-
- }
-
-}
Index: oln/canvas/reconstruction.hh
--- oln/canvas/reconstruction.hh (revision 0)
+++ oln/canvas/reconstruction.hh (revision 0)
@@ -0,0 +1,224 @@
+// Copyright (C) 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_CANVAS_RECONSTRUCTION_HH
+# define OLENA_CANVAS_RECONSTRUCTION_HH
+
+# include <queue>
+
+# include <oln/canvas/backandforth.hh>
+# include <oln/level/compare.hh>
+# include <oln/utils/clone.hh>
+
+namespace oln {
+
+ namespace morpho {
+
+ namespace impl {
+
+ template <typename T, typename A, typename I1, typename I2>
+ struct reconstruction {};
+
+ }
+
+ }
+
+ namespace canvas {
+
+ template <typename I1, typename I2, typename E>
+ struct hybrid_reconstruction : public mlc::any<E>
+ {
+
+ typedef oln_type_of(I1, neighb) nbh_type;
+ typedef oln_nbh_type_of(nbh_type, window) window_type;
+ typedef oln_type_of(I1, concrete) output_type;
+
+ bool exist_init()
+ {
+ for (unsigned i = 0; i < win_minus.card(); ++i)
+ {
+ q = win_minus.get_dp()[i] + (oln_type_of(I1, point))bkd_p;
+ if (this->exact().impl_exist_init())
+ return true;
+ }
+ return false;
+ }
+
+
+ void fwd_loop_body()
+ {
+ this->exact().impl_fwd_loop_body();
+ }
+
+ void bkd_loop_body()
+ {
+ this->exact().impl_bkd_loop_body();
+ }
+
+ void fifo_loop_body()
+ {
+ this->exact().impl_fifo_loop_body();
+ }
+
+ void init()
+ {
+ output_type tmp(marker.size());
+
+ output = tmp;
+ work = clone(marker);
+
+ win_plus = marker.nbh_get().get_win().get_fwd_win_p();
+ win_minus = marker.nbh_get().get_win().get_bkd_win_p();
+ }
+
+ void run()
+ {
+ init();
+
+ for_all_p (fwd_p)
+ fwd_loop_body();
+
+ for_all_p (bkd_p)
+ {
+ bkd_loop_body();
+ if (exist_init())
+ fifo.push(bkd_p);
+ }
+
+ // Propagation Step
+ while (!fifo.empty())
+ {
+ p = fifo.front();
+ fifo.pop();
+
+ window_type win = marker.nbh_get().get_win();
+ for (unsigned i = 0; i < win.card(); ++i)
+ {
+ q = win.get_dp()[i] + p;
+
+ if (output.hold(q))
+ fifo_loop_body();
+ }
+ }
+ }
+
+ oln_type_of(I1, concrete) get_output()
+ {
+ return output.unbox();
+ }
+
+ protected:
+
+ hybrid_reconstruction(const abstract::image_with_nbh<I1>& marker,
+ const abstract::image<I2>& mask) :
+ marker(marker.exact()),
+ mask(mask.exact()),
+ bkd_p(marker.size()),
+ fwd_p(marker.size())
+ {
+ }
+
+ ~hybrid_reconstruction()
+ {
+ mlc_check_method_impl(E, void, exist_init, , );
+ mlc_check_method_impl(E, void, bkd_loop_body, , );
+ mlc_check_method_impl(E, void, fwd_loop_body, , );
+ mlc_check_method_impl(E, void, fifo_loop_body, , );
+ }
+
+ oln_type_of(I1, bkd_piter) bkd_p;
+ oln_type_of(I1, fwd_piter) fwd_p;
+
+ oln_type_of(I1, point) p;
+ oln_type_of(I1, point) q;
+
+ window_type win_plus;
+ window_type win_minus;
+
+ box<oln_type_of(I1, concrete)> work;
+ box<oln_type_of(I1, concrete)> output;
+ box<I1> marker;
+ box<I2> mask;
+
+ std::queue<oln_type_of(I1, point) > fifo;
+
+ };
+
+ template <typename I1, typename I2, typename E>
+ struct sequential_reconstruction :
+ public back_and_forth_until_convergence<I1, E>
+ {
+ typedef back_and_forth_until_convergence<I1, E> super_type;
+ typedef oln_type_of(I1, neighb) nbh_type;
+ typedef oln_nbh_type_of(nbh_type, window) window_type;
+
+ void impl_init()
+ {
+ output = clone(marker);
+ work = clone(marker);
+
+ win_plus = marker.nbh_get().get_win().get_fwd_win_p();
+ win_minus = marker.nbh_get().get_win().get_bkd_win_p();
+ }
+
+ bool impl_is_stable()
+ {
+ return level::is_equal(work, output);
+ }
+
+
+ oln_type_of(I1, concrete) get_output()
+ {
+ return output.unbox();
+ }
+
+ sequential_reconstruction(const abstract::image_with_nbh<I1>& marker,
+ const abstract::image<I2>& mask) :
+ super_type(marker),
+ marker(marker.exact()),
+ mask(mask.exact())
+ {
+ }
+
+ oln_nbh_type_of(nbh_type, window) win_plus;
+ oln_nbh_type_of(nbh_type, window) win_minus;
+
+ box<oln_type_of(I1, concrete)> work;
+ box<oln_type_of(I1, concrete)> output;
+ box<I1> marker;
+ box<I2> mask;
+
+ };
+
+
+ }
+
+
+}
+
+
+#endif // ! OLENA_CANVAS_RECONSTRUCTION_HH
Index: oln/canvas/backandforth.hh
--- oln/canvas/backandforth.hh (revision 0)
+++ oln/canvas/backandforth.hh (revision 0)
@@ -0,0 +1,198 @@
+// Copyright (C) 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_CANVAS_BACKANDFORTH_HH
+# define OLENA_CANVAS_BACKANDFORTH_HH
+
+# include <mlc/any.hh>
+# include <mlc/contract.hh>
+# include <oln/core/abstract/image.hh>
+# include <oln/core/abstract/piter.hh>
+
+
+namespace oln {
+
+
+ namespace canvas
+ {
+
+ template <typename I, typename E>
+ struct back_and_forth_until_convergence : public mlc::any<E>
+ {
+ // Abstract methods.
+
+ // Initialize 'work'.
+ void init()
+ {
+ this->exact().impl_init();
+ }
+
+ // Do something like 'work -> output'.
+ void bkd_loop_body()
+ {
+ this->exact().impl_bkd_loop_body();
+ }
+
+ // Do something like 'work -> output'.
+ void fwd_loop_body()
+ {
+ this->exact().impl_fwd_loop_body();
+ }
+
+ // Check stability from input, output, and work.
+ bool is_stable() const
+ {
+ return this->exact().impl_is_stable();
+ }
+
+ // Do something like 'work := output'.
+ void re_loop()
+ {
+ return this->exact().impl_re_loop();
+ }
+
+ // Concrete method.
+ void run()
+ {
+ bool stability;
+ init();
+ for (;;)
+ {
+ // back
+ for_all_p (bkd_p)
+ bkd_loop_body();
+
+ // forth
+ for_all_p (fwd_p)
+ fwd_loop_body();
+
+ // stability check
+ stability = is_stable();
+ if (stability)
+ return;
+
+ // prepare a new loop iteration
+ re_loop();
+ }
+ }
+
+
+ protected:
+
+ // Ctor.
+ back_and_forth_until_convergence(const abstract::image<I>& input) :
+ bkd_p(input.size()),
+ fwd_p(input.size())
+ {
+ }
+
+ // Attributes.
+ oln_type_of(I, bkd_piter) bkd_p;
+ oln_type_of(I, fwd_piter) fwd_p;
+
+ // Check for impls..
+ ~back_and_forth_until_convergence()
+ {
+ mlc_check_method_impl(E, void, init, , );
+ mlc_check_method_impl(E, void, bkd_loop_body, , );
+ mlc_check_method_impl(E, void, fwd_loop_body, , );
+ mlc_check_method_impl(E, bool, is_stable, , const);
+ mlc_check_method_impl(E, void, re_loop, , );
+ }
+
+ };
+
+
+ template <typename I, typename E>
+ struct back_and_forth : public mlc::any<E>
+ {
+ // Abstract methods.
+
+ // Initialize 'work'.
+ void init()
+ {
+ this->exact().impl_init();
+ }
+
+ // Do something like 'work -> output'.
+ void bkd_loop_body()
+ {
+ this->exact().impl_bkd_loop_body();
+ }
+
+ // Do something like 'work -> output'.
+ void fwd_loop_body()
+ {
+ this->exact().impl_fwd_loop_body();
+ }
+
+ // Concrete method.
+ void run()
+ {
+ init();
+
+ // forth
+ for_all_p (fwd_p)
+ fwd_loop_body();
+
+ // back
+ for_all_p (bkd_p)
+ bkd_loop_body();
+
+ }
+
+
+ protected:
+
+ // Ctor.
+ back_and_forth(const abstract::image<I>& input) :
+ bkd_p(input.size()),
+ fwd_p(input.size())
+ {
+ }
+
+ // Attributes.
+ oln_type_of(I, bkd_piter) bkd_p;
+ oln_type_of(I, fwd_piter) fwd_p;
+
+ // Check for impls..
+ ~back_and_forth()
+ {
+ mlc_check_method_impl(E, void, init, , );
+ mlc_check_method_impl(E, void, bkd_loop_body, , );
+ mlc_check_method_impl(E, void, fwd_loop_body, , );
+ }
+
+ };
+
+ } // end of namespace oln::canvas
+
+
+} // end of namespace oln
+
+
+#endif // ! OLENA_CANVAS_BACKANDFORTH_HH