Je fais le reconstruction auto-duale demain.
Index: ChangeLog
from Damien Thivolle <damien(a)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());
image2d<ntg::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