* green/mln/accu/stat/histo2d.hh: New library file.
---
trunk/milena/sandbox/ChangeLog | 7 +
.../milena/sandbox/green/mln/accu/stat/histo2d.hh | 346 ++++++++++++++++++++
2 files changed, 353 insertions(+), 0 deletions(-)
create mode 100644 trunk/milena/sandbox/green/mln/accu/stat/histo2d.hh
diff --git a/trunk/milena/sandbox/ChangeLog b/trunk/milena/sandbox/ChangeLog
index 1d68213..9c03dec 100644
--- a/trunk/milena/sandbox/ChangeLog
+++ b/trunk/milena/sandbox/ChangeLog
@@ -1,5 +1,12 @@
2009-10-08 Yann Jacquelet <jacquelet(a)lrde.epita.fr>
+ Add histogram accumulator which produce a 2d image result.
+
+ * green/mln/accu/stat/histo2d.hh: New library file.
+
+
+2009-10-08 Yann Jacquelet <jacquelet(a)lrde.epita.fr>
+
Correct bad behaviour in kmean3d (see usage of zero label).
* green/mln/clustering/kmean3d.hh
diff --git a/trunk/milena/sandbox/green/mln/accu/stat/histo2d.hh
b/trunk/milena/sandbox/green/mln/accu/stat/histo2d.hh
new file mode 100644
index 0000000..fbe9a42
--- /dev/null
+++ b/trunk/milena/sandbox/green/mln/accu/stat/histo2d.hh
@@ -0,0 +1,346 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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 MLN_ACCU_STAT_HISTO2D_HH
+# define MLN_ACCU_STAT_HISTO2D_HH
+
+/// \file
+///
+/// \brief Define a histogram as an accumulator which returns an image1d .
+///
+/// This source implements the discrete histogram version. The number of beans
+/// is infer from the number of greylevels. A typical rgb8 image has got
+/// 256x3 bins. Working with a 8 bit quantification in rgb is very costly.
+/// The following sample is a typical use of the histogram.
+///
+/// #include <mln/value/rgb.hh>
+/// #include <mln/core/image/image1d.hh>
+/// #include <mln/core/image/image3d.hh>
+/// #include <mln/io/ppm/load.hh>
+/// #include <mln/accu/stat/histo3d_rgb.hh>
+/// #include <mln/data/compute.hh>
+///
+/// #define OLENA_LENA ""/usr/local/share/olena/images/lena.ppm"
+///
+/// void test()
+/// {
+/// typedef mln::value::rgb<7> rgb7;
+/// mln::image2d<rgb7> img_ref;
+/// mln::image3d<unsigned> img_res;
+///
+/// mln::io::ppm::load(img_ref, OLENA_LENA);
+/// img_res=mln::data::compute(mln::accu::meta::stat::histo3d_rgb(),img_ref);
+/// }
+
+
+# include <iostream>
+
+# include <mln/accu/internal/base.hh>
+
+# include <mln/core/macros.hh>
+# include <mln/core/image/image2d.hh>
+# include <mln/core/alias/point2d.hh>
+# include <mln/core/alias/box2d.hh>
+
+# include <mln/trait/value/comp.hh>
+
+# include <mln/arith/plus.hh>
+
+# include <mln/trace/entering.hh>
+# include <mln/trace/exiting.hh>
+
+# include <mln/value/ops.hh>
+
+namespace mln
+{
+
+ namespace accu
+ {
+
+ namespace stat
+ {
+
+ // Forward declaration
+ template <typename V>
+ struct histo2d;
+
+ } // end of namespace mln::accu::stat
+
+ namespace meta
+ {
+
+ namespace stat
+ {
+
+ struct histo2d : public Meta_Accumulator<histo2d>
+ {
+ template <typename V>
+ struct with
+ {
+ typedef accu::stat::histo2d<V> ret;
+ };
+ };
+
+ } // end of namespace mln::accu::meta::stat
+
+ } // end of namespace mln::accu::meta
+
+ } // end of namespace mln::accu
+
+
+ namespace trait
+ {
+
+ template <typename V>
+ struct accumulator_< mln::accu::stat::histo2d<V> >
+ {
+ typedef accumulator::has_untake::no has_untake;
+ typedef accumulator::has_set_value::no has_set_value;
+ typedef accumulator::has_stop::no has_stop;
+ typedef accumulator::when_pix::use_v when_pix;
+ };
+
+ template <typename V>
+ struct set_precise_binary_<op::eq,
+ accu::stat::histo2d<V>,
+ accu::stat::histo2d<V> >
+ {
+ typedef bool ret;
+ };
+
+ } // end of namespace mln::trait
+
+ namespace accu
+ {
+
+ namespace stat
+ {
+
+ /// \brief Define an histogram which returns an image3d .
+ ///
+ /// Param V defines the space in which we count the values.
+ /// For instance, this histogram works image2d<rgb<2>> or
+ /// image2d<rgb<7>>. The histogram count the occurrence of each value.
+ /// The number of bins depends of the grayscale values, for 8 bits there
+ /// is 256x3 bins. Note that over
+ /// quantification works too.
+ ///
+ /// \ingroup modaccuvalues
+
+ template <typename V>
+ struct histo2d :
+ public mln::accu::internal::base<image2d<unsigned>, histo2d<V> >
+ {
+ typedef V argument;
+ typedef image2d<unsigned> result;
+ typedef result q_result;
+
+ /// Constructors
+ /// \{
+ /// \brief Initialize the size of the resulting image1d.
+ ///
+ /// Initialize the size the resulting image from the theorical dynamic
+ /// of the greylevel values (Use V to manage it).
+ histo2d();
+ /// \}
+
+
+ /// Manipulators.
+ /// \{
+ /// \brief Initialize the histogram with zero value.
+ ///
+ /// This method must be called just before starting the use of the
+ /// histogram. If it's not, resulting values won't converge to the
+ /// density.
+ void init();
+
+
+ /// \brief Update the histogram with the RGB pixel t.
+ /// \param[in] t a greylevel pixel of type V.
+ ///
+ /// The end user shouldn't call this method. In place of it, he can
+ /// go through the data compute interface.
+ void take(const argument& t);
+
+
+ /// \brief Update the histogram with an other histogram.
+ /// \param[in] other the other histogram.
+ void take(const histo2d<V>& other);
+ /// \}
+
+ /// Accessors.
+ /// \{
+ /// \brief Return the histogram as an image1d.
+ ///
+ /// This is the machinery to communicate with data compute interface.
+ /// The end user should'nt use it.
+ result to_result() const;
+ operator result () const;
+ /// \}
+
+ /// \brief Check whethever this accumulator is able to return a result.
+ ///
+ /// Depends if the resulting image1d is valid. We can assume it is quite
+ /// always the case.
+ bool is_valid() const;
+
+ protected:
+ result count_;
+ };
+
+ /// \brief Check wethever an histogram is equal to an other one.
+ /// \param[in] histo1 the first histogram to compare with.
+ /// \param[in] histo2 the second histogram.
+ ///
+ /// The operator compare all the bins from the two histogram.
+
+ template <typename V>
+ bool operator==(const histo2d<V>& histo1,
+ const histo2d<V>& histo2);
+
+#ifndef MLN_INCLUDE_ONLY
+
+ template <typename V>
+ inline
+ histo2d<V>::histo2d()
+ {
+ trace::entering("mln::accu::stat::histo2d::histo2d");
+ typedef mln_trait_value_comp(V,0) comp0;
+ typedef mln_trait_value_comp(V,1) comp1;
+
+ // comp keep a trace of the dimension of the theorical image.
+ // mln_min(comp) --> 0
+ // mln_max(comp) --> 2^(n-1) [127 for n=7][255 for n=8] ...
+
+ count_.init_(box2d(point2d(mln_min(comp0),
+ mln_min(comp1)),
+ point2d(mln_max(comp0),
+ mln_max(comp1))));
+
+ trace::exiting("mln::accu::stat::histo2d::histo2d");
+ }
+
+ template <typename V>
+ inline
+ void histo2d<V>::init()
+ {
+ trace::entering("mln::accu::stat::histo2d::init");
+
+ data::fill(count_, 0);
+ trace::exiting("mln::accu::stat::histo2d::init");
+ }
+
+ template <typename V>
+ inline
+ void histo2d<V>::take(const argument& t)
+ {
+ trace::entering("mln::accu::stat::histo2d::take");
+
+ // Just convert a greyscale value (int_u8 like) to a position for an
+ // iterator on the resulting image.
+ // Take care to the constructor : Point(slice, row, column)
+ ++count_(point2d(t.red(), t.green()));
+
+ trace::exiting("mln::accu::stat::histo2d::take");
+ }
+
+
+ template <typename V>
+ inline
+ void histo2d<V>::take(const histo2d<V>& other)
+ {
+ trace::entering("mln::accu::stat::histo2d::take");
+
+ count_ += other.count_;
+
+ trace::exiting("mln::accu::stat::histo2d::take");
+ }
+
+ template <typename V>
+ inline
+ typename histo2d<V>::result histo2d<V>::to_result() const
+ {
+ trace::entering("mln::accu::stat::histo2d::to_result");
+
+ trace::exiting("mln::accu::stat::histo2d::to_result");
+ return count_;
+ }
+
+ template <typename V>
+ inline
+ histo2d<V>::operator result() const
+ {
+ trace::entering("mln::accu::stat::histo2d::operator result");
+
+ trace::exiting("mln::accu::stat::histo2d::operator result");
+ return count_;
+ }
+
+ template <typename V>
+ inline
+ bool histo2d<V>::is_valid() const
+ {
+ trace::entering("mln::accu::stat::histo2d::is_valid");
+ bool result = count_.is_valid();
+
+ trace::exiting("mln::accu::stat::histo2d::is_valid");
+ return result;
+ }
+
+ template <typename V>
+ bool operator==(const histo2d<V>& histo1,
+ const histo2d<V>& histo2)
+ {
+ trace::entering("mln::accu::stat::operator==");
+
+ bool result = true;
+ const image2d<unsigned>& res1 = histo1.to_result();
+ const image2d<unsigned>& res2 = histo2.to_result();
+
+ mln_precondition(res1.is_valid());
+ mln_precondition(res2.is_valid());
+
+ mln_piter(image2d<unsigned>) p1(res1.domain());
+ mln_piter(image2d<unsigned>) p2(res2.domain());
+
+ for_all_2(p1, p2)
+ result &= (res1(p1) == res2(p2));
+
+ trace::exiting("mln::accu::stat::operator==");
+ return result;
+ }
+
+#endif // ! MLN_INCLUDE_ONLY
+
+
+ } // end of namespace mln::accu::stat
+
+ } // end of namespace mln::accu
+
+} // end of namespace mln
+
+#endif // ! MLN_ACCU_STAT_HISTO2D_HH
--
1.5.6.5