proto-1.0 184: Add reconstruction canvas

Index: ChangeLog from Damien Thivolle <damien@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
participants (1)
-
Damien Thivolle