4436: Do some refactoring for best future olena integration.

* green/mln : New dev directory. * green/mln/accu : New directory. * green/mln/accu/stat : New directory. * green/mln/accu/stat/histo1d.hh : New histo1d location. * green/mln/img_path.hh : New image path defines. * green/mln/io : New directory. * green/mln/io/plot : New directory. * green/mln/io/plot/save_histo_sh : New saving func for histo. * green/tests : New unitary test directory. * green/tests/accu : New directory. * green/tests/accu/stat : New directory. * green/tests/accu/stat/histo1d : New histo1d test directory. * green/tests/accu/stat/histo1d/Makefile.am: New makefle. * green/tests/accu/stat/histo1d/histo1d.cc : New unit tests location. * green/tests/accu/stat/histo1d/gaussian.sh: New tools to test filter. --- trunk/milena/sandbox/ChangeLog | 21 + .../milena/sandbox/green/mln/accu/stat/histo1d.hh | 332 ++++++++++ trunk/milena/sandbox/green/mln/img_path.hh | 35 + .../sandbox/green/mln/io/plot/save_histo_sh.hh | 165 +++++ .../green/tests/accu/stat/histo1d/Makefile.am | 148 +++++ .../green/tests/accu/stat/histo1d/gaussian.sh | 12 + .../green/tests/accu/stat/histo1d/histo1d.cc | 677 ++++++++++++++++++++ 7 files changed, 1390 insertions(+), 0 deletions(-) create mode 100644 trunk/milena/sandbox/green/mln/accu/stat/histo1d.hh create mode 100644 trunk/milena/sandbox/green/mln/img_path.hh create mode 100644 trunk/milena/sandbox/green/mln/io/plot/save_histo_sh.hh create mode 100644 trunk/milena/sandbox/green/tests/accu/stat/histo1d/Makefile.am create mode 100755 trunk/milena/sandbox/green/tests/accu/stat/histo1d/gaussian.sh create mode 100644 trunk/milena/sandbox/green/tests/accu/stat/histo1d/histo1d.cc diff --git a/trunk/milena/sandbox/ChangeLog b/trunk/milena/sandbox/ChangeLog index b0d54dd..4e4dd3a 100644 --- a/trunk/milena/sandbox/ChangeLog +++ b/trunk/milena/sandbox/ChangeLog @@ -3,6 +3,27 @@ Do some refactoring for best future olena integration. * green/mln : New dev directory. + * green/mln/accu : New directory. + * green/mln/accu/stat : New directory. + * green/mln/accu/stat/histo1d.hh : New histo1d location. + * green/mln/img_path.hh : New image path defines. + * green/mln/io : New directory. + * green/mln/io/plot : New directory. + * green/mln/io/plot/save_histo_sh : New saving func for histo. + * green/tests : New unitary test directory. + * green/tests/accu : New directory. + * green/tests/accu/stat : New directory. + * green/tests/accu/stat/histo1d : New histo1d test directory. + * green/tests/accu/stat/histo1d/Makefile.am: New makefle. + * green/tests/accu/stat/histo1d/histo1d.cc : New unit tests location. + * green/tests/accu/stat/histo1d/gaussian.sh: New tools to test filter. + + +2009-09-07 Yann Jacquelet <jacquelet@lrde.epita.fr> + + Do some refactoring for best future olena integration. + + * green/mln : New dev directory. * green/mln/clustering : New directory. * green/mln/clustering/k_mean.hh : New k_mean source location. * green/tests : New unitary test directory. diff --git a/trunk/milena/sandbox/green/mln/accu/stat/histo1d.hh b/trunk/milena/sandbox/green/mln/accu/stat/histo1d.hh new file mode 100644 index 0000000..4cd07fa --- /dev/null +++ b/trunk/milena/sandbox/green/mln/accu/stat/histo1d.hh @@ -0,0 +1,332 @@ +// 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_HISTO1D_HH +#define MLN_ACCU_STAT_HISTO1D_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/image1d.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 histo1d; + + } // end of namespace mln::accu::stat + + } // end of namespace mln::accu + + + namespace trait + { + + template <typename V> + struct accumulator_< mln::accu::stat::histo1d<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::histo1d<V>, + accu::stat::histo1d<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 histo1d : + public mln::accu::internal::base<image1d<unsigned>, histo1d<V> > + { + typedef V argument; + typedef image1d<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). + histo1d(); + /// \} + + + /// 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 histo1d<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 histo1d<V>& histo1, const histo1d<V>& histo2); + +#ifndef MLN_INCLUDE_ONLY + + template <typename V> + inline + histo1d<V>::histo1d() + { + trace::entering("mln::accu::stat::histo1d<V>::histo1d"); + typedef mln_trait_value_comp(V,0) comp; + typedef point<grid::tick, V> v_point1d; + typedef box<v_point1d> v_box1d; + + // 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] ... + + // std::cout << "min : " << mln_min(comp) << std::endl; + // std::cout << "max : " << mln_max(comp) << std::endl; + + // std::cout << "min : " << v_point1d(mln_min(comp)) << std::endl; + // std::cout << "max : " << v_point1d(mln_max(comp)) << std::endl; + + //count_.init_(v_box1d(v_point1d(mln_min(comp)), + // v_point1d(mln_max(comp)))); + // this does not work as image1d is friendly close to box1d + + count_.init_(box1d(point1d(mln_min(comp)), + point1d(mln_max(comp)))); + + trace::exiting("mln::accu::stat::histo1d<V>::histo1d"); + } + + template <typename V> + inline + void histo1d<V>::init() + { + trace::entering("mln::accu::stat::histo1d<V>::init"); + + data::fill(count_, 0); + trace::exiting("mln::accu::stat::histo1d<V>::init"); + } + + template <typename V> + inline + void histo1d<V>::take(const argument& t) + { + trace::entering("mln::accu::stat::histo1d<V>::take"); + + // Just convert a greyscale value (int_u8 like) to a position for an + // iterator on the resulting image. + ++count_(point1d(t)); + + trace::exiting("mln::accu::stat::histo1d<V>::take"); + } + + + template <typename V> + inline + void histo1d<V>::take(const histo1d<V>& other) + { + trace::entering("mln::accu::stat::histo1d<V>::take"); + + count_ += other.count_; + + trace::exiting("mln::accu::stat::histo1d<V>::take"); + } + + template <typename V> + inline + typename histo1d<V>::result histo1d<V>::to_result() const + { + trace::entering("mln::accu::stat::histo1d<V>::to_result"); + + trace::exiting("mln::accu::stat::histo1d<V>::to_result"); + return count_; + } + + template <typename V> + inline + histo1d<V>::operator result() const + { + trace::entering("mln::accu::stat::histo1d<V>::operator result"); + + trace::exiting("mln::accu::stat::histo1d<V>::operator result"); + return count_; + } + + template <typename V> + inline + bool histo1d<V>::is_valid() const + { + trace::entering("mln::accu::stat::histo1d<V>::is_valid"); + bool result = count_.is_valid(); + + trace::exiting("mln::accu::stat::histo1d<V>::is_valid"); + return result; + } + + template <typename V> + bool operator==(const histo1d<V>& histo1, const histo1d<V>& histo2) + { + trace::entering("mln::accu::stat::operator=="); + + bool result = true; + const image1d<unsigned>& res1 = histo1.to_result(); + const image1d<unsigned>& res2 = histo2.to_result(); + + mln_precondition(res1.is_valid()); + mln_precondition(res2.is_valid()); + + mln_piter(image1d<unsigned>) p1(res1.domain()); + mln_piter(image1d<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_HISTO1D_HH diff --git a/trunk/milena/sandbox/green/mln/img_path.hh b/trunk/milena/sandbox/green/mln/img_path.hh new file mode 100644 index 0000000..707fe7e --- /dev/null +++ b/trunk/milena/sandbox/green/mln/img_path.hh @@ -0,0 +1,35 @@ +// 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_IMG_PATH_HH +#define MLN_IMG_PATH_HH + +#define IMG_PATH "/home/green/svn/oln/trunk/milena/sandbox/green/img" +#define OLENA_IMG_PATH IMG_PATH"/olena" +#define SCRIBO_IMG_PATH IMG_PATH"/scribo/pgm_50p" + +#endif // ! MLN_IMG_PATH_HH diff --git a/trunk/milena/sandbox/green/mln/io/plot/save_histo_sh.hh b/trunk/milena/sandbox/green/mln/io/plot/save_histo_sh.hh new file mode 100644 index 0000000..6bf1fbf --- /dev/null +++ b/trunk/milena/sandbox/green/mln/io/plot/save_histo_sh.hh @@ -0,0 +1,165 @@ +// 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_IO_PLOT_SAVE_HISTO_SH_HH +#define MLN_IO_PLOT_SAVE_HISTO_SH_HH + +/// \file +/// +/// \brief Define some functions to export to gnuplot format as a script shell. +/// +/// Theses routines help to visualize histogram data. +/// + +#include <fstream> +#include <string> + +#include <mln/core/macros.hh> +#include <mln/core/image/image1d.hh> +#include <mln/core/image/image2d.hh> +#include <mln/core/image/image3d.hh> + + +namespace mln +{ + + namespace io + { + + namespace plot + { + + /// \brief Save an histogram image1d as a gnuplot script shell. + /// \param[in] img the 1d image which contains the data to save. + /// \param[in] filename the name of the unix script shell. + /// + /// Such image is obtained from the greylevel image histogram. + + template <typename I> + void save_histo_sh(const image1d<I>& img, const std::string& filename); + + /// \brief Save an histogram image3d as a gnuplot script shell. + /// \param[in] img the 3d image which contains the data to save. + /// \param[in] filename the name of the unix script shell. + /// + /// Such image is obtained from the RGB image histogram. + template <typename I> + void save_histo_sh(const image3d<I>& img, const std::string& filename); + + } // end of namespace mln::accu::stat + + } // end of namespace mln::accu + + + namespace io + { + + namespace plot + { + +#ifndef MLN_INCLUDE_ONLY + + template <typename I> + inline + void save_histo_sh(const image1d<I>& img, const std::string& filename) + { + trace::entering("mln::io::plot::save_histo_sh<1d>"); + mln_precondition(img.is_valid()); + + std::ofstream out(filename.c_str()); + mln_piter(image1d<I>) p(img.domain()); + + out << "#!/bin/sh" << std::endl; + out << "##########################" << std::endl; + out << "# Two columns = (x,data) #" << std::endl; + out << "##########################" << std::endl; + out << std::endl; + out << "gnuplot <<EOF" << std::endl; + out << "set terminal x11 persist 1" << std::endl; + out << "plot '-' with points pointtype 20" << std::endl; + //out << "plot '-' with points pointtype 0" << std::endl; + //out << "plot '-' with histograms" << std::endl; + //out << "plot '-' smooth unique" << std::endl; + + for_all(p) + { + // for (unsigned i = 0; i < mln_dim(I); ++i) + out << p[0] << " "; + + out << img(p) << std::endl; + } + out << "e" << std::endl; + out << "EOF" << std::endl; + + out.close(); + trace::exiting("mln::io::plot::save_histo_sh<1d>"); + } + + template <typename I> + inline + void save_histo_sh(const image3d<I>& img, const std::string& filename) + { + trace::entering("mln::io::plot::save_histo_sh<3d>") + mln_precondition(img.is_valid()); + + std::ofstream out(filename.c_str()); + mln_piter(I) p(img.domain()); + + out << "#!/bin/sh" << std::endl; + out << "####################################" << std::endl; + out << "# Columns = (red,green,blue,count) #" << std::endl; + out << "####################################" << std::endl; + out << std::endl; + out << "gnuplot <<EOF" << std::endl; + out << "set terminal x11 persist 1" << std::endl; + out << "splot '-' with points palette pointtype 0" << std::endl; + + for_all(p) + if (0 < img(p)) + { + out << p.row() << " "; + out << p.col() << " "; + out << p.sli() << " "; + out << img(p) << std::endl; + } + out << "e" << std::endl; + out << "EOF" << std::endl; + + out.close(); + trace::exiting("mln::io::plot::save_histo_sh<3d>"); + } + +#endif // ! MLN_INCLUDE_ONLY + + + } // end of namespace mln::accu::stat + + } // end of namespace mln::accu + +} // end of namespace mln + +#endif // ! MLN_IO_PLOT_SAVE_HISTO_SH_HH diff --git a/trunk/milena/sandbox/green/tests/accu/stat/histo1d/Makefile.am b/trunk/milena/sandbox/green/tests/accu/stat/histo1d/Makefile.am new file mode 100644 index 0000000..d970989 --- /dev/null +++ b/trunk/milena/sandbox/green/tests/accu/stat/histo1d/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/histo1d/gaussian.sh b/trunk/milena/sandbox/green/tests/accu/stat/histo1d/gaussian.sh new file mode 100755 index 0000000..4d2164a --- /dev/null +++ b/trunk/milena/sandbox/green/tests/accu/stat/histo1d/gaussian.sh @@ -0,0 +1,12 @@ +#!/bin/sh + +############ +# gaussian # +############ + +gnuplot <<EOF +set terminal x11 persist 1 +square(x)=x*x +gaussian(x,mean,sigma)=exp(-0.5*square((x-mean)/sigma))/(sigma*sqrt(2*pi)) +plot [-20:20] gaussian(x,0,6) +EOF diff --git a/trunk/milena/sandbox/green/tests/accu/stat/histo1d/histo1d.cc b/trunk/milena/sandbox/green/tests/accu/stat/histo1d/histo1d.cc new file mode 100644 index 0000000..020c125 --- /dev/null +++ b/trunk/milena/sandbox/green/tests/accu/stat/histo1d/histo1d.cc @@ -0,0 +1,677 @@ +/// TEST HISTO1D + +#include <mln/img_path.hh> + +#include <mln/io/plot/save_histo_sh.hh> +#include <mln/accu/stat/histo1d.hh> + +#include <mln/io/pgm/load.hh> +#include <mln/io/pgm/save.hh> +#include <mln/io/ppm/save.hh> +#include <mln/io/plot/save.hh> + +#include <mln/data/compute.hh> +#include <mln/data/fill.hh> + +#include <mln/value/int_u8.hh> +#include <mln/value/int_u16.hh> +#include <mln/value/label_8.hh> +#include <mln/value/rgb8.hh> + +#include <mln/core/alias/neighb1d.hh> +#include <mln/core/alias/box1d.hh> +#include <mln/core/alias/point1d.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/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_window1d.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> + +//------------------------------------------------------------------------------ +// TEST IN 8 BITS +//------------------------------------------------------------------------------ + + +void test_8bits_operator_equal() +{ + using namespace mln::accu::stat; + + typedef mln::value::int_u8 int_u8; + mln::accu::stat::histo1d<int_u8> histo1; + mln::accu::stat::histo1d<int_u8> histo2; + int_u8 val = 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 << "(08 bits) histo == histo : ok" << std::endl; +} + +void test_8bits_instantiation_without_argument() +{ + typedef mln::value::int_u8 int_u8; + const mln::accu::stat::histo1d<int_u8> histo; + const mln::image1d<unsigned>& res = histo.to_result(); + const mln::point1d& min = mln::point1d(mln_min(int_u8)); + const mln::point1d& max = mln::point1d(mln_max(int_u8)); + const mln::box1d& ref = mln::box1d(min, max); + + mln_assertion(ref == res.domain()); + mln_assertion(res.is_valid()); + + std::cout << "(08 bits) histo<T> histo : ok" << std::endl; +} + + +void test_8bits_initialization() +{ + typedef mln::value::int_u8 int_u8; + mln::accu::stat::histo1d<int_u8> histo; + mln::image1d<unsigned> img_res = histo.to_result(); + mln::image1d<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_u8>(), img_res); + unsigned ref = mln::data::compute(mln::accu::math::sum<int_u8>(), img_ref); + + mln_assertion(ref == res); + + std::cout << "(08 bits) histo.init() : ok" << std::endl; +} + + +void test_8bits_take_argument() +{ + typedef mln::value::int_u8 int_u8; + mln::accu::stat::histo1d<int_u8> histo1; + mln::accu::stat::histo1d<int_u8> histo2; + int_u8 val = 3; + + histo1.init(); + histo2.init(); + histo1.take(val); + + const mln::image1d<unsigned> img1 = histo1.to_result(); + const mln::image1d<unsigned> img2 = histo2.to_result(); + + const unsigned res = mln::data::compute(mln::accu::math::sum<int_u8>(), img1); + const unsigned ref = mln::data::compute(mln::accu::math::sum<int_u8>(), img2); + + mln_assertion(ref == res-1); + mln_assertion(1 == img1(mln::point1d(val))); + + std::cout << "(08 bits) histo.take(argument) : ok" << std::endl; +} + + +void test_8bits_take_other() +{ + typedef mln::value::int_u8 int_u8; + mln::accu::stat::histo1d<int_u8> histo1; + mln::accu::stat::histo1d<int_u8> histo2; + mln::accu::stat::histo1d<int_u8> histo3; + int_u8 val = 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 << "(08 bits) histo.take(other) : ok" << std::endl; +} + +double count_histo(mln::image1d<unsigned> img) +{ + mln_precondition(img.is_valid()); + + double result = 0.0; + mln_piter_(mln::image1d<unsigned>) p(img.domain()); + + for_all(p) + result += img(p); + + return result; +} + +double mean_histo(mln::image1d<unsigned> img) +{ + mln_precondition(img.is_valid()); + + double count = 0.0; + double sum = 0.0; + double result = 0.0; + mln_piter_(mln::image1d<unsigned>) p(img.domain()); + + for_all(p) + { + count += img(p); + sum += p[0] * img(p); + } + + result = sum / count; + + return result; +} + + +double var_histo(mln::image1d<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::image1d<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; +} + +void test_8bits_integration() +{ + typedef mln::value::int_u8 int_u8; + typedef mln::accu::math::count<double> count; + typedef mln::accu::math::sum<double> sum; + typedef mln::accu::stat::mean<double> mean; + typedef mln::accu::stat::variance<double> variance; + + mln::image2d<int_u8> img_ref; + mln::image1d<unsigned> img_res; + + mln::io::pgm::load(img_ref, OLENA_IMG_PATH"/lena.pgm"); + + const double count_ref = mln::data::compute(count(), img_ref); + const double mean_ref = mln::data::compute(mean(), img_ref); + const double var_ref = mln::data::compute(variance(), img_ref); + + img_res = mln::data::compute(mln::accu::stat::histo1d<int_u8>(), img_ref); + + const double count_res = count_histo(img_res); + const double 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 << "(08 bits) test integration : ok" << std::endl; +} + +double gaussian_distribution(double x, double mean, double sigma) +{ + double num = exp(-0.5*mln::math::sqr((x - mean)/sigma)); + double denom = sigma*mln::math::sqrt(2*mln::math::pi); + double result = num/denom; + + return result; +} + +/// To calibrate with gnuplot (see gaussian.sh) +/// square(x) = x*x +/// gaussian(x,mean,sigma)=exp(-0.5*square((x-mean)/sigma))/(sigma*sqrt(2*pi)) +/// plot [-20:20] gaussian(x,0,6.0) + +void gaussian_filter(double ws[], unsigned size, double sigma) +{ + int h = size/2; + + for (int i = -h; i <= h; ++i) + { + ws[i+h] = gaussian_distribution(i, 0.0, sigma); + } + + double sum = 0.0; + + for (unsigned i = 0; i < size; ++i) + sum += ws[i]; + + for (unsigned i = 0; i < size; ++i) + ws[i] /= sum; +} + +/// The aim of this function is to rebuild an label image2d from the segmenting +/// image of the histogram (label) and the original image (input). +/// label_image2d / for each grey tone, associate its label. + +mln::image2d<mln::value::label_8> +build_8bits(const mln::image2d<mln::value::int_u8>& input, + const mln::image1d<mln::value::label_8>& label) +{ + mln::trace::entering("build_8bits"); + mln_precondition(label.is_valid()); + mln_precondition(input.is_valid()); + + mln::image2d<mln::value::label_8> output; + + mln::initialize(output, input); + + mln_piter_(mln::image2d<mln::value::int_u8>) pi(input.domain()); + mln_piter_(mln::image2d<mln::value::label_8>) po(output.domain()); + + for_all_2(pi, po) + { + mln::value::int_u8 val = input(pi); + unsigned grp = label(mln::point1d(val)); + + output(po) = grp; + } + + mln::trace::exiting("build_8bits"); + return output; +} + + +void test_8bits_classifying() +{ + typedef mln::value::int_u8 int_u8; + typedef mln::value::label_8 label_8; + typedef mln::value::rgb8 rgb8; + typedef mln::accu::stat::mean<double> mean; + + mln::image2d<int_u8> img_ref; + mln::image2d<int_u8> img_out; + mln::image2d<rgb8> img_rgb; + mln::image1d<unsigned> img_res; + mln::image1d<double> img_smooth; + mln::image1d<label_8> labels; + label_8 nlabels; + + //----------------------------------------------------- + // Loading the scribo image and computing its histogram + //----------------------------------------------------- + + std::cout << "(08 bits) LOADING HISTOGRAM" << std::endl; + + // mln::io::pgm::load(img_ref, OLENA_IMG_PATH"/lena.pgm"); + mln::io::pgm::load(img_ref, SCRIBO_IMG_PATH"/mp00082c_50p_8bits.pgm"); + img_res = mln::data::compute(mln::accu::stat::histo1d<int_u8>(), img_ref); + mln::io::plot::save_histo_sh(img_res, "histo0_8bits.sh"); + + + //----------------------------------------------------- + // Smoothing the histogram with a gaussian filter + //----------------------------------------------------- + + std::cout << "(08 bits) SMOOTHING HISTOGRAM" << std::endl; + + double ws[41]; + gaussian_filter(ws, 41, 6.0); + img_smooth = mln::linear::convolve(img_res, mln::make::w_window1d(ws)); + mln::io::plot::save_histo_sh(img_smooth, "histo1_8bits.sh"); + + + //----------------------------------------------------- + // Segmenting the histogram with the watershed method + //----------------------------------------------------- + + std::cout << "SEGMENTING HISTOGRAM" << std::endl; + + /* + labels = mln::labeling::regional_maxima(img_smooth, mln::c2(), nlabels); + std::cout << "N labels : " << nlabels << std::endl; + mln::io::plot::save_histo_sh(labels, "histo2_8bits.sh"); + */ + + + labels = mln::morpho::watershed::flooding(img_smooth, mln::c2(), nlabels); + std::cout << "N labels : " << nlabels << std::endl; + mln::io::plot::save_histo_sh(labels, "histo2_8bits.sh"); + + + //----------------------------------------------------- + // Rebuilding the image with the mean of each region + //----------------------------------------------------- + + std::cout << "(08 bits) BUILDING OUTPUT" << std::endl; + + mln::image2d<label_8>img_label = build_8bits(img_ref, labels); + + std::cout << "(08 bits) COLORING OUTPUT" << std::endl; + + img_out = mln::labeling::mean_values(img_ref, img_label, nlabels); + img_rgb = mln::labeling::colorize(rgb8(), img_label); + + mln::io::pgm::save(img_out, "out_8bits.pgm"); + mln::io::ppm::save(img_rgb, "color_8bits.pgm"); + + //labels = mln::morpho::elementary::dilation(labels, mln::c2()); + //mln::io::plot::save_histo_sh(labels, "histo3.sh"); + //mln::io::plot::save(labels, "labelized.data"); +} + +//------------------------------------------------------------------------------ +// TEST IN 16 BITS +//------------------------------------------------------------------------------ + +void test_16bits_operator_equal() +{ + using namespace mln::accu::stat; + + typedef mln::value::int_u16 int_u16; + mln::accu::stat::histo1d<int_u16> histo1; + mln::accu::stat::histo1d<int_u16> histo2; + int_u16 val = 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 << "(16 bits) histo == histo : ok" << std::endl; +} + +void test_16bits_instantiation_without_argument() +{ + mln::trace::quiet = false; + + typedef mln::value::int_u16 int_u16; + typedef mln::point<mln::grid::tick, int_u16> point1d; + typedef mln::box<point1d> box1d; + const mln::accu::stat::histo1d<int_u16> histo; + const mln::image1d<unsigned>& res = histo.to_result(); + const point1d& min = point1d(mln_min(int_u16)); + const point1d& max = point1d(mln_max(int_u16)); + const box1d& ref = box1d(min, max); + + mln_assertion(ref == res.domain()); + mln_assertion(res.is_valid()); + + std::cout << "(16 bits) histo<T> histo : ok" << std::endl; +} + + +void test_16bits_initialization() +{ + typedef mln::value::int_u16 int_u16; + mln::accu::stat::histo1d<int_u16> histo; + mln::image1d<unsigned> img_res = histo.to_result(); + mln::image1d<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_u16>(), img_res); + unsigned ref = mln::data::compute(mln::accu::math::sum<int_u16>(), img_ref); + + mln_assertion(ref == res); + + std::cout << "(16 bits) histo.init() : ok" << std::endl; +} + + +void test_16bits_take_argument() +{ + typedef mln::value::int_u16 int_u16; + mln::accu::stat::histo1d<int_u16> histo1; + mln::accu::stat::histo1d<int_u16> histo2; + int_u16 val = 3; + + histo1.init(); + histo2.init(); + histo1.take(val); + + const mln::image1d<unsigned> img1 = histo1.to_result(); + const mln::image1d<unsigned> img2 = histo2.to_result(); + + const unsigned res = mln::data::compute(mln::accu::math::sum<int_u16>(),img1); + const unsigned ref = mln::data::compute(mln::accu::math::sum<int_u16>(),img2); + + mln_assertion(ref == res-1); + mln_assertion(1 == img1(mln::point1d(val))); + + std::cout << "(16 bits) histo.take(argument) : ok" << std::endl; +} + + +void test_16bits_take_other() +{ + typedef mln::value::int_u16 int_u16; + mln::accu::stat::histo1d<int_u16> histo1; + mln::accu::stat::histo1d<int_u16> histo2; + mln::accu::stat::histo1d<int_u16> histo3; + int_u16 val = 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 << "(16 bits) histo.take(other) : ok" << std::endl; +} + +void test_16bits_integration() +{ + typedef mln::value::int_u16 int_u16; + typedef mln::accu::math::count<double> count; + typedef mln::accu::math::sum<double> sum; + typedef mln::accu::stat::mean<double> mean; + typedef mln::accu::stat::variance<double> variance; + + mln::image2d<int_u16> img_ref; + mln::image1d<unsigned> img_res; + + mln::io::pgm::load(img_ref, OLENA_IMG_PATH"/lena_16.pgm"); + + const double count_ref = mln::data::compute(count(), img_ref); + const double mean_ref = mln::data::compute(mean(), img_ref); + const double var_ref = mln::data::compute(variance(), img_ref); + + img_res = mln::data::compute(mln::accu::stat::histo1d<int_u16>(), img_ref); + + const double count_res = count_histo(img_res); + const double 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 << "(16 bits) test integration : ok" << std::endl; +} + +/// The aim of this function is to rebuild an label image2d from the segmenting +/// image of the histogram (label) and the original image (input). +/// label_image2d / for each grey tone, associate its label. + +mln::image2d<mln::value::label_8> +build_16bits(const mln::image2d<mln::value::int_u16>& input, + const mln::image1d<mln::value::label_8>& label) +{ + mln::trace::entering("build_16bits"); + mln_precondition(label.is_valid()); + mln_precondition(input.is_valid()); + + mln::image2d<mln::value::label_8> output; + + mln::initialize(output, input); + + mln_piter_(mln::image2d<mln::value::int_u16>) pi(input.domain()); + mln_piter_(mln::image2d<mln::value::label_8>) po(output.domain()); + + for_all_2(pi, po) + { + mln::value::int_u16 val = input(pi); + unsigned grp = label(mln::point1d(val)); + + output(po) = grp; + } + + mln::trace::exiting("build_16bits"); + return output; +} + + +void test_16bits_classifying() +{ + typedef mln::value::int_u16 int_u16; + typedef mln::value::label_8 label_8; + typedef mln::value::rgb8 rgb8; + typedef mln::accu::stat::mean<double> mean; + + mln::image2d<int_u16> img_ref; + mln::image2d<int_u16> img_out; + mln::image2d<rgb8> img_rgb; + mln::image1d<unsigned> img_res; + mln::image1d<double> img_smooth; + mln::image1d<label_8> labels; + label_8 nlabels; + + //----------------------------------------------------- + // Loading the scribo image and computing its histogram + //----------------------------------------------------- + + std::cout << "(16 bits) LOADING HISTOGRAM" << std::endl; + + // mln::io::pgm::load(img_ref, OLENA_IMG_PATH"/lena.pgm"); + mln::io::pgm::load(img_ref, SCRIBO_IMG_PATH"/mp00082c_50p_16bits.pgm"); + img_res = mln::data::compute(mln::accu::stat::histo1d<int_u16>(), img_ref); + mln::io::plot::save_histo_sh(img_res, "histo0_16bits.sh"); + + + //----------------------------------------------------- + // Smoothing the histogram with a gaussian filter + //----------------------------------------------------- + + std::cout << "(16 bits) SMOOTHING HISTOGRAM" << std::endl; + + double ws[41]; + gaussian_filter(ws, 41, 6.0); + img_smooth = mln::linear::convolve(img_res, mln::make::w_window1d(ws)); + mln::io::plot::save_histo_sh(img_smooth, "histo1_16bits.sh"); + + + //----------------------------------------------------- + // Segmenting the histogram with the watershed method + //----------------------------------------------------- + + std::cout << "(16 bits) SEGMENTING HISTOGRAM" << std::endl; + + /* + labels = mln::labeling::regional_maxima(img_smooth, mln::c2(), nlabels); + std::cout << "N labels : " << nlabels << std::endl; + mln::io::plot::save_histo_sh(labels, "histo2.sh"); + */ + + + labels = mln::morpho::watershed::flooding(img_smooth, mln::c2(), nlabels); + std::cout << "N labels : " << nlabels << std::endl; + mln::io::plot::save_histo_sh(labels, "histo2_16bits.sh"); + + + //----------------------------------------------------- + // Rebuilding the image with the mean of each region + //----------------------------------------------------- + + std::cout << "(16 bits) BUILDING OUTPUT" << std::endl; + + mln::image2d<label_8>img_label = build_16bits(img_ref, labels); + + std::cout << "(16 bits) COLORING OUTPUT" << std::endl; + + img_out = mln::labeling::mean_values(img_ref, img_label, nlabels); + img_rgb = mln::labeling::colorize(rgb8(), img_label); + + mln::io::pgm::save(img_out, "out_16bits.pgm"); + mln::io::ppm::save(img_rgb, "color_16bits.pgm"); + + //labels = mln::morpho::elementary::dilation(labels, mln::c2()); + //mln::io::plot::save_histo_sh(labels, "histo3.sh"); + //mln::io::plot::save(labels, "labelized.data"); +} + +int main() +{ + test_8bits_instantiation_without_argument(); + test_8bits_initialization(); + test_8bits_take_argument(); + test_8bits_take_other(); + test_8bits_operator_equal(); + test_8bits_integration(); + + //test_8bits_classifying(); + + // PROBLEME AVEC LES COORDONNEES PAR DEFAUT QUI SONT EN SIGNED SHORT + // SEE mln/core/def/coord.hh + + /* + test_16bits_instantiation_without_argument(); + test_16bits_initialization(); + test_16bits_take_argument(); + test_16bits_take_other(); + test_16bits_operator_equal(); + test_16bits_integration(); + + //test_16bits_classifying(); + */ + return 0; +} -- 1.5.6.5
participants (1)
-
Yann Jacquelet