Je fais le reconstruction auto-duale demain.
Index: ChangeLog from Damien Thivolle damien@lrde.epita.fr
* tests/morpho/tests/reconstruction: Re-enable reconstruction tests. * oln/core/abstract/point.hh: Fix omitted parenthesis. * oln/morpho/reconstruction_canvas.inctrash: Remove. * oln/morpho/reconstruction.trash: Remove. * oln/morpho/reconstruction_by_dilation.hh: Replace windows by neighborhoods. * oln/canvas/reconstruction.hh: Likewise. * oln/morpho/reconstruction_by_erosion.hh: Likewise. * oln/morpho/reconstruction.hh: Disable self-dual reconstruction for now. * oln/morpho/reconstruction_selfdual.hh: Add a reminder.
oln/canvas/reconstruction.hh | 106 ++++++------- oln/core/abstract/point.hh | 4 oln/morpho/reconstruction.hh | 22 +- oln/morpho/reconstruction.trash | 227 ---------------------------- oln/morpho/reconstruction_by_dilation.hh | 154 ++++++++++--------- oln/morpho/reconstruction_by_erosion.hh | 138 +++++++++-------- oln/morpho/reconstruction_canvas.inctrash | 238 ------------------------------ oln/morpho/reconstruction_selfdual.hh | 2 tests/morpho/tests/reconstruction | 45 ++--- 9 files changed, 254 insertions(+), 682 deletions(-)
Index: oln/morpho/reconstruction.hh --- oln/morpho/reconstruction.hh (revision 257) +++ oln/morpho/reconstruction.hh (working copy) @@ -30,7 +30,7 @@
# include <oln/morpho/reconstruction_by_dilation.hh> # include <oln/morpho/reconstruction_by_erosion.hh> -# include <oln/morpho/reconstruction_selfdual.hh> +// # include <oln/morpho/reconstruction_selfdual.hh>
namespace oln {
@@ -49,7 +49,9 @@ { reconstruction<I1, I2, A, Op> tmp(marker, mask); // tmp.entering(); FIXME: something like that ? + tmp.run(); + // tmp.exiting(); FIXME: something like that ? return tmp.get_output(); } @@ -81,16 +83,16 @@
// self dual
- template <typename I1, typename I2> - oln_type_of(I1, concrete) - reconstruction_selfdual(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()); +// template <typename I1, typename I2> +// oln_type_of(I1, concrete) +// reconstruction_selfdual(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(marker, mask, tag::selfdual(), tag::none()); - } +// return reconstruction(marker, mask, tag::selfdual(), tag::none()); +// }
// by dilation
Index: oln/morpho/reconstruction_selfdual.hh --- oln/morpho/reconstruction_selfdual.hh (revision 257) +++ oln/morpho/reconstruction_selfdual.hh (working copy) @@ -31,6 +31,8 @@ # include <oln/canvas/reconstruction.hh> # include <oln/morpho/tags.hh>
+ +//FIXME: Adapt ... namespace oln {
Index: oln/morpho/reconstruction_by_dilation.hh --- oln/morpho/reconstruction_by_dilation.hh (revision 257) +++ oln/morpho/reconstruction_by_dilation.hh (working copy) @@ -30,6 +30,7 @@
# include <oln/canvas/reconstruction.hh> # include <oln/morpho/tags.hh> +# include <oln/morpho/local.hh> # include <oln/funobj/arith.hh>
namespace oln { @@ -38,47 +39,74 @@
namespace impl {
- // Sequential version - template<typename I1, typename I2> - struct reconstruction <I1, I2, tag::sequential_type, tag::by_dilation_type> - : public canvas::sequential_reconstruction<I1, I2, - reconstruction<I1, I2, tag::sequential_type, tag::by_dilation_type> > + + template <typename I1, typename I2, typename A, typename E> + struct reconstruction_by_dilation + : public canvas::reconstruction<I1, I2, A, E> { - typedef reconstruction<I1, I2, tag::sequential_type, - tag::by_dilation_type> self_type; - typedef canvas::sequential_reconstruction<I1, I2, self_type> super_type; + typedef canvas::reconstruction<I1, I2, A, E> super_type;
- reconstruction(const abstract::image_with_nbh<I1>& marker, + using super_type::mask; + using super_type::marker; + using super_type::output; + using super_type::bkd_p; + using super_type::fwd_p; + using super_type::n; + using super_type::p; + + + reconstruction_by_dilation(const abstract::image_with_nbh<I1>& marker, const abstract::image<I2>& mask) : super_type(marker, mask) { }
- using super_type::marker; - using super_type::mask; - using super_type::output; - using super_type::fwd_p; - using super_type::bkd_p; - using super_type::win_plus; - using super_type::win_minus; + + /// Local image "and-value" for dilation on sets + /// (based on the point and its backward neighborhood). + + oln_type_of(I1, value) bkd_or() + { + if (output[bkd_p]) + return true; + p = bkd_p; + for_all_n_of_p(n, p) + if (p.bkd_less(n) and output.hold(n) and output[n]) + return true; + + return false; + } + + + /// Local image "and-value" for dilation on sets + /// (based on the point and its forward neighborhood). + + oln_type_of(I1, value) fwd_or() + { + if (output[fwd_p]) + return true; + p = fwd_p; + for_all_n_of_p(n, p) + if (p.fwd_less(n) and output.hold(n) and output[n]) + return true; + + return false; + }
void impl_bkd_loop_body() { // FIXME: The call to value_box<>::value is needed to have - // f_min_alt compile. Try to get rid of it. - output[bkd_p] = f_min_alt(mask[bkd_p].value(), - local_max(output, bkd_p, win_minus)); + // f_max_alt compile. Try to get rid of it. + output[bkd_p] = f_min_alt(mask[bkd_p].value(), bkd_or()); }
void impl_fwd_loop_body() { // FIXME: The call to value_box<>::value is needed to have - // f_min_alt compile. Try to get rid of it. - output[fwd_p] = f_min_alt(mask[fwd_p].value(), - local_max(output, fwd_p, win_plus)); + // f_max_alt compile. Try to get rid of it. + output[fwd_p] = f_min_alt(mask[fwd_p].value(), fwd_or()); }
- // FIXME: unused... void impl_preconditions() { precondition(level::is_greater_or_equal(mask, marker)); @@ -86,75 +114,67 @@
};
- - // Hybrid version + // Sequential version
template<typename I1, typename I2> - struct reconstruction <I1, I2, tag::hybrid_type, tag::by_dilation_type> - : public canvas::hybrid_reconstruction<I1, I2, - reconstruction<I1, I2, tag::hybrid_type, tag::by_dilation_type> > + struct reconstruction <I1, I2, tag::sequential_type, tag::by_dilation_type> + : public reconstruction_by_dilation<I1, I2, tag::sequential_type, + reconstruction<I1, I2, tag::sequential_type, + tag::by_dilation_type> > { - typedef reconstruction<I1, I2, tag::hybrid_type, + typedef reconstruction<I1, I2, tag::sequential_type, tag::by_dilation_type> self_type; - typedef canvas::hybrid_reconstruction<I1, I2, + typedef reconstruction_by_dilation<I1, I2, tag::sequential_type, self_type> super_type;
- using super_type::mask; - using super_type::marker; - using super_type::work; - using super_type::output; - using super_type::fwd_p; - using super_type::bkd_p; - using super_type::win_plus; - using super_type::win_minus; - using super_type::p; - using super_type::q; - using super_type::fifo; - reconstruction(const abstract::image_with_nbh<I1>& marker, const abstract::image<I2>& mask) : super_type(marker, mask) { } + };
+ // Hybrid version
- void impl_bkd_loop_body() + template<typename I1, typename I2> + struct reconstruction <I1, I2, tag::hybrid_type, tag::by_dilation_type> + : public reconstruction_by_dilation<I1, I2, tag::hybrid_type, + reconstruction<I1, I2, tag::hybrid_type, tag::by_dilation_type> > { - // FIXME: The call to value_box<>::value is needed to have - // f_min_alt compile. Try to get rid of it. - output[bkd_p] = f_min_alt(mask[bkd_p].value(), - local_max(work, bkd_p, win_minus)); - } + typedef reconstruction<I1, I2, tag::hybrid_type, + tag::by_dilation_type> self_type; + typedef reconstruction_by_dilation<I1, I2, tag::hybrid_type, + self_type> super_type;
- void impl_fwd_loop_body() + reconstruction(const abstract::image_with_nbh<I1>& marker, + const abstract::image<I2>& mask) : + super_type(marker, mask) { - // FIXME: The call to value_box<>::value is needed to have - // f_min_alt compile. Try to get rid of it. - output[fwd_p] = f_min_alt(mask[fwd_p].value(), - local_max(work, fwd_p, win_plus)); }
+ using super_type::mask; + using super_type::output; + using super_type::bkd_p; + using super_type::n; + using super_type::p; + using super_type::fifo; + + void impl_fifo_loop_body() { - if ((output[q] < output[p]) && (mask[q] != output[q])) + if ((output[n] < output[p]) and (mask[n] != output[n])) { // FIXME: The calls to value_box<>::value are needed to // have f_min_alt compile. Try to get rid of it. - output[q] = f_min_alt(output[p].value(), mask[q].value()); - fifo.push(q); + output[n] = f_max_alt(output[p].value(), mask[n].value()); + fifo.push(n); } }
- bool impl_exist_init() + bool impl_test_fifo_push() { - return output.hold(q) && (output[q] < output[bkd_p]) && - (output[q] < mask[q]); - } - - void impl_preconditions() - { - precondition(level::is_greater_or_equal(mask, marker)); + return output[n] < output[bkd_p] and output[n] < mask[n]; }
}; Index: tests/morpho/tests/reconstruction --- tests/morpho/tests/reconstruction (revision 257) +++ tests/morpho/tests/reconstruction (working copy) @@ -40,13 +40,11 @@ mask, morpho::tag::hybrid(), morpho::tag::by_dilation()); - // FIXME: The sequential reconstruction is broken, and the test - // doesn't terminate if we compute res_dil_seq. -// res_dil_seq = -// morpho::reconstruction(join(marker, neighb_c4()), -// mask, -// morpho::tag::sequential(), -// morpho::tag::by_dilation()); + res_dil_seq = + morpho::reconstruction(join(marker, neighb_c4()), + mask, + morpho::tag::sequential(), + morpho::tag::by_dilation());
image2dntg::bin marker_c(level::invert(marker)); res_ero_hyb = @@ -54,29 +52,22 @@ level::invert(mask), morpho::tag::hybrid(), morpho::tag::by_erosion()); - // FIXME: Likewise. -// res_ero_seq = -// morpho::reconstruction(join(marker_c, neighb_c4()), -// level::invert(mask), -// morpho::tag::sequential(), -// morpho::tag::by_erosion()); - - // FIXME: Debug. - std::cerr << utils::md5(res_dil_hyb) << std::endl; - io::write(res_dil_hyb, "/tmp/res_dil_hyb.pbm"); -// std::cerr << utils::md5(res_dil_seq) << std::endl; - std::cerr << utils::md5(res_ero_hyb) << std::endl; -// std::cerr << utils::md5(res_ero_seq) << std::endl; + res_ero_seq = + morpho::reconstruction(join(marker_c, neighb_c4()), + level::invert(mask), + morpho::tag::sequential(), + morpho::tag::by_erosion());
if (utils::md5(res_dil_hyb) != key) return true; - // FIXME: Likewise. -// if (!level::is_equal(res_dil_hyb, res_dil_seq)) -// return true; -// if (!level::is_equal(res_ero_hyb, res_ero_seq)) -// return true; -// if (!level::is_equal(res_dil_hyb, level::invert(res_ero_seq))) -// return true; + + + if (!level::is_equal(res_dil_hyb, res_dil_seq)) + return true; + if (!level::is_equal(res_ero_hyb, res_ero_seq)) + return true; + if (!level::is_equal(res_dil_hyb, level::invert(res_ero_seq))) + return true;
return false; } Index: oln/morpho/reconstruction.trash --- oln/morpho/reconstruction.trash (revision 257) +++ oln/morpho/reconstruction.trash (working copy) @@ -1,227 +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 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 <queue> - -# include <mlc/cmp.hh> -# include <mlc/contract.hh> - -# include <oln/convert/nbh_to_se.hh> - -# include <oln/core/abstract/image_operator.hh> -# include <oln/core/abstract/neighborhood.hh> - -# include <oln/level/compare.hh> - -# include <oln/morpho/splitse.hh> -# include <oln/morpho/stat.hh> - -# include <oln/utils/clone.hh> - -namespace oln { - - - namespace tag { - - template <typename Op> struct oper {}; - - struct by_dilation : public oper< by_dilation > {}; - struct by_erosion : public oper< by_erosion > {}; - - - template <typename A> struct algo {}; - - struct sequential : public algo< sequential > {}; - struct hybrid : public algo< hybrid > {}; - - } // end of namespace oln::morpho::tag - - - - namespace morpho { - template <typename I1, typename I2> struct reconstruction_ret; - } // end of namespace oln::morpho - - // super_type - - template <typename I1, typename I2> - struct set_super_type< morpho::reconstruction_ret<I1, I2> > - { - typedef oln_type_of(I1, concrete) output_type; - - typedef morpho::reconstruction_ret<I1,I2> self_type; - typedef abstract::image_binary_operator<output_type, I1, I2, self_type > ret; - }; - - namespace morpho { - - // Reconstruction as a 'classical' procedure returning an image (do not - // use it; prefer morpho::reconstruction). - - namespace proc { - - // FIXME: ... - - } // end of namespace oln::morpho::proc - - - template <typename I1, typename I2> - struct reconstruction_ret : - // FIXME: oln_super_of_ - public oln::internal::get_super_type< reconstruction_ret<I1,I2> >::ret - { - typedef reconstruction_ret<I1, I2> self_type; - typedef typename oln::internal::get_super_type<self_type>::ret super_type; - - box<const I1> marker; - box<const I2> mask; - - reconstruction_ret(const abstract::image_with_nbh<I1>& marker, - const abstract::image<I2>& mask) : - super_type(marker, mask), - marker(marker), - mask(mask) - { - } - - const oln_type_of(I1, neighb)& impl_nbh_get() const - { - return marker.nbh_get(); - } - - }; - - } // end of namespace morpho - -} // end of namespace oln - -# include <oln/morpho/reconstruction_canvas.inc> - -namespace oln { - - namespace morpho { - - namespace impl { - - template<typename Op, typename A, typename I1, typename I2> - struct generic_reconstruction; - - } // end of namespace impl - - } // end of namespace morpho - -} // end of namespace oln - -# include <oln/morpho/reconstruction_by_dilation.inc> -# include <oln/morpho/reconstruction_by_erosion.inc> - -namespace oln { - - namespace morpho { - - namespace impl { - - // Generic implementation of reconstruction (routine). - - template<typename Op, typename A, typename I1, typename I2> - reconstruction_ret<I1,I2> - reconstruction(const abstract::image_with_nbh<I1>& marker, - const abstract::image<I2>& mask) - { - generic_reconstruction<Op, A, I1, I2> tmp(marker, mask); - tmp.run(); - return tmp; - } - - } // end of namespace impl - - /// Generic reconstruction (facade). - - template<typename Op, typename I1, typename I2, typename A> - reconstruction_ret<I1,I2> - reconstruction(const tag::oper<Op>& oper_, - const abstract::image_with_nbh<I1>& marker, - const abstract::image<I2>& mask, - const tag::algo<A>& algo_) - { - return impl::reconstruction<Op,A>(marker.exact(), mask.exact()); - } - - // by dilation - - template<typename I1, typename I2, typename A> - reconstruction_ret<I1,I2> - 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(), marker, mask, algo_); - } - - template<typename I1, typename I2> - reconstruction_ret<I1,I2> - 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(), marker, mask, tag::hybrid()); - } - - // by erosion - - template<typename I1, typename I2, typename A> - reconstruction_ret<I1,I2> - 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(), marker, mask, algo_); - } - - template<typename I1, typename I2> - reconstruction_ret<I1,I2> - 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(), marker, mask, tag::hybrid()); - } - - } // end of namespace oln::morpho - -} // end of namespace oln - -#endif // ! OLENA_MORPHO_RECONSTRUCTION_HH Index: oln/core/abstract/point.hh --- oln/core/abstract/point.hh (revision 257) +++ oln/core/abstract/point.hh (working copy) @@ -139,7 +139,7 @@ /// Anteriority w.r.t. to a bkd image browsing. bool bkd_less(const exact_type& rhs) const { - return not *this == rhs and not this->fwd_less(rhs); + return not (*this == rhs and not this->fwd_less(rhs)); }
/*! \brief Test difference of two points. Nota bene: this method Index: oln/morpho/reconstruction_by_erosion.hh --- oln/morpho/reconstruction_by_erosion.hh (revision 257) +++ oln/morpho/reconstruction_by_erosion.hh (working copy) @@ -30,6 +30,7 @@
# include <oln/canvas/reconstruction.hh> # include <oln/morpho/tags.hh> +# include <oln/morpho/local.hh> # include <oln/funobj/arith.hh>
namespace oln { @@ -38,49 +39,74 @@
namespace impl {
- // Sequential version
- template<typename I1, typename I2> - struct reconstruction <I1, I2, tag::sequential_type, tag::by_erosion_type> - : public canvas::sequential_reconstruction<I1, I2, - reconstruction<I1, I2, tag::sequential_type, - tag::by_erosion_type> > + template <typename I1, typename I2, typename A, typename E> + struct reconstruction_by_erosion + : public canvas::reconstruction<I1, I2, A, E> { - typedef reconstruction<I1, I2, tag::sequential_type, - tag::by_erosion_type> self_type; - typedef canvas::sequential_reconstruction<I1, I2, self_type> super_type; + typedef canvas::reconstruction<I1, I2, A, E> super_type;
- reconstruction(const abstract::image_with_nbh<I1>& marker, + using super_type::mask; + using super_type::marker; + using super_type::output; + using super_type::bkd_p; + using super_type::fwd_p; + using super_type::n; + using super_type::p; + + + reconstruction_by_erosion(const abstract::image_with_nbh<I1>& marker, const abstract::image<I2>& mask) : super_type(marker, mask) { }
- using super_type::marker; - using super_type::mask; - using super_type::output; - using super_type::fwd_p; - using super_type::bkd_p; - using super_type::win_plus; - using super_type::win_minus; + + /// Local image "and-value" for erosion on sets + /// (based on the point and its backward neighborhood). + + oln_type_of(I1, value) bkd_and() + { + if (not output[bkd_p]) + return false; + p = bkd_p; + for_all_n_of_p(n, p) + if (p.bkd_less(n) and output.hold(n) and not output[n]) + return false; + + return true; + } + + + /// Local image "and-value" for erosion on sets + /// (based on the point and its forward neighborhood). + + oln_type_of(I1, value) fwd_and() + { + if (not output[fwd_p]) + return false; + p = fwd_p; + for_all_n_of_p(n, p) + if (p.fwd_less(n) and output.hold(n) and not output[n]) + return false; + + return true; + }
void impl_bkd_loop_body() { // FIXME: The call to value_box<>::value is needed to have // f_max_alt compile. Try to get rid of it. - output[bkd_p] = f_max_alt(mask[bkd_p].value(), - local_min(output, bkd_p, win_minus)); + output[bkd_p] = f_max_alt(mask[bkd_p].value(), bkd_and()); }
void impl_fwd_loop_body() { // FIXME: The call to value_box<>::value is needed to have // f_max_alt compile. Try to get rid of it. - output[fwd_p] = f_max_alt(mask[fwd_p].value(), - local_min(output, fwd_p, win_plus)); + output[fwd_p] = f_max_alt(mask[fwd_p].value(), fwd_and()); }
- // FIXME: unused... void impl_preconditions() { precondition(level::is_greater_or_equal(marker, mask)); @@ -88,16 +114,37 @@
};
+ // Sequential version + + template<typename I1, typename I2> + struct reconstruction <I1, I2, tag::sequential_type, tag::by_erosion_type> + : public reconstruction_by_erosion<I1, I2, tag::sequential_type, + reconstruction<I1, I2, tag::sequential_type, + tag::by_erosion_type> > + { + typedef reconstruction<I1, I2, tag::sequential_type, + tag::by_erosion_type> self_type; + typedef reconstruction_by_erosion<I1, I2, tag::sequential_type, + self_type> super_type; + + reconstruction(const abstract::image_with_nbh<I1>& marker, + const abstract::image<I2>& mask) : + super_type(marker, mask) + { + } + }; + + // Hybrid version
template<typename I1, typename I2> struct reconstruction <I1, I2, tag::hybrid_type, tag::by_erosion_type> - : public canvas::hybrid_reconstruction<I1, I2, + : public reconstruction_by_erosion<I1, I2, tag::hybrid_type, reconstruction<I1, I2, tag::hybrid_type, tag::by_erosion_type> > { typedef reconstruction<I1, I2, tag::hybrid_type, tag::by_erosion_type> self_type; - typedef canvas::hybrid_reconstruction<I1, I2, + typedef reconstruction_by_erosion<I1, I2, tag::hybrid_type, self_type> super_type;
reconstruction(const abstract::image_with_nbh<I1>& marker, @@ -107,54 +154,27 @@ }
using super_type::mask; - using super_type::marker; - using super_type::work; using super_type::output; - using super_type::fwd_p; using super_type::bkd_p; - using super_type::win_plus; - using super_type::win_minus; + using super_type::n; using super_type::p; - using super_type::q; using super_type::fifo;
- void impl_bkd_loop_body() - { - // FIXME: The call to value_box<>::value is needed to have - // f_max_alt compile. Try to get rid of it. - output[bkd_p] = f_max_alt(mask[bkd_p].value(), - local_min(work, bkd_p, win_minus)); - } - - void impl_fwd_loop_body() - { - // FIXME: The call to value_box<>::value is needed to have - // f_max_alt compile. Try to get rid of it. - output[fwd_p] = f_max_alt(mask[fwd_p].value(), - local_min(work, fwd_p, win_plus)); - }
void impl_fifo_loop_body() { - if ((output[q] > output[p]) && (mask[q] != output[q])) + if ((output[n] > output[p]) and (mask[n] != output[n])) { // FIXME: The calls to value_box<>::value are needed to // have f_min_alt compile. Try to get rid of it. - output[q] = f_min_alt(output[p].value(), mask[q].value()); - fifo.push(q); - } + output[n] = f_min_alt(output[p].value(), mask[n].value()); + fifo.push(n); } - - bool impl_exist_init() - { - return output.hold(q) && (output[q] > output[bkd_p]) && - (output[q] > mask[q]); }
- // FIXME: unused... - void impl_preconditions() + bool impl_test_fifo_push() { - precondition(level::is_greater_or_equal(marker, mask)); + return output[n] > output[bkd_p] and output[n] > mask[n]; }
}; Index: oln/canvas/reconstruction.hh --- oln/canvas/reconstruction.hh (revision 257) +++ oln/canvas/reconstruction.hh (working copy) @@ -33,6 +33,7 @@ # include <oln/canvas/backandforth.hh> # include <oln/level/compare.hh> # include <oln/utils/clone.hh> +# include <oln/morpho/tags.hh>
namespace oln {
@@ -49,25 +50,35 @@
namespace canvas {
+ // fwd decl + + template <typename I1, typename I2, typename A, typename E> + struct reconstruction; + template <typename I1, typename I2, typename E> - struct hybrid_reconstruction : public mlc::any<E> + struct reconstruction<I1, I2, morpho::tag::hybrid_type, E> + : public mlc::any<E> {
typedef oln_type_of(I1, neighb) nbh_type; + typedef oln_type_of(I1, point) point_type; typedef oln_nbh_type_of(nbh_type, window) window_type; typedef oln_type_of(I1, concrete) output_type;
- bool exist_init() + bool test_fifo_push() { - 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()) + p = bkd_p; + for_all_n_of_p(n, bkd_p) + if (p.bkd_less(n) and output.hold(n) and this->exact().impl_test_fifo_push()) return true; - } + return false; }
+ void preconditions() + { + this->exact().impl_preconditions(); + }
void fwd_loop_body() { @@ -86,20 +97,16 @@
void init() { - output_type output_tmp(marker.size()); - output = output_tmp; - // FIXME: We can't use `work = clone(marker)' directly here, + // FIXME: We can't use `output = clone(marker)' directly here, // because box's op=(const abstract::image<II>& rhs) would be // called, which is empty (see oln/core/box.hh). - output_type work_tmp(clone(marker)); - work = work_tmp; - - win_plus = marker.nbh_get().get_win().get_fwd_win_p(); - win_minus = marker.nbh_get().get_win().get_bkd_win_p(); + output_type output_tmp(clone(marker)); + output = output_tmp; }
void run() { + preconditions(); init();
for_all_p (fwd_p) @@ -108,7 +115,7 @@ for_all_p (bkd_p) { bkd_loop_body(); - if (exist_init()) + if (test_fifo_push()) fifo.push(bkd_p); }
@@ -118,12 +125,9 @@ p = fifo.front(); fifo.pop();
- window_type win = marker.nbh_get().get_win(); - for (unsigned i = 0; i < win.card(); ++i) + for_all_n_of_p(n, p) { - q = win.get_dp()[i] + p; - - if (output.hold(q)) + if (output.hold(n)) fifo_loop_body(); } } @@ -136,43 +140,44 @@
protected:
- hybrid_reconstruction(const abstract::image_with_nbh<I1>& marker, + 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()) + fwd_p(marker.size()), + n(marker) { }
- ~hybrid_reconstruction() + ~reconstruction() { - mlc_check_method_impl(E, bool, exist_init, , ); + mlc_check_method_impl(E, bool, test_fifo_push, , ); 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, 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<const I1> marker; box<const I2> mask;
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, niter) n; + + box<oln_type_of(I1, concrete)> output; + std::queue<oln_type_of(I1, point) > fifo;
};
+ + + template <typename I1, typename I2, typename E> - struct sequential_reconstruction : + struct reconstruction<I1, I2, morpho::tag::sequential_type, E> : public back_and_forth_until_convergence<I1, E> { typedef back_and_forth_until_convergence<I1, E> super_type; @@ -187,28 +192,25 @@ // called, which is empty (see oln/core/box.hh). output_type output_tmp(clone(marker)); output = output_tmp; - // FIXME: We can't use `work = clone(marker)' directly here, + // FIXME: We can't use `save = clone(marker)' directly here, // because box's op=(const abstract::image<II>& rhs) would be // called, which is empty (see oln/core/box.hh). - output_type work_tmp(clone(marker)); - work = work_tmp; + output_type save_tmp(clone(marker)); + save = save_tmp;
- 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() const { - return level::is_equal(work, output); + return level::is_equal(save, output); }
void impl_re_loop() { - // FIXME: We can't use `output = clone(marker)' directly here, + // FIXME: We can't use `save = clone(output)' directly here, // because box's op=(const abstract::image<II>& rhs) would be // called, which is empty (see oln/core/box.hh). - output_type work_tmp(clone(marker)); - work = work_tmp; + save.unbox() = clone(output); }
oln_type_of(I1, concrete) get_output() @@ -216,21 +218,21 @@ return output.unbox(); }
- sequential_reconstruction(const abstract::image_with_nbh<I1>& marker, + reconstruction(const abstract::image_with_nbh<I1>& marker, const abstract::image<I2>& mask) : super_type(marker), marker(marker.exact()), - mask(mask.exact()) + mask(mask.exact()), + n(marker) { }
- 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)> save; box<oln_type_of(I1, concrete)> output; box<const I1> marker; box<const I2> mask; + oln_type_of(I1, point) p; + oln_type_of(I1, niter) n;
};
Index: oln/morpho/reconstruction_canvas.inctrash --- oln/morpho/reconstruction_canvas.inctrash (revision 257) +++ oln/morpho/reconstruction_canvas.inctrash (working copy) @@ -1,238 +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 { - - template <typename I1, typename I2, typename A, typename E> - struct generic_reconstruction_canvas; - - template <typename I1, typename I2, typename E> - struct generic_reconstruction_canvas<I1, I2, tag::sequential, E> : - public reconstruction_ret<I1, I2> - { - typedef reconstruction_ret<I1, I2> super_type; - typedef oln_type_of(I1, neighb) nbh_type; - typedef oln_type_of(I1, concrete) output_type; - - E& exact__() - { - return *(E*)(void*)(this); - } - - void bkd_loop_body() - { - this->exact__().impl_bkd_loop_body(); - } - void fwd_loop_body() - { - this->exact__().impl_fwd_loop_body(); - } - - void preconditions() - { - mlc::eq<oln_type_of(I1, grid), oln_type_of(I2, grid)>::ensure(); - precondition(this->marker.size() == this->mask.size()); - this->exact__().impl_preconditions(); - } - - void init() - { - // no call to impl_init here because this canvas can't be generalized yet. - this->output = utils::clone(this->marker); - this->work = utils::clone(this->marker); - - win_plus = get_plus_win_p(convert::nbh_to_cse(this->marker.nbh_get())); - win_minus = get_minus_win_p(convert::nbh_to_cse(this->marker.nbh_get())); - } - - bool is_stable() - { - // same explanation as above - return level::is_equal(this->work, this->output); - } - - void impl_run() - { - this->preconditions(); - this->init(); - for (;;) - { - for_all_p (fwd_p) - this->fwd_loop_body(); - for_all_p (bkd_p) - this->bkd_loop_body(); - if (this->is_stable()) - return; - work = utils::clone(this->output); - } - } - - protected: - - generic_reconstruction_canvas(const abstract::image_with_nbh<I1>& marker, - const abstract::image<I2>& mask) : - super_type(marker, mask), - bkd_p(marker.size()), - fwd_p(marker.size()) - { - } - - - oln_type_of(I1, bkd_piter) bkd_p; - oln_type_of(I1, fwd_piter) fwd_p; - - 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; - }; - - template <typename I1, typename I2, typename E> - struct generic_reconstruction_canvas<I1, I2, tag::hybrid, E> : - public reconstruction_ret<I1, I2> - { - typedef reconstruction_ret<I1, I2> super_type; - 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; - - E& exact__() - { - return *(E*)(void*)(this); - } - - - 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 bkd_loop_body() - { - this->exact__().impl_bkd_loop_body(); - } - void fwd_loop_body() - { - this->exact__().impl_fwd_loop_body(); - } - - void fifo_loop_body() - { - this->exact__().impl_fifo_loop_body(); - } - - void preconditions() - { - mlc::eq<oln_type_of(I1, grid), oln_type_of(I2, grid)>::ensure(); - precondition(this->marker.size() == this->mask.size()); - this->exact__().impl_preconditions(); - } - - void init() - { - output_type tmp(this->marker.size()); - - this->output = tmp; - this->work = utils::clone(this->marker); - - win_plus = get_plus_win_p(convert::nbh_to_cse(this->marker.nbh_get())); - win_minus = get_minus_win_p(convert::nbh_to_cse(this->marker.nbh_get())); - } - - void impl_run() - { - this->preconditions(); - this->init(); - - for_all_p (fwd_p) - this->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 = convert::nbh_to_se(this->marker.nbh_get()); - for (unsigned i = 0; i < win.card(); ++i) - { - q = win.get_dp()[i] + p; - - if (this->output.hold(q)) - fifo_loop_body(); - } - } - } - - protected: - - generic_reconstruction_canvas(const abstract::image_with_nbh<I1>& marker, - const abstract::image<I2>& mask) : - super_type(marker, mask), - bkd_p(marker.size()), - fwd_p(marker.size()) - { - } - - - 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; - - std::queue<oln_type_of(I1, point) > fifo; - - }; - - } // end of namespace impl - - } // end of namespace morpho - -} // end of namespace oln