
2005-04-14 Thierry GERAUD <theo@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); } };
participants (1)
-
Thierry GERAUD