Olena-patches
Threads by month
- ----- 2025 -----
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
April 2005
- 8 participants
- 73 discussions
Index: ChangeLog
from Damien Thivolle <damien(a)lrde.epita.fr>
* oln/morpho/reconstruction.hh: Remove a comment.
* oln/morpho/hit_or_miss.hh: New. Hit or miss implementation.
* oln/arith/ops.hh: Add comment to make it compile with g++-3.4.
* oln/arith/min.hh: Add a template parameter.
* oln/arith/max.hh: Add a template parameter.
arith/max.hh | 38 +++++----
arith/min.hh | 38 +++++----
arith/ops.hh | 24 +++---
morpho/hit_or_miss.hh | 186 +++++++++++++++++++++++++++++++++++++++++++++++
morpho/reconstruction.hh | 2
5 files changed, 244 insertions(+), 44 deletions(-)
Index: oln/morpho/reconstruction.hh
--- oln/morpho/reconstruction.hh (revision 164)
+++ oln/morpho/reconstruction.hh (working copy)
@@ -45,8 +45,6 @@
# include <oln/utils/clone.hh>
-// FIXME: ADD TESTS !!!!
-
namespace oln {
Index: oln/morpho/hit_or_miss.hh
--- oln/morpho/hit_or_miss.hh (revision 0)
+++ oln/morpho/hit_or_miss.hh (revision 0)
@@ -0,0 +1,186 @@
+// Copyright (C) 2001, 2003, 2004, 2005 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+// MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef OLENA_MORPHO_HIT_OR_MISS_HH
+# define OLENA_MORPHO_HIT_OR_MISS_HH
+
+# include <oln/core/gen/image_with_nbh.hh>
+# include <oln/morpho/erosion.hh>
+# include <oln/morpho/dilation.hh>
+# include <oln/arith/min.hh>
+# include <oln/utils/invert.hh>
+
+namespace oln {
+
+ namespace tag {
+
+ // No tags yet
+
+ } // end of namespace oln::morpho::tag
+
+
+ namespace morpho {
+ template <typename I, typename W1, typename W2> struct hit_or_miss_ret;
+ } // end of namespace oln::morpho
+
+ // super_type
+
+ template <typename I, typename W1, typename W2>
+ struct set_super_type< morpho::hit_or_miss_ret<I, W1, W2> >
+ {
+ typedef oln_type_of(I, concrete) output_type;
+
+ typedef morpho::hit_or_miss_ret<I, W1, W2> self_type;
+ typedef abstract::image_unary_operator<output_type, I, self_type > ret;
+ };
+
+ namespace morpho {
+
+ // Reconstruction as a 'classical' procedure returning an image (do not
+ // use it; prefer morpho::hit_or_miss).
+
+ namespace proc {
+
+ // FIXME: ...
+
+ } // end of namespace oln::morpho::proc
+
+
+ template <typename I, typename W1, typename W2>
+ struct hit_or_miss_ret :
+ // FIXME: oln_super_of_
+ public oln::internal::get_super_type< hit_or_miss_ret<I, W1, W2> >::ret
+ {
+ typedef hit_or_miss_ret<I, W1, W2> self_type;
+ typedef typename oln::internal::get_super_type<self_type>::ret super_type;
+ const W1& win1;
+ const W2& win2;
+
+ hit_or_miss_ret(const abstract::image<I>& input,
+ const abstract::regular_window<oln_type_of(I, grid), W1> win1,
+ const abstract::regular_window<oln_type_of(I, grid), W2> win2) :
+ super_type(input),
+ win1(win1.exact()),
+ win2(win2.exact())
+ {
+ }
+
+ };
+
+
+ namespace impl {
+
+ template <typename I, typename W1, typename W2>
+ struct generic_hit_or_miss : public hit_or_miss_ret<I, W1, W2>
+ {
+ typedef hit_or_miss_ret<I, W1, W2> super_type;
+
+ generic_hit_or_miss(const abstract::image<I>& input,
+ const abstract::regular_window<oln_type_of(I, grid), W1> win1,
+ const abstract::regular_window<oln_type_of(I, grid), W2> win2) :
+ super_type(input, win1, win2)
+ {
+ }
+
+ void impl_run()
+ {
+ this->output = arith::min(erosion(this->input, this->win1),
+ erosion(utils::invert(this->input),
+ this->win2));
+ }
+ };
+
+ template <typename I, typename W1, typename W2>
+ hit_or_miss_ret<I, W1, W2>
+ hit_or_miss(const abstract::image<I>& input,
+ const abstract::regular_window<oln_type_of(I, grid), W1> win1,
+ const abstract::regular_window<oln_type_of(I, grid), W2> win2)
+ {
+ generic_hit_or_miss<I, W1, W2> tmp(input, win1, win2);
+ tmp.run();
+ return tmp;
+ }
+
+ } //end of namespace impl
+
+ template <typename I, typename W1, typename W2>
+ hit_or_miss_ret<I, W1, W2>
+ hit_or_miss(const abstract::image<I>& input,
+ const abstract::regular_window<oln_type_of(I, grid), W1> win1,
+ const abstract::regular_window<oln_type_of(I, grid), W2> win2)
+ {
+ // FIXME: win1 inter win2 must be empty
+ return impl::hit_or_miss(input.exact(), win1.exact(), win2.exact());
+ }
+
+
+ template<class I, class W1, class W2>
+ dilation_ret<hit_or_miss_ret<I, W1, W2>, W1>
+ hit_or_miss_opening(const abstract::image<I>& input,
+ const abstract::regular_window<oln_type_of(I, grid), W1> win1,
+ const abstract::regular_window<oln_type_of(I, grid), W2> win2)
+ {
+ return dilation(hit_or_miss(input, win1, win2), -win1);
+ }
+
+ template<class I, class W1, class W2>
+ dilation_ret<hit_or_miss_ret<I, W2, W1>, W2>
+ hit_or_miss_opening_bg(const abstract::image<I>& input,
+ const abstract::regular_window<oln_type_of(I, grid), W1> win1,
+ const abstract::regular_window<oln_type_of(I, grid), W2> win2)
+ {
+ return hit_or_miss_opening(input, win2, win1);
+ }
+
+ template<class I, class W1, class W2>
+ utils::image_inverted<dilation_ret<hit_or_miss_ret<utils::image_inverted<I>,
+ W1, W2>, W1> > // !!!
+ hit_or_miss_closing(const abstract::image<I>& input,
+ const abstract::regular_window<oln_type_of(I, grid), W1> win1,
+ const abstract::regular_window<oln_type_of(I, grid), W2> win2)
+ {
+ return utils::invert(hit_or_miss_opening(utils::invert(input),
+ win1, win2));
+ }
+
+ template<class I, class W1, class W2>
+ utils::image_inverted<dilation_ret<hit_or_miss_ret<utils::image_inverted<I>,
+ W2, W1>, W2> > // !!!
+ hit_or_miss_closing_bg(const abstract::image<I>& input,
+ const abstract::regular_window<oln_type_of(I, grid), W1> win1,
+ const abstract::regular_window<oln_type_of(I, grid), W2> win2)
+ {
+ return hit_or_miss_closing(input, win2, win1);
+ }
+
+
+
+ } // end of namespace morpho
+
+} // end of namespace oln
+
+#endif // ! OLENA_MORPHO_HIT_OR_MISS_HH
Index: oln/arith/ops.hh
--- oln/arith/ops.hh (revision 164)
+++ oln/arith/ops.hh (working copy)
@@ -131,18 +131,18 @@
-template <typename I, typename F>
-void operator + (const oln::abstract::image<I>&,
- const oln::pw::abstract::function<F>&)
-{
- struct OLENA_ERROR__args_are_not_compatible();
-}
-template <typename F, typename I>
-void operator + (const oln::pw::abstract::function<F>&,
- const oln::abstract::image<I>&)
-{
- struct OLENA_ERROR__args_are_not_compatible();
-}
+// template <typename I, typename F>
+// void operator + (const oln::abstract::image<I>&,
+// const oln::pw::abstract::function<F>&)
+// {
+// struct OLENA_ERROR__args_are_not_compatible();
+// }
+// template <typename F, typename I>
+// void operator + (const oln::pw::abstract::function<F>&,
+// const oln::abstract::image<I>&)
+// {
+// struct OLENA_ERROR__args_are_not_compatible();
+// }
// FIXME: to be continued...
Index: oln/arith/min.hh
--- oln/arith/min.hh (revision 164)
+++ oln/arith/min.hh (working copy)
@@ -38,38 +38,45 @@
namespace arith {
// fwd decl
namespace impl {
- template <typename I> struct min_type;
+ template <typename I1, typename I2> struct min_type;
}
}
// super_type
- template <typename I>
- struct set_super_type< arith::impl::min_type<I> >
+ template <typename I1, typename I2>
+ struct set_super_type< arith::impl::min_type<I1, I2> >
{
- typedef abstract::image_binary_operator<I, I, I, arith::impl::min_type<I> > ret;
+ typedef oln_type_of(I1, concrete) output_type;
+ typedef arith::impl::min_type<I1, I2> self_type;
+ typedef abstract::image_binary_operator<output_type, I1, I2, self_type> ret;
};
namespace arith {
namespace impl {
- template <class I>
- struct min_type : public abstract::image_binary_operator<I, I, I, min_type<I> >
+ template <typename I1, typename I2>
+ struct min_type :
+ // FIXME: oln_super_of_
+ public oln::internal::get_super_type< min_type<I1,I2> >::ret
{
- typedef abstract::image_binary_operator<I, I, I, min_type<I> > super_type;
+ typedef typename oln::internal::get_super_type< min_type<I1,I2> >::ret
+ super_type;
+ typedef oln_type_of(I1, concrete) output_type;
- min_type(const abstract::image<I>& input1,
- const abstract::image<I>& input2) :
+ min_type(const abstract::image<I1>& input1,
+ const abstract::image<I2>& input2) :
super_type(input1.exact(), input2.exact())
{}
void impl_run()
{
precondition(this->input1.size() == this->input2.size());
- I output(this->input1.size());
- oln_type_of(I, fwd_piter) p(this->input1.size());
+ output_type output(this->input1.size());
+ oln_type_of(I1, fwd_piter) p(this->input1.size());
+
for_all_p (p)
output[p] = ntg::min(this->input1[p].value(), this->input2[p].value());
@@ -80,11 +87,12 @@
}
- template <typename I>
- impl::min_type<I> min(const abstract::image<I>& input1,
- const abstract::image<I>& input2)
+ template <typename I1, typename I2>
+ impl::min_type<I1, I2> min(const abstract::image<I1>& input1,
+ const abstract::image<I2>& input2)
{
- impl::min_type<I> tmp(input1, input2);
+ mlc::eq<oln_type_of(I1, grid), oln_type_of(I2, grid)>::ensure();
+ impl::min_type<I1, I2> tmp(input1, input2);
tmp.run();
return tmp;
}
Index: oln/arith/max.hh
--- oln/arith/max.hh (revision 164)
+++ oln/arith/max.hh (working copy)
@@ -38,38 +38,45 @@
namespace arith {
// fwd decl
namespace impl {
- template <typename I> struct max_type;
+ template <typename I1, typename I2> struct max_type;
}
}
// super_type
- template <typename I>
- struct set_super_type< arith::impl::max_type<I> >
+ template <typename I1, typename I2>
+ struct set_super_type< arith::impl::max_type<I1, I2> >
{
- typedef abstract::image_binary_operator<I, I, I, arith::impl::max_type<I> > ret;
+ typedef oln_type_of(I1, concrete) output_type;
+ typedef arith::impl::max_type<I1, I2> self_type;
+ typedef abstract::image_binary_operator<output_type, I1, I2, self_type> ret;
};
namespace arith {
namespace impl {
- template <class I>
- struct max_type : public abstract::image_binary_operator<I, I, I, max_type<I> >
+ template <typename I1, typename I2>
+ struct max_type :
+ // FIXME: oln_super_of_
+ public oln::internal::get_super_type< max_type<I1,I2> >::ret
{
- typedef abstract::image_binary_operator<I, I, I, max_type<I> > super_type;
+ typedef typename oln::internal::get_super_type< max_type<I1,I2> >::ret
+ super_type;
+ typedef oln_type_of(I1, concrete) output_type;
- max_type(const abstract::image<I>& input1,
- const abstract::image<I>& input2) :
+ max_type(const abstract::image<I1>& input1,
+ const abstract::image<I2>& input2) :
super_type(input1.exact(), input2.exact())
{}
void impl_run()
{
precondition(this->input1.size() == this->input2.size());
- I output(this->input1.size());
- oln_type_of(I, fwd_piter) p(this->input1.size());
+ output_type output(this->input1.size());
+ oln_type_of(I1, fwd_piter) p(this->input1.size());
+
for_all_p (p)
output[p] = ntg::max(this->input1[p].value(), this->input2[p].value());
@@ -80,11 +87,12 @@
}
- template <typename I>
- impl::max_type<I> max(const abstract::image<I>& input1,
- const abstract::image<I>& input2)
+ template <typename I1, typename I2>
+ impl::max_type<I1, I2> max(const abstract::image<I1>& input1,
+ const abstract::image<I2>& input2)
{
- impl::max_type<I> tmp(input1, input2);
+ mlc::eq<oln_type_of(I1, grid), oln_type_of(I2, grid)>::ensure();
+ impl::max_type<I1, I2> tmp(input1, input2);
tmp.run();
return tmp;
}
1
0
Index: ChangeLog
from Damien Thivolle <damien(a)lrde.epita.fr>
* oln/io/write_image_2d_pnm.hh (ntg::bin): Write padding bits at the
end of each line.
* oln/io/read_image_2d_pnm.hh (ntg::bin): Skip padding bits at the end
of each line.
read_image_2d_pnm.hh | 24 +++++++++++++++++++-----
write_image_2d_pnm.hh | 40 ++++++++++++++++++++++------------------
2 files changed, 41 insertions, 23 deletions
Index: oln/io/write_image_2d_pnm.hh
--- oln/io/write_image_2d_pnm.hh (revision 163)
+++ oln/io/write_image_2d_pnm.hh (working copy)
@@ -74,33 +74,43 @@
{
point2d p;
value_type c;
- bool b = false;
for (p.row() = 0; p.row() < to_write_.size().nrows(); ++p.row())
- for (p.col() = 0; p.col() < to_write_.size().ncols(); ++p.col())
+ {
+ for (p.col() = 0; p.col() < to_write_.size().ncols(); ++p.col())
// FIXME: SHOULD NOT BE .value() !!!
- b = write_value_type(to_write_[p].value());
- while (b == false)
- b = write_value_type(c);
- bin_offset = 7;
- bin_v = 0;
+ write_value_type(to_write_[p].value());
+ write_padding(c);
+ }
}
+ template <typename E>
+ void write_padding(const ntg::value<E>&) {}
+
+ void write_padding(const ntg::bin&)
+ {
+ if (bin_offset != 7)
+ {
+ ostr_.write(&bin_v, 1);
+ bin_offset = 7;
+ bin_v = 0;
+ }
+ }
+
//FIXME: Should work with builtin types.
template <typename E>
- bool write_value_type(const ntg::real_value<E> &c)
+ void write_value_type(const ntg::real_value<E> &c)
{
typedef oln_io_type(ntg_nbits(E)) v_type;
v_type v;
v = ntg::cast::bound<E, v_type>(c.exact());
ostr_.write((char*)&v, sizeof (v_type));
- return true;
}
template <typename E>
- bool write_value_type(const ntg::vect_value<E> &c)
+ void write_value_type(const ntg::vect_value<E> &c)
{
for (unsigned i = 0; i < 3; i++)
{
@@ -110,25 +120,19 @@
v = c[i];
ostr_.write((char*)&v, sizeof (v_type));
}
- return true;
}
- bool write_value_type(const ntg::bin &c)
+ void write_value_type(const ntg::bin &c)
{
- bool ret = false;
-
if (bin_offset == -1)
{
- bin_v = ~bin_v;
ostr_.write(&bin_v, 1);
bin_offset = 7;
bin_v = 0;
- ret = true;
}
- if (c == value_type(0))
+ if (c == value_type(1))
bin_v |= 1 << bin_offset;
bin_offset--;
- return ret;
}
};
Index: oln/io/read_image_2d_pnm.hh
--- oln/io/read_image_2d_pnm.hh (revision 163)
+++ oln/io/read_image_2d_pnm.hh (working copy)
@@ -119,14 +119,28 @@
precond(c);
for (p.row() = 0; p.row() < info_.rows && !istr_.eof(); ++p.row())
- for (p.col() = 0; p.col() < info_.cols && !istr_.eof(); ++p.col())
- {
- read_value_type(c);
- tmp[p] = c;
- }
+ {
+ offset = -1;
+ for (p.col() = 0; p.col() < info_.cols && !istr_.eof(); ++p.col())
+ {
+ read_value_type(c);
+ tmp[p] = c;
+ }
+ }
this->output = tmp;
}
+
+// template <typename E>
+// void read_padding(const ntg::value<E>&)
+// {
+// }
+
+// void read_padding(const ntg::bin&)
+// {
+// offset = -1;
+// }
+
//FIXME: Should work with builtin types.
template <typename E>
2
2
Encore un probleme avec vcs, les modifications du patch 163 n'ont pas ete
commitees sur le repository, j'ai donc du le faire a la main...
--
Damien Thivolle
damien(a)lrde.epita.fr
1
0
Index: ChangeLog
from Damien Thivolle <damien(a)lrde.epita.fr>
* tests/morpho/tests/reconstruction: New.
* oln/convert/nbh_to_se.hh: Adapt to new neighborhoods.
* oln/core/abstract/image_neighbness.hh (impl_get_nbh): Add missing
method.
* oln/morpho/reconstruction.hh: New hierarchy.
* oln/morpho/splitse.hh: Adapt to new neighborhoods.
* oln/morpho/reconstruction_by_erosion.inc: New. Implementation for
reconstruction by erosion.
* oln/morpho/reconstruction_canvas.inc: New. Canvas for reconstruction:
sequential & hybrid.
* oln/morpho/reconstruction_by_dilation.inc: New. Implementation for
reconstruction by dilation.
* img/marker.pbm: New.
* img/mask.pbm: New.
img/marker.pbm | 0
img/mask.pbm | 0
oln/convert/nbh_to_se.hh | 8
oln/core/abstract/image_neighbness.hh | 6
oln/morpho/reconstruction.hh | 514 +++++++-----------------------
oln/morpho/reconstruction_by_dilation.inc | 142 ++++++++
oln/morpho/reconstruction_by_erosion.inc | 141 ++++++++
oln/morpho/reconstruction_canvas.inc | 238 +++++++++++++
oln/morpho/splitse.hh | 127 +++----
tests/morpho/tests/reconstruction | 66 +++
10 files changed, 780 insertions, 462 deletions
Index: tests/morpho/tests/reconstruction
--- tests/morpho/tests/reconstruction (revision 0)
+++ tests/morpho/tests/reconstruction (revision 0)
@@ -0,0 +1,66 @@
+// -*- C++ -*-
+
+#include "data.hh"
+#include <oln/basics2d.hh>
+#include <ntg/all.hh>
+
+#include <oln/core/gen/image_with_nbh.hh>
+
+#include <oln/morpho/reconstruction.hh>
+
+#include <oln/io/read_image.hh>
+#include <oln/io/write_image.hh>
+
+#include <oln/level/compare.hh>
+#include <oln/utils/md5.hh>
+#include <oln/utils/invert.hh>
+
+bool check()
+{
+ using namespace oln;
+ image2d<ntg::bin> marker;
+ image2d<ntg::bin> mask;
+ image2d<ntg::bin> res_dil_hyb;
+ image2d<ntg::bin> res_dil_seq;
+ image2d<ntg::bin> res_ero_hyb;
+ image2d<ntg::bin> res_ero_seq;
+
+ utils::key::value_type data_key[16] =
+ {
+ 0x36, 0xa6, 0x2e, 0x7e, 0xbf, 0x21, 0xf6, 0x2b,
+ 0xbf, 0x57, 0x58, 0xdc, 0x9d, 0x72, 0x41, 0x8f
+ };
+ utils::key key(data_key);
+
+ marker = io::read(rdata("marker.pbm"));
+ mask = io::read(rdata("mask.pbm"));
+
+ res_dil_hyb = morpho::reconstruction(tag::by_dilation(),
+ join(marker, neighb_c4()),
+ mask,
+ tag::hybrid());
+ res_dil_seq = morpho::reconstruction(tag::by_dilation(),
+ join(marker, neighb_c4()),
+ mask,
+ tag::sequential());
+
+ res_ero_hyb = morpho::reconstruction(tag::by_erosion(),
+ utils::invert(join(marker, neighb_c4())),
+ utils::invert(mask),
+ tag::hybrid());
+ res_ero_seq = morpho::reconstruction(tag::by_erosion(),
+ utils::invert(join(marker, neighb_c4())),
+ utils::invert(mask),
+ tag::sequential());
+
+ if (utils::md5(res_dil_hyb) != key)
+ 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, utils::invert(res_ero_seq)))
+ return true;
+
+ return false;
+}
Index: oln/convert/nbh_to_se.hh
--- oln/convert/nbh_to_se.hh (revision 162)
+++ oln/convert/nbh_to_se.hh (working copy)
@@ -40,12 +40,12 @@
*/
template<class N>
oln_nbh_type_of(N, window)
- nbh_to_se(const oln::abstract::neighborhood<N>& nbh)
+ nbh_to_se(const N& nbh) // FIXME: UGLY oln::abstract::neighborhood<N>& nbh)
{
oln_nbh_type_of(N, window) output;
for (unsigned i = 0; i < nbh.card(); i++)
- output.add(nbh[i]);
+ output.add(nbh.dp(i));
return output;
}
@@ -61,12 +61,12 @@
*/
template<class N>
oln_nbh_type_of(N, window)
- nbh_to_cse(const oln::abstract::neighborhood<N>& nbh)
+ nbh_to_cse(const N& nbh) // FIXME: UGLY oln::abstract::neighborhood<N>& nbh)
{
oln_nbh_type_of(N, window) output;
for (unsigned i = 0; i < nbh.card(); i++)
- output.add(nbh[i]);
+ output.add(nbh.dp(i));
oln_nbh_type_of(N, dpoint) zero;
dpoint_zero(zero);
Index: oln/core/abstract/image_neighbness.hh
--- oln/core/abstract/image_neighbness.hh (revision 162)
+++ oln/core/abstract/image_neighbness.hh (working copy)
@@ -53,6 +53,12 @@
return this->exact().impl_nbh_get();
}
+ //FIXME: is it the right way ?
+ const neighb_type& impl_nbh_get() const
+ {
+ return this->exact().delegate().nbh_get();
+ }
+
protected:
image_with_nbh() {}
Index: oln/morpho/reconstruction.hh
--- oln/morpho/reconstruction.hh (revision 162)
+++ oln/morpho/reconstruction.hh (working copy)
@@ -49,453 +49,181 @@
namespace oln {
- namespace morpho {
- // fwd decl
- template <typename I, typename E> struct reconstruction_ret;
+ namespace tag {
- }
+ template <typename Op> struct oper {};
- // category
- template <typename I, typename E>
- struct set_category< morpho::reconstruction_ret<I,E> > { typedef category::image ret; };
+ struct by_dilation : public oper< by_dilation > {};
+ struct by_erosion : public oper< by_erosion > {};
- // super_type
- template <typename I, typename E>
- struct set_super_type< morpho::reconstruction_ret<I,E> >
- {
- typedef abstract::image_binary_operator<I, I, I, morpho::reconstruction_ret<I, E> > ret;
- // FIXME: see below
- };
+ template <typename A> struct algo {};
- namespace morpho {
+ struct sequential : public algo< sequential > {};
+ struct hybrid : public algo< hybrid > {};
- template <typename I, typename N>
- struct reconstruction_ret : public abstract::image_binary_operator<I, I, I, reconstruction_ret<I, N> >
- // FIXME: abstract::image_binary_operator<oln_type_of(I, concrete), ...
- {
- typedef abstract::image_binary_operator<I, I, I, reconstruction_ret<I, N> > super_type;
+ } // end of namespace oln::morpho::tag
- const N nbh;
- reconstruction_ret(const abstract::image<I>& input1,
- const abstract::image<I>& input2,
- const abstract::neighborhood<N>& nbh) :
- super_type(input1.exact(), input2.exact()),
- nbh(nbh.exact())
- {}
- };
+ namespace morpho {
+ template <typename I1, typename I2> struct reconstruction_ret;
+ } // end of namespace oln::morpho
- namespace sequential {
+ // super_type
- namespace impl {
+ template <typename I1, typename I2>
+ struct set_super_type< morpho::reconstruction_ret<I1, I2> >
+ {
+ typedef oln_type_of(I1, concrete) output_type;
- template <typename I, typename N, typename E>
- struct reconstruction_sequential_ret : public reconstruction_ret<I, N>
- {
- typedef reconstruction_ret<I, N> super_type;
+ typedef morpho::reconstruction_ret<I1,I2> self_type;
+ typedef abstract::image_binary_operator<output_type, I1, I2, self_type > ret;
+ };
- void fwd_loop_body()
- {
- static_cast<E*>((void*)this)->fwd_loop_body_impl();
- }
+ namespace morpho {
- void bkd_loop_body()
- {
- static_cast<E*>((void*)this)->bkd_loop_body_impl();
- }
+ // Reconstruction as a 'classical' procedure returning an image (do not
+ // use it; prefer morpho::reconstruction).
- void preconditions()
- {
- precondition(this->input1.size() == this->input2.size());
- static_cast<E*>((void*)this)->preconditions_impl();
- }
+ namespace proc {
- void impl_run()
- {
- mlc::eq<oln_type_of(I, size), oln_type_of(N, size)>::ensure();
+ // FIXME: ...
- I output;
- output = utils::clone(this->input1);
- bool non_stability = true;
- while (non_stability)
- {
- work.unbox() = utils::clone(output);
- for_all_p (fwd_p)
- fwd_loop_body();
- for_all_p (bkd_p)
- bkd_loop_body();
+ } // end of namespace oln::morpho::proc
- non_stability = !(level::is_equal(work, output));
- output = work.unbox();
- }
- this->output = output;
- }
- protected:
- reconstruction_sequential_ret(const abstract::image<I>& input1, //marker
- const abstract::image<I>& input2, //mask
- const abstract::neighborhood<N>& nbh)
- : super_type(input1, input2, nbh),
- fwd_p(input1.size()),
- bkd_p(input1.size())
- {
- se_plus = get_plus_se_p(convert::nbh_to_cse(this->nbh));
- se_minus = get_minus_se_p(convert::nbh_to_cse(this->nbh));
- }
+ 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;
- oln_type_of(N, window) se_plus;
- oln_type_of(N, window) se_minus;
- oln_type_of(I, fwd_piter) fwd_p;
- oln_type_of(I, bkd_piter) bkd_p;
- box<I> work;
+ 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)
+ {
+ }
- template <typename I, typename N>
- struct reconstruction_dilation_ret :
- public reconstruction_sequential_ret<I, N, reconstruction_dilation_ret<I, N> >
- {
- typedef reconstruction_sequential_ret<I, N, reconstruction_dilation_ret<I, N> > super_type;
+ const oln_type_of(I1, neighb)& impl_nbh_get() const
+ {
+ return marker.nbh_get();
+ }
- reconstruction_dilation_ret(const abstract::image<I>& input1, //marker
- const abstract::image<I>& input2, //mask
- const abstract::neighborhood<N>& nbh)
+ };
- : super_type(input1, input2, nbh)
- {}
+ } // end of namespace morpho
- void fwd_loop_body_impl()
- {
- this->work[this->fwd_p] = ntg::min(morpho::max(this->work.unbox(),
- this->fwd_p,
- this->se_plus),
- this->input2[this->fwd_p].value());
- }
+} // end of namespace oln
- void bkd_loop_body_impl()
- {
- this->work[this->bkd_p] = ntg::min(morpho::max(this->work.unbox(),
- this->bkd_p,
- this->se_minus),
- this->input2[this->bkd_p].value());
- }
+# include <oln/morpho/reconstruction_canvas.inc>
- void preconditions_impl()
- {
- precondition(level::is_greater_or_equal(this->input2, this->input1));
- }
+namespace oln {
- };
+ namespace morpho {
+ namespace impl {
- template <typename I, typename N>
- struct reconstruction_erosion_ret :
- public reconstruction_sequential_ret<I, N, reconstruction_erosion_ret<I, N> >
- {
- typedef reconstruction_sequential_ret<I, N, reconstruction_erosion_ret<I, N> > super_type;
+ template<typename Op, typename A, typename I1, typename I2>
+ struct generic_reconstruction;
- reconstruction_erosion_ret(const abstract::image<I>& input1, //marker
- const abstract::image<I>& input2, //mask
- const abstract::neighborhood<N>& nbh)
+ } // end of namespace impl
- : super_type(input1, input2, nbh)
- {}
+ } // end of namespace morpho
- void fwd_loop_body_impl()
- {
- this->work[this->fwd_p] = ntg::max(morpho::min(this->work.unbox(),
- this->fwd_p,
- this->se_plus),
- this->input2[this->fwd_p].value());
- }
+} // end of namespace oln
- void bkd_loop_body_impl()
- {
- this->work[this->bkd_p] = ntg::max(morpho::min(this->work.unbox(),
- this->bkd_p,
- this->se_minus),
- this->input2[this->bkd_p].value());
- }
+# include <oln/morpho/reconstruction_by_dilation.inc>
+# include <oln/morpho/reconstruction_by_erosion.inc>
- void preconditions_impl()
- {
- precondition(level::is_greater_or_equal(this->input1, this->input2));
- }
+namespace oln {
- };
+ namespace morpho {
- }
+ namespace impl {
- template<class I, class N>
- reconstruction_ret<I, N>
- geodesic_reconstruction_dilation(const abstract::image<I> & marker,
- const abstract::image<I> & mask,
- const abstract::neighborhood<N>& nbh)
- {
- impl::reconstruction_dilation_ret<I, N> tmp(marker, mask, nbh);
- tmp.run();
- return tmp;
- }
+ // Generic implementation of reconstruction (routine).
- template<class I, class N>
- reconstruction_ret<I, N>
- geodesic_reconstruction_erosion(const abstract::image<I> & marker,
- const abstract::image<I> & mask,
- const abstract::neighborhood<N>& nbh)
+ 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)
{
- impl::reconstruction_erosion_ret<I, N> tmp(marker, mask, nbh);
+ generic_reconstruction<Op, A, I1, I2> tmp(marker, mask);
tmp.run();
return tmp;
}
- }// sequential
+ } // end of namespace impl
+ /// Generic reconstruction (facade).
- namespace hybrid {
+ 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());
+ }
- namespace impl {
+ // by dilation
- template <typename I, typename N, typename E>
- struct reconstruction_hybrid_ret : public reconstruction_ret<I, N>
- {
- typedef reconstruction_ret<I, N> super_type;
+ 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_);
+ }
- bool exist_init()
- {
- // FIXME: to many changes => rewrite!
-// typedef oln_type_of(N, window) se_type;
-// oln_type_of(se_type, fwd_qiter) dp(se_minus);
-// for_all (dp)
-// {
-// q = (oln_type_of(se_type, dpoint))dp +
-// (oln_type_of(I, point))bkd_p;
-// if (static_cast<E*>((void*)this)->exist_init_impl())
-// return true;
-// }
- return false;
- }
+ 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());
+ }
- void fwd_loop_body()
- {
- static_cast<E*>((void*)this)->fwd_loop_body_impl();
- }
+ // by erosion
- void bkd_loop_body()
- {
- static_cast<E*>((void*)this)->bkd_loop_body_impl();
- }
+ 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_);
+ }
- void fifo_loop_body()
- {
- static_cast<E*>((void*)this)->fifo_loop_body_impl();
- }
+ 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());
+ }
- void preconditions()
- {
- precondition(this->input1.size() == this->input2.size());
- static_cast<E*>((void*)this)->preconditions_impl();
- }
+ } // end of namespace oln::morpho
- void impl_run()
- {
- mlc::eq<oln_type_of(I, size), oln_type_of(N, size)>::ensure();
- preconditions();
+} // end of namespace oln
- this->output.unbox() = utils::clone(this->input1);
-
- 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();
- // FIXME: AWFUL commented cause too many changes!
-// typedef oln_type_of(N, window) window_type;
-// window_type w = convert::nbh_to_se(this->nbh);
-// oln_wn_type_of(window_type, fwd_iter) q(w);
-
-// for_all_q_of_p (q)
-// {
-// if (this->output.hold(q))
-// fifo_loop_body();
-// }
- }
- }
-
- protected:
-
- reconstruction_hybrid_ret(const abstract::image<I>& input1, //marker
- const abstract::image<I>& input2, //mask
- const abstract::neighborhood<N>& nbh)
-
- : super_type(input1, input2, nbh),
- fwd_p(input1.size()),
- bkd_p(input1.size())
- {
- se_plus = get_plus_se_p(convert::nbh_to_cse(this->nbh));
- se_minus = get_minus_se_p(convert::nbh_to_cse(this->nbh));
- }
-
- oln_type_of(N, window) se_plus;
- oln_type_of(N, window) se_minus;
- oln_type_of(I, fwd_piter) fwd_p;
- oln_type_of(I, bkd_piter) bkd_p;
- oln_type_of(I, point) p;
- oln_type_of(I, point) q;
- std::queue<oln_type_of(I, point) > fifo;
-
-
- };
-
-
- template <typename I, typename N>
- struct reconstruction_dilation_ret :
- public reconstruction_hybrid_ret<I, N, reconstruction_dilation_ret<I, N> >
- {
- typedef reconstruction_hybrid_ret<I, N, reconstruction_dilation_ret<I, N> > super_type;
-
- reconstruction_dilation_ret(const abstract::image<I>& input1, //marker
- const abstract::image<I>& input2, //mask
- const abstract::neighborhood<N>& nbh)
-
- : super_type(input1, input2, nbh)
- {}
-
- void fwd_loop_body_impl()
- {
- this->output[this->fwd_p] = ntg::min(morpho::max(this->output.unbox(),
- this->fwd_p,
- this->se_plus),
- this->input2[this->fwd_p].value());
- }
-
- void bkd_loop_body_impl()
- {
- this->output[this->bkd_p] = ntg::min(morpho::max(this->output.unbox(),
- this->bkd_p,
- this->se_minus),
- this->input2[this->bkd_p].value());
- }
-
- void fifo_loop_body_impl()
- {
- if ((this->output[this->q] < this->output[this->p]) &&
- (this->input2[this->q] != this->output[this->q]))
- {
- this->output[this->q] = ntg::min(this->output[this->p].value(),
- this->input2[this->q].value());
- this->fifo.push(this->q);
- }
- }
-
- bool exist_init_impl()
- {
- return this->output.hold(this->q) &&
- (this->output[this->q] < this->output[this->bkd_p]) &&
- (this->output[this->q] < this->input2[this->q]);
- }
-
- void preconditions_impl()
- {
- precondition(level::is_greater_or_equal(this->input2, this->input1));
- }
-
- };
-
-
-
- template <typename I, typename N>
- struct reconstruction_erosion_ret :
- public reconstruction_hybrid_ret<I, N, reconstruction_erosion_ret<I, N> >
- {
- typedef reconstruction_hybrid_ret<I, N, reconstruction_erosion_ret<I, N> > super_type;
-
- reconstruction_erosion_ret(const abstract::image<I>& input1, //marker
- const abstract::image<I>& input2, //mask
- const abstract::neighborhood<N>& nbh)
-
- : super_type(input1, input2, nbh)
- {}
-
- void fwd_loop_body_impl()
- {
- this->output[this->fwd_p] = ntg::max(morpho::min(this->output.unbox(),
- this->fwd_p,
- this->se_plus),
- this->input2[this->fwd_p].value());
- }
-
- void bkd_loop_body_impl()
- {
- this->output[this->bkd_p] = ntg::max(morpho::min(this->output.unbox(),
- this->bkd_p,
- this->se_minus),
- this->input2[this->bkd_p].value());
- }
-
- void fifo_loop_body_impl()
- {
- if ((this->output[this->q] > this->output[this->p]) &&
- (this->input2[this->q] != this->output[this->q]))
- {
- this->output[this->q] = ntg::max(this->output[this->p].value(),
- this->input2[this->q].value());
- this->fifo.push(this->q);
- }
- }
-
- bool exist_init_impl()
- {
- return this->output.hold(this->q) &&
- (this->output[this->q] > this->output[this->bkd_p]) &&
- (this->output[this->q] > this->input2[this->q]);
- }
-
- void preconditions_impl()
- {
- precondition(level::is_greater_or_equal(this->input1, this->input2));
- }
-
- };
-
- }
-
- template<class I, class N>
- reconstruction_ret<I, N>
- geodesic_reconstruction_dilation(const abstract::image<I> & marker,
- const abstract::image<I> & mask,
- const abstract::neighborhood<N>& nbh)
- {
- impl::reconstruction_dilation_ret<I, N> tmp(marker, mask, nbh);
- tmp.run();
- return tmp;
- }
-
- template<class I, class N>
- reconstruction_ret<I, N>
- geodesic_reconstruction_erosion(const abstract::image<I> & marker,
- const abstract::image<I> & mask,
- const abstract::neighborhood<N>& nbh)
- {
- impl::reconstruction_erosion_ret<I, N> tmp(marker, mask, nbh);
- tmp.run();
- return tmp;
- }
- }// hybrid
-
- }
-
-}
-
#endif // ! OLENA_MORPHO_RECONSTRUCTION_HH
Index: oln/morpho/splitse.hh
--- oln/morpho/splitse.hh (revision 162)
+++ oln/morpho/splitse.hh (working copy)
@@ -34,6 +34,10 @@
# 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 {
@@ -76,22 +80,21 @@
template<class W>
W
- get_plus_win_only(const abstract::window<W>& win)
+ get_plus_win_only(const W& win) // FIXME: abstract::window<W>& win)
{
- oln_wn_type_of(W, fwd_iter) q(win.exact());
W out;
- // FIXME: too many changes: rewrite!
-// for_all (q)
-// {
-// 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;
-// }
-// }
+ 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;
}
@@ -110,26 +113,24 @@
*/
template<class W>
W
- get_plus_win_p(const abstract::window<W>& win)
+ get_plus_win_p(const W& win) // abstract::window<W>& win)
{
- oln_wn_type_of(W, fwd_iter) q(win.exact());
W out;
-
- // FIXME: too many changes: rewrite!
-// for_all (dp)
-// {
-// 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);
-// }
+ 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;
}
@@ -147,23 +148,21 @@
*/
template<class W>
W
- get_minus_win_only(const abstract::window<W>& win)
+ get_minus_win_only(const W& win) // abstract::window<W>& win)
{
- oln_wn_type_of(W, fwd_iter) q(win.exact());
W out;
-
- // FIXME: too many changes: rewrite!
-// for_all (dp)
-// {
-// 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;
-// }
-// }
+ 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;
}
@@ -182,26 +181,24 @@
*/
template<class W>
W
- get_minus_win_p(const abstract::window<W>& win)
+ get_minus_win_p(const W& win) // abstract::window<W>& win)
{
- oln_wn_type_of(W, fwd_iter) q(win.exact());
W out;
-
- // FIXME: too many changes: rewrite!
-// for_all (dp)
-// {
-// 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);
-// }
+ 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;
}
Index: oln/morpho/reconstruction_by_erosion.inc
--- oln/morpho/reconstruction_by_erosion.inc (revision 0)
+++ oln/morpho/reconstruction_by_erosion.inc (revision 0)
@@ -0,0 +1,141 @@
+// 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_canvas.inc
--- oln/morpho/reconstruction_canvas.inc (revision 0)
+++ oln/morpho/reconstruction_canvas.inc (revision 0)
@@ -0,0 +1,238 @@
+// 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
Index: oln/morpho/reconstruction_by_dilation.inc
--- oln/morpho/reconstruction_by_dilation.inc (revision 0)
+++ oln/morpho/reconstruction_by_dilation.inc (revision 0)
@@ -0,0 +1,142 @@
+// 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: img/marker.pbm
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: img/marker.pbm
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Index: img/mask.pbm
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: img/mask.pbm
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
1
1
Index: ChangeLog
from Damien Thivolle <damien(a)lrde.epita.fr>
* tests/utils/tests/invert: New.
* oln/funobj/invert.hh: Invert functor.
* oln/core/abstract/image_by_delegation.hh (image): Add missing method.
* oln/core/box.hh: Comment code that prevents from compiling with
g++-3.4.
* oln/core/pw/image.hh: Likewise.
* oln/utils/invert.hh: Inverted images implentation.
* oln/morpho/erosion.hh: Add a forward declaration to allow compilation
with g++-3.4.
oln/core/abstract/image_by_delegation.hh | 2
oln/core/box.hh | 6 +
oln/core/pw/image.hh | 28 ++++----
oln/funobj/invert.hh | 82 ++++++++++++++++++++++++
oln/morpho/erosion.hh | 26 ++++---
oln/utils/invert.hh | 103 +++++++++++++++++++++++++++++++
tests/utils/tests/invert | 38 +++++++++++
7 files changed, 258 insertions, 27 deletions
Index: tests/utils/tests/invert
--- tests/utils/tests/invert (revision 0)
+++ tests/utils/tests/invert (revision 0)
@@ -0,0 +1,38 @@
+#include "data.hh"
+
+#include <ntg/all.hh>
+
+#include <oln/basics2d.hh>
+#include <oln/utils/invert.hh>
+#include <oln/io/read_image.hh>
+#include <oln/level/compare.hh>
+
+
+bool check()
+{
+ oln::image2d<ntg::bin> ima_bin;
+ oln::image2d<ntg::int_u8> ima_int;
+ oln::image2d<ntg::rgb_8> ima_rgb;
+
+ ima_bin = oln::io::read(rdata("16x16.pbm"));
+ ima_int = oln::io::read(rdata("16x16.pgm"));
+ ima_rgb = oln::io::read(rdata("16x16.ppm"));
+
+ if (oln::level::is_equal(ima_bin,
+ oln::utils::invert(oln::utils::invert(ima_bin))) &&
+ oln::level::is_equal(ima_int,
+ oln::utils::invert(oln::utils::invert(ima_int))) &&
+ oln::level::is_equal(ima_rgb,
+ oln::utils::invert(oln::utils::invert(ima_rgb))))
+ {
+ std::cout << "OK" << std::endl;
+ return false;
+ }
+ else
+ {
+ std::cout << "FAIL" << std::endl;
+ return true;
+ }
+}
+
+
Index: oln/funobj/invert.hh
--- oln/funobj/invert.hh (revision 0)
+++ oln/funobj/invert.hh (revision 0)
@@ -0,0 +1,82 @@
+// 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_FUNOBJ_INVERT_HH
+# define OLENA_FUNOBJ_INVERT_HH
+
+# include <mlc/contract.hh>
+
+# include <ntg/all.hh>
+
+namespace oln {
+
+ namespace funobj {
+
+ struct invert
+ {
+ template <typename V>
+ V operator()(const ntg::vect_value<V>& v) const
+ {
+ V ret;
+
+ for (unsigned i = 0; i < ntg_nb_comp(V); i++)
+ ret[i] = ntg_max_val(ntg_comp_type(V)) - v[i];
+ return ret;
+ }
+
+ template <typename V>
+ V operator()(const ntg::real_value<V>& v) const
+ {
+ V ret;
+
+ ret = ntg_max_val(V) - v;
+ return ret;
+ }
+
+ template <typename V>
+ V operator()(const ntg::enum_value<V>& v) const
+ {
+ V ret;
+ ntg_integer_type(V) max_val = ntg_max_val(V);
+ ntg_integer_type(V) value = v.exact();
+
+ ret = max_val - value;
+ return ret;
+ }
+
+ invert() {}
+
+ };
+
+ } // end of namespace funobj
+
+} // end of namespace oln
+
+
+#endif // ! OLENA_FUNOBJ_INVERT_HH
+
+
Index: oln/core/abstract/image_by_delegation.hh
--- oln/core/abstract/image_by_delegation.hh (revision 161)
+++ oln/core/abstract/image_by_delegation.hh (working copy)
@@ -96,6 +96,7 @@
public:
+ I& image() { return this->image_.unbox(); }
I& impl_delegate() { return this->image_.unbox(); }
const I& impl_delegate() const { return this->image_.unbox(); }
};
@@ -128,6 +129,7 @@
public:
+ const I& image() const { return this->image_.unbox(); }
const I& impl_delegate() const { return this->image_.unbox(); }
};
Index: oln/core/box.hh
--- oln/core/box.hh (revision 161)
+++ oln/core/box.hh (working copy)
@@ -1,3 +1,4 @@
+
// Copyright (C) 2005 EPITA Research and Development Laboratory
//
// This file is part of the Olena Library. This library is free
@@ -130,7 +131,8 @@
template <typename II>
void operator=(const abstract::image<II>& rhs)
{
- mlc::false_type::ensure();
+ // FIXME: Does not work with g++-3.4.
+// mlc::false_type::ensure();
}
// FIXME: add versions for I2 (neq I) to produce explicit errors
@@ -218,7 +220,7 @@
return *this;
}
- /// Delegation relies on a constant image.
+ /// Delegation relies on a constant image.
const I& impl_delegate() const
{
return this->image_;
Index: oln/core/pw/image.hh
--- oln/core/pw/image.hh (revision 161)
+++ oln/core/pw/image.hh (working copy)
@@ -46,7 +46,7 @@
// fwd decl
namespace pw {
template <typename I> struct image;
- }
+ }
// super type
template <typename I>
@@ -192,7 +192,7 @@
void impl_resize_border(size_t new_border, bool copy_border) const
{
}
-
+
};
@@ -256,22 +256,22 @@
-
+ // FIXME: Does not work with g++-3.4.
/// Specialization of image_for_all_p that gives a compile-time error.
- template <typename I>
- void image_for_all_p(const abstract::image<I>&)
- {
- struct OLENA_ERROR__arg_of__image_for_all_p__should_not_be_an_image();
- }
+// template <typename I>
+// void image_for_all_p(const abstract::image<I>&)
+// {
+// struct OLENA_ERROR__arg_of__image_for_all_p__should_not_be_an_image();
+// }
- /// Specialization of image_for_all_p that gives a compile-time error.
+// /// Specialization of image_for_all_p that gives a compile-time error.
- template <typename P>
- void image_for_all_p(const abstract::point<P>&)
- {
- struct OLENA_ERROR__arg_of__image_for_all_p__should_not_be_a_point();
- }
+// template <typename P>
+// void image_for_all_p(const abstract::point<P>&)
+// {
+// struct OLENA_ERROR__arg_of__image_for_all_p__should_not_be_a_point();
+// }
Index: oln/utils/invert.hh
--- oln/utils/invert.hh (revision 0)
+++ oln/utils/invert.hh (revision 0)
@@ -0,0 +1,103 @@
+// Copyright (C) 2001, 2002, 2003, 2004, 2005 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+// MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+
+#ifndef OLENA_CORE_UTILS_INVERT_HH
+# define OLENA_CORE_UTILS_INVERT_HH
+
+# include <oln/core/abstract/image_by_delegation.hh>
+# include <oln/funobj/invert.hh>
+
+namespace oln {
+
+ namespace utils {
+ template <typename I> struct image_inverted;
+ }
+
+ // super type
+
+ template <typename I>
+ struct set_super_type < utils::image_inverted<I> >
+ { typedef abstract::image_by_delegation<const I, utils::image_inverted<I> > ret; };
+
+ // props
+
+ template <typename I>
+ struct set_props < category::image, utils::image_inverted<I> >
+ {
+ typedef oln_type_of(I, concrete) concrete_type;
+ };
+
+
+
+ namespace utils {
+
+ template <typename I>
+ struct image_inverted :
+ public abstract::image_by_delegation<const I, image_inverted<I> >
+ {
+ typedef abstract::image_by_delegation<const I, image_inverted<I> > super_type;
+ typedef oln_type_of(I, value) value_type;
+ typedef oln_type_of(I, point) point_type;
+
+ public:
+
+ image_inverted()
+ {
+ }
+
+ image_inverted(const abstract::image<I>& image) :
+ super_type(image)
+ {
+ }
+
+ I& real() const
+ {
+ return this->image_.unbox();
+ }
+
+ const value_type impl_get(const point_type& p) const
+ {
+ const static oln::funobj::invert& obj = oln::funobj::invert();
+ return obj(this->image_[p].value());
+ }
+
+ };
+
+ template <typename I>
+ image_inverted<I> invert(const abstract::image<I>& input)
+ {
+ image_inverted<I> tmp(input);
+ return tmp;
+ }
+
+ } // end of namespace utils
+
+} // end of namespace oln
+
+#endif // ! OLENA_CORE_UTILS_INVERT_HH
+
Index: oln/morpho/erosion.hh
--- oln/morpho/erosion.hh (revision 161)
+++ oln/morpho/erosion.hh (working copy)
@@ -45,6 +45,10 @@
namespace morpho {
template <typename I> struct erosion_ret;
+
+ template<typename I, typename W>
+ erosion_ret<I> erosion(const abstract::image<I>& input,
+ const abstract::window<W>& win);
}
// super_type
@@ -126,13 +130,13 @@
void impl_run()
{
- oln_type_of(super_type, output) tmp(input.size()); // FIXME: trick
- output = tmp;
+ oln_type_of(super_type, output) tmp(this->input.size()); // FIXME: trick
+ this->output = tmp;
// FIXME: output.resize(input.size);
- oln_type_of(I, fwd_piter) p(input.size());
+ oln_type_of(I, fwd_piter) p(this->input.size());
for_all_p (p)
- output[p] = morpho::min(input, p, win);
+ this->output[p] = morpho::min(this->input, p, this->win);
}
};
@@ -146,10 +150,10 @@
tmp.run();
return tmp;
}
-
+
/// Rectangle2d implementation of erosion (type).
template <typename I>
@@ -171,11 +175,11 @@
box<oln_type_of(super_type, output)> temp; // FIXME: box?
// FIXME: output_type temp;
- win_hline2d hline(win.width);
- win_vline2d vline(win.height);
-
- temp = morpho::erosion(input, hline);
- output = morpho::erosion(temp, vline);
+ win_hline2d hline(this->win.width);
+ win_vline2d vline(this->win.height);
+
+ temp = oln::morpho::erosion(this->input, hline);
+ this->output = oln::morpho::erosion(temp, vline);
}
};
@@ -190,9 +194,9 @@
return tmp;
}
-
+
} // end of namespace oln::morpho::impl
1
0
15 Apr '05
https://svn.lrde.epita.fr/svn/oln/prototypes/proto-1.0
ChangeLog | 4 ++++
tests/morpho/tests/elementary_dilation | 2 +-
2 files changed, 5 insertions(+), 1 deletion(-)
Index: olena/ChangeLog
from Roland Levillain <roland(a)lrde.epita.fr>
* tests/morpho/tests/elementary_dilation: Typo.
2005-04-15 Roland Levillain <roland(a)lrde.epita.fr>
Index: olena/tests/morpho/tests/elementary_dilation
--- olena/tests/morpho/tests/elementary_dilation (revision 160)
+++ olena/tests/morpho/tests/elementary_dilation (working copy)
@@ -21,7 +21,7 @@
im_type ima;
ima = oln::io::read(rdata("16x16.pbm"));
- if (oln::utils::md5(oln::morpho::elementary_erosiont(ima) != key)
+ if (oln::utils::md5(oln::morpho::elementary_dilation(ima) != key)
return true;
return false;
1
0
https://svn.lrde.epita.fr/svn/oln/prototypes/proto-1.0
ChangeLog | 7 +++++++
tests/morpho/tests/elementary_dilation | 28 ++++++++++++++++++++++++++++
tests/morpho/tests/elementary_erosion | 28 ++++++++++++++++++++++++++++
3 files changed, 63 insertions(+)
Index: olena/ChangeLog
from Roland Levillain <roland(a)lrde.epita.fr>
Add tests for elementary dilation/erosion.
* tests/morpho/tests/elementary_dilation,
* tests/morpho/tests/elementary_erosion: New tests.
2005-04-15 Roland Levillain <roland(a)lrde.epita.fr>
Index: olena/tests/morpho/tests/elementary_erosion
--- olena/tests/morpho/tests/elementary_erosion (revision 0)
+++ olena/tests/morpho/tests/elementary_erosion (revision 0)
@@ -0,0 +1,28 @@
+ // -*- C++ -*-
+#include "data.hh"
+#include <oln/utils/md5.hh>
+
+#include <oln/io/read_image.hh>
+#include <oln/basics2d.hh>
+#include <oln/morpho/elementary_erosion.hh>
+#include <oln/level/compare.hh>
+#include <ntg/all.hh>
+
+bool check()
+{
+ // MD5 sum of object.pbm's elementary erosion result.
+ // FIXME: Replace this fake with the actual result.
+ oln::utils::key::value_type data_key[16] =
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+ oln::utils::key key(data_key);
+
+ typedef oln::image2d<ntg::bin> im_type;
+ im_type ima;
+ ima = oln::io::read(rdata("16x16.pbm"));
+
+ if (oln::utils::md5(oln::morpho::elementary_erosion(ima) != key)
+ return true;
+
+ return false;
+}
Index: olena/tests/morpho/tests/elementary_dilation
--- olena/tests/morpho/tests/elementary_dilation (revision 0)
+++ olena/tests/morpho/tests/elementary_dilation (revision 0)
@@ -0,0 +1,28 @@
+ // -*- C++ -*-
+#include "data.hh"
+#include <oln/utils/md5.hh>
+
+#include <oln/io/read_image.hh>
+#include <oln/basics2d.hh>
+#include <oln/morpho/elementary_dilation.hh>
+#include <oln/level/compare.hh>
+#include <ntg/all.hh>
+
+bool check()
+{
+ // MD5 sum of object.pbm's elementary dilation result.
+ // FIXME: Replace this fake with the actual result.
+ oln::utils::key::value_type data_key[16] =
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+ oln::utils::key key(data_key);
+
+ typedef oln::image2d<ntg::bin> im_type;
+ im_type ima;
+ ima = oln::io::read(rdata("16x16.pbm"));
+
+ if (oln::utils::md5(oln::morpho::elementary_erosiont(ima) != key)
+ return true;
+
+ return false;
+}
1
0
15 Apr '05
https://svn.lrde.epita.fr/svn/oln/prototypes/proto-1.0
ChangeLog | 15 +++++++++++++++
oln/morpho/geodesic_dilation.hh | 13 ++++++++-----
oln/morpho/geodesic_erosion.hh | 13 ++++++++-----
tests/morpho/tests/closing | 15 +++++++++------
tests/morpho/tests/erosion | 35 ++++++++++++++++++-----------------
tests/morpho/tests/geodesic_dilation | 4 +---
tests/morpho/tests/geodesic_erosion | 4 +---
tests/morpho/tests/opening | 15 +++++++++------
8 files changed, 69 insertions(+), 45 deletions(-)
Index: olena/ChangeLog
from Roland Levillain <roland(a)lrde.epita.fr>
Repair geodesic erosion and dilation (cont.).
* oln/morpho/geodesic_dilation.hh
(morpho::proc::geodesic_dilation)
* oln/morpho/geodesic_erosion.hh
(morpho::proc::geodesic_erosion): Fix iterator definition, as well
as min/max operation.
* olena/tests/morpho/tests/closing
* olena/tests/morpho/tests/erosion
* olena/tests/morpho/tests/geodesic_dilation,
* olena/tests/morpho/tests/geodesic_erosion,
* olena/tests/morpho/tests/opening: Aesthetic changes.
2005-04-15 Roland Levillain <roland(a)lrde.epita.fr>
Index: olena/tests/morpho/tests/opening
--- olena/tests/morpho/tests/opening (revision 158)
+++ olena/tests/morpho/tests/opening (working copy)
@@ -8,19 +8,22 @@
#include <oln/level/compare.hh>
#include <ntg/all.hh>
+using namespace oln;
+
bool check()
{
- // MD5 sum of object.pbm's geodesic dilation result.
- oln::utils::key::value_type data_key[16] =
+ // MD5 sum of object.pbm's opening result.
+ // FIXME: Replace this fake with the actual result.
+ utils::key::value_type data_key[16] =
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
- oln::utils::key key(data_key);
+ utils::key key(data_key);
- typedef oln::image2d<ntg::bin> im_type;
+ typedef image2d<ntg::bin> im_type;
im_type ima;
- ima = oln::io::read(rdata("16x16.pbm"));
+ ima = io::read(rdata("16x16.pbm"));
- if (oln::utils::md5(oln::morpho::opening(ima, oln::win_c8p())) != key)
+ if (utils::md5(morpho::opening(ima, win_c8p())) != key)
return true;
return false;
Index: olena/tests/morpho/tests/geodesic_erosion
--- olena/tests/morpho/tests/geodesic_erosion (revision 158)
+++ olena/tests/morpho/tests/geodesic_erosion (working copy)
@@ -14,6 +14,7 @@
bool check()
{
// MD5 sum of object.pbm's geodesic erosion result.
+ // FIXME: Replace this fake with the actual result.
utils::key::value_type data_key[16] =
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
@@ -30,12 +31,9 @@
marker = morpho::closing(mask, win_c4p()).exact();
// Classical procedure.
- // FIXME: Re-enable when proc::geodesic_erosion is fixed.
-#if 0
if (utils::md5(morpho::proc::geodesic_erosion(join(marker, nbh),
mask).exact()) != key)
return true;
-#endif
// Facade to object-algorithm.
if (utils::md5(morpho::geodesic_erosion(join(marker, nbh),
Index: olena/tests/morpho/tests/geodesic_dilation
--- olena/tests/morpho/tests/geodesic_dilation (revision 158)
+++ olena/tests/morpho/tests/geodesic_dilation (working copy)
@@ -14,6 +14,7 @@
bool check()
{
// MD5 sum of object.pbm's geodesic dilation result.
+ // FIXME: Replace this fake with the actual result.
utils::key::value_type data_key[16] =
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
@@ -30,12 +31,9 @@
marker = morpho::opening(mask, win_c4p()).exact();
// Classical procedure.
- // FIXME: Re-enable when proc::geodesic_dilation is fixed.
-#if 0
if (utils::md5(morpho::proc::geodesic_dilation(join(marker, nbh),
mask).exact()) != key)
return true;
-#endif
// Facade to object-algorithm.
if (utils::md5(morpho::geodesic_dilation(join(marker, nbh),
Index: olena/tests/morpho/tests/erosion
--- olena/tests/morpho/tests/erosion (revision 158)
+++ olena/tests/morpho/tests/erosion (working copy)
@@ -8,27 +8,28 @@
#include <oln/level/compare.hh>
#include <ntg/all.hh>
+using namespace oln;
+
bool check()
{
- oln::utils::key::value_type data_key[16] =
- {0x7c, 0x4f, 0xf, 0xc7, 0x27, 0x1, 0x98, 0x81,
- 0xfd, 0xb, 0x2e, 0xf6, 0x1c, 0x84, 0xc9, 0x1e};
-
- oln::utils::key key(data_key);
+ // MD5 sum of object.pbm's erosion result.
+ // FIXME: Replace this fake with the actual result.
+ utils::key::value_type data_key[16] =
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+ utils::key key(data_key);
- typedef oln::image2d<ntg::bin> im_type;
+ typedef image2d<ntg::bin> im_type;
im_type ima;
- ima = oln::io::read(rdata("16x16.pbm"));
+ ima = io::read(rdata("16x16.pbm"));
- std::cout << oln::utils::md5(oln::morpho::erosion(ima, oln::win_c8p())) << std::endl;
- if (oln::utils::md5(oln::morpho::erosion(ima, oln::win_c8p())) == key)
- {
- std::cout << "OK" << std::endl;
- return false;
- }
- else
- {
- std::cout << "FAIL" << std::endl;
+ // Classical procedure.
+ if (utils::md5(morpho::proc::erosion(ima, win_c8p())) != key)
return true;
- }
+
+ // Facade to object-algorithm.
+ if (utils::md5(morpho::erosion(ima, win_c8p())) != key)
+ return true;
+
+ return false;
}
Index: olena/tests/morpho/tests/closing
--- olena/tests/morpho/tests/closing (revision 158)
+++ olena/tests/morpho/tests/closing (working copy)
@@ -8,19 +8,22 @@
#include <oln/level/compare.hh>
#include <ntg/all.hh>
+using namespace oln;
+
bool check()
{
- // MD5 sum of object.pbm's geodesic dilation result.
- oln::utils::key::value_type data_key[16] =
+ // MD5 sum of object.pbm's closing result.
+ // FIXME: Replace this fake with the actual result.
+ utils::key::value_type data_key[16] =
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
- oln::utils::key key(data_key);
+ utils::key key(data_key);
- typedef oln::image2d<ntg::bin> im_type;
+ typedef image2d<ntg::bin> im_type;
im_type ima;
- ima = oln::io::read(rdata("16x16.pbm"));
+ ima = io::read(rdata("16x16.pbm"));
- if (oln::utils::md5(oln::morpho::closing(ima, oln::win_c8p())) != key)
+ if (utils::md5(morpho::closing(ima, win_c8p())) != key)
return true;
return false;
Index: olena/oln/morpho/geodesic_dilation.hh
--- olena/oln/morpho/geodesic_dilation.hh (revision 158)
+++ olena/oln/morpho/geodesic_dilation.hh (working copy)
@@ -33,7 +33,6 @@
# include <oln/core/abstract/image_operator.hh>
# include <oln/morpho/stat.hh>
# include <oln/level/compare.hh>
-# include <oln/convert/nbh_to_se.hh>
# include <oln/arith/min.hh>
# include <oln/core/abstract/neighborhood.hh>
@@ -59,11 +58,15 @@
oln_type_of(I1, concrete) output(marker.size());
// FIXME: Useless?
// marker.border_adapt_copy(marker.nbh_get().delta());
- oln_type_of(I1, piter) p(marker);
+ oln_type_of(I1, piter) p(marker.size());
for_all_p (p)
- output[p] =
- arith::min(morpho::max(marker, p, marker.nbh_get().get_win()),
- mask[p]);
+ {
+ oln_type_of(I1, value) a =
+ morpho::max(marker, p, marker.nbh_get().get_win());
+ oln_type_of(I2, value) b = mask[p];
+ // Min.
+ output[p] = a < b ? a : b;
+ }
return output;
}
Index: olena/oln/morpho/geodesic_erosion.hh
--- olena/oln/morpho/geodesic_erosion.hh (revision 158)
+++ olena/oln/morpho/geodesic_erosion.hh (working copy)
@@ -33,7 +33,6 @@
# include <oln/core/abstract/image_operator.hh>
# include <oln/morpho/stat.hh>
# include <oln/level/compare.hh>
-# include <oln/convert/nbh_to_se.hh>
# include <oln/arith/max.hh>
# include <oln/core/abstract/neighborhood.hh>
@@ -59,11 +58,15 @@
oln_type_of(I1, concrete) output(marker.size());
// FIXME: Useless?
// marker.border_adapt_copy(marker.nbh_get().delta());
- oln_type_of(I1, piter) p(marker);
+ oln_type_of(I1, piter) p(marker.size());
for_all_p (p)
- output[p] =
- arith::max(morpho::min(marker, p, marker.nbh_get().get_win()),
- mask[p]);
+ {
+ oln_type_of(I1, value) a =
+ morpho::min(marker, p, marker.nbh_get().get_win());
+ oln_type_of(I2, value) b = mask[p];
+ // Max.
+ output[p] = a > b ? a : b;
+ }
return output;
}
1
0
proto-1.0 158: Add generic morphological opening and closing, repair geodesic erosion and dilation
by Roland Levillain 15 Apr '05
by Roland Levillain 15 Apr '05
15 Apr '05
https://svn.lrde.epita.fr/svn/oln/prototypes/proto-1.0
ChangeLog | 24 ++++
oln/core/abstract/image_with_extension.hh | 2
oln/core/gen/image_with_nbh.hh | 6 -
oln/makefile.src | 2
oln/morpho/closing.hh | 166 ++++++++++++++++++++++++++++++
oln/morpho/geodesic_dilation.hh | 11 +
oln/morpho/geodesic_erosion.hh | 13 +-
oln/morpho/opening.hh | 166 ++++++++++++++++++++++++++++++
tests/core/tests/readwrite_image | 1
tests/core/tests/setget | 11 +
tests/morpho/tests/closing | 27 ++++
tests/morpho/tests/dilation | 1
tests/morpho/tests/erosion | 1
tests/morpho/tests/geodesic_dilation | 76 +++++++------
tests/morpho/tests/geodesic_erosion | 75 ++++++-------
tests/morpho/tests/opening | 27 ++++
16 files changed, 519 insertions(+), 90 deletions(-)
Index: olena/ChangeLog
from Roland Levillain <roland(a)lrde.epita.fr>
Add generic morphological opening and closing.
Repair geodesic erosion and dilation.
* oln/morpho/closing.hh, oln/morpho/opening.hh: New files.
* oln/makefile.src (OLN_DEP): Add morpho/closing.hh and
morpho/opening.hh.
* tests/morpho/tests/closing, tests/morpho/tests/opening: New
tests.
* tests/core/tests/readwrite_image, tests/core/tests/setget:
Update tests.
* oln/morpho/geodesic_dilation.hh (impl_run): Fix access to window.
* oln/morpho/geodesic_erosion.hh (impl_run): Likewise.
Fix precondition.
* oln/core/abstract/image_with_extension.hh
(image_with_extension::image_with_extension): Remove const before
reference of the first argument.
* oln/core/gen/image_with_nbh.hh
(image_with_nbh::image_with_nbh, join): Likewise.
(nbh_): Make it non const.
Index: olena/tests/morpho/tests/opening
--- olena/tests/morpho/tests/opening (revision 0)
+++ olena/tests/morpho/tests/opening (revision 0)
@@ -0,0 +1,27 @@
+ // -*- C++ -*-
+#include "data.hh"
+#include <oln/utils/md5.hh>
+
+#include <oln/io/read_image.hh>
+#include <oln/basics2d.hh>
+#include <oln/morpho/opening.hh>
+#include <oln/level/compare.hh>
+#include <ntg/all.hh>
+
+bool check()
+{
+ // MD5 sum of object.pbm's geodesic dilation result.
+ oln::utils::key::value_type data_key[16] =
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+ oln::utils::key key(data_key);
+
+ typedef oln::image2d<ntg::bin> im_type;
+ im_type ima;
+ ima = oln::io::read(rdata("16x16.pbm"));
+
+ if (oln::utils::md5(oln::morpho::opening(ima, oln::win_c8p())) != key)
+ return true;
+
+ return false;
+}
Index: olena/tests/morpho/tests/geodesic_erosion
--- olena/tests/morpho/tests/geodesic_erosion (revision 157)
+++ olena/tests/morpho/tests/geodesic_erosion (working copy)
@@ -1,45 +1,46 @@
+ // -*- C++ -*-
#include "data.hh"
-//#include <oln/utils/md5.hh>
+#include <oln/utils/md5.hh>
#include <iostream>
-//#include <oln/io/read_image.hh>
-//#include <oln/basics2d.hh>
-//#include <oln/core/abstract/image_with_nbh.hh>
-//#include <oln/morpho/opening.hh>
-//#include <oln/morpho/geodesic_erosion.hh>
-//#include <ntg/all.hh>
+#include <oln/io/read_image.hh>
+#include <oln/basics2d.hh>
+#include <oln/core/gen/image_with_nbh.hh>
+#include <oln/morpho/closing.hh>
+#include <oln/morpho/geodesic_erosion.hh>
+#include <ntg/all.hh>
+using namespace oln;
bool check()
{
- // FIXME : really test this algorithm
- // FAKE test below
- std::cout << "FIXME : md5 does not math with olena-0.10 reference" << std::endl;
- return false;
- // FIXME : end fake test
+ // MD5 sum of object.pbm's geodesic erosion result.
+ utils::key::value_type data_key[16] =
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+ utils::key key(data_key);
+
+ typedef image2d<ntg::bin> im_type;
+
+ neighborhood2d nbh(neighb_c4());
+
+ im_type marker;
+ im_type mask;
+
+ mask = io::read(rdata("object.pbm"));
+ marker = morpho::closing(mask, win_c4p()).exact();
+
+ // Classical procedure.
+ // FIXME: Re-enable when proc::geodesic_erosion is fixed.
+#if 0
+ if (utils::md5(morpho::proc::geodesic_erosion(join(marker, nbh),
+ mask).exact()) != key)
+ return true;
+#endif
+
+ // Facade to object-algorithm.
+ if (utils::md5(morpho::geodesic_erosion(join(marker, nbh),
+ mask).exact()) != key)
+ return true;
-// oln::utils::key::value_type data_key[16] =
-// {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; // md5 of object.pbm's geodesic_erosion result
-// oln::utils::key key(data_key);
-
-// typedef oln::image2d<ntg::bin> im_type;
-
-// oln::neighborhood2d nbh(oln::neighb_c4());
-
-// im_type marker;
-// im_type mask;
-
-// marker = oln::io::read(rdata("object.pbm"));
-// mask = oln::morpho::opening(mask, oln::win_c4p()).exact();
-
-// if (oln::utils::md5(oln::morpho::geodesic_erosion(join(marker, nbh), mask).exact()) == key)
-// {
-// std::cout << "OK" << std::endl;
-// return false;
-// }
-// else
-// {
-// std::cout << "FAIL" << std::endl;
-// return true;
-// }
+ return false;
}
Index: olena/tests/morpho/tests/dilation
--- olena/tests/morpho/tests/dilation (revision 157)
+++ olena/tests/morpho/tests/dilation (working copy)
@@ -1,3 +1,4 @@
+ // -*- C++ -*-
#include "data.hh"
#include <oln/utils/md5.hh>
Index: olena/tests/morpho/tests/geodesic_dilation
--- olena/tests/morpho/tests/geodesic_dilation (revision 157)
+++ olena/tests/morpho/tests/geodesic_dilation (working copy)
@@ -1,44 +1,46 @@
+ // -*- C++ -*-
#include "data.hh"
-//#include <oln/utils/md5.hh>
+#include <oln/utils/md5.hh>
#include <iostream>
-//#include <oln/io/read_image.hh>
-//#include <oln/basics2d.hh>
-//#include <oln/core/abstract/image_with_nbh.hh>
-//#include <oln/morpho/opening.hh>
-//#include <oln/morpho/geodesic_erosion.hh>
-//#include <ntg/all.hh>
+#include <oln/io/read_image.hh>
+#include <oln/basics2d.hh>
+#include <oln/core/gen/image_with_nbh.hh>
+#include <oln/morpho/opening.hh>
+#include <oln/morpho/geodesic_dilation.hh>
+#include <ntg/all.hh>
+
+using namespace oln;
bool check()
{
- // FIXME : really test this algorithm
- // FAKE test below
- std::cout << "FIXME : md5 does not math with olena-0.10 reference" << std::endl;
- return false;
- // FIXME : end fake test
+ // MD5 sum of object.pbm's geodesic dilation result.
+ utils::key::value_type data_key[16] =
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+ utils::key key(data_key);
+
+ typedef image2d<ntg::bin> im_type;
+
+ neighborhood2d nbh(neighb_c4());
+
+ im_type marker;
+ im_type mask;
+
+ mask = io::read(rdata("object.pbm"));
+ marker = morpho::opening(mask, win_c4p()).exact();
+
+ // Classical procedure.
+ // FIXME: Re-enable when proc::geodesic_dilation is fixed.
+#if 0
+ if (utils::md5(morpho::proc::geodesic_dilation(join(marker, nbh),
+ mask).exact()) != key)
+ return true;
+#endif
+
+ // Facade to object-algorithm.
+ if (utils::md5(morpho::geodesic_dilation(join(marker, nbh),
+ mask).exact()) != key)
+ return true;
-// oln::utils::key::value_type data_key[16] =
-// {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; // md5 of object.pbm's geodesic_dilation result
-// oln::utils::key key(data_key);
-
-// typedef oln::image2d<ntg::bin> im_type;
-
-// oln::neighborhood2d nbh(oln::neighb_c4());
-
-// im_type marker;
-// im_type mask;
-
-// mask = oln::io::read(rdata("object.pbm"));
-// marker = oln::morpho::opening(mask, oln::win_c4p()).exact();
-
-// if (oln::utils::md5(oln::morpho::geodesic_dilation(join(marker, nbh), mask).exact()) == key)
-// {
-// std::cout << "OK" << std::endl;
-// return false;
-// }
-// else
-// {
-// std::cout << "FAIL" << std::endl;
-// return true;
-// }
+ return false;
}
Index: olena/tests/morpho/tests/erosion
--- olena/tests/morpho/tests/erosion (revision 157)
+++ olena/tests/morpho/tests/erosion (working copy)
@@ -1,3 +1,4 @@
+ // -*- C++ -*-
#include "data.hh"
#include <oln/utils/md5.hh>
Index: olena/tests/morpho/tests/closing
--- olena/tests/morpho/tests/closing (revision 0)
+++ olena/tests/morpho/tests/closing (revision 0)
@@ -0,0 +1,27 @@
+ // -*- C++ -*-
+#include "data.hh"
+#include <oln/utils/md5.hh>
+
+#include <oln/io/read_image.hh>
+#include <oln/basics2d.hh>
+#include <oln/morpho/closing.hh>
+#include <oln/level/compare.hh>
+#include <ntg/all.hh>
+
+bool check()
+{
+ // MD5 sum of object.pbm's geodesic dilation result.
+ oln::utils::key::value_type data_key[16] =
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+ oln::utils::key key(data_key);
+
+ typedef oln::image2d<ntg::bin> im_type;
+ im_type ima;
+ ima = oln::io::read(rdata("16x16.pbm"));
+
+ if (oln::utils::md5(oln::morpho::closing(ima, oln::win_c8p())) != key)
+ return true;
+
+ return false;
+}
Index: olena/tests/core/tests/readwrite_image
--- olena/tests/core/tests/readwrite_image (revision 157)
+++ olena/tests/core/tests/readwrite_image (working copy)
@@ -22,6 +22,7 @@
template <>
struct set_props <category::image, dummy_image>
{
+ typedef grid2d grid_type;
typedef is_a<abstract::readwrite_image> image_constness;
typedef is_a<abstract::image2d> image_dimension_type;
Index: olena/tests/core/tests/setget
--- olena/tests/core/tests/setget (revision 157)
+++ olena/tests/core/tests/setget (working copy)
@@ -15,17 +15,18 @@
template <>
struct set_props < category::image, dummy_image >
{
- typedef int concrete_type;
- typedef int image_dimension_type;
+ typedef mlc::no_type grid_type;
+ typedef mlc::no_type concrete_type;
+ typedef mlc::no_type image_dimension_type;
typedef int size_type;
typedef int point_type;
typedef int value_type;
typedef mlc::no_type delegated_type;
- typedef fwd_piter2d piter_type;
- typedef fwd_piter2d fwd_piter_type;
- typedef bkd_piter2d bkd_piter_type;
+ typedef mlc::no_type piter_type;
+ typedef mlc::no_type fwd_piter_type;
+ typedef mlc::no_type bkd_piter_type;
};
struct dummy_image : public abstract::readwrite_image< dummy_image >
Index: olena/oln/core/abstract/image_with_extension.hh
--- olena/oln/core/abstract/image_with_extension.hh (revision 157)
+++ olena/oln/core/abstract/image_with_extension.hh (working copy)
@@ -68,7 +68,7 @@
{
}
- image_with_extension(const abstract::image<I>& image) :
+ image_with_extension(abstract::image<I>& image) :
super_type(image)
{
}
Index: olena/oln/core/gen/image_with_nbh.hh
--- olena/oln/core/gen/image_with_nbh.hh (revision 157)
+++ olena/oln/core/gen/image_with_nbh.hh (working copy)
@@ -58,7 +58,7 @@
public:
- image_with_nbh(const abstract::image<I>& image,
+ image_with_nbh(abstract::image<I>& image,
const abstract::neighborhood<N>& nbh) :
super_type(image),
nbh_(nbh.exact())
@@ -72,7 +72,7 @@
protected:
- N& nbh_;
+ const N& nbh_;
};
@@ -80,7 +80,7 @@
template <typename I, typename N>
image_with_nbh<I, N>
- join(const abstract::image<I>& image,
+ join(abstract::image<I>& image,
const abstract::neighborhood<N>& nbh)
{
image_with_nbh<I, N> tmp(image, nbh);
Index: olena/oln/makefile.src
--- olena/oln/makefile.src (revision 157)
+++ olena/oln/makefile.src (working copy)
@@ -137,8 +137,10 @@
level/fill.hh \
\
morpho/cc_tarjan.hh \
+ morpho/closing.hh \
morpho/dilation.hh \
morpho/erosion.hh \
+ morpho/opening.hh \
morpho/reconstruction.hh \
morpho/splitse.hh \
morpho/stat.hh \
Index: olena/oln/morpho/geodesic_dilation.hh
--- olena/oln/morpho/geodesic_dilation.hh (revision 157)
+++ olena/oln/morpho/geodesic_dilation.hh (working copy)
@@ -57,10 +57,12 @@
precondition(marker.size() == mask.size());
precondition(level::is_greater_or_equal(mask, marker));
oln_type_of(I1, concrete) output(marker.size());
- marker.border_adapt_copy(marker.nbh_get().delta());
+ // FIXME: Useless?
+ // marker.border_adapt_copy(marker.nbh_get().delta());
oln_type_of(I1, piter) p(marker);
for_all_p (p)
- output[p] = arith::min(morpho::max(marker, p, convert::nbh_to_cse(marker.nbh_get())),
+ output[p] =
+ arith::min(morpho::max(marker, p, marker.nbh_get().get_win()),
mask[p]);
return output;
}
@@ -110,7 +112,10 @@
mlc::eq<oln_type_of(I1, size), oln_type_of(I2, size)>::ensure();
precondition((this->input1).size() == (this->input2).size());
precondition(level::is_greater_or_equal(this->input2, this->input1));
- this->output = arith::min(dilation(this->input1.unbox(), this->input1.unbox().nbh_get()).output.unbox(), this->input2.unbox()).output;
+ this->output =
+ arith::min(dilation(this->input1.unbox(),
+ this->input1.unbox().nbh_get().get_win()).output.unbox(),
+ this->input2.unbox()).output;
}
};
Index: olena/oln/morpho/closing.hh
--- olena/oln/morpho/closing.hh (revision 0)
+++ olena/oln/morpho/closing.hh (revision 0)
@@ -0,0 +1,166 @@
+// Copyright (C) 2001, 2002, 2003, 2004, 2005 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+// MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef OLENA_MORPHO_CLOSING_HH
+# define OLENA_MORPHO_CLOSING_HH
+
+# include <mlc/cmp.hh>
+# include <mlc/to_string.hh>
+
+# include <oln/core/abstract/images.hh>
+# include <oln/core/abstract/image_operator.hh>
+
+# include <oln/morpho/dilation.hh>
+# include <oln/morpho/erosion.hh>
+# include <oln/core/2d/window2d.hh>
+
+
+namespace oln {
+
+
+ // fwd decl
+
+ namespace morpho {
+ template <typename I> struct closing_ret;
+ }
+
+ // super_type
+
+ template <typename I>
+ struct set_super_type< morpho::closing_ret<I> >
+ {
+ typedef oln_type_of(I, concrete) output_type;
+
+ typedef morpho::closing_ret<I> self_type;
+ typedef abstract::image_unary_operator<output_type, I, self_type > ret;
+ };
+
+
+
+
+ namespace morpho {
+
+
+
+ // Closing as a 'classical' procedure returning an image (do not
+ // use it; prefer morpho::closing).
+
+ namespace proc {
+
+ template<typename I, typename W>
+ oln_type_of(I, concrete) closing(const abstract::image<I>& input,
+ const abstract::window<W>& win)
+ {
+ mlc::eq<oln_type_of(I, grid), oln_wn_type_of(W, grid)>::ensure();
+ oln_type_of(I, concrete) output(input.size());
+ output = morpho::erosion(morpho::dilation(input, win), win);
+ return output;
+ }
+
+ } // end of namespace oln::morpho::proc
+
+
+
+ /// Closing return type.
+
+ template <typename I>
+ struct closing_ret : public oln_super_of_(closing_ret<I>)
+ {
+ typedef oln_super_of(closing_ret<I>) super_type;
+
+ closing_ret(const abstract::image<I>& input) :
+ super_type(input)
+ {
+ }
+
+ };
+
+
+ // Various implementation.
+
+ namespace impl {
+
+
+ /// Generic implementation of closing (type).
+
+ template <typename I, typename W>
+ struct generic_closing : public closing_ret<I>
+ {
+ typedef closing_ret<I> super_type;
+ // FIXME: typedef oln_type_of(super_type, output) output_type;
+
+ const W& win;
+
+ generic_closing(const abstract::image<I>& input,
+ const abstract::window<W>& win) :
+ super_type(input),
+ win(win.exact())
+ {
+ }
+
+ void impl_run()
+ {
+ oln_type_of(super_type, output) tmp(input.size());
+ tmp = morpho::erosion(morpho::dilation(input, win), win);
+ output = tmp;
+ }
+ };
+
+ // Generic implementation of closing (routine).
+
+ template<typename I, typename W>
+ closing_ret<I> closing(const abstract::image<I>& input,
+ const abstract::window<W>& win)
+ {
+ impl::generic_closing<I,W> tmp(input, win);
+ tmp.run();
+ return tmp;
+ }
+
+ // FIXME: Add specialized implementations.
+
+ } // end of namespace oln::morpho::impl
+
+
+ /// Generic closing (facade).
+
+ template<typename I, typename W>
+ closing_ret<I> closing(const abstract::image<I>& input,
+ const abstract::window<W>& win)
+ {
+ mlc::eq<oln_type_of(I, grid), oln_wn_type_of(W, grid)>::ensure();
+ return impl::closing(input.exact(), win.exact());
+ }
+
+
+ } // end of namespace oln::morpho
+
+
+} // end of namespace oln
+
+
+#endif // ! OLENA_MORPHO_CLOSING_HH
Index: olena/oln/morpho/opening.hh
--- olena/oln/morpho/opening.hh (revision 0)
+++ olena/oln/morpho/opening.hh (revision 0)
@@ -0,0 +1,166 @@
+// Copyright (C) 2001, 2002, 2003, 2004, 2005 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+// MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef OLENA_MORPHO_OPENING_HH
+# define OLENA_MORPHO_OPENING_HH
+
+# include <mlc/cmp.hh>
+# include <mlc/to_string.hh>
+
+# include <oln/core/abstract/images.hh>
+# include <oln/core/abstract/image_operator.hh>
+
+# include <oln/morpho/dilation.hh>
+# include <oln/morpho/erosion.hh>
+# include <oln/core/2d/window2d.hh>
+
+
+namespace oln {
+
+
+ // fwd decl
+
+ namespace morpho {
+ template <typename I> struct opening_ret;
+ }
+
+ // super_type
+
+ template <typename I>
+ struct set_super_type< morpho::opening_ret<I> >
+ {
+ typedef oln_type_of(I, concrete) output_type;
+
+ typedef morpho::opening_ret<I> self_type;
+ typedef abstract::image_unary_operator<output_type, I, self_type > ret;
+ };
+
+
+
+
+ namespace morpho {
+
+
+
+ // Opening as a 'classical' procedure returning an image (do not
+ // use it; prefer morpho::opening).
+
+ namespace proc {
+
+ template<typename I, typename W>
+ oln_type_of(I, concrete) opening(const abstract::image<I>& input,
+ const abstract::window<W>& win)
+ {
+ mlc::eq<oln_type_of(I, grid), oln_wn_type_of(W, grid)>::ensure();
+ oln_type_of(I, concrete) output(input.size());
+ output = morpho::dilation(morpho::erosion(input, win), win);
+ return output;
+ }
+
+ } // end of namespace oln::morpho::proc
+
+
+
+ /// Opening return type.
+
+ template <typename I>
+ struct opening_ret : public oln_super_of_(opening_ret<I>)
+ {
+ typedef oln_super_of(opening_ret<I>) super_type;
+
+ opening_ret(const abstract::image<I>& input) :
+ super_type(input)
+ {
+ }
+
+ };
+
+
+ // Various implementation.
+
+ namespace impl {
+
+
+ /// Generic implementation of opening (type).
+
+ template <typename I, typename W>
+ struct generic_opening : public opening_ret<I>
+ {
+ typedef opening_ret<I> super_type;
+ // FIXME: typedef oln_type_of(super_type, output) output_type;
+
+ const W& win;
+
+ generic_opening(const abstract::image<I>& input,
+ const abstract::window<W>& win) :
+ super_type(input),
+ win(win.exact())
+ {
+ }
+
+ void impl_run()
+ {
+ oln_type_of(super_type, output) tmp(input.size());
+ tmp = morpho::dilation(morpho::erosion(input, win), win);
+ output = tmp;
+ }
+ };
+
+ // Generic implementation of opening (routine).
+
+ template<typename I, typename W>
+ opening_ret<I> opening(const abstract::image<I>& input,
+ const abstract::window<W>& win)
+ {
+ impl::generic_opening<I,W> tmp(input, win);
+ tmp.run();
+ return tmp;
+ }
+
+ // FIXME: Add specialized implementations.
+
+ } // end of namespace oln::morpho::impl
+
+
+ /// Generic opening (facade).
+
+ template<typename I, typename W>
+ opening_ret<I> opening(const abstract::image<I>& input,
+ const abstract::window<W>& win)
+ {
+ mlc::eq<oln_type_of(I, grid), oln_wn_type_of(W, grid)>::ensure();
+ return impl::opening(input.exact(), win.exact());
+ }
+
+
+ } // end of namespace oln::morpho
+
+
+} // end of namespace oln
+
+
+#endif // ! OLENA_MORPHO_OPENING_HH
Index: olena/oln/morpho/geodesic_erosion.hh
--- olena/oln/morpho/geodesic_erosion.hh (revision 157)
+++ olena/oln/morpho/geodesic_erosion.hh (working copy)
@@ -57,10 +57,12 @@
precondition(marker.size() == mask.size());
precondition(level::is_greater_or_equal(marker, mask));
oln_type_of(I1, concrete) output(marker.size());
- marker.border_adapt_copy(marker.nbh_get().delta());
+ // FIXME: Useless?
+ // marker.border_adapt_copy(marker.nbh_get().delta());
oln_type_of(I1, piter) p(marker);
for_all_p (p)
- output[p] = arith::max(morpho::min(marker, p, convert::nbh_to_cse(marker.nbh_get())),
+ output[p] =
+ arith::max(morpho::min(marker, p, marker.nbh_get().get_win()),
mask[p]);
return output;
}
@@ -108,8 +110,11 @@
{
mlc::eq<oln_type_of(I1, size), oln_type_of(I2, size)>::ensure();
precondition((this->input1).size() == (this->input2).size());
- precondition(level::is_greater_or_equal(this->input2, this->input1));
- this->output = arith::max(erosion(this->input1.unbox(), this->input1.unbox().nbh_get()).output.unbox(), this->input2.unbox()).output;
+ precondition(level::is_greater_or_equal(this->input1, this->input2));
+ this->output =
+ arith::max(erosion(this->input1.unbox(),
+ this->input1.unbox().nbh_get().get_win()).output.unbox(),
+ this->input2.unbox()).output;
}
};
1
0
2005-04-14 Thierry GERAUD <theo(a)tegucigalpa.lrde.epita.fr>
* oln/core/accum.hh: Rewrite and move...
* oln/funobj/accum.hh: ...here.
* tests/morpho/tests/geodesic_erosion: Add include.
* tests/morpho/tests/geodesic_dilation: Likewise.
* tests/morpho/tests/erosion: Fix bug.
* oln/core/typedefs.hh: Add decls for iterators.
* oln/core/abstract/image.hh (grid_type): New property.
* oln/core/1d/image1d.hh: Update.
* oln/core/2d/image2d.hh: Likewise.
* oln/core/3d/image3d.hh: Likewise.
* oln/core/abstract/qiter.hh: Fix bug.
* oln/core/abstract/image_like_.hh (real const): Remove 'const' in
return since an image-like behaves as a mutable.
(real): Remove.
(box<I>): Add operator= for image_like_.
* oln/core/2d/window2d.hh (win_hline2d, win_vline2d): New types.
* oln/core/box.hh: Clean up and add new methods.
* oln/core/gen/regular_fwd_qiter.hh: Fix ctor signature.
* oln/core/gen/regular_bkd_qiter.hh: Likewise.
* oln/core/gen/regular_qiter.hh: Likewise.
* oln/core/gen/regular_window.hh: Add includes.
* oln/makefile.src: Update.
* oln/morpho/stat.hh: Update.
* oln/morpho/erosion.hh:
Index: tests/morpho/tests/geodesic_erosion
===================================================================
--- tests/morpho/tests/geodesic_erosion (revision 155)
+++ tests/morpho/tests/geodesic_erosion (working copy)
@@ -1,6 +1,6 @@
#include "data.hh"
//#include <oln/utils/md5.hh>
-
+#include <iostream>
//#include <oln/io/read_image.hh>
//#include <oln/basics2d.hh>
//#include <oln/core/abstract/image_with_nbh.hh>
Index: tests/morpho/tests/geodesic_dilation
===================================================================
--- tests/morpho/tests/geodesic_dilation (revision 155)
+++ tests/morpho/tests/geodesic_dilation (working copy)
@@ -1,6 +1,6 @@
#include "data.hh"
//#include <oln/utils/md5.hh>
-
+#include <iostream>
//#include <oln/io/read_image.hh>
//#include <oln/basics2d.hh>
//#include <oln/core/abstract/image_with_nbh.hh>
Index: tests/morpho/tests/erosion
===================================================================
--- tests/morpho/tests/erosion (revision 155)
+++ tests/morpho/tests/erosion (working copy)
@@ -19,7 +19,7 @@
im_type ima;
ima = oln::io::read(rdata("16x16.pbm"));
- std::cout << oln::utils::md5(oln::morpho::dilation(ima, oln::win_c8p())) << std::endl;
+ std::cout << oln::utils::md5(oln::morpho::erosion(ima, oln::win_c8p())) << std::endl;
if (oln::utils::md5(oln::morpho::erosion(ima, oln::win_c8p())) == key)
{
std::cout << "OK" << std::endl;
Index: oln/funobj/accum.hh
===================================================================
--- oln/funobj/accum.hh (revision 0)
+++ oln/funobj/accum.hh (working copy)
@@ -25,45 +25,93 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-#ifndef OLENA_CORE_ACCUM_HH
-# define OLENA_CORE_ACCUM_HH
+#ifndef OLENA_CORE_FUNOBJ_ACCUM_HH
+# define OLENA_CORE_FUNOBJ_ACCUM_HH
+# include <mlc/contract.hh>
-/*! \class max_accumulator
-**
-** This is a \a functor. It saves the maximum T value
-** that has been passed as an argument of its operator()
-** method. To retrieve the value saved, just use the
-** max_accumulator as a T instance.
-*/
+namespace oln
+{
-// FIXME: no namespace !!!
-// FIXME: move this file !!!
+ namespace funobj
+ {
-template <class T>
-struct max_accumulator
-{
-
- max_accumulator (T t) : acc_(t)
- {}
+ /// Max accumulator.
- void
- operator()(T t)
- {
- if (t > acc_)
- acc_ = t;
- }
+ template <class T>
+ struct max_accumulator
+ {
- operator T() const
- {
- return acc_;
- }
+ max_accumulator() :
+ ok_(false)
+ {}
+
+ void operator()(const T& t)
+ {
+ if (not ok_)
+ {
+ ok_ = true;
+ acc_ = t;
+ return;
+ }
+ if (t > acc_)
+ acc_ = t;
+ }
+
+ operator T() const
+ {
+ precondition(ok_);
+ return acc_;
+ }
+
+ private:
+
+ bool ok_;
+ T acc_;
-private:
+ };
+
+
+ /// Min accumulator.
+
+ template <class T>
+ struct min_accumulator
+ {
- T acc_;
-
-};
+ min_accumulator() :
+ ok_(false)
+ {}
+
+ void operator()(const T& t)
+ {
+ if (not ok_)
+ {
+ ok_ = true;
+ acc_ = t;
+ return;
+ }
+ if (t < acc_)
+ acc_ = t;
+ }
+
+ operator T() const
+ {
+ precondition(ok_);
+ return acc_;
+ }
+
+ private:
+
+ bool ok_;
+ T acc_;
-#endif // OLENA_CORE_ACCUM_HH
+ };
+
+
+ } // end of namespace oln::funobj
+
+} // end of namespace oln
+
+
+#endif // ! OLENA_CORE_FUNOBJ_ACCUM_HH
Index: oln/core/typedefs.hh
===================================================================
--- oln/core/typedefs.hh (revision 155)
+++ oln/core/typedefs.hh (working copy)
@@ -55,10 +55,24 @@
mlc_decl_typedef(grid_type);
+ // iterators
+
mlc_decl_typedef(iter_type);
mlc_decl_typedef(fwd_iter_type);
mlc_decl_typedef(bkd_iter_type);
+ mlc_decl_typedef(piter_type);
+ mlc_decl_typedef(fwd_piter_type);
+ mlc_decl_typedef(bkd_piter_type);
+
+ mlc_decl_typedef(qiter_type);
+ mlc_decl_typedef(fwd_qiter_type);
+ mlc_decl_typedef(bkd_qiter_type);
+
+ mlc_decl_typedef(niter_type);
+ mlc_decl_typedef(fwd_niter_type);
+ mlc_decl_typedef(bkd_niter_type);
+
// category::image
mlc_decl_typedef(data_type);
@@ -71,11 +85,6 @@
mlc_decl_typedef(image_type);
mlc_decl_typedef(concrete_type);
- mlc_decl_typedef(piter_type);
- mlc_decl_typedef(fwd_piter_type);
- mlc_decl_typedef(bkd_piter_type);
- mlc_decl_typedef(fwd_niter_type);
-
mlc_decl_typedef(delegated_type);
mlc_decl_typedef(size_type);
mlc_decl_typedef(window_type);
@@ -92,10 +101,7 @@
mlc_decl_typedef(input1_type);
mlc_decl_typedef(input2_type);
- // category::window
- mlc_decl_typedef(fwd_qiter_type);
- mlc_decl_typedef(bkd_qiter_type);
// category::grid
Index: oln/core/abstract/image.hh
===================================================================
--- oln/core/abstract/image.hh (revision 155)
+++ oln/core/abstract/image.hh (working copy)
@@ -62,10 +62,13 @@
template <>
struct set_default_props < category::image >
{
+ typedef mlc::undefined_type grid_type;
+
typedef mlc::undefined_type concrete_type;
typedef mlc::undefined_type value_type;
typedef mlc::undefined_type point_type;
typedef mlc::undefined_type size_type;
+
typedef mlc::undefined_type piter_type;
typedef mlc::undefined_type fwd_piter_type;
typedef mlc::undefined_type bkd_piter_type;
@@ -90,6 +93,8 @@
template <typename I>
struct get_props < category::image, I >
{
+ typedef oln_type_of(I, grid) grid_type;
+
typedef oln_type_of(I, concrete) concrete_type;
typedef oln_type_of(I, value) value_type;
typedef oln_type_of(I, point) point_type;
@@ -116,6 +121,8 @@
ostr << "props_of( oln::category::image, " << mlc_to_string(I) << " ) =" << std::endl
<< "{" << std::endl
+ << "\t grid_type = " << mlc_to_string(grid_type) << std::endl
+
<< "\t concrete_type = " << mlc_to_string(concrete_type) << std::endl
<< "\t value_type = " << mlc_to_string(value_type) << std::endl
<< "\t point_type = " << mlc_to_string(point_type) << std::endl
@@ -139,6 +146,7 @@
static void ensure()
{
+ mlc::is_ok< grid_type >::ensure();
mlc::is_ok< concrete_type >::ensure();
mlc::is_ok< value_type >::ensure();
mlc::is_ok< point_type >::ensure();
Index: oln/core/abstract/qiter.hh
===================================================================
--- oln/core/abstract/qiter.hh (revision 155)
+++ oln/core/abstract/qiter.hh (working copy)
@@ -38,7 +38,7 @@
for(q.ensure_is_qiter(), q.start_at_p(p); q.is_valid(); q.next())
# define for_all_remaining_q( q ) \
- for(q.ensure_is_piter(); q.is_valid(); q.next())
+ for(q.ensure_is_qiter(); q.is_valid(); q.next())
# define oln_qit_type_of(QiterType, Alias) \
Index: oln/core/abstract/image_like_.hh
===================================================================
--- oln/core/abstract/image_like_.hh (revision 155)
+++ oln/core/abstract/image_like_.hh (working copy)
@@ -74,23 +74,37 @@
{
}
- const I& real() const
+ I& real() const
{
return this->image_.unbox();
}
- I& real()
- {
- return this->image_.unbox();
- }
-
};
} // end of namespace oln::abstract
+} // end of namespace oln
+
+# include <oln/core/box.hh>
+
+
+namespace oln
+{
+
+
+ template <typename I>
+ template <typename E>
+ box<I>& box<I>::operator=(const abstract::image_like_<I, E>& rhs)
+ {
+ this->image_ = rhs.real();
+ return *this;
+ }
+
+
} // end of namespace oln
+
#endif // ! OLENA_CORE_ABSTRACT_IMAGE_LIKE__HH
Index: oln/core/1d/image1d.hh
===================================================================
--- oln/core/1d/image1d.hh (revision 155)
+++ oln/core/1d/image1d.hh (working copy)
@@ -52,6 +52,8 @@
template <typename T>
struct set_props < category::image, image1d<T> >
{
+ typedef grid1d grid_type;
+
// intrusive property:
typedef is_a<abstract::image1d> image_dimension_type;
// FIXME: should be generalized
Index: oln/core/2d/image2d.hh
===================================================================
--- oln/core/2d/image2d.hh (revision 155)
+++ oln/core/2d/image2d.hh (working copy)
@@ -62,6 +62,8 @@
template <typename T>
struct set_props < category::image, image2d<T> >
{
+ typedef grid2d grid_type;
+
// intrusive property:
typedef is_a<abstract::image2d> image_dimension_type;
// FIXME: should be generalized
Index: oln/core/2d/window2d.hh
===================================================================
--- oln/core/2d/window2d.hh (revision 155)
+++ oln/core/2d/window2d.hh (working copy)
@@ -37,6 +37,9 @@
namespace oln
{
+
+ //------------------------------------------- window2d
+
// fwd decl
struct window2d;
@@ -65,6 +68,9 @@
};
+ //------------------------------------ win_rectangle2d
+
+
// fwd decl
struct win_rectangle2d;
@@ -100,9 +106,78 @@
};
+ //------------------------------------ win_hline2d
- // classical 2d windows
+ // fwd decl
+ struct win_hline2d;
+
+ // super type
+ template <>
+ struct set_super_type< win_hline2d > { typedef abstract::regular_window< grid2d, win_hline2d > ret; };
+
+
+ /// Class win_hline2d.
+ struct win_hline2d : public oln_super_of_(win_hline2d)
+ {
+ typedef oln_super_of_(win_hline2d) super_type;
+
+ win_hline2d(unsigned length) :
+ length(length)
+ {
+ int
+ min_dcol = (1 - int(length)) / 2,
+ max_dcol = int(length) / 2;
+ for (int dcol = min_dcol; dcol <= max_dcol; ++dcol)
+ {
+ dpoint2d dp(0, dcol);
+ this->add_(dp);
+ }
+ }
+
+ const unsigned length;
+ };
+
+
+
+ //------------------------------------ win_vline2d
+
+
+ // fwd decl
+ struct win_vline2d;
+
+ // super type
+ template <>
+ struct set_super_type< win_vline2d > { typedef abstract::regular_window< grid2d, win_vline2d > ret; };
+
+
+ /// Class win_vline2d.
+ struct win_vline2d : public oln_super_of_(win_vline2d)
+ {
+ typedef oln_super_of_(win_vline2d) super_type;
+
+ win_vline2d(unsigned length) :
+ length(length)
+ {
+ int
+ min_drow = (1 - int(length)) / 2,
+ max_drow = int(length) / 2;
+ for (int drow = min_drow; drow <= max_drow; ++drow)
+ {
+ dpoint2d dp(drow, 0);
+ this->add_(dp);
+ }
+ }
+
+ const unsigned length;
+ };
+
+
+
+
+ //------------------------------- classical 2d windows
+
+
/*!
** \brief Create a window (2 dimensions) of 4 elements.
** \return The new window.
Index: oln/core/box.hh
===================================================================
--- oln/core/box.hh (revision 155)
+++ oln/core/box.hh (working copy)
@@ -28,13 +28,19 @@
#ifndef OLENA_CORE_BOX_HH
# define OLENA_CORE_BOX_HH
+# include <mlc/bool.hh>
# include <oln/core/abstract/image_entry.hh>
+
+
namespace oln {
- // fwd decl
+ // fwd decls
template <typename I> struct box;
+ namespace abstract {
+ template <typename I, typename E> struct image_like_;
+ }
// category
@@ -65,7 +71,7 @@
};
- /// Class oln::box...
+ /// Class oln::box<I> encapsulating a mutable image.
template <typename I>
struct box : public abstract::image_entry< box<I> >
@@ -84,24 +90,49 @@
this->exact_ptr = this;
}
+ box(const box<I>& rhs) :
+ image_(const_cast<I&>(rhs.image_))
+ {
+ this->exact_ptr = this;
+ }
+
+ // operator= that are ok
+
box<I>& operator=(abstract::image<I>& rhs)
{
this->image_ = rhs.exact();
return *this;
}
- box(const box<I>& rhs) :
- image_(const_cast<I&>(rhs.image_))
+ box<I>& operator=(const box<I>& rhs)
{
- this->exact_ptr = this;
+ this->image_ = const_cast<I&>(rhs.image_);
+ return *this;
}
- box<I> operator=(const box<I>& rhs)
+ template <typename E>
+ box<I>& operator=(const abstract::image_like_<I, E>& rhs); // impl in image_like_.hh
+
+ // operator= that are not ok
+
+ template <typename II>
+ void operator=(const box<II>& rhs)
{
- this->image_ = const_cast<I&>(rhs.image_);
- return *this;
+ mlc::false_type::ensure();
}
+ template <typename II, typename E>
+ void operator=(const abstract::image_like_<II, E>& rhs)
+ {
+ mlc::false_type::ensure();
+ }
+
+ template <typename II>
+ void operator=(const abstract::image<II>& rhs)
+ {
+ mlc::false_type::ensure();
+ }
+
// FIXME: add versions for I2 (neq I) to produce explicit errors
I& impl_delegate()
@@ -116,15 +147,15 @@
/// Hooks.
- I& unbox()
+ I& unbox() const
{
- return this->image_;
+ return const_cast<I&>(this->image_);
}
- const I& unbox() const
- {
- return this->image_;
- }
+// const I& unbox() const
+// {
+// return this->image_;
+// }
private:
@@ -134,6 +165,8 @@
};
+ /// Class oln::box<const I> encapsulating a constant image.
+
template <typename I>
struct box<const I> : public abstract::image_entry< box<const I> >
{
Index: oln/core/accum.hh
===================================================================
--- oln/core/accum.hh (revision 155)
+++ oln/core/accum.hh (working copy)
@@ -1,69 +0,0 @@
-// Copyright (C) 2001, 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_CORE_ACCUM_HH
-# define OLENA_CORE_ACCUM_HH
-
-
-/*! \class max_accumulator
-**
-** This is a \a functor. It saves the maximum T value
-** that has been passed as an argument of its operator()
-** method. To retrieve the value saved, just use the
-** max_accumulator as a T instance.
-*/
-
-
-// FIXME: no namespace !!!
-// FIXME: move this file !!!
-
-template <class T>
-struct max_accumulator
-{
-
- max_accumulator (T t) : acc_(t)
- {}
-
- void
- operator()(T t)
- {
- if (t > acc_)
- acc_ = t;
- }
-
- operator T() const
- {
- return acc_;
- }
-
-private:
-
- T acc_;
-
-};
-
-#endif // OLENA_CORE_ACCUM_HH
Index: oln/core/3d/image3d.hh
===================================================================
--- oln/core/3d/image3d.hh (revision 155)
+++ oln/core/3d/image3d.hh (working copy)
@@ -55,6 +55,8 @@
template <typename T>
struct set_props < category::image, image3d<T> >
{
+ typedef grid3d grid_type;
+
// intrusive property:
typedef is_a<abstract::image3d> image_dimension_type;
// FIXME: should be generalized
Index: oln/core/gen/regular_fwd_qiter.hh
===================================================================
--- oln/core/gen/regular_fwd_qiter.hh (revision 155)
+++ oln/core/gen/regular_fwd_qiter.hh (working copy)
@@ -54,7 +54,7 @@
typedef regular_fwd_qiter<G,W> self_type;
typedef abstract::regular_qiter<G, self_type> super_type;
- regular_fwd_qiter(const abstract::regular_window<G,W>& win) :
+ regular_fwd_qiter(const abstract::window<W>& win) :
super_type(win)
{
this->invalidate();
Index: oln/core/gen/regular_bkd_qiter.hh
===================================================================
--- oln/core/gen/regular_bkd_qiter.hh (revision 155)
+++ oln/core/gen/regular_bkd_qiter.hh (working copy)
@@ -54,7 +54,7 @@
typedef regular_bkd_qiter<G,W> self_type;
typedef abstract::regular_qiter<G, self_type> super_type;
- regular_bkd_qiter(const abstract::regular_window<G,W>& win) :
+ regular_bkd_qiter(const abstract::window<W>& win) :
super_type(win)
{
this->invalidate();
Index: oln/core/gen/regular_qiter.hh
===================================================================
--- oln/core/gen/regular_qiter.hh (revision 155)
+++ oln/core/gen/regular_qiter.hh (working copy)
@@ -30,7 +30,7 @@
# include <oln/core/abstract/grid.hh>
# include <oln/core/abstract/qiter.hh>
-# include <oln/core/gen/regular_window.hh>
+# include <oln/core/abstract/window.hh>
namespace oln {
@@ -67,7 +67,7 @@
typedef oln_grd_type_of(G, dimvalue) dimvalue_type;
static const unsigned dim = dimvalue_type::val;
- regular_qiter(const regular_window<G, oln_qit_type_of(E, window)>& win) :
+ regular_qiter(const abstract::window<oln_qit_type_of(E, window)>& win) :
super_type(win.exact())
{
}
Index: oln/core/gen/regular_window.hh
===================================================================
--- oln/core/gen/regular_window.hh (revision 155)
+++ oln/core/gen/regular_window.hh (working copy)
@@ -178,5 +178,8 @@
return ostr;
}
+# include <oln/core/gen/regular_fwd_qiter.hh>
+# include <oln/core/gen/regular_bkd_qiter.hh>
+
#endif // ! OLENA_CORE_GEN_REGULAR_WINDOW_HH
Index: oln/makefile.src
===================================================================
--- oln/makefile.src (revision 155)
+++ oln/makefile.src (working copy)
@@ -81,8 +81,6 @@
core/abstract/size.hh \
core/abstract/window.hh \
\
- core/accum.hh \
- \
core/any/all.hh \
core/any/dpoint.hh \
core/any/grid.hh \
@@ -126,6 +124,8 @@
fancy/iota.hh \
fancy/print.hh \
\
+ funobj/accum.hh \
+ \
io/gz_stream.hh \
io/read_image.hh \
io/read_image_2d_pnm.hh \
Index: oln/morpho/stat.hh
===================================================================
--- oln/morpho/stat.hh (revision 155)
+++ oln/morpho/stat.hh (working copy)
@@ -32,6 +32,7 @@
# include <ntg/bin.hh>
# include <oln/core/abstract/images.hh>
# include <oln/core/abstract/window.hh>
+# include <oln/funobj/accum.hh>
namespace oln {
@@ -49,16 +50,13 @@
mlc::eq<oln_type_of(I, grid), oln_wn_type_of(W, grid)>::ensure();
oln_wn_type_of(W, fwd_iter) q(win);
- oln_type_of(I, value) val;
-
- q.start_at_p(p);
- val = input[q];
+ funobj::min_accumulator<oln_type_of(I, value)> minval;
- for_all_remaining_q (q)
- if (input.hold(q) and input[q].value() < val)
- val = input[q].value();
+ for_all_q_of_p (q, p)
+ if (input.hold(q))
+ minval(input[q]);
- return val;
+ return minval;
}
@@ -89,16 +87,13 @@
mlc::eq<oln_type_of(I, grid), oln_wn_type_of(W, grid)>::ensure();
oln_wn_type_of(W, fwd_iter) q(win);
- oln_type_of(I, value) val;
+ funobj::max_accumulator<oln_type_of(I, value)> maxval;
+
+ for_all_q_of_p (q, p)
+ if (input.hold(q))
+ maxval(input[q]);
- q.start_at_p(p);
- val = input[q];
-
- for_all_remaining_q (q)
- if (input.hold(q) and input[q].value() > val)
- val = input[q].value();
-
- return val;
+ return maxval;
}
Index: oln/morpho/erosion.hh
===================================================================
--- oln/morpho/erosion.hh (revision 155)
+++ oln/morpho/erosion.hh (working copy)
@@ -29,6 +29,7 @@
# define OLENA_MORPHO_EROSION_HH
# include <mlc/cmp.hh>
+# include <mlc/to_string.hh>
# include <oln/core/abstract/images.hh>
# include <oln/core/abstract/image_operator.hh>
@@ -164,13 +165,13 @@
void impl_run()
{
- oln_type_of(super_type, output) temp(input.size()); // FIXME: trick
+ oln_type_of(super_type, output) temp;
- win_rectangle2d hline(1, win.width);
- win_rectangle2d vline(win.height, 1);
+ win_hline2d hline(win.width);
+ win_vline2d vline(win.height);
temp = morpho::erosion(input, hline);
- output = morpho::erosion(temp, vline);
+ output = morpho::erosion(temp, vline);
}
};
1
0