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