Index: olena/ChangeLog
from Niels Van Vliet <niels(a)lrde.epita.fr>
* oln/utils/histogram.hh: Inherit from mlc_hierarchy::any.
* value_to_point.hh: Inherit from conversion_from_type_to_type.
* tests/utils/tests/histogram: Add namespace.
* tests/morpho/tests/area: Add file.
Index: olena/oln/utils/histogram.hh
--- olena/oln/utils/histogram.hh Mon, 02 Feb 2004 15:36:12 +0100
van-vl_n (oln/10_histogram. 1.6.1.14.1.2 644)
+++ olena/oln/utils/histogram.hh Fri, 06 Feb 2004 15:03:47 +0100
van-vl_n (oln/10_histogram. 1.6.1.14.1.2 644)
@@ -28,60 +28,134 @@
#ifndef OLENA_UTILS_HISTOGRAM_HH
# define OLENA_UTILS_HISTOGRAM_HH
-# include <ntg/basics.hh>
-# include <oln/basics.hh>
+
+# include <oln/core/image1d.hh>
+# include <oln/core/image3d.hh>
+
# include <oln/convert/value_to_point.hh>
+
+# include <oln/core/abstract/image.hh>
+
# include <vector>
namespace oln {
namespace utils {
- template< typename T, typename CPT, class V2P>
- class histogram;
+ namespace internal {
+ //! Return the size of the space needed to explore the type T
+ template <typename T>
+ struct img_max_size
+ {
+ private:
+ typedef typename ntg_is_a(T, ntg::non_vectorial)::ensure_type ensure_type;
+ public:
+ typedef image1d_size size_type;
+ typedef T comp_type;
+
+ image1d_size
+ operator()()
+ {
+ size_type s(ntg_max_val(comp_type) - ntg_min_val(comp_type) + 1,
+ 1);
+ return s;
+ }
+ };
- template< typename T, typename CPT, class V2P >
- T
- min(const histogram<T, CPT, V2P>& hist);
- template< typename T, typename CPT, class V2P >
- T
- max(const histogram<T, CPT, V2P>& hist);
+ template <unsigned Qbits, template <unsigned> class S>
+ struct img_max_size<ntg::color<3, Qbits, S> >
+ {
+ public:
+ typedef image3d_size size_type;
+ typedef typename ntg::color<3, Qbits, S>::comp_type comp_type;
+
+ image3d_size
+ operator()()
+ {
+ size_type s(ntg_max_val(comp_type) - ntg_min_val(comp_type) + 1,
+ ntg_max_val(comp_type) - ntg_min_val(comp_type) + 1,
+ ntg_max_val(comp_type) - ntg_min_val(comp_type) + 1,
+ 1);
+ return s;
+ }
+ };
+ }
+
+ namespace abstract
+ {
+ template<class T,
+ typename CPT,
+ class Exact = mlc::final>
+ class histogram: public mlc_hierarchy::any<Exact>
+ {
+ public:
+ typedef histogram<T, CPT, Exact> self_type;
+ typedef Exact exact_type;
+ typedef CPT cpt_type;
+
+ void
+ clear()
+ {
+ this->exact().clear_impl();
+ }
+
+ const CPT&
+ operator[](const T &v)const
+ {
+ return this->exact().at(v);
+ }
+
+ CPT&
+ operator[](const T &v)
+ {
+ return this->exact().at(v);
+ }
+
+ template <class I>
+ void
+ init(const oln::abstract::image<I> &img)
+ {
+ return this->exact().init_impl(img.exact());
+ }
+ };
+ }
template<typename T,
typename CPT = unsigned,
- class V2P = value_to_point<T> >
- class histogram
+ class V2P = oln::convert::value_to_point<T>,
+ class Exact = mlc::final>
+ class histogram: public abstract::histogram
+ <T, CPT, typename mlc::exact_vt<histogram<T, CPT, V2P, Exact>,
Exact>::ret>
{
public:
+ typedef histogram<T, CPT, V2P, Exact> self_type;
+ typedef Exact exact_type;
typedef T input_type;
typedef V2P value_to_point_type;
typedef CPT cpt_type;
- typedef histogram<T, CPT, V2P> self_type;
typedef typename value_to_point_type::result_type point_type;
enum {dim = value_to_point_type::result_type::dim};
+ typedef abstract::histogram<T, CPT, self_type> upper_type;
typedef typename dim_traits<dim, CPT>::img_type img_type;
- friend T min<T, CPT, V2P>(const histogram<T, CPT, V2P>& hist);
- friend T max<T, CPT, V2P>(const histogram<T, CPT, V2P>& hist);
-
histogram(const value_to_point_type & c2p = value_to_point_type()):
- v2p_(c2p), img_(v2p_.size())
+ v2p_(c2p), img_(internal::img_max_size<input_type>()())
{
clear();
}
template <class I>
- histogram(const abstract::image<I> & input,
+ histogram(const oln::abstract::image<I> & input,
const value_to_point_type & v2p = value_to_point_type()):
- v2p_(v2p), img_(v2p_.size())
+ v2p_(v2p), img_(internal::img_max_size<input_type>()())
{
clear();
init(input);
}
void
- clear()
+ clear_impl()
{
typename img_type::iter_type it(img_ );
for_all(it)
@@ -89,20 +163,20 @@
}
const CPT&
- operator[](const T &v)const
+ at(const T &v)const
{
return img_[v2p_(v)];
}
CPT&
- operator[](const T &v)
+ at(const T &v)
{
return img_[v2p_(v)];
}
template <class I>
void
- init(const abstract::image<I> &img)
+ init_impl(const oln::abstract::image<I> &img)
{
oln_iter_type(I) it_img(img);
@@ -122,9 +196,9 @@
};
//Note: If there is no min an assertion will fail at the end of
the loop.
- template< typename T, typename CPT, class V2P >
+ template< typename T, typename CPT, class Exact>
inline T
- min(const histogram<T, CPT, V2P>& hist)
+ min(const abstract::histogram<T, CPT, Exact>& hist)
{
typedef typename ntg_is_a(T, ntg::non_vectorial)::ensure_type
ensure_type;
@@ -134,11 +208,10 @@
break;
return i;
}
-
//Note: If there is no max an assertion will fail at the end of
the loop.
- template< typename T, typename CPT, class V2P >
+ template< typename T, typename CPT, class Exact>
inline T
- max(const histogram<T, CPT, V2P>& hist)
+ max(const abstract::histogram<T, CPT, Exact>& hist)
{
typedef typename ntg_is_a(T, ntg::non_vectorial)::ensure_type
ensure_type;
@@ -169,8 +242,13 @@
value are accessed, and delay the _real_ min and max compuation
until min() or max() is called. */
- template< typename T, typename CPT = unsigned, class V2P =
value_to_point<T> >
- class histogram_minmax : public histogram<T, CPT, V2P>
+ template< typename T,
+ typename CPT = unsigned,
+ class V2P = convert::value_to_point<T>,
+ class Exact = mlc::final>
+ class histogram_minmax : public histogram
+ <T, CPT, V2P,
+ typename mlc::exact_vt<histogram_minmax<T, CPT, V2P, Exact>,
Exact>::ret>
{
private:
typedef typename ntg_is_a(T, ntg::non_vectorial)::ensure_type
ensure_type;
@@ -183,31 +261,32 @@
if (idx < min_)
min_ = idx;
}
-
public:
-
+ typedef histogram_minmax<T, CPT, V2P, Exact> self_type;
+ typedef Exact exact_type;
+ typedef histogram<T, CPT, V2P, histogram_minmax<T, CPT, V2P,
Exact>
upper_type;
typedef V2P value_to_point_type;
histogram_minmax(const value_to_point_type & v2p =
value_to_point_type()) :
- histogram<T, CPT, V2P>(v2p),
+ upper_type(v2p),
min_(ntg_min_val(T)), max_(ntg_max_val(T)) {}
template <class I>
- histogram_minmax(const abstract::image<I> & input,
+ histogram_minmax(const oln::abstract::image<I> & input,
const value_to_point_type & v2p = value_to_point_type()) :
- histogram<T, CPT, V2P>(input, v2p),
+ upper_type(input, v2p),
min_(ntg_min_val(T)), max_(ntg_max_val(T)) {}
const CPT&
- operator[](const T& i) const
+ at(const T& i) const
{
adjust(i);
return img_[v2p_(i)];
}
CPT&
- operator[](const T& i)
+ at(const T& i)
{
adjust(i);
return img_[v2p_(i)];
@@ -235,8 +314,13 @@
T min_, max_; // indices of min and max elements
};
- template< typename T, typename CPT = unsigned, class V2P =
value_to_point<T> >
- class histogram_min : public histogram<T, CPT, V2P>
+ template< typename T,
+ typename CPT = unsigned,
+ class V2P = convert::value_to_point<T>,
+ class Exact = mlc::final>
+ class histogram_min : public histogram<T, CPT, V2P,
+ typename mlc::exact_vt<histogram_min<T, CPT, V2P, Exact>,
+ Exact>::ret>
{
private:
typedef typename ntg_is_a(T, ntg::non_vectorial)::ensure_type
ensure_type;
@@ -248,26 +332,29 @@
min_ = idx;
}
public:
+ typedef histogram_min<T, CPT, V2P, Exact> self_type;
+ typedef Exact exact_type;
typedef V2P value_to_point_type;
+ typedef histogram<T, CPT, V2P, histogram_min<T, CPT, V2P, Exact>
upper_type;
+
histogram_min(const value_to_point_type & v2p =
value_to_point_type()) :
- histogram<T, CPT, V2P>(v2p), min_(ntg_min_val(T)) {}
+ upper_type(v2p), min_(ntg_min_val(T)) {}
template <class I>
- histogram_min(const abstract::image<I> & input,
+ histogram_min(const oln::abstract::image<I> & input,
const value_to_point_type & v2p = value_to_point_type()) :
- histogram<T, CPT, V2P>(input, v2p), min_(ntg_min_val(T)) {}
+ upper_type(input, v2p), min_(ntg_min_val(T)) {}
const CPT&
- operator[](const T& i) const
+ at(const T& i) const
{
- adjust(i);
return img_[v2p_(i)];
}
CPT&
- operator[](const T& i)
+ at(const T& i)
{
adjust(i);
return img_[v2p_(i)];
@@ -292,8 +379,13 @@
T min_; // index of min element
};
- template< typename T, typename CPT = unsigned, class V2P =
value_to_point<T> >
- class histogram_max : public histogram<T, CPT, V2P>
+ template< typename T,
+ typename CPT = unsigned,
+ class V2P = convert::value_to_point<T> ,
+ class Exact = mlc::final>
+ class histogram_max : public histogram<T, CPT, V2P,
+ typename mlc::exact_vt<histogram_max<T, CPT, V2P, Exact>,
+ Exact>::ret>
{
protected:
void
@@ -304,25 +396,27 @@
}
public:
+ typedef histogram_max<T, CPT, V2P, Exact> self_type;
+ typedef Exact exact_type;
typedef V2P value_to_point_type;
+ typedef histogram<T, CPT, V2P, histogram_max<T, CPT, V2P, Exact>
upper_type;
histogram_max(const value_to_point_type & v2p =
value_to_point_type()) :
- histogram<T, CPT, V2P>(v2p),max_(ntg_max_val(T)) {}
+ upper_type(v2p),max_(ntg_max_val(T)) {}
template <class I>
- histogram_max(const abstract::image<I> & input,
+ histogram_max(const oln::abstract::image<I> & input,
const value_to_point_type & v2p = value_to_point_type()) :
- histogram<T, CPT, V2P>(input, v2p),max_(ntg_max_val(T)) {}
+ upper_type(input, v2p),max_(ntg_max_val(T)) {}
const CPT&
- operator[](const T& i) const
+ at(const T& i) const
{
- adjust(i);
return img_[v2p_(i)];
}
CPT&
- operator[](const T& i)
+ at(const T& i)
{
adjust(i);
return img_[v2p_(i)];
@@ -347,34 +441,34 @@
T max_; // index of max element
};
- template< typename T, typename CPT, class V2P >
+ template< typename T, typename CPT, class V2P, class Exact >
inline T
- min(histogram_minmax<T, CPT, V2P>& hist)
+ min(histogram_minmax<T, CPT, V2P, Exact>& hist)
{
return hist.min();
}
- template< typename T, typename CPT, class V2P >
+ template< typename T, typename CPT, class V2P, class Exact >
inline T
- min(histogram_min<T, CPT, V2P>& hist)
+ min(histogram_min<T, CPT, V2P, Exact>& hist)
{
return hist.min();
}
- template< typename T, typename CPT, class V2P >
+ template< typename T, typename CPT, class V2P, class Exact >
inline T
- max(histogram_minmax<T, CPT, V2P>& hist)
+ max(histogram_minmax<T, CPT, V2P, Exact>& hist)
{
return hist.max();
}
- template< typename T, typename CPT, class V2P >
+ template< typename T, typename CPT, class V2P, class Exact >
inline T
- max(histogram_max<T, CPT, V2P>& hist)
+ max(histogram_max<T, CPT, V2P, Exact>& hist)
{
return hist.max();
}
template<class I>
void
- distrib_sort(const abstract::image<I>& im,
+ distrib_sort(const oln::abstract::image<I>& im,
std::vector<oln_point_type(I)> &v)
{
typedef oln_value_type(I) val;
@@ -406,7 +500,7 @@
template<class I>
void
- distrib_sort_inv(const abstract::image<I>& im,
+ distrib_sort_inv(const oln::abstract::image<I>& im,
std::vector<oln_point_type(I)> &v)
{
typedef oln_value_type(I) val;
Index: olena/tests/utils/tests/histogram
--- olena/tests/utils/tests/histogram Mon, 02 Feb 2004 15:36:12 +0100
van-vl_n (oln/u/27_histogram. 1.2.1.2 604)
+++ olena/tests/utils/tests/histogram Wed, 04 Feb 2004 18:24:49 +0100
van-vl_n (oln/u/27_histogram. 1.2.1.2 604)
@@ -92,9 +92,9 @@
histogram<int_s<4> > his4(is4);
res = res &&
- min(his4) == -4
+ utils::min(his4) == -4
&&
- max(his4) == 3;
+ utils::max(his4) == 3;
histogram_min<int_s<4> > his4_min(is4);
histogram_max<int_s<4> > his4_max(is4);
@@ -106,14 +106,14 @@
his4_minmax[2] = his4_min[2] = his4_max[2] = his4[2] = 42;
res = res &&
- min(his4) == -5 &&
- max(his4) == 2 &&
- min(his4) == min(his4_min) &&
- min(his4) == min(his4_max) &&
- min(his4) == min(his4_minmax) &&
- max(his4) == max(his4_min) &&
- max(his4) == max(his4_max) &&
- max(his4) == max(his4_minmax);
+ utils::min(his4) == -5 &&
+ utils::max(his4) == 2 &&
+ utils::min(his4) == utils::min(his4_min) &&
+ utils::min(his4) == utils::min(his4_max) &&
+ utils::min(his4) == utils::min(his4_minmax) &&
+ utils::max(his4) == utils::max(his4_min) &&
+ utils::max(his4) == utils::max(his4_max) &&
+ utils::max(his4) == utils::max(his4_minmax);
return res;
};
Index: olena/oln/convert/value_to_point.hh
--- olena/oln/convert/value_to_point.hh Mon, 02 Feb 2004 10:57:28 +0100
van-vl_n (oln/j/43_value_to_p 1.1 644)
+++ olena/oln/convert/value_to_point.hh Fri, 06 Feb 2004 15:14:05 +0100
van-vl_n (oln/j/43_value_to_p 1.1 644)
@@ -27,66 +27,62 @@
#ifndef OLENA_VALUE_TO_POINT
# define OLENA_VALUE_TO_POINT
-# include <oln/core/image1d.hh>
-# include <oln/core/image2d.hh>
-# include <oln/core/image3d.hh>
+# include <oln/core/point1d.hh>
+# include <oln/core/point3d.hh>
# include <ntg/int.hh>
# include <ntg/color/color.hh>
+# include <oln/convert/conversion.hh>
namespace oln {
- template <typename T>
- struct value_to_point
- {
+ namespace convert {
+
+ template <typename Argument_type,
+ class Exact = mlc::final>
+ struct value_to_point:
+ public abstract::conversion_from_type_to_type
+ <Argument_type,
+ point1d,
+ typename mlc::exact_vt<value_to_point<Argument_type,
+ Exact>,
+ Exact>::ret>
+ {
+ private:
+ typedef typename ntg_is_a(Argument_type,
ntg::non_vectorial)::ensure_type ensure_type;
+ public:
typedef point1d result_type;
- typedef T input_type;
- typedef image1d_size size_type;
+ typedef Argument_type argument_type;
+ template <class input_type>
result_type
- operator()(const input_type &input) const
+ doit(const input_type &input) const
{
result_type r(input - ntg_min_val(input_type));
return r;
}
-
- size_type
- size() const
- {
- return size_type(ntg_max_val(input_type) -
ntg_min_val(input_type) + 1,
- 1);
- }
- protected:
- typedef typename ntg_is_a(input_type,
ntg::non_vectorial)::ensure_type ensure_type;
};
- //FIXME: the number of components is not a parameter (due to size_type)
- template <unsigned Qbits,template <unsigned> class S>
- struct value_to_point<typename ntg::color<3, Qbits, S> >
+ template <unsigned Qbits, template <unsigned> class S, class Exact>
+ struct value_to_point<ntg::color<3, Qbits, S>, Exact>:
+ public abstract::conversion_from_type_to_type
+ <typename ntg::color<3, Qbits, S>,
+ point3d,
+ typename mlc::exact_vt<value_to_point<typename ntg::color<3, Qbits, S>,
+ Exact>,
+ Exact>::ret>
{
- enum {nbcomps = 3, qbits = Qbits};
-
- typedef ntg::color<nbcomps, qbits, S> input_type;
- typedef typename dim_traits<nbcomps, unsigned>::img_type::size_type
- size_type;
- typedef typename input_type::comp_type comp_type;
+ public:
typedef point3d result_type;
+ typedef typename ntg::color<3, Qbits, S> argument_type;
result_type
- operator()(const input_type &input) const
+ operator()(const argument_type &input) const
{
result_type r;
- for (unsigned i = 0; i < nbcomps; ++i)
+ for (unsigned i = 0; i < 3; ++i)
r.nth(i) = input[i];
return r;
}
-
- size_type
- size() const
- {
- return size_type(ntg_max_val(comp_type) - ntg_min_val(comp_type) + 1,
- ntg_max_val(comp_type) - ntg_min_val(comp_type) + 1,
- ntg_max_val(comp_type) - ntg_min_val(comp_type) + 1,
- 1);
- }
};
}
+}
#endif
Index: olena/tests/morpho/tests/area
--- olena/tests/morpho/tests/area Fri, 06 Feb 2004 15:24:17 +0100
van-vl_n ()
+++ olena/tests/morpho/tests/area Fri, 06 Feb 2004 10:30:34 +0100
van-vl_n (oln/j/44_area 644)
@@ -0,0 +1,197 @@
+// -*- c++ -*-
+
+#include <oln/basics2d.hh>
+#include <oln/basics1d.hh>
+#include <oln/morpho/attribute_closing_opening.hh>
+#include <ntg/all.hh>
+
+#include "check.hh"
+#include "data.hh"
+
+using namespace oln;
+using namespace ntg;
+
+#define OK_OR_FAIL \
+ std::cout << "OK" << std::endl; \
+ else \
+ { \
+ std::cout << "FAIL" << std::endl; \
+ fail = true; \
+ }
+
+bool
+check_opening1d()
+{
+ bool fail(false);
+
+ image1d<int_u8> im(11);
+ image1d<int_u8>::iter_type it(im);
+ for_all(it)
+ im[it] = ntg_min_val(int_u8);
+ im(0) = 0;
+ im(1) = 1 ;
+ im(2) = 1 ;
+ im(3) = 0;
+ im(4) = 1 ;
+ im(5) = 2 ;
+ im(6) = 3 ;
+ im(7) = 3 ;
+ im(8) = 5 ;
+ im(9) = 1 ;
+ im(10) = 0;
+
+ image1d<int_u8> im2 =
+ morpho::tarjan::area_opening(im, neighb_c2(), 2);
+
+ fail = fail ||
+ im2(0) != 0 ||
+ im2(1) != 1 ||
+ im2(2) != 1 ||
+ im2(3) != 0 ||
+ im2(4) != 1 ||
+ im2(5) != 2 ||
+ im2(6) != 3 ||
+ im2(7) != 3 ||
+ im2(8) != 3 ||
+ im2(9) != 1 ||
+ im2(10)!= 0;
+
+ image1d<int_u8> im3 =
+ morpho::tarjan::area_opening(im, neighb_c2(), 3);
+ fail = fail ||
+ im3(0) != 0 ||
+ im3(1) != 0 ||
+ im3(2) != 0 ||
+ im3(3) != 0 ||
+ im3(4) != 1 ||
+ im3(5) != 2 ||
+ im3(6) != 3 ||
+ im3(7) != 3 ||
+ im3(8) != 3 ||
+ im3(9) != 1 ||
+ im3(10)!= 0;
+
+ image1d<int_u8> im4 =
+ morpho::tarjan::area_opening(im, neighb_c2(), 4);
+ fail = fail ||
+ im4(0) != 0 ||
+ im4(1) != 0 ||
+ im4(2) != 0 ||
+ im4(3) != 0 ||
+ im4(4) != 1 ||
+ im4(5) != 2 ||
+ im4(6) != 2 ||
+ im4(7) != 2 ||
+ im4(8) != 2 ||
+ im4(9) != 1 ||
+ im4(10)!= 0;
+ return fail;
+}
+
+
+bool
+check_opening1d_s()
+{
+ bool fail(false);
+
+ image1d<int_s<3> > im(11);
+ image1d<int_s<3> >::iter_type it(im);
+ for_all(it)
+ im[it] = ntg_min_val(int_s<3> );
+ im(0) = -4;
+ im(1) = -2 ;
+ im(2) = -2 ;
+ im(3) = -4;
+ im(4) = -2 ;
+ im(5) = 0 ;
+ im(6) = 2 ;
+ im(7) = 2 ;
+ im(8) = 3 ;
+ im(9) = -2 ;
+ im(10) = -4;
+
+ image1d<int_s<3> > im2 =
+ morpho::tarjan::area_opening(im, neighb_c2(), 2);
+
+ fail = fail ||
+ im2(0) != -4 ||
+ im2(1) != -2 ||
+ im2(2) != -2 ||
+ im2(3) != -4 ||
+ im2(4) != -2 ||
+ im2(5) != 0 ||
+ im2(6) != 2 ||
+ im2(7) != 2 ||
+ im2(8) != 2 ||
+ im2(9) != -2 ||
+ im2(10)!= -4;
+
+ image1d<int_s<3> > im3 =
+ morpho::tarjan::area_opening(im, neighb_c2(), 3);
+ fail = fail ||
+ im3(0) != -4 ||
+ im3(1) != -4 ||
+ im3(2) != -4 ||
+ im3(3) != -4 ||
+ im3(4) != -2 ||
+ im3(5) != 0 ||
+ im3(6) != 2 ||
+ im3(7) != 2 ||
+ im3(8) != 2 ||
+ im3(9) != -2 ||
+ im3(10)!= -4;
+
+ image1d<int_s<3> > im4 =
+ morpho::tarjan::area_opening(im, neighb_c2(), 4);
+ fail = fail ||
+ im4(0) != -4 ||
+ im4(1) != -4 ||
+ im4(2) != -4 ||
+ im4(3) != -4 ||
+ im4(4) != -2 ||
+ im4(5) != 0 ||
+ im4(6) != 0 ||
+ im4(7) != 0 ||
+ im4(8) != 0 ||
+ im4(9) != -2 ||
+ im4(10)!= -4;
+
+ return fail;
+}
+
+bool
+check_lena()
+{
+ bool fail(false);
+
+ image2d<int_u8> lena = load(rdata("lena.pgm"));
+ image2d<int_u8> lena5 = morpho::tarjan::area_closing(lena,
neighb_c8(), 100);
+
+ unsigned l = 0;
+ image2d<int_u8>::iter_type it_l(lena5);
+ for_all(it_l)
+ l += lena5[it_l];
+ fail = fail ||
+ l != 31472398;
+ return fail;
+}
+
+bool
+check()
+{
+ bool fail = false;
+
+ std::cout << "area opening 1d ... " << std::flush;
+ if (check_opening1d() == false)
+ OK_OR_FAIL;
+
+ std::cout << "area opening with int_s<3> ... " <<
std::flush;
+ if (check_opening1d_s() == false)
+ OK_OR_FAIL;
+
+ std::cout << "area closing 2d on lena.pgm ... " << std::flush;
+ if (check_lena() == false)
+ OK_OR_FAIL;
+
+ return fail;
+}