* green/tests/accu/stat/histo3d_rgb : New directory.
* green/tests/accu/stat/histo3d_rgb/Makefile.am : New makefile.
* green/tests/accu/stat/histo3d_rgb/histo3d_rgb.cc : New unitary tests.
* green/mln/accu/stat/histo3d_rgb/histo3d_rgb.hh : New library code.
* green/mln/fun/v2v/rgb8_to_rgbn.hh : New converting fun.
---
trunk/milena/sandbox/ChangeLog | 18 +
.../sandbox/green/mln/accu/stat/histo3d_rgb.hh | 330 ++++++++++++++++++++
.../sandbox/green/mln/fun/v2v/rgb8_to_rgbn.hh | 82 +++++
.../green/tests/accu/stat/histo3d_rgb/Makefile.am | 148 +++++++++
.../tests/accu/stat/histo3d_rgb/histo3d_rgb.cc | 315 +++++++++++++++++++
5 files changed, 893 insertions(+), 0 deletions(-)
create mode 100644 trunk/milena/sandbox/green/mln/accu/stat/histo3d_rgb.hh
create mode 100644 trunk/milena/sandbox/green/mln/fun/v2v/rgb8_to_rgbn.hh
create mode 100644 trunk/milena/sandbox/green/tests/accu/stat/histo3d_rgb/Makefile.am
create mode 100644 trunk/milena/sandbox/green/tests/accu/stat/histo3d_rgb/histo3d_rgb.cc
diff --git a/trunk/milena/sandbox/ChangeLog b/trunk/milena/sandbox/ChangeLog
index 584044a..0da6ae7 100644
--- a/trunk/milena/sandbox/ChangeLog
+++ b/trunk/milena/sandbox/ChangeLog
@@ -1,5 +1,23 @@
2009-09-07 Yann Jacquelet <jacquelet(a)lrde.epita.fr>
+ Work with histogram as image 3d on rgb color space.
+
+ * green/tests/accu/stat/histo3d_rgb : New directory.
+ * green/tests/accu/stat/histo3d_rgb/Makefile.am : New makefile.
+ * green/tests/accu/stat/histo3d_rgb/histo3d_rgb.cc : New unitary tests.
+ * green/mln/accu/stat/histo3d_rgb/histo3d_rgb.hh : New library code.
+ * green/mln/fun/v2v/rgb8_to_rgbn.hh : New converting fun.
+
+2009-09-07 Yann Jacquelet <jacquelet(a)lrde.epita.fr>
+
+ Prepare unitary test with histogram 2d.
+
+ * green/tests/accu/stat/histo2d : New directory.
+ * green/tests/accu/stat/histo2d/Makefile.am : New makefile.
+ * green/tests/accu/stat/histo2d/gaussian2d.sh : New calibrating tool.
+
+2009-09-07 Yann Jacquelet <jacquelet(a)lrde.epita.fr>
+
Make some test on 14 bits grayscale image.
* green/mln/accu/stat/histo1d/histo1d.hh : Improve documentation.
diff --git a/trunk/milena/sandbox/green/mln/accu/stat/histo3d_rgb.hh
b/trunk/milena/sandbox/green/mln/accu/stat/histo3d_rgb.hh
new file mode 100644
index 0000000..8a10c0b
--- /dev/null
+++ b/trunk/milena/sandbox/green/mln/accu/stat/histo3d_rgb.hh
@@ -0,0 +1,330 @@
+// 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_HISTO3D_RGB_HH
+#define MLN_ACCU_STAT_HISTO3D_RGB_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 int_u8 image has got
+/// 256 bins. An int_u16 image has got 65535 bins.
+/// The following sample is a typical use of the histogram.
+///
+/// #include <mln/value/int_u8.hh>
+/// #include <mln/core/image/image1d.hh>
+/// #include <mln/core/image/image2d.hh>
+/// #include <mln/io/pgm/load.hh>
+/// #include <mln/accu/stat/histo1d.hh>
+/// #include <mln/data/compute.hh>
+/// #include <mln/io/plot/save_histo_sh.hh>
+///
+/// #define OLENA_LENA ""/usr/local/share/olena/images/lena.pgm"
+///
+/// void test()
+/// {
+/// typedef mln::value::int_u8 int_u8;
+/// mln::image2d<int_u8> img_ref;
+/// mln::image1d<unsigned> img_res;
+///
+/// mln::io::pgm::load(img_ref, OLENA_LENA);
+/// img_res = mln::data::compute(mln::accu::stat::histo1d<int_u8>(), img_ref);
+/// }
+
+
+#include <iostream>
+
+#include <mln/accu/internal/base.hh>
+
+#include <mln/core/macros.hh>
+#include <mln/core/image/image3d.hh>
+#include <mln/core/alias/point3d.hh>
+#include <mln/core/alias/box3d.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 histo3d_rgb;
+
+ } // end of namespace mln::accu::stat
+
+ } // end of namespace mln::accu
+
+
+ namespace trait
+ {
+
+ template <typename V>
+ struct accumulator_< mln::accu::stat::histo3d_rgb<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::histo3d_rgb<V>,
+ accu::stat::histo3d_rgb<V> >
+ {
+ typedef bool ret;
+ };
+
+ } // end of namespace mln::trait
+
+ namespace accu
+ {
+
+ namespace stat
+ {
+
+ /// \brief Define an histogram which returns an image1d .
+ ///
+ /// Param V defines the space in which we count the values.
+ /// For instance, this histogram works image2d<int_u8> or
+ /// image1d<int_u16>. The histogram count the occurrence of each value.
+ /// The number of bins depends of the greyscale values, for 8 bits there
+ /// is 256 bins, for 16 bits there is 65536 bins. Note that over
+ /// quantification works too.
+ ///
+ /// \ingroup modaccuvalues
+
+ template <typename V>
+ struct histo3d_rgb :
+ public mln::accu::internal::base<image3d<unsigned>, histo3d_rgb<V> >
+ {
+ typedef V argument;
+ typedef image3d<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).
+ histo3d_rgb();
+ /// \}
+
+
+ /// 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 histo3d_rgb<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 histo3d_rgb<V>& histo1,
+ const histo3d_rgb<V>& histo2);
+
+#ifndef MLN_INCLUDE_ONLY
+
+ template <typename V>
+ inline
+ histo3d_rgb<V>::histo3d_rgb()
+ {
+ trace::entering("mln::accu::stat::histo3d_rgb<V>::histo3d_rgb");
+ typedef mln_trait_value_comp(V,0) comp0;
+ typedef mln_trait_value_comp(V,1) comp1;
+ typedef mln_trait_value_comp(V,2) comp2;
+
+ // 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_(box3d(point3d(mln_min(comp0),
+ mln_min(comp1),
+ mln_min(comp2)),
+ point3d(mln_max(comp0),
+ mln_max(comp1),
+ mln_max(comp2))));
+
+ trace::exiting("mln::accu::stat::histo3d_rgb<V>::histo3d_rgb");
+ }
+
+ template <typename V>
+ inline
+ void histo3d_rgb<V>::init()
+ {
+ trace::entering("mln::accu::stat::histo3d_rgb<V>::init");
+
+ data::fill(count_, 0);
+ trace::exiting("mln::accu::stat::histo3d_rgb<V>::init");
+ }
+
+ template <typename V>
+ inline
+ void histo3d_rgb<V>::take(const argument& t)
+ {
+ trace::entering("mln::accu::stat::histo3d_rgb<V>::take");
+
+ // Just convert a greyscale value (int_u8 like) to a position for an
+ // iterator on the resulting image.
+ ++count_(point3d(t.red(), t.green(), t.blue()));
+
+ trace::exiting("mln::accu::stat::histo3d_rgb<V>::take");
+ }
+
+
+ template <typename V>
+ inline
+ void histo3d_rgb<V>::take(const histo3d_rgb<V>& other)
+ {
+ trace::entering("mln::accu::stat::histo3d_rgb<V>::take");
+
+ count_ += other.count_;
+
+ trace::exiting("mln::accu::stat::histo3d_rgb<V>::take");
+ }
+
+ template <typename V>
+ inline
+ typename histo3d_rgb<V>::result histo3d_rgb<V>::to_result() const
+ {
+ trace::entering("mln::accu::stat::histo3d_rgb<V>::to_result");
+
+ trace::exiting("mln::accu::stat::histo3d_rgb<V>::to_result");
+ return count_;
+ }
+
+ template <typename V>
+ inline
+ histo3d_rgb<V>::operator result() const
+ {
+ trace::entering("mln::accu::stat::histo3d_rgb<V>::operator result");
+
+ trace::exiting("mln::accu::stat::histo3d_rgb<V>::operator result");
+ return count_;
+ }
+
+ template <typename V>
+ inline
+ bool histo3d_rgb<V>::is_valid() const
+ {
+ trace::entering("mln::accu::stat::histo3d_rgb<V>::is_valid");
+ bool result = count_.is_valid();
+
+ trace::exiting("mln::accu::stat::histo3d_rgb<V>::is_valid");
+ return result;
+ }
+
+ template <typename V>
+ bool operator==(const histo3d_rgb<V>& histo1,
+ const histo3d_rgb<V>& histo2)
+ {
+ trace::entering("mln::accu::stat::operator==");
+
+ bool result = true;
+ const image3d<unsigned>& res1 = histo1.to_result();
+ const image3d<unsigned>& res2 = histo2.to_result();
+
+ mln_precondition(res1.is_valid());
+ mln_precondition(res2.is_valid());
+
+ mln_piter(image3d<unsigned>) p1(res1.domain());
+ mln_piter(image3d<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_HISTO3D_RGB_HH
diff --git a/trunk/milena/sandbox/green/mln/fun/v2v/rgb8_to_rgbn.hh
b/trunk/milena/sandbox/green/mln/fun/v2v/rgb8_to_rgbn.hh
new file mode 100644
index 0000000..b40ca5b
--- /dev/null
+++ b/trunk/milena/sandbox/green/mln/fun/v2v/rgb8_to_rgbn.hh
@@ -0,0 +1,82 @@
+// 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_FUN_V2V_RGB8_TO_RGBN_HH
+#define MLN_FUN_V2V_RGB8_TO_RGBN_HH
+
+#include <mln/value/rgb8.hh>
+#include <mln/value/rgb.hh>
+#include <mln/core/contract.hh>
+
+/// \file
+///
+/// \brief Convert rgb8 value to rgbn, n < 8.
+
+namespace mln
+{
+
+ namespace fun
+ {
+
+ namespace v2v
+ {
+
+ /// \brief Convert rgb8 value to rgbn, n < 8.
+ ///
+ /// \ingroup modfunv2v
+
+ template <unsigned n>
+ struct rgb8_to_rgbn : Function_v2v< rgb8_to_rgbn<n> >
+ {
+ typedef value::rgb8 argument;
+ typedef value::rgb<n> result;
+
+ result operator()(const argument& c) const
+ {
+ mln_precondition(8 > n);
+
+ unsigned size = pow(2,(8-n));
+ /*
+ std::cout << "c : " << c << std::endl;
+ std::cout << "red : " << c.red() << std::endl;
+ std::cout << "size : " << size << std::endl;
+ std::cout << "res : " << (c.red() / size) << std::endl;
+ std::cout << "max : " << (mln_max(mln::value::int_u<n>))
<< std::endl;
+ */
+ result res(c.red() / size, c.green() / size, c.blue() / size);
+
+ return res;
+ }
+ };
+
+ }
+
+ }
+
+}
+
+#endif // ! MLN_FUN_V2V_RGB8_TO_RGBN_HH
diff --git a/trunk/milena/sandbox/green/tests/accu/stat/histo3d_rgb/Makefile.am
b/trunk/milena/sandbox/green/tests/accu/stat/histo3d_rgb/Makefile.am
new file mode 100644
index 0000000..d970989
--- /dev/null
+++ b/trunk/milena/sandbox/green/tests/accu/stat/histo3d_rgb/Makefile.am
@@ -0,0 +1,148 @@
+#
+# Generic Makefile
+#
+
+#########
+# TOOLS #
+#########
+
+INCLUDES= -I$(HOME)/svn/oln/trunk/milena/sandbox/green
+CXXFLAGS= -ggdb -O0 -Wall -W -pedantic -ansi -pipe $(INCLUDES)
+ECHO= echo
+RM= rm
+MKDIR= mkdir -p
+CP= cp
+
+SOURCE_PATTERN= green/tests
+BUILD__PATTERN= green/build/tests
+
+
+ifeq ($(findstring $(BUILD__PATTERN),$(PWD)), $(BUILD__PATTERN))
+# Case where make is done from build directory.
+SOURCE_DIR= $(subst $(BUILD__PATTERN),$(SOURCE_PATTERN),$(PWD))
+BUILD__DIR= $(PWD)
+else
+# Case where make is done from source directory.
+SOURCE_DIR= $(PWD)
+BUILD__DIR= $(subst $(SOURCE_PATTERN),$(BUILD__PATTERN),$(PWD))
+endif
+
+SRC= $(notdir $(wildcard $(SOURCE_DIR)/*.cc))
+OLD= $(notdir $(wildcard $(SOURCE_DIR)/*~))
+OBJ= $(patsubst %.cc,%.o,$(SRC))
+SOURCE_MAKEFILE=Makefile.am
+BUILD__MAKEFILE=Makefile
+TARGET_FILE= $(notdir $(PWD))
+SOURCE_FILES= $(notdir $(wildcard $(SOURCE_DIR)/*.*))
+BUILD__FILES= $(filter-out $(SRC) $(SOURCE_MAKEFILE), $(SOURCE_FILES))
+
+BUILD__F_PATH= $(addprefix $(BUILD__DIR)/,$(BUILD__FILES))
+SOURCE_F_PATH= $(addprefix $(SOURCE_DIR)/,$(SOURCE_FILES))
+
+BUILD__M_PATH= $(addprefix $(BUILD__DIR)/,$(BUILD__MAKEFILE))
+SOURCE_M_PATH= $(addprefix $(SOURCE_DIR)/,$(SOURCE_MAKEFILE))
+
+TARGET_F_PATH= $(addprefix $(BUILD__DIR)/,$(TARGET_FILE))
+OBJ_F_PATH= $(addprefix $(BUILD__DIR)/,$(OBJ))
+SRC_F_PATH= $(addprefix $(SOURCE_DIR)/,$(SRC))
+OLD_F_PATH= $(addprefix $(SOURCE_DIR)/,$(OLD))
+
+#############
+# BOOTSTRAP #
+#############
+
+
+bootstrap: $(BUILD__DIR) $(BUILD__F_PATH) $(BUILD__M_PATH)
+
+# Create, if nessary, the destination directory
+$(BUILD__DIR):
+ $(MKDIR) $(BUILD__DIR)
+
+# Copy, if nessary, all the files, except the Makefile.am
+$(BUILD__F_PATH): $(SOURCE_F_PATH)
+ $(CP) $(addprefix $(SOURCE_DIR)/,$(@F)) $@
+
+# Copy if nessary, the Makefile.am into Makefile
+$(BUILD__M_PATH): $(SOURCE_M_PATH)
+ $(CP) $(SOURCE_M_PATH) $(BUILD__M_PATH)
+
+
+#######
+# ALL #
+#######
+
+# We assume that the call is done from the build directory.
+# With the directive vpath, hidden files are found in the source directory.
+
+all: $(TARGET_F_PATH)
+
+
+$(TARGET_F_PATH): $(OBJ_F_PATH)
+ $(LINK.cc) $< $(LOADLIBES) $(LDLIBS) -o $@
+
+$(OBJ_F_PATH):$(SRC_F_PATH)
+ $(COMPILE.cc) $(OUTPUT_OPTION) $<
+
+
+#########
+# CLEAN #
+#########
+
+# Force every time the deletion
+clean: clean_target clean_obj clean_dst clean_old #clean_make
+
+
+clean_target:
+ -@$(RM) $(TARGET_F_PATH) &> /dev/null
+
+clean_obj:
+ -@$(RM) $(OBJ_F_PATH) &> /dev/null
+
+clean_dst:
+ -@$(RM) $(BUILD_F_PATH) &> /dev/null
+
+clean_make:
+ -@$(RM) $(BUILD_M_PATH) &> /dev/null
+
+clean_old:
+ -@$(RM) $(OLD_F_PATH) &> /dev/null
+
+
+#########
+# PRINT #
+#########
+
+print: print_tools print_bootstrap
+
+print_tools:
+ @$(ECHO) "HOME = $(HOME)"
+ @$(ECHO) "INCLUDES = $(INCLUDES)"
+ @$(ECHO) "CXXFLAGS = $(CXXFLAGS)"
+ @$(ECHO) "ECHO = $(ECHO)"
+ @$(ECHO) "RM = $(RM)"
+ @$(ECHO) "MKDIR = $(MKDIR)"
+ @$(ECHO) "CP = $(CP)"
+ @$(ECHO)
+
+print_bootstrap:
+ @$(ECHO) "PWD = $(PWD)"
+ @$(ECHO) "SOURCE_PATTERN = $(SOURCE_PATTERN)"
+ @$(ECHO) "BUILD__PATTERN = $(BUILD__PATTERN)"
+ @$(ECHO) "SOURCE_DIR = $(SOURCE_DIR)"
+ @$(ECHO) "BUILD__DIR = $(BUILD__DIR)"
+ @$(ECHO) "SOURCE_MAKEFILE = $(SOURCE_MAKEFILE)"
+ @$(ECHO) "BUILD__MAKEFILE = $(BUILD__MAKEFILE)"
+ @$(ECHO) "TARGET_FILE = $(TARGET_FILE)"
+ @$(ECHO) "SOURCE_FILES = $(SOURCE_FILES)"
+ @$(ECHO) "SOURCE_F_PATH = $(SOURCE_F_PATH)"
+ @$(ECHO) "BUILD__FILES = $(BUILD__FILES)"
+ @$(ECHO) "BUILD__F_PATH = $(BUILD__F_PATH)"
+ @$(ECHO) "BUILD__M_PATH = $(BUILD__M_PATH)"
+ @$(ECHO) "SOURCE_M_PATH = $(SOURCE_M_PATH)"
+ @$(ECHO) "SRC = $(SRC)"
+ @$(ECHO) "OBJ = $(OBJ)"
+ @$(ECHO) "OLD = $(OLD)"
+ @$(ECHO) "SRC_F_PATH = $(SRC_F_PATH)"
+ @$(ECHO) "OBJ_F_PATH = $(OBJ_F_PATH)"
+ @$(ECHO) "OLD_F_PATH = $(OLD_F_PATH)"
+ @$(ECHO)
diff --git a/trunk/milena/sandbox/green/tests/accu/stat/histo3d_rgb/histo3d_rgb.cc
b/trunk/milena/sandbox/green/tests/accu/stat/histo3d_rgb/histo3d_rgb.cc
new file mode 100644
index 0000000..b2af06e
--- /dev/null
+++ b/trunk/milena/sandbox/green/tests/accu/stat/histo3d_rgb/histo3d_rgb.cc
@@ -0,0 +1,315 @@
+/// TEST HISTO3D_RGB
+
+#include <mln/img_path.hh>
+
+#include <mln/io/plot/save_histo_sh.hh>
+#include <mln/accu/stat/histo3d_rgb.hh>
+#include <mln/fun/v2v/rgb8_to_rgbn.hh>
+
+#include <mln/io/ppm/load.hh>
+#include <mln/io/ppm/save.hh>
+#include <mln/io/plot/save.hh>
+
+#include <mln/data/compute.hh>
+#include <mln/data/transform.hh>
+#include <mln/data/fill.hh>
+
+#include <mln/value/label_8.hh>
+#include <mln/value/rgb8.hh>
+#include <mln/value/rgb.hh>
+#include <mln/value/int_u.hh>
+
+#include <mln/core/alias/neighb3d.hh>
+#include <mln/core/alias/box3d.hh>
+#include <mln/core/alias/point3d.hh>
+
+#include <mln/core/routine/initialize.hh>
+#include <mln/core/contract.hh>
+#include <mln/core/grids.hh>
+
+#include <mln/accu/math/sum.hh>
+#include <mln/accu/math/count.hh>
+#include <mln/accu/stat/mean.hh>
+#include <mln/accu/stat/variance.hh>
+#include <mln/accu/stat/var.hh>
+
+#include <mln/morpho/watershed/flooding.hh>
+#include <mln/morpho/elementary/dilation.hh>
+#include <mln/morpho/elementary/closing.hh>
+
+#include <mln/linear/convolve.hh>
+#include <mln/linear/gaussian.hh>
+#include <mln/labeling/regional_maxima.hh>
+#include <mln/labeling/colorize.hh>
+#include <mln/labeling/mean_values.hh>
+
+#include <mln/make/w_window3d.hh>
+
+#include <mln/math/sqr.hh>
+#include <mln/math/pi.hh>
+#include <mln/math/abs.hh>
+
+#include <mln/core/image/dmorph/image_if.hh>
+#include <mln/pw/value.hh>
+
+
+template <unsigned n>
+void test_operator_equal()
+{
+ using namespace mln::accu::stat;
+
+ typedef mln::value::rgb<n> rgbn;
+ mln::accu::stat::histo3d_rgb<rgbn> histo1;
+ mln::accu::stat::histo3d_rgb<rgbn> histo2;
+ rgbn val(3,3,3);
+
+ histo1.init();
+ histo2.init();
+
+ mln_assertion(histo1 == histo2);
+
+ histo1.take(val);
+
+ /// FIXME mln_assertion(histo1 != histo2); doesn't work!!
+ mln_assertion(!(histo1 == histo2));
+
+ histo2.take(val);
+
+ mln_assertion(histo1 == histo2);
+
+ std::cout << "(" << n << " bits) histo == histo
: ok" << std::endl;
+}
+
+template <unsigned n>
+void test_instantiation_without_argument()
+{
+ typedef mln::value::rgb<n> rgbn;
+ typedef mln_trait_value_comp(rgbn,0) comp;
+ const mln::accu::stat::histo3d_rgb<rgbn> histo;
+ const mln::image3d<unsigned>& res = histo.to_result();
+ const mln::point3d& min =mln::point3d(mln_min(comp),
+ mln_min(comp),
+ mln_min(comp));
+ const mln::point3d& max =mln::point3d(mln_max(comp),
+ mln_max(comp),
+ mln_max(comp));
+ const mln::box3d& ref = mln::box3d(min, max);
+
+ mln_assertion(ref == res.domain());
+ mln_assertion(res.is_valid());
+
+ std::cout << "(" << n << " bits) histo<T> histo
: ok" << std::endl;
+}
+
+template <unsigned n>
+void test_initialization()
+{
+ typedef mln::value::int_u<n> int_un;
+ typedef mln::value::rgb<n> rgbn;
+ mln::accu::stat::histo3d_rgb<rgbn> histo;
+ mln::image3d<unsigned> img_res = histo.to_result();
+ mln::image3d<unsigned> img_ref;
+
+ mln::initialize(img_ref, img_res);
+ mln::data::fill(img_ref, 0);
+ histo.init();
+
+ unsigned res = mln::data::compute(mln::accu::math::sum<int_un>(), img_res);
+ unsigned ref = mln::data::compute(mln::accu::math::sum<int_un>(), img_ref);
+
+ mln_assertion(ref == res);
+
+ std::cout << "(" << n << " bits) histo.init()
: ok" << std::endl;
+}
+
+template <unsigned n>
+void test_take_argument()
+{
+ typedef mln::value::int_u<n> int_un;
+ typedef mln::value::rgb<n> rgbn;
+ mln::accu::stat::histo3d_rgb<rgbn> histo1;
+ mln::accu::stat::histo3d_rgb<rgbn> histo2;
+ rgbn val(3,3,3);
+
+ histo1.init();
+ histo2.init();
+ histo1.take(val);
+
+ const mln::image3d<unsigned> img1 = histo1.to_result();
+ const mln::image3d<unsigned> img2 = histo2.to_result();
+
+ const unsigned res = mln::data::compute(mln::accu::math::sum<int_un>(), img1);
+ const unsigned ref = mln::data::compute(mln::accu::math::sum<int_un>(), img2);
+
+ mln_assertion(ref == res-1);
+ mln_assertion(1 == img1(mln::point3d(val.red(), val.green(), val.blue())));
+
+ std::cout << "(" << n << " bits) histo.take(argument)
: ok" << std::endl;
+}
+
+template <unsigned n>
+void test_take_other()
+{
+ typedef mln::value::rgb<n> rgbn;
+ mln::accu::stat::histo3d_rgb<rgbn> histo1;
+ mln::accu::stat::histo3d_rgb<rgbn> histo2;
+ mln::accu::stat::histo3d_rgb<rgbn> histo3;
+ rgbn val(3,3,3);
+
+ histo1.init();
+ histo2.init();
+ histo3.init();
+
+ histo1.take(val);
+ histo1.take(val);
+ histo3.take(val);
+ histo2.take(val);
+ histo2.take(histo3);
+
+ mln_assertion(histo1 == histo2);
+
+ std::cout << "(" << n << " bits) histo.take(other)
: ok" << std::endl;
+}
+
+double count_histo(mln::image3d<unsigned> img)
+{
+ mln_precondition(img.is_valid());
+
+ double result = 0.0;
+ mln_piter_(mln::image3d<unsigned>) p(img.domain());
+
+ for_all(p)
+ result += img(p);
+
+ return result;
+}
+
+mln::algebra::vec<3,float> mean_histo(mln::image3d<unsigned> img)
+{
+ mln_precondition(img.is_valid());
+
+ double count = 0.0;
+ double sum0 = 0.0;
+ double sum1 = 0.0;
+ double sum2 = 0.0;
+ mln::algebra::vec<3,float> result;
+
+ mln_piter_(mln::image3d<unsigned>) p(img.domain());
+
+ for_all(p)
+ {
+ count += img(p);
+ sum0 += p[0] * img(p);
+ sum1 += p[1] * img(p);
+ sum2 += p[2] * img(p);
+ }
+
+ result[0] = sum0/count;
+ result[1] = sum1/count;
+ result[2] = sum2/count;
+
+ return result;
+}
+
+
+double var_histo(mln::image3d<unsigned> img)
+{
+ mln_precondition(img.is_valid());
+
+ double count = 0.0;
+ double sum = 0.0;
+ double sum2 = 0.0;
+ double result = 0.0;
+ mln_piter_(mln::image3d<unsigned>) p(img.domain());
+
+ for_all(p)
+ {
+ count += img(p);
+ sum += p[0] * img(p);
+ sum2 += p[0] * p[0] * img(p);
+ }
+
+ result = sum2 / count - (sum / count) * (sum / count);
+
+ return result;
+}
+
+/*
+double var_histo2(mln::image3d<unsigned> img)
+{
+ mln_precondition(img.is_valid());
+
+ double count = count_histo(img);
+ double mean = mean_histo(img);
+ double result = 0.0;
+ mln_piter_(mln::image3d<unsigned>) p(img.domain());
+
+ for_all(p)
+ {
+ result += img(p) * (p[0] - mean) * (p[0] - mean);
+ }
+
+ result /= count;
+
+ return result;
+}
+*/
+template <unsigned n>
+void test_integration()
+{
+ // mln::trace::quiet = false;
+
+ typedef mln::value::rgb8 rgb8;
+ typedef mln::value::rgb<n> rgbn;
+ typedef mln::algebra::vec<3,float> vec3f;
+ typedef mln::algebra::mat<3,3,float> mat3f;
+ typedef mln::accu::math::count<rgbn> count;
+ typedef mln::accu::math::sum<rgbn,vec3f> sum;
+ typedef mln::accu::stat::mean<rgbn,vec3f,vec3f> mean;
+ typedef mln::accu::stat::var<rgbn> var;
+
+ mln::image2d<rgb8> img_fst;
+ mln::image2d<rgbn> img_ref;
+ mln::image3d<unsigned> img_res;
+
+ mln::io::ppm::load(img_fst, OLENA_IMG_PATH"/lena.ppm");
+ img_ref = mln::data::transform(img_fst, mln::fun::v2v::rgb8_to_rgbn<n>());
+ // CF COMPATIBILITE DES ACCU AVEC LE RGB
+
+
+ const double count_ref = mln::data::compute(count(), img_ref);
+ const vec3f sum_ref = mln::data::compute(sum(), img_ref);
+ const vec3f mean_ref = mln::data::compute(mean(), img_ref);
+ // const mat3f var_ref = mln::data::compute(var(), img_ref);
+
+
+ img_res = mln::data::compute(mln::accu::stat::histo3d_rgb<rgbn>(), img_ref);
+
+
+ const double count_res = count_histo(img_res);
+ const vec3f mean_res = mean_histo(img_res);
+
+ //const double var_res = var_histo(img_res);
+
+ mln_assertion(count_ref == count_res);
+ mln_assertion( mean_ref == mean_res );
+ //mln_assertion(0.0001 > abs(var_ref - var_res));
+
+ std::cout << "(" << n << " bits) test integration
: ok" << std::endl;
+}
+
+int main()
+{
+
+
+ test_operator_equal<3>();
+ test_instantiation_without_argument<3>();
+ test_initialization<3>();
+ test_take_argument<3>();
+ test_take_other<3>();
+ test_integration<3>();
+
+ // p2p/fold+transform_domain for hcv
+
+ return 0;
+}
--
1.5.6.5