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;
}
};