2005-04-14 Thierry GERAUD <theo(a)tegucigalpa.lrde.epita.fr>
* oln/core/typedefs.hh (oln_super_of): New macro.
* oln/core/abstract/image_operator.hh (set_props): Declare
output_type.
* oln/core/1d/qiter1d.hh: Remove typedefs.
* oln/core/2d/qiter2d.hh: Likewise.
* oln/core/3d/qiter3d.hh: Likewise.
* oln/core/1d/window1d.hh: Use inheritance.
* oln/core/2d/window2d.hh: Likewise.
(win_rectangle2d): New class.
* oln/core/3d/window3d.hh: Likewise.
* oln/core/any/dpoint.hh (operator+): Move to...
* oln/core/any/point.hh: ...here.
* oln/core/gen/regular_fwd_qiter.hh: Add parameter W.
* oln/core/gen/regular_bkd_qiter.hh: Likewise.
* oln/core/gen/regular_qiter.hh: Update.
* oln/core/gen/regular_window.hh: Update.
* oln/core/gen/regular_neighborhood.hh: Update.
* oln/morpho/stat.hh (stat_): Remove.
* oln/morpho/erosion.hh: Rewrite.
Index: oln/core/typedefs.hh
===================================================================
--- oln/core/typedefs.hh (revision 153)
+++ oln/core/typedefs.hh (working copy)
@@ -38,8 +38,14 @@
# include <mlc/to_string.hh>
+# define oln_super_of_(Type) \
+oln::internal::get_super_type<Type>::ret
+# define oln_super_of(Type) \
+typename oln_super_of_(Type)
+
+
namespace oln
{
Index: oln/core/abstract/image.hh
===================================================================
--- oln/core/abstract/image.hh (revision 153)
+++ oln/core/abstract/image.hh (working copy)
@@ -39,6 +39,7 @@
+
namespace oln {
Index: oln/core/abstract/image_operator.hh
===================================================================
--- oln/core/abstract/image_operator.hh (revision 153)
+++ oln/core/abstract/image_operator.hh (working copy)
@@ -48,8 +48,18 @@
template <typename O, typename I1, typename I2, typename E>
struct set_super_type< abstract::image_binary_operator<O, I1, I2, E> > {
typedef abstract::image_operator<O, E> ret; };
+ // props
+ template <typename O, typename E>
+ struct set_props < category::image, abstract::image_operator<O, E> >
+ {
+ typedef O output_type;
+ };
+
+
+
+
namespace abstract {
Index: oln/core/1d/qiter1d.hh
===================================================================
--- oln/core/1d/qiter1d.hh (revision 153)
+++ oln/core/1d/qiter1d.hh (working copy)
@@ -31,18 +31,11 @@
# include <oln/core/1d/grid1d.hh>
# include <oln/core/1d/point1d.hh>
# include <oln/core/1d/dpoint1d.hh>
+
# include <oln/core/1d/window1d.hh>
# include <oln/core/gen/regular_fwd_qiter.hh>
# include <oln/core/gen/regular_bkd_qiter.hh>
-namespace oln {
-
- typedef regular_fwd_qiter<grid1d> fwd_qiter1d;
- typedef regular_bkd_qiter<grid1d> bkd_qiter1d;
-
-}
-
-
#endif // ! OLENA_CORE_1D_QITER1D_HH
Index: oln/core/1d/window1d.hh
===================================================================
--- oln/core/1d/window1d.hh (revision 153)
+++ oln/core/1d/window1d.hh (working copy)
@@ -36,8 +36,37 @@
namespace oln {
- typedef regular_window< grid1d > window1d;
+ // fwd decl
+ struct window1d;
+
+ // super type
+ template <>
+ struct set_super_type< window1d > { typedef abstract::regular_window< grid1d,
window1d > ret; };
+
+
+ struct window1d : public abstract::regular_window< grid1d, window1d >
+ {
+ typedef abstract::regular_window< grid1d, window1d > super_type;
+
+ window1d()
+ {}
+
+ window1d(unsigned n, const coord_t crd[]) :
+ super_type(n, crd)
+ {}
+
+ window1d& add(const dpoint1d& dp)
+ {
+ this->add_(dp);
+ return *this;
+ }
+
+ };
+
+
+
+
// classical 1d windows
/*!
Index: oln/core/2d/qiter2d.hh
===================================================================
--- oln/core/2d/qiter2d.hh (revision 153)
+++ oln/core/2d/qiter2d.hh (working copy)
@@ -31,18 +31,11 @@
# include <oln/core/2d/grid2d.hh>
# include <oln/core/2d/point2d.hh>
# include <oln/core/2d/dpoint2d.hh>
+
# include <oln/core/2d/window2d.hh>
# include <oln/core/gen/regular_fwd_qiter.hh>
# include <oln/core/gen/regular_bkd_qiter.hh>
-namespace oln {
-
- typedef regular_fwd_qiter<grid2d> fwd_qiter2d;
- typedef regular_bkd_qiter<grid2d> bkd_qiter2d;
-
-}
-
-
#endif // ! OLENA_CORE_2D_QITER2D_HH
Index: oln/core/2d/window2d.hh
===================================================================
--- oln/core/2d/window2d.hh (revision 153)
+++ oln/core/2d/window2d.hh (working copy)
@@ -37,8 +37,70 @@
namespace oln
{
- typedef regular_window< grid2d > window2d;
+ // fwd decl
+ struct window2d;
+ // super type
+ template <>
+ struct set_super_type< window2d > { typedef abstract::regular_window< grid2d,
window2d > ret; };
+
+
+ struct window2d : public oln_super_of_(window2d)
+ {
+ typedef oln_super_of_(window2d) super_type;
+
+ window2d()
+ {}
+
+ window2d(unsigned n, const coord_t crd[]) :
+ super_type(n, crd)
+ {}
+
+ window2d& add(const dpoint2d& dp)
+ {
+ this->add_(dp);
+ return *this;
+ }
+
+ };
+
+
+ // fwd decl
+ struct win_rectangle2d;
+
+ // super type
+ template <>
+ struct set_super_type< win_rectangle2d > { typedef abstract::regular_window<
grid2d, win_rectangle2d > ret; };
+
+
+ /// Class win_rectangle2d.
+ struct win_rectangle2d : public oln_super_of_(win_rectangle2d)
+ {
+ typedef oln_super_of_(win_rectangle2d) super_type;
+
+ win_rectangle2d(unsigned height, unsigned width) :
+ height(height),
+ width(width)
+ {
+ int
+ min_drow = (1 - int(height)) / 2,
+ max_drow = int(height) / 2,
+ min_dcol = (1 - int(width)) / 2,
+ max_dcol = int(width) / 2;
+ for (int drow = min_drow; drow <= max_drow; ++drow)
+ for (int dcol = min_dcol; dcol <= max_dcol; ++dcol)
+ {
+ dpoint2d dp(drow, dcol);
+ this->add_(dp);
+ }
+ }
+
+ const unsigned height;
+ const unsigned width;
+ };
+
+
+
// classical 2d windows
/*!
Index: oln/core/3d/qiter3d.hh
===================================================================
--- oln/core/3d/qiter3d.hh (revision 153)
+++ oln/core/3d/qiter3d.hh (working copy)
@@ -31,18 +31,11 @@
# include <oln/core/3d/grid3d.hh>
# include <oln/core/3d/point3d.hh>
# include <oln/core/3d/dpoint3d.hh>
+
# include <oln/core/3d/window3d.hh>
# include <oln/core/gen/regular_fwd_qiter.hh>
# include <oln/core/gen/regular_bkd_qiter.hh>
-namespace oln {
-
- typedef regular_fwd_qiter<grid3d> fwd_qiter3d;
- typedef regular_bkd_qiter<grid3d> bkd_qiter3d;
-
-}
-
-
#endif // ! OLENA_CORE_3D_QITER3D_HH
Index: oln/core/3d/window3d.hh
===================================================================
--- oln/core/3d/window3d.hh (revision 153)
+++ oln/core/3d/window3d.hh (working copy)
@@ -36,8 +36,37 @@
namespace oln {
- typedef regular_window< grid3d > window3d;
+ // fwd decl
+ struct window3d;
+
+ // super type
+ template <>
+ struct set_super_type< window3d > { typedef abstract::regular_window< grid3d,
window3d > ret; };
+
+
+ struct window3d : public abstract::regular_window< grid3d, window3d >
+ {
+ typedef abstract::regular_window< grid3d, window3d > super_type;
+
+ window3d()
+ {}
+
+ window3d(unsigned n, const coord_t crd[]) :
+ super_type(n, crd)
+ {}
+
+ window3d& add(const dpoint3d& dp)
+ {
+ this->add_(dp);
+ return *this;
+ }
+
+ };
+
+
+
+
// classical 3d windows
/*!
Index: oln/core/any/point.hh
===================================================================
--- oln/core/any/point.hh (revision 153)
+++ oln/core/any/point.hh (working copy)
@@ -127,8 +127,15 @@
# include <oln/core/any/dpoint.hh>
+
namespace oln {
+ template <typename P>
+ const any_point any_dpoint::operator+(const abstract::point<P>& rhs) const
+ {
+ return any_point();
+ }
+
const any_dpoint any_point::impl_minus(const any_point& rhs) const
{
precondition(false);
Index: oln/core/any/dpoint.hh
===================================================================
--- oln/core/any/dpoint.hh (revision 153)
+++ oln/core/any/dpoint.hh (working copy)
@@ -31,7 +31,6 @@
# include <iostream>
# include <mlc/contract.hh>
# include <oln/core/abstract/dpoint.hh>
-# include <oln/core/any/point.hh>
namespace oln {
@@ -124,14 +123,5 @@
# include <oln/core/any/point.hh>
-namespace oln {
- template <typename P>
- const any_point any_dpoint::operator+(const abstract::point<P>& rhs) const
- {
- return any_point();
- }
-
-}
-
#endif // ! OLENA_CORE_ANY_DPOINT_HH
Index: oln/core/gen/regular_fwd_qiter.hh
===================================================================
--- oln/core/gen/regular_fwd_qiter.hh (revision 153)
+++ oln/core/gen/regular_fwd_qiter.hh (working copy)
@@ -34,20 +34,27 @@
namespace oln {
// fwd decl
- template <typename G> struct regular_fwd_qiter;
+ template <typename G, typename W> struct regular_fwd_qiter;
// category
- template <typename G>
- struct set_super_type< regular_fwd_qiter<G> > { typedef
abstract::regular_qiter< G, regular_fwd_qiter<G> > ret; };
+ template <typename G, typename W>
+ struct set_super_type< regular_fwd_qiter<G,W> > { typedef
abstract::regular_qiter< G, regular_fwd_qiter<G,W> > ret; };
+ // props
+ template <typename G, typename W>
+ struct set_props < category::qiter, regular_fwd_qiter<G,W> >
+ {
+ typedef W window_type;
+ };
- template <typename G>
- struct regular_fwd_qiter : public abstract::regular_qiter< G,
regular_fwd_qiter<G> >
+
+ template <typename G, typename W>
+ struct regular_fwd_qiter : public abstract::regular_qiter< G,
regular_fwd_qiter<G,W> >
{
- typedef regular_fwd_qiter<G> self_type;
+ typedef regular_fwd_qiter<G,W> self_type;
typedef abstract::regular_qiter<G, self_type> super_type;
- regular_fwd_qiter(const regular_window<G>& win) :
+ regular_fwd_qiter(const abstract::regular_window<G,W>& win) :
super_type(win)
{
this->invalidate();
Index: oln/core/gen/regular_bkd_qiter.hh
===================================================================
--- oln/core/gen/regular_bkd_qiter.hh (revision 153)
+++ oln/core/gen/regular_bkd_qiter.hh (working copy)
@@ -34,21 +34,27 @@
namespace oln {
// bkd decl
- template <typename G>
- struct regular_bkd_qiter;
+ template <typename G, typename W> struct regular_bkd_qiter;
// category
- template <typename G>
- struct set_super_type< regular_bkd_qiter<G> > { typedef
abstract::regular_qiter< G, regular_bkd_qiter<G> > ret; };
+ template <typename G, typename W>
+ struct set_super_type< regular_bkd_qiter<G,W> > { typedef
abstract::regular_qiter< G, regular_bkd_qiter<G,W> > ret; };
+ // props
+ template <typename G, typename W>
+ struct set_props < category::qiter, regular_bkd_qiter<G,W> >
+ {
+ typedef W window_type;
+ };
- template <typename G>
- struct regular_bkd_qiter : public abstract::regular_qiter< G,
regular_bkd_qiter<G> >
+
+ template <typename G, typename W>
+ struct regular_bkd_qiter : public abstract::regular_qiter< G,
regular_bkd_qiter<G,W> >
{
- typedef regular_bkd_qiter<G> self_type;
+ typedef regular_bkd_qiter<G,W> self_type;
typedef abstract::regular_qiter<G, self_type> super_type;
- regular_bkd_qiter(const regular_window<G>& win) :
+ regular_bkd_qiter(const abstract::regular_window<G,W>& win) :
super_type(win)
{
this->invalidate();
Index: oln/core/gen/regular_qiter.hh
===================================================================
--- oln/core/gen/regular_qiter.hh (revision 153)
+++ oln/core/gen/regular_qiter.hh (working copy)
@@ -48,8 +48,7 @@
template <typename G, typename E>
struct set_props < category::qiter, abstract::regular_qiter<G,E> >
{
- typedef G grid_type;
- typedef regular_window<G> window_type;
+ typedef G grid_type;
};
@@ -68,8 +67,8 @@
typedef oln_grd_type_of(G, dimvalue) dimvalue_type;
static const unsigned dim = dimvalue_type::val;
- regular_qiter(const regular_window<G>& win) :
- super_type(win)
+ regular_qiter(const regular_window<G, 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 153)
+++ oln/core/gen/regular_window.hh (working copy)
@@ -43,124 +43,133 @@
namespace oln {
// fwd decls
- template <typename G> class regular_window;
- template <typename G> class regular_fwd_qiter;
+ template <typename G, typename W> class regular_fwd_qiter;
+ namespace abstract {
+ template <typename G, typename E> class regular_window;
+ }
// super_type
- template <typename G> struct set_super_type< regular_window<G> > {
typedef abstract::window< regular_window<G> > ret; };
+ template <typename G, typename E> struct set_super_type<
abstract::regular_window<G, E> > { typedef abstract::window<E> ret; };
// props
- template <typename G>
- struct set_props< category::window, regular_window<G> >
+ template <typename G, typename E>
+ struct set_props< category::window, abstract::regular_window<G, E> >
{
typedef G grid_type;
typedef oln_grd_type_of(G, dpoint) dpoint_type;
typedef oln_grd_type_of(G, size) size_type;
- typedef regular_fwd_qiter<G> fwd_iter_type;
-// typedef regular_fwd_dpiter<G> fwd_dpiter_type; // FIXME: later...
+ typedef regular_fwd_qiter<G,E> fwd_iter_type;
+ // typedef regular_fwd_dpiter<G> fwd_dpiter_type; // FIXME: later...
};
- template <typename G>
- class regular_window : public abstract::window< regular_window<G> >
+
+
+ namespace abstract
{
- public:
+ template <typename G, typename E>
+ class regular_window : public window<E>
+ {
+
+ public:
- typedef regular_window<G> self_type;
+ typedef regular_window<G, E> self_type;
- typedef oln_grd_type_of(G, coord) coord_type;
- typedef oln_grd_type_of(G, dpoint) dpoint_type;
- typedef oln_grd_type_of(G, dimvalue) dimvalue_type;
+ typedef oln_grd_type_of(G, coord) coord_type;
+ typedef oln_grd_type_of(G, dpoint) dpoint_type;
+ typedef oln_grd_type_of(G, dimvalue) dimvalue_type;
- static const unsigned dim = dimvalue_type::val;
+ static const unsigned dim = dimvalue_type::val;
- regular_window() :
- dp_(),
- delta_(0)
- {
- }
+ coord_type delta() const
+ {
+ return this->delta_;
+ }
- regular_window(unsigned n, const coord_type crd[]) :
- dp_(),
- delta_(0)
- {
- precondition(n != 0);
- // FIXME: size of crd wrt n
- for (unsigned i = 0; i < n; ++i)
- {
- dpoint_type dp;
- for (unsigned c = 0; c < dim; ++c)
- dp.nth(c) = crd[i * dim + c];
- this->add(dp);
- }
- }
+ unsigned card() const
+ {
+ return this->dp_.size();
+ }
- self_type& add(const dpoint_type& dp)
- {
- this->dpset_.insert(dp);
- this->dp_.clear();
- std::copy(this->dpset_.begin(), this->dpset_.end(),
- std::back_inserter(this->dp_));
- this->delta_update_(dp);
- return *this;
- }
+ const dpoint_type dp(unsigned i) const
+ {
+ precondition(i < this->card());
+ return this->dp_[i];
+ }
- coord_type delta() const
- {
- return this->delta_;
- }
+ const self_type operator-() const
+ {
+ self_type tmp;
+ for (unsigned i = 0; i < this->card(); ++i)
+ tmp.add_(- this->dp_[i]);
+ return tmp;
+ }
- unsigned card() const
- {
- return this->dp_.size();
- }
+ void sym()
+ {
+ *this = - *this;
+ }
- const dpoint_type dp(unsigned i) const
- {
- precondition(i < this->card());
- return this->dp_[i];
- }
+ const std::vector<dpoint_type>& get_dp() const
+ {
+ return this->dp_;
+ }
- const self_type operator-() const
- {
- self_type tmp;
- for (unsigned i = 0; i < this->card(); ++i)
- tmp.add(- this->dp_[i]);
- return tmp;
- }
+ protected:
- void sym()
- {
- *this = - *this;
- }
+ regular_window() :
+ dp_(),
+ delta_(0)
+ {
+ }
- const std::vector<dpoint_type>& get_dp() const
- {
- return this->dp_;
- }
+ regular_window(unsigned n, const coord_type crd[]) :
+ dp_(),
+ delta_(0)
+ {
+ precondition(n != 0);
+ // FIXME: size of crd wrt n
+ for (unsigned i = 0; i < n; ++i)
+ {
+ dpoint_type dp;
+ for (unsigned c = 0; c < dim; ++c)
+ dp.nth(c) = crd[i * dim + c];
+ this->add_(dp);
+ }
+ }
- private:
+ void add_(const dpoint_type& dp)
+ {
+ this->dpset_.insert(dp);
+ this->dp_.clear();
+ std::copy(this->dpset_.begin(), this->dpset_.end(),
+ std::back_inserter(this->dp_));
+ this->delta_update_(dp);
+ }
+
+ private:
- std::set<dpoint_type, fwd_less_dpoint> dpset_;
- std::vector<dpoint_type> dp_;
- coord_type delta_;
+ std::set<dpoint_type, fwd_less_dpoint> dpset_;
+ std::vector<dpoint_type> dp_;
+ coord_type delta_;
- void delta_update_(const dpoint_type& dp)
- {
- for (unsigned c = 0; c < dim; ++c)
- if (abs(dp.nth(c)) > this->delta_)
- this->delta_ = abs(dp.nth(c));
- }
+ void delta_update_(const dpoint_type& dp)
+ {
+ for (unsigned c = 0; c < dim; ++c)
+ if (abs(dp.nth(c)) > this->delta_)
+ this->delta_ = abs(dp.nth(c));
+ }
- };
+ };
+ } // end of namespace oln::abstract
} // end of namespace oln
-template<class G>
-std::ostream& operator<<(std::ostream& ostr, const
oln::regular_window<G>& win)
+template<typename G, typename E>
+std::ostream& operator<<(std::ostream& ostr, const
oln::abstract::regular_window<G, E>& win)
{
ostr << "[";
for (unsigned i = 0; i < win.card(); ++i)
Index: oln/core/gen/regular_neighborhood.hh
===================================================================
--- oln/core/gen/regular_neighborhood.hh (revision 153)
+++ oln/core/gen/regular_neighborhood.hh (working copy)
@@ -40,13 +40,27 @@
// super_type
template <typename G> struct set_super_type< regular_neighborhood<G>
> { typedef abstract::neighborhood< regular_neighborhood<G> > ret; };
+
+ // FIXME: temporary code to get a window type from a grid type
+ struct grid1d; struct window1d;
+ struct grid2d; struct window2d;
+ struct grid3d; struct window3d;
+ namespace internal {
+ template <typename grid_type> struct to_window;
+ template <> struct to_window <grid1d> { typedef window1d ret; };
+ template <> struct to_window <grid2d> { typedef window2d ret; };
+ template <> struct to_window <grid3d> { typedef window3d ret; };
+ }
+ // FIXME: end of temporary code
+
+
// props
template <typename G>
struct set_props< category::neighborhood, regular_neighborhood<G> >
{
typedef oln_grd_type_of(G, dpoint) dpoint_type;
typedef oln_grd_type_of(G, size) size_type;
- typedef regular_window<G> window_type;
+ typedef typename internal::to_window<G>::ret window_type;
};
@@ -58,6 +72,7 @@
public:
typedef regular_neighborhood<G> self_type;
+ typedef oln_nbh_type_of(self_type, window) window_type;
typedef oln_grd_type_of(G, coord) coord_type;
typedef oln_grd_type_of(G, dpoint) dpoint_type;
@@ -69,7 +84,7 @@
{
}
- regular_neighborhood(const regular_window<G>& win)
+ regular_neighborhood(const window_type& win)
{
for (unsigned i = 0; i < win.card(); ++i)
this->add(win.dp(i));
@@ -117,7 +132,7 @@
return this->win_.get_dp();
}
- const regular_neighborhood<G>& get_win() const
+ const window_type& get_win() const
{
return this->win_;
}
@@ -125,7 +140,7 @@
private:
/// Only attribute (to delegate to).
- regular_window<G> win_;
+ window_type win_;
};
Index: oln/morpho/stat.hh
===================================================================
--- oln/morpho/stat.hh (revision 153)
+++ oln/morpho/stat.hh (working copy)
@@ -30,7 +30,7 @@
# include <mlc/cmp.hh>
# include <ntg/bin.hh>
-# include <oln/core/abstract/image.hh>
+# include <oln/core/abstract/images.hh>
# include <oln/core/abstract/window.hh>
@@ -38,160 +38,87 @@
namespace morpho {
- namespace internal {
- /*!
- ** \brief Min and Max on a window.
- **
- ** We need to use this inner definition in order to specialize
- ** max and min on binary images.
- **
- ** \param I Image exact type.
- ** \param W Window type.
- ** \param V Associated value type.
- */
- template <class I, class W, class V = oln_type_of(I, value)>
- struct stat_
- {
- /*!
- ** \brief Maximum of a window.
- **
- ** Look for the maximum in the window win disposed
- ** on the image input, at the point p.
- **
- ** \arg input Input image.
- ** \arg p Point of the image to move the window on.
- ** \arg win The window to use.
- */
- static V
- max(const abstract::image<I>& input,
- const oln_type_of(I, point)& p,
- const abstract::window<W>& win)
- {
- mlc::eq<oln_type_of(I, grid), oln_wn_type_of(W, grid)>::ensure();
+ /// Local min on a function.
- oln_wn_type_of(W, fwd_iter) q(win);
- q.start_at_p(p);
- V val = input[q];
- for_all_remaining_q (q)
- if (input.hold(q))
- if (val < input[q].value())
- val = input[q].value();
- return val;
- }
+ template <typename I, typename W>
+ oln_type_of(I, value) min(const abstract::image<I>& input,
+ const oln_type_of(I, point)& p,
+ const abstract::window<W>& win)
+ {
+ mlc::eq<oln_type_of(I, grid), oln_wn_type_of(W, grid)>::ensure();
- /*!
- ** \brief Minimum of a window.
- **
- ** Look for the minimum in the window win disposed
- ** on the image input, at the point p.
- **
- ** \arg input Input image.
- ** \arg p Point of the image to move the window on.
- ** \arg win The window to use.
- */
- static V
- min(const abstract::image<I>& input,
- const oln_type_of(I, point)& p,
- const abstract::window<W>& win)
- {
- 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;
- oln_wn_type_of(W, fwd_iter) q(win);
- q.start_at(p);
- V val = input[q];
- for_all_remaining_q (q)
- if (input.hold(q))
- if (val > input[q].value())
- val = input[q].value();
- return val;
- }
+ 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;
+ }
- /* Binary specialization. */
- template <class I, class W>
- struct stat_<I, W, ntg::bin>
- {
- static ntg::bin
- max(const abstract::image<I>& input,
- const oln_type_of(I, point)& p,
- const abstract::window<W>& win)
- {
- mlc::eq<oln_type_of(I, grid), oln_wn_type_of(W, grid)>::ensure();
- oln_wn_type_of(W, fwd_iter) q(win);
- for_all_q_of_p (q, p)
- if (input.hold(q))
- if (input[q] == true)
- return true;
- return false;
- }
+ /// Local min on a set.
- static ntg::bin
- min(const abstract::image<I>& input,
- const oln_type_of(I, point)& p,
- const abstract::window<W>& win)
- {
- mlc::eq<oln_type_of(I, grid), oln_wn_type_of(W, grid)>::ensure();
- oln_wn_type_of(W, fwd_iter) q(win);
- for_all_q_of_p (q, p)
- if (input.hold(q))
- if (input[q] == false)
- return false;
- return true;
- }
+ template <typename I, typename W>
+ bool min(const abstract::binary_image<I>& input,
+ const oln_type_of(I, point)& p,
+ const abstract::window<W>& win)
+ {
+ mlc::eq<oln_type_of(I, grid), oln_wn_type_of(W, grid)>::ensure();
- };
+ oln_wn_type_of(W, fwd_iter) q(win);
+ for_all_q_of_p (q, p)
+ if (input.hold(q) and not input[q])
+ return false;
+ return true;
+ }
- } // internal
- /*!
- ** \brief Maximum of a window.
- **
- ** Look for the maximum in the window win disposed
- ** on the image input, at the point p.
- **
- ** \param I Image exact type.
- ** \param W Window type.
- **
- ** \arg input Input image.
- ** \arg p Point of the image to move the window on.
- ** \arg win The window to use.
- */
- template<class I, class W>
- oln_type_of(I, value)
- max(const abstract::image<I>& input,
- const oln_type_of(I, point)& p,
- const abstract::window<W>& win)
+ /// Local max on a function.
+
+ template <typename I, typename W>
+ oln_type_of(I, value) max(const abstract::image<I>& input,
+ const oln_type_of(I, point)& p,
+ const abstract::window<W>& win)
{
- // FIXME: test dim I == dim W
- return internal::stat_<I, W>::max(input.exact(), p, win.exact());
+ 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];
+
+ for_all_remaining_q (q)
+ if (input.hold(q) and input[q].value() > val)
+ val = input[q].value();
+
+ return val;
}
- /*! ** \brief Minimum of a window.
- **
- ** Look for the minimum in the window win disposed
- ** on the image input, at the point p.
- **
- ** \param I Image exact type.
- ** \param W Window type.
- **
- ** \arg input Input image.
- ** \arg p Point of the image to move the window on.
- ** \arg win The window to use.
- */
- template<class I, class W>
- oln_type_of(I, value)
- min(const abstract::image<I>& input,
- const oln_type_of(I, point)& p,
- // const mlc_exact_type(I)::iter_type& p,
- const abstract::window<W>& win)
+
+ /// Local max on a set.
+
+ template <typename I, typename W>
+ bool max(const abstract::binary_image<I>& input,
+ const oln_type_of(I, point)& p,
+ const abstract::window<W>& win)
{
- // FIXME: test dim I == dim W
- return internal::stat_<I, W>::min(input.exact(), p, win.exact());
+ mlc::eq<oln_type_of(I, grid), oln_wn_type_of(W, grid)>::ensure();
+
+ oln_wn_type_of(W, fwd_iter) q(win);
+ for_all_q_of_p (q, p)
+ if (input.hold(q) and input[q])
+ return true;
+ return false;
}
+
} // end of namespace morpho
} // end of namespace oln
Index: oln/morpho/erosion.hh
===================================================================
--- oln/morpho/erosion.hh (revision 153)
+++ oln/morpho/erosion.hh (working copy)
@@ -30,23 +30,50 @@
# include <mlc/cmp.hh>
+# include <oln/core/abstract/images.hh>
# include <oln/core/abstract/image_operator.hh>
# include <oln/morpho/stat.hh>
+# include <oln/core/2d/window2d.hh>
+
namespace oln {
+
+ // fwd decl
+
namespace morpho {
+ template <typename I> struct erosion_ret;
+ }
+ // super_type
+ template <typename I>
+ struct set_super_type< morpho::erosion_ret<I> >
+ {
+ typedef oln_type_of(I, concrete) output_type;
+
+ typedef morpho::erosion_ret<I> self_type;
+ typedef abstract::image_unary_operator<output_type, I, self_type > ret;
+ };
+
+
+
+
+ namespace morpho {
+
+
+
+ // Erosion as a 'classical' procedure returning an image (do not
+ // use it; prefer morpho::erosion).
+
namespace proc {
- /// Erosion as a procedure (do not use it; prefer morpho::erosion).
-
template<typename I, typename W>
oln_type_of(I, concrete) erosion(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());
oln_type_of(I, fwd_piter) p(input.size());
for_all_p (p)
@@ -58,136 +85,127 @@
- /*!
- ** \brief Perform a morphological erosion.
- **
- ** Compute the morphological erosion of input using win
- ** as structuring element.
- **
- ** On grey-scale images, each point is replaced by the minimum
- ** value of its neighbors, as indicated by win. On binary
- ** images, a logical and is performed between neighbors. The
- ** morpho::fast version of this function use a different
- ** algorithm: an histogram of the value of the neighborhood
- ** indicated by win is updated while iterating over all point of
- ** the image. Doing so is more efficient when the structuring
- ** element is large.
- **
- ** \param I Exact type of the input image.
- ** \param W Exact type of the structuring element.
- **
- **
- ** \arg input Input image.
- ** \arg win Structuring element to use.
- **
- ** \code
- ** #include <oln/basics2d.hh>
- ** #include <oln/morpho/erosion.hh>
- ** #include <oln/level/compare.hh>
- ** #include <ntg/all.hh>
- ** int main()
- ** {
- ** typedef oln::image2d<ntg::bin> im_type;
- **
- ** im_type im1(oln::load(IMG_IN "object.pbm"));
- ** save(oln::morpho::erosion(im1, oln::win_c8p()),
- ** IMG_OUT "oln_morpho_erosion.pbm");
- ** }
- ** \endcode
- **
- ** \image html object_pbm.png
- ** \image latex object_pbm.png
- ** =>
- ** \image html oln_morpho_erosion.png
- ** \image latex oln_morpho_erosion.png
- **
- ** \see oln::morpho::fast::erosion()
- */
+ /// Erosion return type.
- // fwd decl
- template <typename I, typename W> struct erosion_ret;
-
- }
-
- // super_type
- template <typename I, typename W>
- struct set_super_type< morpho::erosion_ret<I,W> >
- {
- typedef abstract::image_unary_operator<oln_type_of(I, concrete), I,
morpho::erosion_ret<I,W> > ret;
- };
-
-
-
-
- namespace morpho {
-
- /// Erosion return.
-
- template <typename I, typename W>
- struct erosion_ret : public abstract::image_unary_operator<oln_type_of(I,
concrete), I, erosion_ret<I,W> >
+ template <typename I>
+ struct erosion_ret : public oln_super_of_(erosion_ret<I>)
{
- typedef abstract::image_unary_operator<oln_type_of(I, concrete), I,
erosion_ret<I,W> > super_type;
- typedef typename super_type::output_type output_type;
+ typedef oln_super_of(erosion_ret<I>) super_type;
- const W win;
-
- erosion_ret(const abstract::image<I>& input,
- const abstract::window<W>& win) :
- super_type(input),
- win(win.exact())
+ erosion_ret(const abstract::image<I>& input) :
+ super_type(input)
{
}
};
+ // Various implementation.
+
namespace impl {
- /// Erosion generic implementation.
+ /// Generic implementation of erosion (type).
+
template <typename I, typename W>
- struct generic_erosion : public erosion_ret<I,W>
+ struct generic_erosion : public erosion_ret<I>
{
- typedef erosion_ret<I,W> super_type;
- typedef typename super_type::output_type output_type;
+ typedef erosion_ret<I> super_type;
+ const W& win;
+
generic_erosion(const abstract::image<I>& input,
const abstract::window<W>& win) :
- super_type(input, win)
+ super_type(input),
+ win(win.exact())
{
}
void impl_run()
{
- mlc::eq<oln_type_of(I, size), oln_wn_type_of(W, size)>::ensure();
+ oln_type_of(super_type, output) tmp(input.size()); // FIXME: trick
+ output = tmp;
- output_type tmp(this->input.size()); // FIXME: trick
- this->output = tmp;
-
- oln_type_of(I, fwd_piter) p(this->input.size());
+ oln_type_of(I, fwd_piter) p(input.size());
for_all_p (p)
- this->output[p] = morpho::min(this->input, p, this->win);
+ output[p] = morpho::min(input, p, win);
}
};
+ // Generic implementation of erosion (routine).
+
+ template<typename I, typename W>
+ erosion_ret<I> erosion(const abstract::image<I>& input,
+ const abstract::window<W>& win)
+ {
+ impl::generic_erosion<I,W> tmp(input, win);
+ tmp.run();
+ return tmp;
+ }
+
+
+
+
+ /// Rectangle2d implementation of erosion (type).
+
+ template <typename I>
+ struct rectangle2d_erosion : public erosion_ret<I>
+ {
+ typedef erosion_ret<I> super_type;
+
+ const win_rectangle2d& win;
+
+ rectangle2d_erosion(const abstract::image<I>& input,
+ const win_rectangle2d& win) :
+ super_type(input),
+ win(win)
+ {}
+
+ void impl_run()
+ {
+ oln_type_of(super_type, output) temp(input.size()); // FIXME: trick
+
+ win_rectangle2d hline(1, win.width);
+ win_rectangle2d vline(win.height, 1);
+
+ temp = morpho::erosion(input, hline);
+ output = morpho::erosion(temp, vline);
+ }
+ };
+
+ // Rectangle2d implementation of erosion (routine).
+
+ template<typename I>
+ erosion_ret<I> erosion(const abstract::image<I>& input,
+ const win_rectangle2d& win)
+ {
+ impl::rectangle2d_erosion<I> tmp(input, win);
+ tmp.run();
+ return tmp;
+ }
+
+
+
+
} // end of namespace oln::morpho::impl
- /// Erosion generic routine.
+ /// Generic erosion (facade).
+
template<typename I, typename W>
- erosion_ret<I,W> erosion(const abstract::image<I>& input,
- const abstract::window<W>& win)
+ erosion_ret<I> erosion(const abstract::image<I>& input,
+ const abstract::window<W>& win)
{
- impl::generic_erosion<I,W> tmp(input, win);
- tmp.run();
- return tmp;
+ mlc::eq<oln_type_of(I, grid), oln_wn_type_of(W, grid)>::ensure();
+ return impl::erosion(input.exact(), win.exact());
}
} // end of namespace oln::morpho
+
} // end of namespace oln