4448: 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. --- 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@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@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@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
participants (1)
-
Yann Jacquelet