4469: Save work in progress for histo and hsl.

* green/mln/accu/stat/histo3d_hsl.hh : New library file. * green/tests/accu/stat/histo3d_hsl : New directory. * green/tests/accu/stat/Makefile.am : New makefile. * green/tests/accu/stat/histo3d_hsl.cc : New source file. --- trunk/milena/sandbox/ChangeLog | 10 + .../sandbox/green/mln/accu/stat/histo3d_hsl.hh | 347 ++++++++++++++++++ .../green/tests/accu/stat/histo3d_hsl/Makefile.am | 148 ++++++++ .../tests/accu/stat/histo3d_hsl/histo3d_hsl.cc | 375 ++++++++++++++++++++ 4 files changed, 880 insertions(+), 0 deletions(-) create mode 100644 trunk/milena/sandbox/green/mln/accu/stat/histo3d_hsl.hh create mode 100644 trunk/milena/sandbox/green/tests/accu/stat/histo3d_hsl/Makefile.am create mode 100644 trunk/milena/sandbox/green/tests/accu/stat/histo3d_hsl/histo3d_hsl.cc diff --git a/trunk/milena/sandbox/ChangeLog b/trunk/milena/sandbox/ChangeLog index 00a840e..2530228 100644 --- a/trunk/milena/sandbox/ChangeLog +++ b/trunk/milena/sandbox/ChangeLog @@ -1,5 +1,15 @@ 2009-09-11 Yann Jacquelet <jacquelet@lrde.epita.fr> + Save work in progress for histo and hsl. + + * green/mln/accu/stat/histo3d_hsl.hh : New library file. + + * green/tests/accu/stat/histo3d_hsl : New directory. + * green/tests/accu/stat/Makefile.am : New makefile. + * green/tests/accu/stat/histo3d_hsl.cc : New source file. + +2009-09-11 Yann Jacquelet <jacquelet@lrde.epita.fr> + Do some refactoring in green's sandbox. * green/doc/examples : New directory. diff --git a/trunk/milena/sandbox/green/mln/accu/stat/histo3d_hsl.hh b/trunk/milena/sandbox/green/mln/accu/stat/histo3d_hsl.hh new file mode 100644 index 0000000..40da72c --- /dev/null +++ b/trunk/milena/sandbox/green/mln/accu/stat/histo3d_hsl.hh @@ -0,0 +1,347 @@ +// 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_HSL_HH +#define MLN_ACCU_STAT_HISTO3D_HSL_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/core/value/int_u.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> + +// make hue cyclic +#include <mln/fun/p2p/flod.hh> +#include <mln/core/image/dmorph/transformed_image.hh> + +namespace mln +{ + + namespace accu + { + + namespace stat + { + + // Forward declaration + template <typename V> + struct histo3d_hsl; + + } // end of namespace mln::accu::stat + + } // end of namespace mln::accu + + + namespace trait + { + + template <typename V> + struct accumulator_< mln::accu::stat::histo3d_hsl<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_hsl<V>, + accu::stat::histo3d_hsl<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 + + /// q is the number of bins per axe because quantification info are died. + /// we assume that V is a kind of hsl_<float,float,float> + + template <typename q, typename V> + struct histo3d_hsl : + public mln::accu::internal::base<image3d<unsigned>, histo3d_hsl<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_hsl(); + /// \} + + + /// 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_hsl<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_hsl<V>& histo1, + const histo3d_hsl<V>& histo2); + +#ifndef MLN_INCLUDE_ONLY + + template <typename V> + inline + histo3d_hsl<V>::histo3d_hsl() + { + trace::entering("mln::accu::stat::histo3d_hsl<V>::histo3d_hsl"); + + // As there is no info about preceding color space + // we ask the end user to specify the quantification he's looking for. + + count_.init_(box3d(point3d(mln_min(int_u<q>), + mln_min(int_u<q>), + mln_min(int_u<q>)), + point3d(mln_max(int_u<q>), + mln_max(int_u<q>), + mln_max(int_u<q>)))); + + // Make the hue domain cyclic + fun::p2p::fold<point3d,1,0,0> fold_(count_.domain()); + transform_domain(count_, fold_); + + // Build the interpolate ?? + // cf code igr + + trace::exiting("mln::accu::stat::histo3d_hsl<V>::histo3d_hsl"); + } + + template <typename V> + inline + void histo3d_hsl<V>::init() + { + trace::entering("mln::accu::stat::histo3d_hsl<V>::init"); + + data::fill(count_, 0); + trace::exiting("mln::accu::stat::histo3d_hsl<V>::init"); + } + + template <typename V> + inline + void histo3d_hsl<V>::take(const argument& t) + { + trace::entering("mln::accu::stat::histo3d_hsl<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())); + + + // Technical way to access i° component without kwnowing the name + // mln::trait::value_<argument>::get_comp_0(t); + + ++count_(point3d(t.hue(), t.sat(), t.lum())); + + trace::exiting("mln::accu::stat::histo3d_hsl<V>::take"); + } + + + template <typename V> + inline + void histo3d_hsl<V>::take(const histo3d_hsl<V>& other) + { + trace::entering("mln::accu::stat::histo3d_hsl<V>::take"); + + count_ += other.count_; + + trace::exiting("mln::accu::stat::histo3d_hsl<V>::take"); + } + + template <typename V> + inline + typename histo3d_hsl<V>::result histo3d_hsl<V>::to_result() const + { + trace::entering("mln::accu::stat::histo3d_hsl<V>::to_result"); + + trace::exiting("mln::accu::stat::histo3d_hsl<V>::to_result"); + return count_; + } + + template <typename V> + inline + histo3d_hsl<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_hsl<V>::is_valid() const + { + trace::entering("mln::accu::stat::histo3d_hsl<V>::is_valid"); + bool result = count_.is_valid(); + + trace::exiting("mln::accu::stat::histo3d_hsl<V>::is_valid"); + return result; + } + + template <typename V> + bool operator==(const histo3d_hsl<V>& histo1, + const histo3d_hsl<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/tests/accu/stat/histo3d_hsl/Makefile.am b/trunk/milena/sandbox/green/tests/accu/stat/histo3d_hsl/Makefile.am new file mode 100644 index 0000000..d970989 --- /dev/null +++ b/trunk/milena/sandbox/green/tests/accu/stat/histo3d_hsl/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_hsl/histo3d_hsl.cc b/trunk/milena/sandbox/green/tests/accu/stat/histo3d_hsl/histo3d_hsl.cc new file mode 100644 index 0000000..6d8f0b8 --- /dev/null +++ b/trunk/milena/sandbox/green/tests/accu/stat/histo3d_hsl/histo3d_hsl.cc @@ -0,0 +1,375 @@ +/// TEST HISTO3D_HSL + +#include <mln/img_path.hh> + +#include <mln/io/plot/save_histo_sh.hh> +#include <mln/accu/stat/histo3d_hsl.hh> +#include <mln/fun/v2v/rgb8_to_rgbn.hh> +#include <mln/fun/v2v/rgb_to_hsl.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/hsl.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/literal/zero.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> + +#include <mln/trait/image/print.hh> +#include <mln/trait/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(const 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> conv(const mln::algebra::vec<3,float>& vec) +{ + mln::algebra::vec<3,float> result; + + result[0] = vec[2]; + result[1] = vec[0]; + result[2] = vec[1]; + + return result; +} + +mln::algebra::vec<3,float> mean_histo(const mln::image3d<unsigned>& img) +{ + mln_precondition(img.is_valid()); + typedef mln::algebra::vec<3,float> vec3f; + double count = 0.0; + vec3f sum = mln::literal::zero; + vec3f result; + + mln_piter_(mln::image3d<unsigned>) p(img.domain()); + + for_all(p) + { + count += img(p); + sum += conv((vec3f)p) * img(p); + } + + result = sum / count; + + return result; +} + + +double var_histo(const mln::image3d<unsigned>& img) +{ + mln_precondition(img.is_valid()); + typedef mln::algebra::vec<3,float> vec3f; + typedef mln::algebra::mat<3,3,float> mat3f; + 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; +} + +mln::algebra::mat<3,3,float> var_histo2(const mln::image3d<unsigned>& img) +{ + mln_precondition(img.is_valid()); + typedef mln::algebra::vec<3,float> vec3f; + typedef mln::algebra::mat<3,3,float> mat3f; + + double count = count_histo(img); + vec3f mean = mean_histo(img); + vec3f point; + mat3f result = mln::literal::zero; + mln_piter_(mln::image3d<unsigned>) p(img.domain()); + + for_all(p) + { + point = conv((vec3f)p) - mean; + result += img(p) * (point * point.t()); + } + + result /= count; + + return result; +} + +template <unsigned n> +void test_integration() +{ + 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<vec3f> 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>()); + + 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 mat3f var_res = var_histo2(img_res); + + std::cout << "count_ref : " << count_ref << std::endl; + std::cout << "mean_ref : " << mean_ref << std::endl; + std::cout << "var_ref : " << var_ref << std::endl; + + std::cout << "count_res : " << count_res << std::endl; + std::cout << "mean_res : " << mean_res << std::endl; + std::cout << "var_res : " << var_res << std::endl; + + + mln_assertion(count_ref == count_res); + + mln_assertion(0.0001 > abs(mean_ref[0] - mean_res[0])); + mln_assertion(0.0001 > abs(mean_ref[1] - mean_res[1])); + mln_assertion(0.0001 > abs(mean_ref[2] - mean_res[2])); + + mln_assertion(0.0001 > abs(var_ref(0,0) - var_res(0,0))); + mln_assertion(0.0001 > abs(var_ref(0,1) - var_res(0,1))); + mln_assertion(0.0001 > abs(var_ref(1,0) - var_res(1,0))); + + mln_assertion(0.0001 > abs(var_ref(1,1) - var_res(1,1))); + mln_assertion(0.0001 > abs(var_ref(0,2) - var_res(0,2))); + mln_assertion(0.0001 > abs(var_ref(2,0) - var_res(2,0))); + + + mln_assertion(0.0001 > abs(var_ref(2,2) - var_res(2,2))); + mln_assertion(0.0001 > abs(var_ref(2,1) - var_res(2,1))); + mln_assertion(0.0001 > abs(var_ref(1,2) - var_res(1,2))); + + std::cout << "(" << n << " bits) test integration : ok" << std::endl; +} + +*/ + +void test() +{ + typedef mln::value::rgb8 rgb8; + typedef mln::value::hsl_f hsl_f; + typedef mln::fun::v2v::f_rgb_to_hsl_<hsl_f> rgb_to_hsl_f; + mln::image2d<rgb8> img_fst; + mln::image2d<hsl_f> img_ref; + rgb_to_hsl_f instance; + rgb8 rgb(255,127,0); + hsl_f hsl = instance(rgb); + + std::cout << hsl.hue() << std::endl; + std::cout << hsl.lum() << std::endl; + std::cout << hsl.sat() << std::endl; + + + mln::io::ppm::load(img_fst, OLENA_IMG_PATH"/lena.ppm"); + img_ref = mln::data::transform(img_fst, rgb_to_hsl_f()); + + //mln::accu::stat::histo3d_hsl<hsl_f>(); + +} + +int main() +{ + /* + test_operator_equal<8>(); + test_instantiation_without_argument<8>(); + test_initialization<8>(); + test_take_argument<8>(); + test_take_other<8>(); + test_integration<8>(); + */ + + // p2p/fold+transform_domain for hcv + + test(); + + return 0; +} -- 1.5.6.5
participants (1)
-
Yann Jacquelet