LRE
Sign In
Sign Up
Sign In
Sign Up
Manage this list
×
Keyboard Shortcuts
Thread View
j
: Next unread message
k
: Previous unread message
j a
: Jump to all threads
j l
: Jump to MailingList overview
2025
January
2024
December
November
October
September
August
July
June
May
April
March
February
January
2023
December
November
October
September
August
July
June
May
April
March
February
January
2022
December
November
October
September
August
July
June
May
April
March
February
January
2021
December
November
October
September
August
July
June
May
April
March
February
January
2020
December
November
October
September
August
July
June
May
April
March
February
January
2019
December
November
October
September
August
July
June
May
April
March
February
January
2018
December
November
October
September
August
July
June
May
April
March
February
January
2017
December
November
October
September
August
July
June
May
April
March
February
January
2016
December
November
October
September
August
July
June
May
April
March
February
January
2015
December
November
October
September
August
July
June
May
April
March
February
January
2014
December
November
October
September
August
July
June
May
April
March
February
January
2013
December
November
October
September
August
July
June
May
April
March
February
January
2012
December
November
October
September
August
July
June
May
April
March
February
January
2011
December
November
October
September
August
July
June
May
April
March
February
January
2010
December
November
October
September
August
July
June
May
April
March
February
January
2009
December
November
October
September
August
July
June
May
April
March
February
January
2008
December
November
October
September
August
July
June
May
April
March
February
January
2007
December
November
October
September
August
July
June
May
April
March
February
January
2006
December
November
October
September
August
July
June
May
April
March
February
January
2005
December
November
October
September
August
July
June
May
April
March
February
January
2004
December
November
October
September
August
July
June
May
April
March
List overview
Download
Olena-patches
----- 2025 -----
January 2025
----- 2024 -----
December 2024
November 2024
October 2024
September 2024
August 2024
July 2024
June 2024
May 2024
April 2024
March 2024
February 2024
January 2024
----- 2023 -----
December 2023
November 2023
October 2023
September 2023
August 2023
July 2023
June 2023
May 2023
April 2023
March 2023
February 2023
January 2023
----- 2022 -----
December 2022
November 2022
October 2022
September 2022
August 2022
July 2022
June 2022
May 2022
April 2022
March 2022
February 2022
January 2022
----- 2021 -----
December 2021
November 2021
October 2021
September 2021
August 2021
July 2021
June 2021
May 2021
April 2021
March 2021
February 2021
January 2021
----- 2020 -----
December 2020
November 2020
October 2020
September 2020
August 2020
July 2020
June 2020
May 2020
April 2020
March 2020
February 2020
January 2020
----- 2019 -----
December 2019
November 2019
October 2019
September 2019
August 2019
July 2019
June 2019
May 2019
April 2019
March 2019
February 2019
January 2019
----- 2018 -----
December 2018
November 2018
October 2018
September 2018
August 2018
July 2018
June 2018
May 2018
April 2018
March 2018
February 2018
January 2018
----- 2017 -----
December 2017
November 2017
October 2017
September 2017
August 2017
July 2017
June 2017
May 2017
April 2017
March 2017
February 2017
January 2017
----- 2016 -----
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
June 2016
May 2016
April 2016
March 2016
February 2016
January 2016
----- 2015 -----
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
----- 2014 -----
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
----- 2013 -----
December 2013
November 2013
October 2013
September 2013
August 2013
July 2013
June 2013
May 2013
April 2013
March 2013
February 2013
January 2013
----- 2012 -----
December 2012
November 2012
October 2012
September 2012
August 2012
July 2012
June 2012
May 2012
April 2012
March 2012
February 2012
January 2012
----- 2011 -----
December 2011
November 2011
October 2011
September 2011
August 2011
July 2011
June 2011
May 2011
April 2011
March 2011
February 2011
January 2011
----- 2010 -----
December 2010
November 2010
October 2010
September 2010
August 2010
July 2010
June 2010
May 2010
April 2010
March 2010
February 2010
January 2010
----- 2009 -----
December 2009
November 2009
October 2009
September 2009
August 2009
July 2009
June 2009
May 2009
April 2009
March 2009
February 2009
January 2009
----- 2008 -----
December 2008
November 2008
October 2008
September 2008
August 2008
July 2008
June 2008
May 2008
April 2008
March 2008
February 2008
January 2008
----- 2007 -----
December 2007
November 2007
October 2007
September 2007
August 2007
July 2007
June 2007
May 2007
April 2007
March 2007
February 2007
January 2007
----- 2006 -----
December 2006
November 2006
October 2006
September 2006
August 2006
July 2006
June 2006
May 2006
April 2006
March 2006
February 2006
January 2006
----- 2005 -----
December 2005
November 2005
October 2005
September 2005
August 2005
July 2005
June 2005
May 2005
April 2005
March 2005
February 2005
January 2005
----- 2004 -----
December 2004
November 2004
October 2004
September 2004
August 2004
July 2004
June 2004
May 2004
April 2004
March 2004
olena-patches@lrde.epita.fr
9625 discussions
Start a n
N
ew thread
last-svn-commit-43-g7e1539b Define gnuplot shell export format.
by Yann Jacquelet
* mln/io/plot/save_image_sh.hh: New header file. Give an example of code. * use/io/plot/save_image_sh: New directory. * use/io/plot/save_image_sh/Makefile.am: New makefile. * use/io/plot/save_image_sh/save_image_sh.cc: New source file. Make some unitary tests on gnuplot shell export. * tests/io/plot/save_image_sh: New directory. * tests/io/plot/save_image_sh/Makefile.am: New makefile. * tests/io/plot/save_image_sh/save_image_sh.cc: New source file. --- scribo/sandbox/green/ChangeLog | 109 +++++---- scribo/sandbox/green/README | 52 ++--- scribo/sandbox/green/mln/io/plot/save_image_sh.hh | 36 +++- .../green/tests/io/plot/save_image_sh/Makefile.am | 13 +- .../tests/io/plot/save_image_sh/save_image_sh.cc | 284 ++++++++++++++------ .../histo1d => io/plot/save_image_sh}/Makefile.am | 0 .../plot/save_image_sh/save_image_sh.cc} | 4 +- 7 files changed, 329 insertions(+), 169 deletions(-) copy scribo/sandbox/green/use/{accu/stat/histo1d => io/plot/save_image_sh}/Makefile.am (100%) copy scribo/sandbox/green/use/{accu/stat/histo1d/histo1d.cc => io/plot/save_image_sh/save_image_sh.cc} (91%) diff --git a/scribo/sandbox/green/ChangeLog b/scribo/sandbox/green/ChangeLog index db589a1..5a7ceaa 100644 --- a/scribo/sandbox/green/ChangeLog +++ b/scribo/sandbox/green/ChangeLog @@ -1,54 +1,20 @@ -2010-06-24 Yann Jacquelet <jacquelet(a)lrde.epita.fr> +2010-06-23 green <jacquelet(a)lrde.epita.fr> - Import files from milena/sandbox/green. + Define gnuplot shell export format. - * gaussian.sh: New gnuplot shell file. - * guassian2d.sh: New gnuplot shell file. - * test_labelling.cc: New source. - * tests/clustering/k_mean/Makefile.am: New makefile. - * tests/clustering/k_mean/k_mean.cc: New source. - * tests/clustering/kmean1d/Makefile.am: New makefile. - * tests/clustering/kmean1d/kmean1d.cc: New source. - * tests/io/plot/save_image_sh/Makefile.am: New makefile. - * tests/io/plot/save_image_sh/save_image_sh.cc: New source. + * mln/io/plot/save_image_sh.hh: New header file. -2010-06-24 Yann Jacquelet <jacquelet(a)lrde.epita.fr> + Give an example of code. - Import files from milena/sandbox/green. + * use/io/plot/save_image_sh: New directory. + * use/io/plot/save_image_sh/Makefile.am: New makefile. + * use/io/plot/save_image_sh/save_image_sh.cc: New source file. - * mln/accu/stat/histo1d.hh: New header file. - * mln/accu/stat/histo2d.hh: New header file. - * mln/accu/stat/histo3d_hsl.hh: New header file. - * mln/accu/stat/histo3d_rgb.hh: New header file. - * mln/clustering/k_mean.hh: New header file. - * mln/clustering/kmean1d.hh: New header file. - * mln/clustering/kmean2d.hh: New header file. - * mln/clustering/kmean3d.hh: New header file. - * mln/clustering/kmean_rgb.hh: New header file. - * mln/display/display_histo.hh: New header file. - * mln/display/project_histo.hh: New header file. - * mln/fun/p2b/achromatic.hh: New header file. - * mln/fun/p2b/component_equals.hh: New header file. - * mln/fun/v2v/achromatism.hh: New header file. - * mln/fun/v2v/hue_concentration.hh: New header file. - * mln/fun/v2v/int_u16_to_int_u14.hh: New header file. - * mln/fun/v2v/int_u16_to_int_u14.hh: New header file. - * mln/fun/v2v/log.hh: New header file. - * mln/fun/v2v/rg_to_rgb.hh: New header file. - * mln/fun/v2v/rgb8_to_int_u8: New header file. - * mln/fun/v2v/rgb_to_achromastism_map.hh: New header file. - * mln/fun/v2v/rgb_to_hsv.hh: New header file. - * mln/fun/v2v/rgb_to_hue_map.hh: New header file. - * mln/fun/v2v/rgb_to_saturation_map.hh: New header file. - * mln/fun/v2v/rgb_to_value_map.hh: New header file. - * mln/img_path.hh: New header file. - * mln/io/plot/save_image_sh.hh: New header file. - * mln/math/cell.hh: New header file. - * mln/math/floor.hh: New header file. - * tests/accu/stat/histo1d/Makefile.am: New makefile. - * tests/accu/stat/histo1d/histo1d.cc: New source. - * tests/accu/stat/histo2d/Makefile.am: New makefile. - * tests/accu/stat/histo2d/histo2d.cc: New source. + Make some unitary tests on gnuplot shell export. + + * tests/io/plot/save_image_sh: New directory. + * tests/io/plot/save_image_sh/Makefile.am: New makefile. + * tests/io/plot/save_image_sh/save_image_sh.cc: New source file. 2010-06-21 Yann Jacquelet <jacquelet(a)lrde.epita.fr> @@ -130,6 +96,57 @@ * tests/accu/stat/histo3d_hsl/Makefile.am: New makefile. * tests/accu/stat/histo3d_hsl/histo3d_hsl.cc: New source. +2010-06-21 Yann Jacquelet <jacquelet(a)lrde.epita.fr> + + Import files from milena/sandbox/green. + + * gaussian.sh: New gnuplot shell file. + * guassian2d.sh: New gnuplot shell file. + * test_labelling.cc: New source. + * tests/clustering/k_mean/Makefile.am: New makefile. + * tests/clustering/k_mean/k_mean.cc: New source. + * tests/clustering/kmean1d/Makefile.am: New makefile. + * tests/clustering/kmean1d/kmean1d.cc: New source. + * tests/io/plot/save_image_sh/Makefile.am: New makefile. + * tests/io/plot/save_image_sh/save_image_sh.cc: New source. + +2010-06-21 Yann Jacquelet <jacquelet(a)lrde.epita.fr> + + Import files from milena/sandbox/green. + + * mln/accu/stat/histo1d.hh: New header file. + * mln/accu/stat/histo2d.hh: New header file. + * mln/accu/stat/histo3d_hsl.hh: New header file. + * mln/accu/stat/histo3d_rgb.hh: New header file. + * mln/clustering/k_mean.hh: New header file. + * mln/clustering/kmean1d.hh: New header file. + * mln/clustering/kmean2d.hh: New header file. + * mln/clustering/kmean3d.hh: New header file. + * mln/clustering/kmean_rgb.hh: New header file. + * mln/display/display_histo.hh: New header file. + * mln/display/project_histo.hh: New header file. + * mln/fun/p2b/achromatic.hh: New header file. + * mln/fun/p2b/component_equals.hh: New header file. + * mln/fun/v2v/achromatism.hh: New header file. + * mln/fun/v2v/hue_concentration.hh: New header file. + * mln/fun/v2v/int_u16_to_int_u14.hh: New header file. + * mln/fun/v2v/int_u16_to_int_u14.hh: New header file. + * mln/fun/v2v/log.hh: New header file. + * mln/fun/v2v/rg_to_rgb.hh: New header file. + * mln/fun/v2v/rgb8_to_int_u8: New header file. + * mln/fun/v2v/rgb_to_achromastism_map.hh: New header file. + * mln/fun/v2v/rgb_to_hsv.hh: New header file. + * mln/fun/v2v/rgb_to_hue_map.hh: New header file. + * mln/fun/v2v/rgb_to_saturation_map.hh: New header file. + * mln/fun/v2v/rgb_to_value_map.hh: New header file. + * mln/img_path.hh: New header file. + * mln/io/plot/save_image_sh.hh: New header file. + * mln/math/cell.hh: New header file. + * mln/math/floor.hh: New header file. + * tests/accu/stat/histo1d/Makefile.am: New makefile. + * tests/accu/stat/histo1d/histo1d.cc: New source. + * tests/accu/stat/histo2d/Makefile.am: New makefile. + * tests/accu/stat/histo2d/histo2d.cc: New source. 2010-06-21 Yann Jacquelet <jacquelet(a)lrde.epita.fr> diff --git a/scribo/sandbox/green/README b/scribo/sandbox/green/README index 4b6fb26..03106d3 100644 --- a/scribo/sandbox/green/README +++ b/scribo/sandbox/green/README @@ -153,8 +153,8 @@ d'exécution (chmod 755 gnuplot_shell_file.sh). Comme je trouve le format extrêmement pratique, il se retrouve preque partout dans mes sources. -V HISTOGRAMMES --------------- +VI HISTOGRAMMES +--------------- Un des travaux demandés par théo est la réalisation d'une librairie d'histogramme permettant de fournir un résultat sous forme d'image. @@ -173,7 +173,7 @@ a) version 1d * mln/accu/stat/histo1d.hh: Accumulateur histogramme image1d. * use/accu/stat/histo1d: Code minimal utilisant un histogramme 1d. -* tests/accu/stat/histo1d: Test unitaire sur l'histogramme 1d. +* tests/accu/stat/histo1d: Tests unitaires sur l'histogramme 1d. b) version 2d @@ -203,52 +203,42 @@ d) version 3d HSL * mln/accu/stat/histo3d_hsl.hh: Accumulateur histogramme image3d HSL. * use/accu/stat/histo3_hsl: Code minimal utilisant un histogramme 3d HSL. -* tests/accu/stat/histo3d_hsl: Test unitaire sur l'histogramme HSL 3d. +* tests/accu/stat/histo3d_hsl: Tests unitaires sur l'histogramme HSL 3d. Le code HSL ne compile plus car l'interface liant la transformation du domaine et la fonction fold a changée. Je n'ai pas le temps de regarder plus avant. +VII SAUVEGARDE FORMAT GNUPLOT SHELL +----------------------------------- -V MLN ------ - -a) La sauvegarde des images au format gnuplot shell - -* mln/io/plot/save_image_sh.hh: Librairie sauvegarde format gnuplot shell. - -to do ... - - - -b) Les histogrammes - - - - - - - +Ce travail est personnel. Ces développements m'ont été tellement +utiles que je ne regrette pas l'investissement effectué. L'idée est de +pouvoir avoir un format d'image en écriture lisible. J'ai pris celui +de gnuplot, ce qui permet en plus de pouvoir "sucrer" la présentation +des données à loisir. Les images sont plus lourdes car le codage est +textuel et un peu plus "verbose" mais se compresse aisément par +n'importe quel algorithme type huffman (tous les archiveurs en possède un). +* mln/io/plot/save_image_sh.hh: Librairie de sauvegarde au format gnuplot shell. +* use/io/plot/save_image_sh: Code simple d'utilisation de la sauvegarde. +* tests/io/plot/save_image_sh: Tests unitaires sur l'export. -* tests/accu/stat/histo1d +VI MLN +----- +a) La sauvegarde des images au format gnuplot shell -* tests/accu/stat/histo2d +* mln/io/plot/save_image_sh.hh: Librairie sauvegarde format gnuplot shell. +to do ... -* use/accu/stat/histo3d_rgb -* tests/accu/stat/histo3d_rgb -* use/accu/stat/histo3d_hsl -* tests/accu/stat/histo3d_hsl -VI SAUVEGARDE FORMAT GNUPLOT SHELL ----------------------------------- VII VISUALISATION HISTOGRAMMES 3D diff --git a/scribo/sandbox/green/mln/io/plot/save_image_sh.hh b/scribo/sandbox/green/mln/io/plot/save_image_sh.hh index 137f78d..7e28f6f 100644 --- a/scribo/sandbox/green/mln/io/plot/save_image_sh.hh +++ b/scribo/sandbox/green/mln/io/plot/save_image_sh.hh @@ -38,6 +38,29 @@ /// The script file call gnuplot in batch mode, the result window persists and /// that's all. /// +/// The following sample is a typical use of the gnuplot shell export library. +/// +/// #include <mln/accu/stat/histo1d.hh> +/// #include <mln/data/compute.hh> +/// #include <mln/core/image/image1d.hh> +/// #include <mln/core/image/image2d.hh> +/// #include <mln/img_path.hh> +/// #include <mln/io/pgm/load.hh> +/// #include <mln/io/plot/save_image_sh.hh> +/// #include <mln/value/int_u8.hh> +/// +/// int main() +/// { +/// typedef mln::value::int_u8 t_int_u8; +/// mln::image2d<t_int_u8> img; +/// mln::image1d<unsigned> histo; +/// +/// mln::io::pgm::load(img, OLENA_IMG_PATH"/lena.pgm"); +/// histo = mln::data::compute(mln::accu::meta::histo::histo1d(), img); +/// mln::io::plot::save_image_sh(histo, "histo.sh"); +/// +/// return 0; +/// } # include <fstream> # include <string> @@ -92,7 +115,6 @@ namespace mln /// filename parameter as unix path. The script shell file must have the /// permission to execute (chmod 755). Launch the script shell to call /// gnuplot in batchmode with fine parameters. - template <typename I> bool save_image_sh(const Image<I>& img, const std::string& filename); @@ -112,6 +134,18 @@ namespace mln bool save_image_sh(const util::array< image1d<I> >& stack, const std::string& filename); + /// \brief Save a stack of stack of image. + /// + /// This is an experimental support. + /// + /// \param[in] stack the stack of image to save. + /// \param[in] filename the name of the unix script shell. + /// \return the status of the opening file operation. + /// + /// The result depends on the permission to save the file with + /// filename parameter as unix path. The script shell file must have the + /// permission to execute (chmod 755). Launch the script shell to call + /// gnuplot in batchmode with fine parameters. template <typename I> bool save_image_sh(const util::array< util::array< image1d<I> > >& stack, const std::string& filename); diff --git a/scribo/sandbox/green/tests/io/plot/save_image_sh/Makefile.am b/scribo/sandbox/green/tests/io/plot/save_image_sh/Makefile.am index d970989..77f9015 100644 --- a/scribo/sandbox/green/tests/io/plot/save_image_sh/Makefile.am +++ b/scribo/sandbox/green/tests/io/plot/save_image_sh/Makefile.am @@ -6,8 +6,13 @@ # TOOLS # ######### -INCLUDES= -I$(HOME)/svn/oln/trunk/milena/sandbox/green +#LOADLIBES= -lboost_filesystem +INCLUDES1= -I$(HOME)/git/olena/scribo/sandbox/green +INCLUDES2= -I$(HOME)/git/olena/milena +INCLUDES= $(INCLUDES1) $(INCLUDES2) CXXFLAGS= -ggdb -O0 -Wall -W -pedantic -ansi -pipe $(INCLUDES) +#CXXFLAGS= -DNDEBUG -O1 -Wall -W -pedantic -ansi -pipe $(INCLUDES) +#CXXFLAGS= -DNDEBUG -O3 -Wall -W -pedantic -ansi -pipe $(INCLUDES) ECHO= echo RM= rm MKDIR= mkdir -p @@ -20,10 +25,10 @@ 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) +BUILD__DIR= $(PWD)/ else # Case where make is done from source directory. -SOURCE_DIR= $(PWD) +SOURCE_DIR= $(PWD)/ BUILD__DIR= $(subst $(SOURCE_PATTERN),$(BUILD__PATTERN),$(PWD)) endif @@ -60,7 +65,7 @@ $(BUILD__DIR): # Copy, if nessary, all the files, except the Makefile.am $(BUILD__F_PATH): $(SOURCE_F_PATH) - $(CP) $(addprefix $(SOURCE_DIR)/,$(@F)) $@ + $(CP) $(addprefix $(SOURCE_DIR),$(@F)) $@ # Copy if nessary, the Makefile.am into Makefile $(BUILD__M_PATH): $(SOURCE_M_PATH) diff --git a/scribo/sandbox/green/tests/io/plot/save_image_sh/save_image_sh.cc b/scribo/sandbox/green/tests/io/plot/save_image_sh/save_image_sh.cc index c9c817b..c60533e 100644 --- a/scribo/sandbox/green/tests/io/plot/save_image_sh/save_image_sh.cc +++ b/scribo/sandbox/green/tests/io/plot/save_image_sh/save_image_sh.cc @@ -1,4 +1,36 @@ -/// TEST SAVE_IMAGE_SH.HH +// Copyright (C) 2007,2008,2009,2010 EPITA 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. + +/// \file +/// +/// \brief This source manages unitary testing on gnuplot shell export library. +/// +/// Tests are performed in various image format, such as image1d, image2d<bool>, +/// image2d<int_u8>, image2d<int_u16>, image2d<int_s8>, image2d<int_s16>, +/// image2d<float>, image2d<double>, image2d<rgb8>, image2d<rgb16>, +/// image2d<hsl_f>, image2d<hsl_d>, image2d<hsi_f>, image2d<hsi_d>, image3d. #include <iostream> #include <limits.h> @@ -32,9 +64,13 @@ #include <mln/literal/colors.hh> #include <mln/debug/println.hh> -//------------------------------------------------------------------------------ -// TEST TO SAVE UNSIGNED 8 BITS 1D GRAYSCALE IMAGE -//------------------------------------------------------------------------------ + +/// image1d<int_u8>. +/// \{ +/// \brief Test saving a grayscale image1d. +/// +/// As working on the image1d interface is something extremely rare, we need +/// to use the plot interface to first load some datas and then export them. mln::image1d<mln::value::int_u8> convert_array_to_image1d(const mln::util::array<mln::value::int_u8>& array) @@ -64,7 +100,7 @@ void test_save_image_sh_1d() image1d img; array1d array; - + mln::io::plot::load(array, OLENA_IMG_PATH"/fly.plot"); img = convert_array_to_image1d(array); @@ -73,16 +109,20 @@ void test_save_image_sh_1d() // Save it where we have the full permissions. bool ref_true = mln::io::plot::save_image_sh(img, "fly1d.sh"); - + mln_assertion(true == ref_true); mln_assertion(false == ref_false); std::cout << "save image 1d : ok" << std::endl; } -//------------------------------------------------------------------------------ -// Test to save image2d<bool> -//------------------------------------------------------------------------------ +/// \} +/// image2d<bool>. +/// \{ +/// \brief Test saving an image2d<bool>. +/// +/// Boolean image2d are extremly convenient for storing mask. We have a lots +/// of example in milena. void test_save_image2d_bool() { @@ -93,22 +133,26 @@ void test_save_image2d_bool() image2d_bool img_bool; mln::io::pbm::load(img_bool, OLENA_IMG_PATH"/lena.pbm"); - + // Save it were it is impossible to do it !! bool ref_false = mln::io::plot::save_image_sh(img_bool, null_lena); // Save it where we have the full permissions. bool ref_true = mln::io::plot::save_image_sh(img_bool, lena); - + mln_assertion(true == ref_true); mln_assertion(false == ref_false); std::cout << "save image2d<bool>: ok" << std::endl; } -//------------------------------------------------------------------------------ -// Test to save image2d<int_u8> -//------------------------------------------------------------------------------ +/// \} +/// image2d<int_u8>. +/// \{ +/// \brief Test saving a grayscale image2d. +/// +/// Grayscale image2d are very popular in image processing. It's the test we do +/// not fail! void test_save_image2d_int_u8() { @@ -120,27 +164,36 @@ void test_save_image2d_int_u8() image2d_int_u8 img_int_u8; mln::io::pgm::load(img_int_u8, OLENA_IMG_PATH"/lena.pgm"); - + // Save it were it is impossible to do it !! bool ref_false = mln::io::plot::save_image_sh(img_int_u8, null_lena); // Save it where we have the full permissions. bool ref_true = mln::io::plot::save_image_sh(img_int_u8, lena); - + mln_assertion(true == ref_true); mln_assertion(false == ref_false); std::cout << "save image2d<int_u8>: ok" << std::endl; } -//------------------------------------------------------------------------------ -// Test to save image2d<int_u16> -//------------------------------------------------------------------------------ +/// \} + +/// image2d<int_u16>. +/// \{ +/// \brief Test saving an extended grayscale image2d. +/// +/// This kind of image are not so current. But for medical use, we can get now, +/// some dicom in 12 bits and new generation bring us 16 bits. As 16 bits is a +/// strange format for image processing people, there is not a common +/// acceptation for the underline format. Xv or imageMagick doesn't agree for +/// the representation of the file. + struct int_u16_to_int_u8 : mln::Function_v2v< int_u16_to_int_u8 > { typedef mln::value::int_u16 argument; typedef mln::value::int_u8 result; - + result operator()(const argument& c) const { result res(c / 256); @@ -170,22 +223,28 @@ void test_save_image2d_int_u16() // Save it where we have the full permissions. bool ref_true = mln::io::plot::save_image_sh(img_int_u16, lena); - + mln_assertion(true == ref_true); mln_assertion(false == ref_false); std::cout << "save image2d<int_u16> : ok" << std::endl; } +/// \} + +/// image2d<int_s8>. +/// \{ +/// \brief Test saving an signed image2d. +/// +/// This kind of image are very artificial. It is given for exhaustivity of +/// testing. In fact, this kind of image traduces some step in a computing +/// chain. -//------------------------------------------------------------------------------ -// Test to save image2d<int_s8> -//------------------------------------------------------------------------------ struct int_u8_to_int_s8 : mln::Function_v2v< int_u8_to_int_s8 > { typedef mln::value::int_u8 argument; typedef mln::value::int_s8 result; - + result operator()(const argument& c) const { argument tmp_int_u8; @@ -197,7 +256,7 @@ struct int_u8_to_int_s8 : mln::Function_v2v< int_u8_to_int_s8 > { res = SCHAR_MAX; } - else if (SCHAR_MAX < c) + else if (static_cast<unsigned>(SCHAR_MAX) < c) { tmp_int_u8 = c - SCHAR_MAX; res = static_cast<mln::value::int_s8>(tmp_int_u8); @@ -226,28 +285,34 @@ void test_save_image2d_int_s8() image2d_int_u8 img_int_u8; mln::io::pgm::load(img_int_u8, OLENA_IMG_PATH"/lena.pgm"); - img_int_s8 = mln::data::transform(img_int_u8, int_u8_to_int_s8()); - + img_int_s8 = mln::data::transform(img_int_u8, int_u8_to_int_s8()); + // Save it were it is impossible to do it !! bool ref_false = mln::io::plot::save_image_sh(img_int_s8, null_lena); // Save it where we have the full permissions. bool ref_true = mln::io::plot::save_image_sh(img_int_s8, lena); - + mln_assertion(true == ref_true); mln_assertion(false == ref_false); std::cout << "save image2d<int_s8>: ok" << std::endl; } -//------------------------------------------------------------------------------ -// Test to save image2d<int_s16> -//------------------------------------------------------------------------------ +/// \} + +/// image2d<int_s16>. +/// \{ +/// \brief Test saving an extended image2d. +/// +/// This kind of image are very artificial. It is given for exhaustivity of +/// testing. In fact, this kind of image traduces some step in a computing +/// chain. struct int_u16_to_int_s16 : mln::Function_v2v< int_u16_to_int_s16 > { typedef mln::value::int_u16 argument; typedef mln::value::int_s16 result; - + result operator()(const argument& c) const { argument tmp_int_u16; @@ -258,7 +323,7 @@ struct int_u16_to_int_s16 : mln::Function_v2v< int_u16_to_int_s16 > { res = SHRT_MAX; } - else if (SHRT_MAX < c) + else if (static_cast<unsigned>(SHRT_MAX) < c) { tmp_int_u16 = c - SHRT_MAX; res = static_cast<mln::value::int_s16>(tmp_int_u16); @@ -286,29 +351,33 @@ void test_save_image2d_int_s16() image2d_int_u16 img_int_u16; mln::io::pgm::load(img_int_u16, OLENA_IMG_PATH"/lena_16_gnuplot.pgm"); - img_int_s16 = mln::data::transform(img_int_u16, int_u16_to_int_s16()); + img_int_s16 = mln::data::transform(img_int_u16, int_u16_to_int_s16()); // Save it were it is impossible to do it !! bool ref_false = mln::io::plot::save_image_sh(img_int_s16, null_lena); // Save it where we have the full permissions. bool ref_true = mln::io::plot::save_image_sh(img_int_s16, lena); - + mln_assertion(true == ref_true); mln_assertion(false == ref_false); std::cout << "save image2d<int_s16> : ok" << std::endl; } +/// \} -//------------------------------------------------------------------------------ -// Test to save image2d<float> -//------------------------------------------------------------------------------ +/// image2d<float>. +/// \{ +/// \brief Test saving a float image2d. +/// +/// This kind of image is a common way to save some attributes localized on +/// pixels. struct int_u8_to_float : mln::Function_v2v< int_u8_to_float > { typedef mln::value::int_u8 argument; typedef float result; - + result operator()(const argument& c) const { result res = static_cast<float>(c)/3; @@ -330,27 +399,32 @@ void test_save_image2d_float() mln::io::pgm::load(img_int_u8, OLENA_IMG_PATH"/lena.pgm"); img_float = mln::data::transform(img_int_u8, int_u8_to_float()); - + // Save it were it is impossible to do it !! bool ref_false = mln::io::plot::save_image_sh(img_float, null_lena); // Save it where we have the full permissions. bool ref_true = mln::io::plot::save_image_sh(img_float, lena); - + mln_assertion(true == ref_true); mln_assertion(false == ref_false); std::cout << "save image2d<float> : ok" << std::endl; } -//------------------------------------------------------------------------------ -// Test to save image2d<double> -//------------------------------------------------------------------------------ +/// \} + +/// image2d<double>. +/// \{ +/// \brief Test saving a double image2d. +/// +/// This kind of image is a common way to save some attributes localized on +/// pixels. struct int_u16_to_double : mln::Function_v2v< int_u16_to_double > { typedef mln::value::int_u16 argument; typedef double result; - + result operator()(const argument& c) const { result res = static_cast<float>(c)/256; @@ -372,23 +446,25 @@ void test_save_image2d_double() mln::io::pgm::load(img_int_u16, OLENA_IMG_PATH"/lena_16_gnuplot.pgm"); img_double = mln::data::transform(img_int_u16, int_u16_to_double()); - + // Save it were it is impossible to do it !! bool ref_false = mln::io::plot::save_image_sh(img_double, null_lena); // Save it where we have the full permissions. bool ref_true = mln::io::plot::save_image_sh(img_double, lena); - + mln_assertion(true == ref_true); mln_assertion(false == ref_false); std::cout << "save image2d<double> : ok" << std::endl; } +/// \} - -//------------------------------------------------------------------------------ -// Test to save image2d<rgb8> -//------------------------------------------------------------------------------ +/// image2d<rgb8>. +/// \{ +/// \brief Test saving a RGB color image2d. +/// +/// This kind of format is extremely popular in image, and in photography. void test_save_image2d_rgb8() { @@ -400,28 +476,33 @@ void test_save_image2d_rgb8() image2d_rgb8 img_rgb8; mln::io::ppm::load(img_rgb8, OLENA_IMG_PATH"/lena.ppm"); - + // Save it were it is impossible to do it !! bool ref_false = mln::io::plot::save_image_sh(img_rgb8, null_lena); // Save it where we have the full permissions. bool ref_true = mln::io::plot::save_image_sh(img_rgb8, lena); - + mln_assertion(true == ref_true); mln_assertion(false == ref_false); std::cout << "save image2d<rgb8> : ok" << std::endl; } -//------------------------------------------------------------------------------ -// Test to save image2d<rgb16> -//------------------------------------------------------------------------------ +/// \} + +/// image2d<rgb16>. +/// \{ +/// \brief Test saving a 16 bits RGB color image2d. +/// +/// As this kind of image is less popular, the library enable this export by +/// the will of exhaustivity. struct rgb16_to_int_u16 : mln::Function_v2v< rgb16_to_int_u16 > { typedef mln::value::rgb16 argument; typedef mln::value::int_u16 result; - + result operator()(const argument& c) const { result res((c.red() + c.green() + c.blue())/3); @@ -447,23 +528,28 @@ void test_save_image2d_rgb16() mln::io::ppm::load(img_rgb16, OLENA_IMG_PATH"/lena_16.ppm"); //img_int_u16 = mln::data::transform(img_rgb16, rgb16_to_int_u16()); //mln::io::pgm::save(img_int_u16, "lena_16.pgm"); - + // Save it were it is impossible to do it !! bool ref_false=mln::io::plot::save_image_sh(img_rgb16, null_lena); // Save it where we have the full permissions. bool ref_true = mln::io::plot::save_image_sh(img_rgb16, lena); // mln::io::plot::save_image_sh(img_int_u16, lena2); - + mln_assertion(true == ref_true); mln_assertion(false == ref_false); std::cout << "save image2d<rgb16> : ok" << std::endl; } +/// \} -//------------------------------------------------------------------------------ -// Test to save image2d<hsl_f> -//------------------------------------------------------------------------------ +/// image2d<hsl_f>. +/// \{ +/// \brief Test saving a HSL float color image2d. +/// +/// This kind of image allow to show the power of gnuplot. Raw data +/// are hsl, then hsl equations are integrated in the gnuplot shell +/// file. So decoding needs more time. void test_save_image2d_hsl_f() { @@ -484,21 +570,27 @@ void test_save_image2d_hsl_f() //mln::data::fill(img_rgb8, mln::literal::blue); img_hsl_f = mln::data::transform(img_rgb8, rgb_to_hsl()); - + // Save it were it is impossible to do it !! bool ref_false = mln::io::plot::save_image_sh(img_hsl_f, null_lena); // Save it where we have the full permissions. bool ref_true = mln::io::plot::save_image_sh(img_hsl_f, lena); - + mln_assertion(true == ref_true); mln_assertion(false == ref_false); std::cout << "save image2d<hsl_f> : ok" << std::endl; } -//------------------------------------------------------------------------------ -// Test to save image2d<hsl_d> -//------------------------------------------------------------------------------ +/// \} + +/// image2d<hsl_d>. +/// \{ +/// \brief Test saving a HSL double color image2d. +/// +/// This kind of image allow to show the power of gnuplot. Raw data +/// are hsl, then hsl equations are integrated in the gnuplot shell +/// file. So decoding needs more time. void test_save_image2d_hsl_d() { @@ -519,22 +611,27 @@ void test_save_image2d_hsl_d() //mln::data::fill(img_rgb16, mln::literal::blue); img_hsl_d = mln::data::transform(img_rgb16, rgb_to_hsl()); - + // Save it were it is impossible to do it !! bool ref_false = mln::io::plot::save_image_sh(img_hsl_d, null_lena); // Save it where we have the full permissions. bool ref_true = mln::io::plot::save_image_sh(img_hsl_d, lena); - + mln_assertion(true == ref_true); mln_assertion(false == ref_false); std::cout << "save image2d<hsl_d> : ok" << std::endl; } +/// \} -//------------------------------------------------------------------------------ -// Test to save image2d<hsi_f> -//------------------------------------------------------------------------------ +/// image2d<hsi_f>. +/// \{ +/// \brief Test saving a HSI float color image2d. +/// +/// This kind of image allow to show the power of gnuplot. Raw data +/// are hsi, then hsi equations are integrated in the gnuplot shell +/// file. So decoding needs more time. void test_save_image2d_hsi_f() { @@ -555,21 +652,27 @@ void test_save_image2d_hsi_f() //mln::data::fill(img_rgb8, mln::literal::blue); img_hsi_f = mln::data::transform(img_rgb8, rgb_to_hsi()); - + // Save it were it is impossible to do it !! bool ref_false = mln::io::plot::save_image_sh(img_hsi_f, null_lena); // Save it where we have the full permissions. bool ref_true = mln::io::plot::save_image_sh(img_hsi_f, lena); - + mln_assertion(true == ref_true); mln_assertion(false == ref_false); std::cout << "save image2d<hsi_f> : ok" << std::endl; } -//------------------------------------------------------------------------------ -// Test to save image2d<hsi_d> -//------------------------------------------------------------------------------ +/// \} + +/// image2d<hsi_d>. +/// \{ +/// \brief Test saving a HSI double color image2d. +/// +/// This kind of image allow to show the power of gnuplot. Raw data +/// are hsi, then hsi equations are integrated in the gnuplot shell +/// file. So decoding needs more time. void test_save_image2d_hsi_d() { @@ -590,21 +693,28 @@ void test_save_image2d_hsi_d() //mln::data::fill(img_rgb16, mln::literal::blue); img_hsi_d = mln::data::transform(img_rgb16, rgb_to_hsi()); - + // Save it were it is impossible to do it !! bool ref_false = mln::io::plot::save_image_sh(img_hsi_d, null_lena); // Save it where we have the full permissions. bool ref_true = mln::io::plot::save_image_sh(img_hsi_d, lena); - + mln_assertion(true == ref_true); mln_assertion(false == ref_false); std::cout << "save image2d<hsi_d> : ok" << std::endl; } -//------------------------------------------------------------------------------ -// TEST TO SAVE 8 BITS 3D RGB IMAGE -//------------------------------------------------------------------------------ +/// \} + +/// image3d<int_8>. +/// \{ +/// \brief Test saving a grayscale image3d. +/// +/// It seems important to be able to export in 3d, but it's not so popular +/// in the team. We try to simulate this functionnality. +/// +/// \fixme The data visualization is very hard in 3d compact with gnuplot. void test_save_image_sh_3d() { @@ -619,18 +729,20 @@ void test_save_image_sh_3d() array.append(OLENA_IMG_PATH"/fly.pgm"); mln::io::pgms::load(img, array); - + // Save it were it is impossible to do it !! bool ref_false = mln::io::plot::save_image_sh(img, "/dev/null/fly3d.sh"); // Save it where we have the full permissions. bool ref_true = mln::io::plot::save_image_sh(img, "fly3d.sh"); - + mln_assertion(true == ref_true); mln_assertion(false == ref_false); std::cout << "save image 3d : ok" << std::endl; } +/// \} + int main() { @@ -649,7 +761,7 @@ int main() test_save_image2d_rgb8(); test_save_image2d_rgb16(); - + test_save_image2d_hsl_f(); test_save_image2d_hsl_d(); diff --git a/scribo/sandbox/green/use/accu/stat/histo1d/Makefile.am b/scribo/sandbox/green/use/io/plot/save_image_sh/Makefile.am similarity index 100% copy from scribo/sandbox/green/use/accu/stat/histo1d/Makefile.am copy to scribo/sandbox/green/use/io/plot/save_image_sh/Makefile.am diff --git a/scribo/sandbox/green/use/accu/stat/histo1d/histo1d.cc b/scribo/sandbox/green/use/io/plot/save_image_sh/save_image_sh.cc similarity index 91% copy from scribo/sandbox/green/use/accu/stat/histo1d/histo1d.cc copy to scribo/sandbox/green/use/io/plot/save_image_sh/save_image_sh.cc index af39d94..bd4b84f 100644 --- a/scribo/sandbox/green/use/accu/stat/histo1d/histo1d.cc +++ b/scribo/sandbox/green/use/io/plot/save_image_sh/save_image_sh.cc @@ -25,7 +25,7 @@ /// \file /// -/// \brief Minimal code for building 1d image histogram version. +/// \brief Example of code using the gnuplot shell export library. /// #include <mln/accu/stat/histo1d.hh> @@ -34,6 +34,7 @@ #include <mln/core/image/image2d.hh> #include <mln/img_path.hh> #include <mln/io/pgm/load.hh> +#include <mln/io/plot/save_image_sh.hh> #include <mln/value/int_u8.hh> @@ -46,6 +47,7 @@ int main() mln::io::pgm::load(img, OLENA_IMG_PATH"/lena.pgm"); histo = mln::data::compute(mln::accu::meta::stat::histo1d(), img); + mln::io::plot::save_image_sh(histo, "histo.sh"); return 0; } -- 1.5.6.5
14Â years, 2Â months
1
0
0
0
last-svn-commit-44-g02c36c2 Define documentation files.
by Yann Jacquelet
* README.green: New index for source files in scribo/sandbox/green. * README.img: New index for image database. * README.result: New index for histogram database. --- scribo/sandbox/green/ChangeLog | 11 ++- scribo/sandbox/green/{README => README.green} | 58 ++++++++-- scribo/sandbox/green/README.img | 124 +++++++++++++++++++++ scribo/sandbox/green/README.result | 143 +++++++++++++++++++++++++ 4 files changed, 324 insertions(+), 12 deletions(-) rename scribo/sandbox/green/{README => README.green} (89%) create mode 100644 scribo/sandbox/green/README.img create mode 100644 scribo/sandbox/green/README.result diff --git a/scribo/sandbox/green/ChangeLog b/scribo/sandbox/green/ChangeLog index 5a7ceaa..7bb6646 100644 --- a/scribo/sandbox/green/ChangeLog +++ b/scribo/sandbox/green/ChangeLog @@ -1,4 +1,13 @@ -2010-06-23 green <jacquelet(a)lrde.epita.fr> +2010-06-24 Yann Jacquelet <jacquelet(a)lrde.epita.fr> + + Define documentation files. + + * README: Delete this file and replace it by README.green. + * README.green: New index for source files in scribo/sandbox/green. + * README.img: New index for image database. + * README.result: New index for histogram database. + +2010-06-23 Yann Jacquelet <jacquelet(a)lrde.epita.fr> Define gnuplot shell export format. diff --git a/scribo/sandbox/green/README b/scribo/sandbox/green/README.green similarity index 89% rename from scribo/sandbox/green/README rename to scribo/sandbox/green/README.green index 03106d3..3f3c9a9 100644 --- a/scribo/sandbox/green/README +++ b/scribo/sandbox/green/README.green @@ -227,26 +227,62 @@ n'importe quel algorithme type huffman (tous les archiveurs en possède un). -VI MLN ------ +VIII VISUALISATION HISTOGRAMMES 3D +---------------------------------- -a) La sauvegarde des images au format gnuplot shell +==> to do -* mln/io/plot/save_image_sh.hh: Librairie sauvegarde format gnuplot shell. -to do ... +* demo/accu/stat/histo2d +* mln/display/dispay_histo.hh +* mln/display/project_histo.hh +IX KMEANS +--------- + +Ce travail m'avait été demandé par théo. Je le laisse inachevé, quelque part +perdu pendant l'optimisation du code et sa transformation en canevas. + +* mln/clustering/k_mean.hh: Première implémentation avec matrices et vecteurs. +* mln/clustering/kmean1d.hh: Implémentation 1d avec des images. +* mln/clustering/kmean2d.hh: Implémentation 2d avec des images. +* mln/clustering/kmean3d.hh: Implémentation 3d avec des images. +* mln/clustering/kmean_rgb.hh: Impl. 3d aplatie et en cours de mise en canevas. + +* tests/clustering/k_mean: Tests unitaires sur la permière version. +* tests/clustering/kmean1d: Tests unitaire sur la version 1d. + +* demo/clustering/kmean1d: Utilisation de la version 1d. +* demo/clustering/kmean2d: Utilisation de la version 2d. +* demo/clustering/kmean3d: Utilisation de la version 3d. +* demo/clustering/kmean_rgb: Utilisation de la version aplatie. + +* bench/clustering/distance: Comparaison algorithmes d'évaluation des distances. + +==> to do + +X REGIONAL MAXIMA +----------------- + +==> to do + + +XI ANNOTATING +------------- + +==> to do + + +a) La sauvegarde des images au format gnuplot shell + +* mln/io/plot/save_image_sh.hh: Librairie sauvegarde format gnuplot shell. + +to do ... -VII VISUALISATION HISTOGRAMMES 3D ---------------------------------- -c) La visualisation des histogrammes 3d -* demo/accu/stat/histo2d -* mln/display/dispay_histo.hh -* mln/displayproject_histo.hh diff --git a/scribo/sandbox/green/README.img b/scribo/sandbox/green/README.img new file mode 100644 index 0000000..c606a93 --- /dev/null +++ b/scribo/sandbox/green/README.img @@ -0,0 +1,124 @@ +I DESCRIPTION DES BASES D'IMAGES +-------------------------------- + +img ==> Répertoire des bases d'images +img/afp ==> Extrait de la base AFP (50 photos avec texte) +img/annotating-1 ==> Base diversifiée internet trop faible qualité +img/annotating-2 ==> Base diversifiée internet meilleur qualité +img/icdar ==> Base ICDAR en 20p/50p/100p (+quelques ajouts) +img/inim ==> Base complète du cours inim +img/olena ==> Images de tests d'olena (+quelques ajouts) + + +II DESCRIPTION DE CHAQUE BASE +----------------------------- + +A) BASE AFP + +img/afp/magick-pal-30-gen.sh ==> Génération base AFP 30 couleurs (imageMagick) +img/afp/magick-pal-20-gen.sh ==> Génération base AFP 20 couleurs (imageMagick) +img/afp/magick-pal-10-gen.sh ==> Génération base AFP 10 couleurs (imageMagick) + +img/afp/gimp-pal-30-gen.sh ==> Génération base AFP 30 couleurs (Gimp) +img/afp/gimp-pal-20-gen.sh ==> Génération base AFP 20 couleurs (Gimp) +img/afp/gimp-pal-10-gen.sh ==> Génération base AFP 10 couleurs (Gimp) + +Ne pas oublier le script de réduction des couleurs pour Gimp. + +$ more ~/.gimp-2.6/scripts/reduce-color.scm +(define (reduce-color filein fileout nbcol) + (let* ((image (car (gimp-file-load RUN-NONINTERACTIVE filein filein))) + (drawable (car (gimp-image-get-active-layer image))) + ) + (gimp-image-convert-indexed image NO-DITHER MAKE-PALETTE nbcol FALSE FALSE "") + (gimp-image-convert-rgb image) + (gimp-file-save RUN-NONINTERACTIVE image drawable fileout fileout) + (gimp-image-delete image) + )) + +img/afp/magick-pal-30 ==> Base AFP 30 couleurs (imageMagick) +img/afp/magick-pal-20 ==> Base AFP 20 couleurs (imageMagick) +img/afp/magick-pal-10 ==> Base AFP 10 couleurs (imageMagick) + +img/afp/gimp-pal-30 ==> Base AFP 30 couleurs (Gimp) +img/afp/gimp-pal-20 ==> Base AFP 20 couleurs (Gimp) +img/afp/gimp-pal-10 ==> Base AFP 10 couleurs (Gimp) + +img/afp/ppm ==> Base AFP originale convertie en ppm +img/afp/jpg ==> Base AFP originale + + +B) BASE ANNOTATING-1 + +img/annotating-1/screenshot ==> Fond d'écran, capture d'écran +img/annotating-1/slide ==> Transparents commerciaux ou conférences +img/annotating-1/handwritten ==> Ecritures manuscrites +img/annotating-1/map ==> Cartes marines, de régions, de villes +img/annotating-1/photo ==> Photo AFP +img/annotating-1/logo ==> Logos de toute sorte, de toute taille +img/annotating-1/typed ==> Documents textuels impimés +img/annotating-1/fax ==> Faxs +img/annotating-1/bill ==> Factures téléphones, eau ... + + +C) BASE ANNOTATING-2 + +img/annotating-2/slide ==> Transparents commerciaux ou conférences +img/annotating-2/handwritten ==> Ecritures manuscrites +img/annotating-2/logo ==> Logos de toute sorte, de toute taille +img/annotating-2/typed ==> Documents textuels impimés +img/annotating-1/bill ==> Factures téléphones, eau ... + + +D) BASE ICDAR + +img/icdar/100p/pbm ==> Base ICDAR 100% en noir & blanc +img/icdar/100p/pgm ==> Base ICDAR 100% en niveaux de gris +img/icdar/100p/ppm ==> Base ICDAR 100% en couleur +img/icdar/100p/gradient-thin ==> Masques de gradient thin sur base ICDAR 100% +img/icdar/100p/gradient-thick ==> Masques de gradient thick sur base ICDAR 100% + +img/icdar/50p/pbm ==> Base ICDAR 50% en noir & blanc +img/icdar/50p/pgm ==> Base ICDAR 50% en niveaux de gris +img/icdar/50p/ppm ==> Base ICDAR 50% en couleur + +img/icdar/20p/pbm ==> Base ICDAR 20% en noir & blanc +img/icdar/20p/pgm ==> Base ICDAR 20% en niveaux de gris +img/icdar/20p/ppm ==> Base ICDAR 20% en couleur + +img/icdar/20p/crop ==> Plein de crops sur la base ICDAR 20% (couleur) + +img/icdar/magick-pal-30-gen.sh => Génération base ICDAR 30 couleurs(imageMagick) +img/icdar/magick-pal-20-gen.sh => Génération base ICDAR 20 couleurs(imageMagick) +img/icdar/magick-pal-10-gen.sh => Génération base ICDAR 10 couleurs(imageMagick) + +img/icdar/gimp-pal-30-gen.sh ==> Génération base ICDAR 30 couleurs (Gimp) +img/icdar/gimp-pal-20-gen.sh ==> Génération base ICDAR 20 couleurs (Gimp) +img/icdar/gimp-pal-10-gen.sh ==> Génération base ICDAR 10 couleurs (Gimp) + +img/icdar/20p/magick-pal-30 ==> Base ICDAR 20% en noir & blanc +img/icdar/20p/magick-pal-20 ==> Base ICDAR 20% en niveaux de gris +img/icdar/20p/magick-pal-10 ==> Base ICDAR 20% en couleur + +img/icdar/20p/gimp-pal-30 ==> Base ICDAR 20% en noir & blanc +img/icdar/20p/gimp-pal-20 ==> Base ICDAR 20% en niveaux de gris +img/icdar/20p/gimp-pal-10 ==> Base ICDAR 20% en couleur + +img/icdar/20p/text-only ==> Images ICDAR avec textes uniquement +img/icdar/20p/text-color ==> Images ICDAR avec textes et couleurs +img/icdar/20p/text-photo ==> Images ICDAR avec textes et photos + + +E) BASE INIM + +img/inim/bg ==> Arrière plan (ppm) +img/inim/fg ==> Avant plan (ppm) +img/inim/in ==> Images d'entrées (ppm) + + +F) BASE OLENA + +Des images générales provenant d'Olena et d'autres pour tester, pour debugger +dans différents formats. + + diff --git a/scribo/sandbox/green/README.result b/scribo/sandbox/green/README.result new file mode 100644 index 0000000..4038a5b --- /dev/null +++ b/scribo/sandbox/green/README.result @@ -0,0 +1,143 @@ +I DESCRIPTION DES BASES D'IMAGES +-------------------------------- + +result ==> Répertoire des bases d'images +result/annotating/afp ==> Analyse de la base AFP +result/annotating/icdar ==> Analyse de la base ICDAR + + +II DESCRIPTION DES TYPES D'IMAGES +--------------------------------- + +Les deux bases d'images contiennent toutes les deux la même +structure. Les résultats sont donc générés sur les images d'origine +(input) et les images dont on a réduit le nombre de couleurs à +30/20/10 soit par gimp, soit par imageMagick. + +result/annotating/afp/input ==> Résultats base originale AFP +result/annotating/afp/magick-pal-30 ==> Résultats AFP 30 couleurs (imageMagick) +result/annotating/afp/magick-pal-20 ==> Résultats AFP 20 couleurs (imageMagick) +result/annotating/afp/magick-pal-10 ==> Résultats AFP 10 couleurs (imageMagick) +result/annotating/afp/gimp-pal-30 ==> Résultats AFP 30 couleurs (Gimp) +result/annotating/afp/gimp-pal-20 ==> Résultats AFP 20 couleurs (Gimp) +result/annotating/afp/gimp-pal-10 ==> Résultats AFP 10 couleurs (Gimp) + +result/annotating/icdar/input ==> Résultats base originale ICDAR +result/annotating/icdar/magick-pal-30 => Résultats ICDAR 30 clrs (imageMagick) +result/annotating/icdar/magick-pal-20 => Résultats ICDAR 20 clrs (imageMagick) +result/annotating/icdar/magick-pal-10 => Résultats ICDAR 10 clrs (imageMagick) +result/annotating/icdar/gimp-pal-30 ==> Résultats ICDAR 30 couleurs (Gimp) +result/annotating/icdar/gimp-pal-20 ==> Résultats ICDAR 20 couleurs (Gimp) +result/annotating/icdar/gimp-pal-10 ==> Résultats ICDAR 10 couleurs (Gimp) + + +II DESCRIPTION DES COMPOSANTES COULEURS +--------------------------------------- + +Pour chaque type d'image, on extraira ensuite les différents composantes +rouge (r), verte (v), bleue (b), teinte (h), saturation (s) et valeur (v). + +result/annotating/afp/input/r ==> comp. rouge base AFP +result/annotating/afp/input/g ==> comp. verte base AFP +result/annotating/afp/input/b ==> comp. bleue base AFP +result/annotating/afp/input/h ==> comp. teinte base AFP +result/annotating/afp/input/s ==> comp. saturation base AFP +result/annotating/afp/input/v ==> comp. valeur base AFP + +result/annotating/afp/magick-pal-30/r ==> comp. rouge AFP 30 clr.(imageMagick) +result/annotating/afp/magick-pal-30/g ==> comp. verte AFP 30 clr.(imageMagick) +result/annotating/afp/magick-pal-30/b ==> comp. bleue AFP 30 clr.(imageMagick) +result/annotating/afp/magick-pal-30/h ==> comp. teinte AFP 30 c.(imageMagick) +result/annotating/afp/magick-pal-30/s ==> comp. sat. AFP 30 clr.(imageMagick) +result/annotating/afp/magick-pal-30/v ==> comp. val. AFP 30 clr.(imageMagick) + +result/annotating/afp/magick-pal-20/r ==> comp. rouge AFP 20 clr.(imageMagick) +result/annotating/afp/magick-pal-20/g ==> comp. verte AFP 20 clr.(imageMagick) +result/annotating/afp/magick-pal-20/b ==> comp. bleue AFP 20 clr.(imageMagick) +result/annotating/afp/magick-pal-20/h ==> comp. teinte AFP 20 c.(imageMagick) +result/annotating/afp/magick-pal-20/s ==> comp. sat. AFP 20 clr.(imageMagick) +result/annotating/afp/magick-pal-20/v ==> comp. val. AFP 20 clr.(imageMagick) + +result/annotating/afp/magick-pal-10/r ==> comp. rouge AFP 10 clr.(imageMagick) +result/annotating/afp/magick-pal-10/g ==> comp. verte AFP 10 clr.(imageMagick) +result/annotating/afp/magick-pal-10/b ==> comp. bleue AFP 10 clr.(imageMagick) +result/annotating/afp/magick-pal-10/h ==> comp. teinte AFP 10 c.(imageMagick) +result/annotating/afp/magick-pal-10/s ==> comp. sat. AFP 10 clr.(imageMagick) +result/annotating/afp/magick-pal-10/v ==> comp. val. AFP 10 clr.(imageMagick) + +result/annotating/afp/gimp-pal-30/r ==> comp. rouge AFP 30 clr.(Gimp) +result/annotating/afp/gimp-pal-30/g ==> comp. verte AFP 30 clr.(Gimp) +result/annotating/afp/gimp-pal-30/b ==> comp. bleue AFP 30 clr.(Gimp) +result/annotating/afp/gimp-pal-30/h ==> comp. teinte AFP 30 clr.(Gimp) +result/annotating/afp/gimp-pal-30/s ==> comp. saturation AFP 30 clr.(Gimp) +result/annotating/afp/gimp-pal-30/v ==> comp. valeur AFP 30 clr.(Gimp) + +result/annotating/afp/gimp-pal-20/r ==> comp. rouge AFP 20 clr.(Gimp) +result/annotating/afp/gimp-pal-20/g ==> comp. verte AFP 20 clr.(Gimp) +result/annotating/afp/gimp-pal-20/b ==> comp. bleue AFP 20 clr.(Gimp) +result/annotating/afp/gimp-pal-20/h ==> comp. teinte AFP 20 clr.(Gimp) +result/annotating/afp/gimp-pal-20/s ==> comp. saturation AFP 20 clr.(Gimp) +result/annotating/afp/gimp-pal-20/v ==> comp. valeur AFP 20 clr.(Gimp) + +result/annotating/icdar/input/r ==> comp. rouge base ICDAR +result/annotating/icdar/input/g ==> comp. verte base ICDAR +result/annotating/icdar/input/b ==> comp. bleue base ICDAR +result/annotating/icdar/input/h ==> comp. teinte base ICDAR +result/annotating/icdar/input/s ==> comp. saturation base ICDAR +result/annotating/icdar/input/v ==> comp. valeur base ICDAR + +result/annotating/icdar/magick-pal-30/r => comp. rouge ICDAR 30 c.(imageMagick) +result/annotating/icdar/magick-pal-30/g => comp. verte ICDAR 30 c.(imageMagick) +result/annotating/icdar/magick-pal-30/b => comp. bleue ICDAR 30 c.(imageMagick) +result/annotating/icdar/magick-pal-30/h => comp. teinte ICDAR 30 c.(imageMagick) +result/annotating/icdar/magick-pal-30/s => comp. sat. ICDAR 30 c.(imageMagick) +result/annotating/icdar/magick-pal-30/v => comp. val. ICDAR 30 c.(imageMagick) + +result/annotating/icdar/magick-pal-20/r => comp. rouge ICDAR 20 c.(imageMagick) +result/annotating/icdar/magick-pal-20/g => comp. verte ICDAR 20 c.(imageMagick) +result/annotating/icdar/magick-pal-20/b => comp. bleue ICDAR 20 c.(imageMagick) +result/annotating/icdar/magick-pal-20/h => comp. teinte ICDAR 20 c.(imageMagick) +result/annotating/icdar/magick-pal-20/s => comp. sat. ICDAR 20 c.(imageMagick) +result/annotating/icdar/magick-pal-20/v => comp. val. ICDAR 20 c.(imageMagick) + +result/annotating/icdar/magick-pal-10/r => comp. rouge ICDAR 10 c.(imageMagick) +result/annotating/icdar/magick-pal-10/g => comp. verte ICDAR 10 c.(imageMagick) +result/annotating/icdar/magick-pal-10/b => comp. bleue ICDAR 10 c.(imageMagick) +result/annotating/icdar/magick-pal-10/h => comp. teinte ICDAR 10 c.(imageMagick) +result/annotating/icdar/magick-pal-10/s => comp. sat. ICDAR 10 c.(imageMagick) +result/annotating/icdar/magick-pal-10/v => comp. val. ICDAR 10 c.(imageMagick) + +result/annotating/icdar/gimp-pal-30/r => comp. rouge ICDAR 30 c.(Gimp) +result/annotating/icdar/gimp-pal-30/g => comp. verte ICDAR 30 c.(Gimp) +result/annotating/icdar/gimp-pal-30/b => comp. bleue ICDAR 30 c.(Gimp) +result/annotating/icdar/gimp-pal-30/h => comp. teinte ICDAR 30 c.(Gimp) +result/annotating/icdar/gimp-pal-30/s => comp. saturation ICDAR 30 c.(Gimp) +result/annotating/icdar/gimp-pal-30/v => comp. valeur ICDAR 30 c.(Gimp) + +result/annotating/icdar/gimp-pal-20/r => comp. rouge ICDAR 20 c.(Gimp) +result/annotating/icdar/gimp-pal-20/g => comp. verte ICDAR 20 c.(Gimp) +result/annotating/icdar/gimp-pal-20/b => comp. bleue ICDAR 20 c.(Gimp) +result/annotating/icdar/gimp-pal-20/h => comp. teinte ICDAR 20 c.(Gimp) +result/annotating/icdar/gimp-pal-20/s => comp. saturation ICDAR 20 c.(Gimp) +result/annotating/icdar/gimp-pal-20/v => comp. valeur ICDAR 20 c.(Gimp) + +result/annotating/icdar/gimp-pal-10/r => comp. rouge ICDAR 10 c.(Gimp) +result/annotating/icdar/gimp-pal-10/g => comp. verte ICDAR 10 c.(Gimp) +result/annotating/icdar/gimp-pal-10/b => comp. bleue ICDAR 10 c.(Gimp) +result/annotating/icdar/gimp-pal-10/h => comp. teinte ICDAR 10 c.(Gimp) +result/annotating/icdar/gimp-pal-10/s => comp. saturation ICDAR 10 c.(Gimp) +result/annotating/icdar/gimp-pal-10/v => comp. valeur ICDAR 10 c.(Gimp) + + +III DESCRIPTION DES TYPES DE RESULTAT +------------------------------------- + +Pour chaque composante et pour chaque image de la base, on obtient une +image en niveau de gris correspondant à la composante (pgm) et son +histogramme normalisé (gnuplot shell). L'histogramme normalisé est un +histogramme dont l'aire vaut 1 (c'est une densité en fait, autrement +dit chaque fréquence a été divisée par la somme des fréquences). Un +script add_range.sh, a permis de rajouter les bornes des axes pour la +visualisation pour chacun des histogrammes générés. Cette +représentation des histogrammes des composantes sous forme de densité +permet de comparer visuellement les images des différentes classes. -- 1.5.6.5
14Â years, 2Â months
1
0
0
0
last-svn-commit-45-g0c912a2 Implement the kmean algorithh and start to optimize it.
by Yann Jacquelet
Implement the first version with vectors and matrices. * mln/clustering/k_mean.hh: New library component. * use/clustering/k_mean: New directory. * use/clustering/k_mean/Makefile.am: New makefile. * use/clustering/k_mean/k_mean.cc: New source file. * tests/clustering/k_mean: New directory. * tests/clustering/k_mean/Makefile.am: New makefile. * tests/clustering/k_mean/k_mean.cc: New source file. Implement the second version with image and working in 1d. * mln/clustering/kmean1d.hh: New library component. * use/clustering/kmean1d: New directory. * use/clustering/kmean1d/Makefile.am: New makefile. * use/clustering/kmean1d/kmean1d.cc: New source file. * demo/clustering/kmean1d: New directory. * demo/clustering/kmean1d/Makefile.am: New makefile. * demo/clustering/kmean1d/kmean1d.cc: New source file. Implement transformation between RG space and RGB space. * mln/fun/v2v/rg_to_rgb.hh: New library component. * use/fun/v2v/rg_to_rgb: New directory. * use/fun/v2v/rg_to_rgb/Makefile.am: New makefile. * use/fun/v2v/rg_to_rgb/rg_to_rgb.cc: New source file. Implement the third version working in 2d (r/g). * mln/clustering/kmean2d.hh: New library component. * use/clustering/kmean2d: New directory. * use/clustering/kmean2d/Makefile.am: New makefile. * use/clustering/kmean2d/kmean2d.cc: New source file. * demo/clustering/kmean2d: New directory. * demo/clustering/kmean2d/Makefile.am: New makefile. * demo/clustering/kmean2d/kmean2d.cc: New source file. Implement the fourth version working in 3d (rgb). * mln/clustering/kmean3d.hh: New library component. * use/clustering/kmean3d: New directory. * use/clustering/kmean3d/Makefile.am: New makefile. * use/clustering/kmean3d/kmean3d.cc: New source file. * demo/clustering/kmean3d: New directory. * demo/clustering/kmean3d/Makefile.am: New makefile. * demo/clustering/kmean3d/kmean3d.cc: New source file. Implement the fith version as a function (working in rgb space). * mln/clustering/kmean_rgb.hh: New library component. * use/clustering/kmean_rgb: New directory. * use/clustering/kmean_rgb/Makefile.am: New makefile. * use/clustering/kmean_rgb/kmean_rgb.cc: New source file. * demo/clustering/kmean_rgb: New directory. * demo/clustering/kmean_rgb/Makefile.am: New makefile. * demo/clustering/kmean_rgb/kmean_rgb.cc: New source file. Benchmark distance algorithm for the kmean algorithm. * bench/clustering/distance: New directory. * bench/clustering/distance/Makefile.am: New makefile. * bench/clustering/distance/distance.cc: New source file. --- scribo/sandbox/green/ChangeLog | 77 ++ scribo/sandbox/green/README.green | 150 ++++- .../green/bench/clustering/distance/Makefile.am | 153 ++++ .../green/bench/clustering/distance/distance.cc | 842 ++++++++++++++++++++ .../green/demo/clustering/kmean1d/Makefile.am | 153 ++++ .../green/demo/clustering/kmean1d/kmean1d.cc | 258 ++++++ .../green/demo/clustering/kmean2d/Makefile.am | 153 ++++ .../green/demo/clustering/kmean2d/kmean2d.cc | 278 +++++++ .../green/demo/clustering/kmean3d/Makefile.am | 153 ++++ .../green/demo/clustering/kmean3d/kmean3d.cc | 265 ++++++ .../green/demo/clustering/kmean_rgb/Makefile.am | 153 ++++ .../green/demo/clustering/kmean_rgb/kmean_rgb.cc | 239 ++++++ scribo/sandbox/green/mln/clustering/k_mean.hh | 365 ++++++--- scribo/sandbox/green/mln/clustering/kmean1d.hh | 194 ++--- scribo/sandbox/green/mln/clustering/kmean2d.hh | 329 ++++---- scribo/sandbox/green/mln/clustering/kmean3d.hh | 246 +++--- scribo/sandbox/green/mln/clustering/kmean_rgb.hh | 87 ++- scribo/sandbox/green/mln/fun/v2v/rg_to_rgb.hh | 59 ++- .../green/tests/clustering/k_mean/Makefile.am | 13 +- .../green/tests/clustering/k_mean/k_mean.cc | 395 ++++++---- .../stat/histo1d => clustering/k_mean}/Makefile.am | 0 .../sandbox/green/use/clustering/k_mean/k_mean.cc | 55 ++ .../histo1d => clustering/kmean1d}/Makefile.am | 0 .../green/use/clustering/kmean1d/kmean1d.cc | 50 ++ .../histo1d => clustering/kmean2d}/Makefile.am | 0 .../green/use/clustering/kmean2d/kmean2d.cc | 61 ++ .../histo1d => clustering/kmean3d}/Makefile.am | 0 .../green/use/clustering/kmean3d/kmean3d.cc | 63 ++ .../histo1d => clustering/kmean_rgb}/Makefile.am | 0 .../green/use/clustering/kmean_rgb/kmean_rgb.cc | 63 ++ .../stat/histo1d => fun/v2v/rg_to_rgb}/Makefile.am | 0 .../green/use/fun/v2v/rg_to_rgb/rg_to_rgb.cc | 68 ++ 32 files changed, 4224 insertions(+), 698 deletions(-) create mode 100644 scribo/sandbox/green/bench/clustering/distance/Makefile.am create mode 100644 scribo/sandbox/green/bench/clustering/distance/distance.cc create mode 100644 scribo/sandbox/green/demo/clustering/kmean1d/Makefile.am create mode 100644 scribo/sandbox/green/demo/clustering/kmean1d/kmean1d.cc create mode 100644 scribo/sandbox/green/demo/clustering/kmean2d/Makefile.am create mode 100644 scribo/sandbox/green/demo/clustering/kmean2d/kmean2d.cc create mode 100644 scribo/sandbox/green/demo/clustering/kmean3d/Makefile.am create mode 100644 scribo/sandbox/green/demo/clustering/kmean3d/kmean3d.cc create mode 100644 scribo/sandbox/green/demo/clustering/kmean_rgb/Makefile.am create mode 100644 scribo/sandbox/green/demo/clustering/kmean_rgb/kmean_rgb.cc copy scribo/sandbox/green/use/{accu/stat/histo1d => clustering/k_mean}/Makefile.am (100%) create mode 100644 scribo/sandbox/green/use/clustering/k_mean/k_mean.cc copy scribo/sandbox/green/use/{accu/stat/histo1d => clustering/kmean1d}/Makefile.am (100%) create mode 100644 scribo/sandbox/green/use/clustering/kmean1d/kmean1d.cc copy scribo/sandbox/green/use/{accu/stat/histo1d => clustering/kmean2d}/Makefile.am (100%) create mode 100644 scribo/sandbox/green/use/clustering/kmean2d/kmean2d.cc copy scribo/sandbox/green/use/{accu/stat/histo1d => clustering/kmean3d}/Makefile.am (100%) create mode 100644 scribo/sandbox/green/use/clustering/kmean3d/kmean3d.cc copy scribo/sandbox/green/use/{accu/stat/histo1d => clustering/kmean_rgb}/Makefile.am (100%) create mode 100644 scribo/sandbox/green/use/clustering/kmean_rgb/kmean_rgb.cc copy scribo/sandbox/green/use/{accu/stat/histo1d => fun/v2v/rg_to_rgb}/Makefile.am (100%) create mode 100644 scribo/sandbox/green/use/fun/v2v/rg_to_rgb/rg_to_rgb.cc diff --git a/scribo/sandbox/green/ChangeLog b/scribo/sandbox/green/ChangeLog index 7bb6646..4ddaa54 100644 --- a/scribo/sandbox/green/ChangeLog +++ b/scribo/sandbox/green/ChangeLog @@ -1,3 +1,80 @@ +2010-06-28 Yann Jacquelet <jacquelet(a)lrde.epita.fr> + + Implement the kmean algorithh and start to optimize it. + + Implement the first version with vectors and matrices. + + * mln/clustering/k_mean.hh: New library component. + + * use/clustering/k_mean: New directory. + * use/clustering/k_mean/Makefile.am: New makefile. + * use/clustering/k_mean/k_mean.cc: New source file. + + * tests/clustering/k_mean: New directory. + * tests/clustering/k_mean/Makefile.am: New makefile. + * tests/clustering/k_mean/k_mean.cc: New source file. + + Implement the second version with image and working in 1d. + + * mln/clustering/kmean1d.hh: New library component. + + * use/clustering/kmean1d: New directory. + * use/clustering/kmean1d/Makefile.am: New makefile. + * use/clustering/kmean1d/kmean1d.cc: New source file. + + * demo/clustering/kmean1d: New directory. + * demo/clustering/kmean1d/Makefile.am: New makefile. + * demo/clustering/kmean1d/kmean1d.cc: New source file. + + Implement transformation between RG space and RGB space. + + * mln/fun/v2v/rg_to_rgb.hh: New library component. + * use/fun/v2v/rg_to_rgb: New directory. + * use/fun/v2v/rg_to_rgb/Makefile.am: New makefile. + * use/fun/v2v/rg_to_rgb/rg_to_rgb.cc: New source file. + + Implement the third version working in 2d (r/g). + + * mln/clustering/kmean2d.hh: New library component. + + * use/clustering/kmean2d: New directory. + * use/clustering/kmean2d/Makefile.am: New makefile. + * use/clustering/kmean2d/kmean2d.cc: New source file. + + * demo/clustering/kmean2d: New directory. + * demo/clustering/kmean2d/Makefile.am: New makefile. + * demo/clustering/kmean2d/kmean2d.cc: New source file. + + Implement the fourth version working in 3d (rgb). + + * mln/clustering/kmean3d.hh: New library component. + + * use/clustering/kmean3d: New directory. + * use/clustering/kmean3d/Makefile.am: New makefile. + * use/clustering/kmean3d/kmean3d.cc: New source file. + + * demo/clustering/kmean3d: New directory. + * demo/clustering/kmean3d/Makefile.am: New makefile. + * demo/clustering/kmean3d/kmean3d.cc: New source file. + + Implement the fith version as a function (working in rgb space). + + * mln/clustering/kmean_rgb.hh: New library component. + + * use/clustering/kmean_rgb: New directory. + * use/clustering/kmean_rgb/Makefile.am: New makefile. + * use/clustering/kmean_rgb/kmean_rgb.cc: New source file. + + * demo/clustering/kmean_rgb: New directory. + * demo/clustering/kmean_rgb/Makefile.am: New makefile. + * demo/clustering/kmean_rgb/kmean_rgb.cc: New source file. + + Benchmark distance algorithm for the kmean algorithm. + + * bench/clustering/distance: New directory. + * bench/clustering/distance/Makefile.am: New makefile. + * bench/clustering/distance/distance.cc: New source file. + 2010-06-24 Yann Jacquelet <jacquelet(a)lrde.epita.fr> Define documentation files. diff --git a/scribo/sandbox/green/README.green b/scribo/sandbox/green/README.green index 3f3c9a9..02d8654 100644 --- a/scribo/sandbox/green/README.green +++ b/scribo/sandbox/green/README.green @@ -33,8 +33,7 @@ n'y a rien à copier. Rendons-nous dans le répertoire de compilation et lançon le makefile. #:~/git/olena/scribo/sandbox/green/demo/annotating/hsv$ -cd ../../../build/demo/annotating/hsv - +#:cd ../../../build/demo/annotating/hsv #:~/git/olena/scribo/sandbox/green/build/demo/annotating/hsv$ make clean all L'exécutable est généré par le makefile, il porte le nom du @@ -168,6 +167,14 @@ de comptage puisqu'il est décrit sous la forme de triplets de float contient une séquence d'appels pour les routines permettant de considérer la dimension de la teinte comme circulaire. +Après réflexion, le code des histogrammes et tous les accumulateurs +qui en découlent devraient être rangés dans l'espace de nommage +mln::accu::histo. Cela permettrait de ne pas parasiter mln::accu::stat +avec tous les éléments propres aux histogrammes et de ne pas faire un +espace de nommage à rallonge en introduisant histo dans stat. Donc +mln::accu::stat semble être une bonne postion pour le rangement final +du code relatif aux histogrammes. + a) version 1d @@ -198,7 +205,6 @@ c) version 3d RGB * use/accu/stat/histo3_rgb: Code minimal utilisant un histogramme 3d RGB. - d) version 3d HSL * mln/accu/stat/histo3d_hsl.hh: Accumulateur histogramme image3d HSL. @@ -245,23 +251,145 @@ IX KMEANS Ce travail m'avait été demandé par théo. Je le laisse inachevé, quelque part perdu pendant l'optimisation du code et sa transformation en canevas. + +a) Première implémentation avec matrices et vecteurs + +Cette version est bien documentée et permet de mieux comprendre les autres +versions. Par ailleurs, elle n'est pas spécialement optimisée ce qui fait +qu'elle colle davantage au modèle de l'algorithme kmean traditionnel. + * mln/clustering/k_mean.hh: Première implémentation avec matrices et vecteurs. +* use/clustering/k_mean: Code minimal utilisant cette première implémentation. +* tests/clustering/k_mean: Tests unitaires sur la permière version. + + +b) Seconde implémentation avec image en 1d + +Cette seconde version intègre une optimisation testée par théo il y a +longtemps. Je me demande si ce n'étais pas pendant sa thèse qu'il +avait travaillé sur cette version. Bref, dans la mesure où +l'optimisation passe par la création d'un histogramme, cette version +devient dépendante des histogrammes réalisés plutôt (il est aussi +dépendant de la sauvegarde au format gnuplot shell). L'idée générale +de l'optimisation est de ne plus raisonner sur l'image, mais sur +l'histogramme. Car à un moment donné, la classification ne tient +compte que de la valeur du pixel en intensité (pas de ses coordonnées +dans l'image). Donc tout pixel de même intensité sera classé de +manière identique. D'où l'intérêt de travailler avec les +histogrammes. Les limites de cette optimisation se trouvent dans la +taille des histogrammes. L'optimisation marche à merveille pour de +faibles quantifications (8 bits c'est parfait). Par contre, lorsque +l'on passe à un histogramme couleur, la taille de l'histogramme +devient problématique et peut dépasser la taille de l'image. Cette +optimisation n'a alors plus aucun sens. + * mln/clustering/kmean1d.hh: Implémentation 1d avec des images. +* use/clustering/kmean1d : Code minimal utilisant cette seconde implémentation. +* demo/clustering/kmean1d : Demonstrateur. + +La visualisation de la convergence des moyennes, générée par le +démonstrateur, n'est pas très lisible. La lecture textuelle du fichier +gnuplot shell (mean_cnv.sh) permet d'interpréter ce qui se passe, par +contre le graphique est à refaire. + + +c) kmean2d + +Cette troisième version est identique à la seconde, sauf qu'elle +permet de faire la classification dans un espace à deux +dimensions. Malheureusement, un tel travail dans cet espace coûte +beaucoup plus cher à l'exécution. + +* mln/fun/v2v/rg_to_rgb.hh: Transformation de l'espace RG vers l'espace RGB. +* use/fun/v2v/rg_to_rgb: Exemple de code pour l'utilisation de rg_to_rgb. + * mln/clustering/kmean2d.hh: Implémentation 2d avec des images. -* mln/clustering/kmean3d.hh: Implémentation 3d avec des images. -* mln/clustering/kmean_rgb.hh: Impl. 3d aplatie et en cours de mise en canevas. +* use/clustering/kmean2d : Code minimal utilisant cette seconde implémentation. +* demo/clustering/kmean2d : Demonstrateur. -* tests/clustering/k_mean: Tests unitaires sur la permière version. -* tests/clustering/kmean1d: Tests unitaire sur la version 1d. +La visualisation de la convergence des moyennes est cette fois-ci +complètement aboutie. Le fichier semble avoir quelques soucis, il +manque des lignes dans le splot initial, en remettre pour qu'il y en +ait autant que les blocs de données. L'espace des couleurs étant le +bicanal r/g, on peut visualiser sur une troisième dimension +l'évolution des centres dans l'espace initial. L'effet est très réussi +et aussi très parlant. Chaque run, correspond alors à une trajectoire +particulière. L'affichage des variations des variances a été rénové et +est lui aussi beaucoup plus lisible. + + +d) kmean3d + +Cette quatrième version est la copie conforme de la version +précédente. Les problèmes de visualisation sur les fichiés générés +sont les mêmes. L'affichage des convergences est identique. Le recours +à une dégradation de l'image d'entrée est impérative pour avoir des +temps encore acceptables. -* demo/clustering/kmean1d: Utilisation de la version 1d. -* demo/clustering/kmean2d: Utilisation de la version 2d. -* demo/clustering/kmean3d: Utilisation de la version 3d. +* mln/clustering/kmean3d.hh: Implémentation 3d avec des images. +* use/clustering/kmean3d : Code minimal utilisant cette quatrième impl. +* demo/clustering/kmean3d : Demonstrateur. + + +e) kmean aplati + +Cette cinquième version est très spéciale. Elle doit permettre de +gagner du temps d'exécution. Le concept est simple au départ, tout +écrire d'un seul tenant. L'exercice est fastidieux et difficile +(intellectuellement). Une fois fait, il faut réfléchir à ce qui peut +être mis sous forme de canevas. Par exemple, la manière de calculer +les distances peut être une information paramétrable. Cela pemettrait +de faire un benchmark in situ. La transcription actuelle compile. Elle +n'intègre pas tous les outils de debuggage que nous pouvions avoir sur +les autres versions. Par ailleurs, comme le code est réuni en une +seule fonction, nous avons pour l'instant une seule sortie, l'image de +labels de la classification réalisée. A partir de cette image, nous +pouvons en reconstruire d'autres. Il manque quand même la possibilité +d'observer les convergences. Le travail était en cours, à prendre donc +avec beaucoup de pincettes. La dernière exécution house.ppm, 3 +centres, 10 itérations et 10 runs fonctionne parfaitement sur les +premiers runs puis l'affichage s'emballe sans que l'on y comprenne +rien. Un dump dans un fichier révèle le non appariement de certaines +traces (entering/exiting). Une piste à suivre est la sortie anticipée +d'une de mes boucles sans pour autant fermer une trace ... ??? + +* mln/clustering/kmean_rgb.hh: Implémentation 3d avec des images. +* use/clustering/kmean_rgb : Code minimal utilisant cette quatrième impl. * demo/clustering/kmean_rgb: Utilisation de la version aplatie. + +f) optimisation possible + +Le calcul des distances entre les points et les différents centres +peut être réalisé par des transformées. Certes, les distances ne seront +pas les mêmes que la distance euclidienne, mais elles s'en approchent +et cela constitue très certainement une très bonne approximation pour +l'objectif que nous cherchons à atteindre. Le but de ce benchmark est +de regarder quel type de transformation est le plus rapide pour +arriver à nos fins en fonction des données d'entrée. Cette +optimisation n'a pas encore été intégrée dans le code, et reste une +piste à exploiter. + * bench/clustering/distance: Comparaison algorithmes d'évaluation des distances. -==> to do +Une routine du benchmark ne compile plus. Il semble qu'il y ait un +mauvais appel à la fonction at_ dans la routine +influence_zone_geodesic.hh ligne 127. Le but du benchmark est de +tester les distances en 2d et 3d pour des voisinages différents (c04, +c08, c06, c18, c26) sur les routines distance euclidienne classique, +zone d'influence geodesique et zone d'influence "front". La première +serie de test vise à garder une taille d' image constante et +d'augmenter le nombre de centres pour voir comment se comporte les +algorithmes et la seconde serie, vise à garder un nombre constant de +centres et à agrandir progressivement l'image. Attention, le benchmark +essaye d'être assez exhaustif et donc se paye par un temps d'execution +assez long. Les différents fichiers générés reprennent les différents +tests effectués et montrent l'évolution du temps de calcul suivant la +progression du paramètre observé (taille de l'image ou nombre de +centres). + +==> to do : le changelog + commit + give it to scribo-z branch + X REGIONAL MAXIMA ----------------- diff --git a/scribo/sandbox/green/bench/clustering/distance/Makefile.am b/scribo/sandbox/green/bench/clustering/distance/Makefile.am new file mode 100644 index 0000000..ca5e187 --- /dev/null +++ b/scribo/sandbox/green/bench/clustering/distance/Makefile.am @@ -0,0 +1,153 @@ +# +# Generic Makefile +# + +######### +# TOOLS # +######### + +#LOADLIBES= -lboost_filesystem +INCLUDES1= -I$(HOME)/git/olena/scribo/sandbox/green +INCLUDES2= -I$(HOME)/git/olena/milena +INCLUDES= $(INCLUDES1) $(INCLUDES2) +#CXXFLAGS= -ggdb -O0 -Wall -W -pedantic -ansi -pipe $(INCLUDES) +#CXXFLAGS= -DNDEBUG -O1 -Wall -W -pedantic -ansi -pipe $(INCLUDES) +CXXFLAGS= -DNDEBUG -O3 -Wall -W -pedantic -ansi -pipe $(INCLUDES) +ECHO= echo +RM= rm +MKDIR= mkdir -p +CP= cp + +SOURCE_PATTERN= green/bench +BUILD__PATTERN= green/build/bench + + +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/scribo/sandbox/green/bench/clustering/distance/distance.cc b/scribo/sandbox/green/bench/clustering/distance/distance.cc new file mode 100644 index 0000000..4daea44 --- /dev/null +++ b/scribo/sandbox/green/bench/clustering/distance/distance.cc @@ -0,0 +1,842 @@ +// Copyright (C) 2007,2008,2009,2010 EPITA 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. + +#include <mln/core/alias/box3d.hh> +#include <mln/core/alias/neighb2d.hh> +#include <mln/core/alias/neighb3d.hh> +#include <mln/core/alias/point3d.hh> +#include <mln/core/alias/w_window2d_int.hh> +#include <mln/core/alias/w_window3d_int.hh> +#include <mln/core/image/image2d.hh> +#include <mln/core/image/image3d.hh> +#include <mln/core/routine/initialize.hh> + +#include <mln/data/fill.hh> + +#include <mln/io/pgm/save.hh> +#include <mln/io/plot/save_image_sh.hh> + +#include <mln/literal/zero.hh> + +#include <mln/make/w_window2d_int.hh> +#include <mln/make/w_window3d_int.hh> + +#include <mln/opt/at.hh> + +#include <mln/transform/influence_zone_geodesic.hh> +#include <mln/transform/influence_zone_front.hh> + +#include <mln/util/array.hh> +#include <mln/util/timer.hh> + +#include <mln/value/label_8.hh> + + +/// Build inputs, build seeds, count distance. +/// \{ +/// \brief Build 2d/3d input image and 2d/3d seed image. +/// +/// Building seeds means making a rectangular grid over a virtual image with +/// a specific size and collects together in a array each node of this grid. +/// In the context of the kmean algorithm, seeds are equavalent to centers. +/// Building input means creating a label image and associates to each seed +/// a unique label id. +/// Distance are square euclidian distance in 2d and in 3d. +mln::image2d<mln::value::label_8> build_input2d(unsigned nb_seed, unsigned size) +{ + typedef mln::value::label_8 t_lbl; + mln::image2d<t_lbl> input(mln::box2d(mln::point2d(0,0), + mln::point2d(size,size))); + + mln::data::fill(input, mln::literal::zero); + + unsigned top = size / nb_seed; + unsigned lbl = 0; + + for (unsigned i = top/2; i < size; i += top) + for (unsigned j = top/2; j < size; j += top) + input(mln::point2d(i,j)) = ++lbl; + + //mln::io::pgm::save(input, "input.pgm"); + + return input; +} + +mln::image3d<mln::value::label_8> build_input3d(unsigned nb_seed, unsigned size) +{ + typedef mln::value::label_8 t_lbl; + mln::image3d<t_lbl> input(mln::box3d(mln::point3d(0,0,0), + mln::point3d(size,size,size))); + + mln::data::fill(input, mln::literal::zero); + + unsigned top = size / nb_seed; + unsigned lbl = 0; + + for (unsigned i = top/2; i < size; i += top) + for (unsigned j = top/2; j < size; j += top) + for (unsigned k = top/2; k < size; k += top) + input(mln::point3d(k,i,j)) = ++lbl; + + //mln::io::pgm::save(input, "input.pgm"); + + return input; +} + +mln::util::array<mln::point3d> build_seed3d(unsigned nb_seed, unsigned size) +{ + mln::util::array<mln::point3d> result; + unsigned top = size / nb_seed; + + for (unsigned i = top/2; i < size; i += top) + for (unsigned j = top/2; j < size; j += top) + for (unsigned k = top/2; k < size; k += top) + result.append(mln::point3d(k,i,j)); + + // std::cout << result << std::endl; + + return result; +} + +mln::util::array<mln::point2d> build_seed2d(unsigned nb_seed, unsigned size) +{ + mln::util::array<mln::point2d> result; + unsigned top = size / nb_seed; + + for (unsigned i = top/2; i < size; i += top) + for (unsigned j = top/2; j < size; j += top) + result.append(mln::point2d(j,i)); + + // std::cout << result << std::endl; + + return result; +} + +unsigned distance(mln::point3d p1, mln::point3d p2) +{ + unsigned row2 = (p1.row() - p2.row())*(p1.row() - p2.row()); + unsigned col2 = (p1.col() - p2.col())*(p1.col() - p2.col()); + unsigned sli2 = (p1.sli() - p2.sli())*(p1.sli() - p2.sli()); + unsigned res = row2 + col2 + sli2; + + return res; +} + +unsigned distance(mln::point2d p1, mln::point2d p2) +{ + unsigned row2 = (p1.row() - p2.row())*(p1.row() - p2.row()); + unsigned col2 = (p1.col() - p2.col())*(p1.col() - p2.col()); + unsigned res = row2 + col2; + + return res; +} +/// \} + +/// Benchmark geodesic distance. +/// \{ +/// \brief The geodesic material for the benchmark process. +/// +/// This part of the file contains all we need to benchmarck the +/// geodesic distance. First of all, we have the calling functions +/// that encapsulate the real call to geodesic routine. They bring us +/// a clean place where starting and stopping the timer without any +/// other code interference. Printing results could be done at this step. +/// At least, we have the test routine that call the previous functions +/// by passing arguments like different size of inputs and different +/// neighbouring. The test routines save their results in gnuplot script shell +/// file that enable to show charts. +void influence_zone_geodesic_2d(mln::util::timer& timer, + const mln::image2d<mln::value::label_8>& input, + const mln::neighb2d & neighb) +{ + mln::image2d<mln::value::label_8> output; + + timer.start(); + output = mln::transform::influence_zone_geodesic(input, neighb); + timer.stop(); + + //mln::io::pgm::save(output, "output.pgm"); +} + +/// \fixme influence_zone_geodesic_3d doesn't compile! +void influence_zone_geodesic_3d(mln::util::timer& timer, + const mln::image3d<mln::value::label_8>& input, + const mln::neighb3d & neighb) +{ + mln::image3d<mln::value::label_8> output; + + timer.start(); + // FIXME : Problem with the influence_zone_geodesic in 3d (bad call to at_). + // output = mln::transform::influence_zone_geodesic(input, neighb); + timer.stop(); + + //mln::io::pgm::save(output, "output.pgm"); +} + + +int test_influence_zone_geodesic_2d() +{ + mln::util::timer timer; + +// Test the label c4 + mln::image1d<float> chart_seed_c04(16*16+2); + + mln::data::fill(chart_seed_c04, mln::literal::zero); + + for (unsigned i = 1; i < 16+1; ++i) + { + influence_zone_geodesic_2d(timer,build_input2d(i,256),mln::c4()); + std::cout << "c04|256x256|" << i << " = " << timer.read() << std::endl; + mln::opt::at(chart_seed_c04, i*i) = timer.read(); + } + + mln::io::plot::save_image_sh(chart_seed_c04, "geodesic.c04.2d.seed.sh"); + + // Test the label c8 + mln::image1d<float> chart_seed_c08(16*16+2); + + mln::data::fill(chart_seed_c08, mln::literal::zero); + + for (unsigned i = 1; i < 16+1; ++i) + { + influence_zone_geodesic_2d(timer,build_input2d(i,256),mln::c8()); + std::cout << "c08|256x256|" << i << " = " << timer.read() << std::endl; + mln::opt::at(chart_seed_c08, i*i) = timer.read(); + } + + mln::io::plot::save_image_sh(chart_seed_c08, "geodesic.c08.2d.seed.sh"); + + // Test the size of the image + // 1, 2, 4, 8, 16, 32, 64, 128, 256 + mln::image1d<float> chart_size_c04(256+1); + + mln::data::fill(chart_size_c04, mln::literal::zero); + + for (unsigned i = 16; i < 256+1; ++i) + { + influence_zone_geodesic_2d(timer, build_input2d(4,i),mln::c4()); + std::cout << "c04|" << i << "x" << i << "|16 = " + << timer.read() << std::endl; + mln::opt::at(chart_size_c04, i) = timer.read(); + } + + mln::io::plot::save_image_sh(chart_size_c04, "geodesic.c04.2d.size.sh"); + + // Test the size of the image + // 1, 2, 4, 8, 16, 32, 64, 128, 256 + mln::image1d<float> chart_size_c08(256+1); + + mln::data::fill(chart_size_c08, mln::literal::zero); + + for (unsigned i = 16; i < 256+1; ++i) + { + influence_zone_geodesic_2d(timer, build_input2d(4,i),mln::c8()); + std::cout << "c08|" << i << "x" << i << "|16 = " + << timer.read() << std::endl; + mln::opt::at(chart_size_c08, i) = timer.read(); + } + + mln::io::plot::save_image_sh(chart_size_c08, "geodesic.c08.2d.size.sh"); + + + return 0; +} + + +void test_influence_zone_geodesic_3d() +{ + mln::util::timer timer; + + // Test the number of labels c06 + mln::image1d<float> chart_seed_c06(5*5*5+2); + + mln::data::fill(chart_seed_c06, mln::literal::zero); + + for (unsigned i = 1; i < 5+1; ++i) + { + influence_zone_geodesic_3d(timer, build_input3d(i,128), mln::c6()); + std::cout << "c06|128x128x128|" << i << " = " << timer.read() << std::endl; + mln::opt::at(chart_seed_c06, i*i*i) = timer.read(); + } + + mln::io::plot::save_image_sh(chart_seed_c06, "geodesic.c06.3d.seed.sh"); + + // Test the number of labels c18 + mln::image1d<float> chart_seed_c18(5*5*5+2); + + mln::data::fill(chart_seed_c18, mln::literal::zero); + + for (unsigned i = 1; i < 5+1; ++i) + { + influence_zone_geodesic_3d(timer, build_input3d(i,128), mln::c18()); + std::cout << "c18|128x128x128|" << i << " = " << timer.read() << std::endl; + mln::opt::at(chart_seed_c18, i*i*i) = timer.read(); + } + + mln::io::plot::save_image_sh(chart_seed_c18, "geodesic.c18.3d.seed.sh"); + + // Test the number of labels c26 + mln::image1d<float> chart_seed_c26(5*5*5+2); + + mln::data::fill(chart_seed_c26, mln::literal::zero); + + for (unsigned i = 1; i < 5+1; ++i) + { + influence_zone_geodesic_3d(timer, build_input3d(i,128), mln::c26()); + std::cout << "c26|128x128x128|" << i << " = " << timer.read() << std::endl; + mln::opt::at(chart_seed_c26, i*i*i) = timer.read(); + } + + mln::io::plot::save_image_sh(chart_seed_c26, "geodesic.c26.3d.seed.sh"); + + // Test the size of the image c06 + // 1, 2, 4, 8, 16, 32, 64, 128, 256 + mln::image1d<float> chart_size_c06(128+1); + + mln::data::fill(chart_size_c06, mln::literal::zero); + + for (unsigned i = 6; i < 128+1; ++i) + { + influence_zone_geodesic_3d(timer, build_input3d(2,i), mln::c6()); + std::cout << "c06|" << i << "x" << i << "x" << i << "|8 = " + << timer.read() << std::endl; + mln::opt::at(chart_size_c06, i) = timer.read(); + } + + mln::io::plot::save_image_sh(chart_size_c06, "geodesic.c06.3d.size.sh"); + + // Test the size of the image c18 + // 1, 2, 4, 8, 16, 32, 64, 128, 256 + mln::image1d<float> chart_size_c18(128+1); + + mln::data::fill(chart_size_c18, mln::literal::zero); + + for (unsigned i = 6; i < 128+1; ++i) + { + influence_zone_geodesic_3d(timer, build_input3d(2,i), mln::c18()); + std::cout << "c18|" << i << "x" << i << "x" << i << "|8 = " + << timer.read() << std::endl; + mln::opt::at(chart_size_c18, i) = timer.read(); + } + + mln::io::plot::save_image_sh(chart_size_c18, "geodesic.c18.3d.size.sh"); + + // Test the size of the image c26 + // 1, 2, 4, 8, 16, 32, 64, 128, 256 + mln::image1d<float> chart_size_c26(128+1); + + mln::data::fill(chart_size_c26, mln::literal::zero); + + for (unsigned i = 6; i < 128+1; ++i) + { + influence_zone_geodesic_3d(timer, build_input3d(2,i), mln::c26()); + std::cout << "c26|" << i << "x" << i << "x" << i << "|8 = " + << timer.read() << std::endl; + mln::opt::at(chart_size_c26, i) = timer.read(); + } + + mln::io::plot::save_image_sh(chart_size_c26, "geodesic.c26.3d.size.sh"); +} +/// \} + +/// Benchmark front distance. +/// \{ +/// \brief The front material for the benchmark process. +/// +/// This part of the file contains all we need to benchmarck the +/// front distance. First of all, we have the calling functions +/// that encapsulate the real call to geodesic routine. They bring us +/// a clean place where starting and stopping the timer without any +/// other code interference. Printing results could be done at this step. +/// At least, we have the test routine that call the previous functions +/// by passing arguments like different size of inputs and different +/// neighbouring. The test routines save their results in gnuplot script shell +/// file that enable to show charts. +void influence_zone_front_2d(mln::util::timer& timer, + const mln::image2d<mln::value::label_8>& input, + const mln::neighb2d& neighb, + const mln::w_window2d_int& w2d) +{ + mln::image2d<mln::value::label_8> output; + + timer.start(); + output = mln::transform::influence_zone_front(input, neighb, w2d); + timer.stop(); + + //mln::io::pgm::save(output, "output.pgm"); +} + + +void influence_zone_front_3d(mln::util::timer& timer, + const mln::image3d<mln::value::label_8>& input, + const mln::neighb3d& neighb, + const mln::w_window3d_int& w3d) +{ + mln::image3d<mln::value::label_8> output; + + timer.start(); + output = mln::transform::influence_zone_front(input, neighb, w3d); + timer.stop(); + + //mln::io::pgm::save(output, "output.pgm"); +} + + +void test_influence_zone_front_3d() +{ + mln::util::timer timer; + + int ws_c06[] = { + // Internal slice + 0, 0, 0, + 0, 2, 0, + 0, 0, 0, + // Middle slice + 0, 2, 0, + 2, 0, 2, + 0, 2, 0, + // External slice + 0, 0, 0, + 0, 2, 0, + 0, 0, 0 }; + + int ws_c18[] = { + // Internal slice + 0, 6, 0, + 6, 4, 6, + 0, 6, 0, + // Middle slice + 6, 4, 6, + 4, 0, 4, + 6, 4, 6, + // External slice + 0, 6, 0, + 6, 4, 6, + 0, 6, 0 }; + + int ws_c26[] = { + // Internal slice + 7, 6, 7, + 6, 4, 6, + 7, 6, 7, + // Middle slice + 6, 4, 6, + 4, 0, 4, + 6, 4, 6, + // External slice + 7, 6, 7, + 6, 4, 6, + 7, 6, 7 }; + + mln::w_window3d_int w3d_c06 = mln::make::w_window3d_int(ws_c06); + mln::w_window3d_int w3d_c18 = mln::make::w_window3d_int(ws_c18); + mln::w_window3d_int w3d_c26 = mln::make::w_window3d_int(ws_c26); + + // Test the number of labels c06 + mln::image1d<float> chart_seed_c06(5*5*5+2); + + mln::data::fill(chart_seed_c06, mln::literal::zero); + + for (unsigned i = 1; i < 5+1; ++i) + { + influence_zone_front_3d(timer, build_input3d(i,128), mln::c6(), w3d_c06); + std::cout << "c06|128x128x128|" << i << " = " << timer.read() << std::endl; + mln::opt::at(chart_seed_c06, i*i*i) = timer.read(); + } + + mln::io::plot::save_image_sh(chart_seed_c06, "front.c06.3d.seed.sh"); + + // Test the number of labels c18 + mln::image1d<float> chart_seed_c18(5*5*5+2); + + mln::data::fill(chart_seed_c18, mln::literal::zero); + + for (unsigned i = 1; i < 5+1; ++i) + { + influence_zone_front_3d(timer, build_input3d(i,128), mln::c18(), w3d_c18); + std::cout << "c18|128x128x128|" << i << " = " << timer.read() << std::endl; + mln::opt::at(chart_seed_c18, i*i*i) = timer.read(); + } + + mln::io::plot::save_image_sh(chart_seed_c18, "front.c18.3d.seed.sh"); + + // Test the number of labels c26 + mln::image1d<float> chart_seed_c26(5*5*5+2); + + mln::data::fill(chart_seed_c26, mln::literal::zero); + + for (unsigned i = 1; i < 5+1; ++i) + { + influence_zone_front_3d(timer, build_input3d(i,128), mln::c26(), w3d_c26); + std::cout << "c26|128x128x128|" << i << " = " << timer.read() << std::endl; + mln::opt::at(chart_seed_c26, i*i*i) = timer.read(); + } + + mln::io::plot::save_image_sh(chart_seed_c26, "front.c26.3d.seed.sh"); + + // Test the size of the image c06 + // 1, 2, 4, 8, 16, 32, 64, 128, 256 + mln::image1d<float> chart_size_c06(128+1); + + mln::data::fill(chart_size_c06, mln::literal::zero); + + for (unsigned i = 6; i < 128+1; ++i) + { + influence_zone_front_3d(timer, build_input3d(2,i), mln::c6(), w3d_c06); + std::cout << "c06|" << i << "x" << i << "x" << i << "|8 = " + << timer.read() << std::endl; + mln::opt::at(chart_size_c06, i) = timer.read(); + } + + mln::io::plot::save_image_sh(chart_size_c06, "front.c06.3d.size.sh"); + + // Test the size of the image c18 + // 1, 2, 4, 8, 16, 32, 64, 128, 256 + mln::image1d<float> chart_size_c18(128+1); + + mln::data::fill(chart_size_c18, mln::literal::zero); + + for (unsigned i = 6; i < 128+1; ++i) + { + influence_zone_front_3d(timer, build_input3d(2,i), mln::c18(), w3d_c18); + std::cout << "c18|" << i << "x" << i << "x" << i << "|8 = " + << timer.read() << std::endl; + mln::opt::at(chart_size_c18, i) = timer.read(); + } + + mln::io::plot::save_image_sh(chart_size_c18, "front.c18.3d.size.sh"); + + // Test the size of the image c26 + // 1, 2, 4, 8, 16, 32, 64, 128, 256 + mln::image1d<float> chart_size_c26(128+1); + + mln::data::fill(chart_size_c26, mln::literal::zero); + + for (unsigned i = 6; i < 128+1; ++i) + { + influence_zone_front_3d(timer, build_input3d(2,i), mln::c26(), w3d_c26); + std::cout << "c26|" << i << "x" << i << "x" << i << "|8 = " + << timer.read() << std::endl; + mln::opt::at(chart_size_c26, i) = timer.read(); + } + + mln::io::plot::save_image_sh(chart_size_c26, "front.c26.3d.size.sh"); +} + +void test_influence_zone_front_2d() +{ + mln::util::timer timer; + + int ws_c04[] = { + 0, 2, 0, + 2, 0, 2, + 0, 2, 0}; + + int ws_c08[] = { + 6, 4, 6, + 4, 0, 4, + 6, 4, 6}; + + mln::w_window2d_int w2d_c04 = mln::make::w_window2d_int(ws_c04); + mln::w_window2d_int w2d_c08 = mln::make::w_window2d_int(ws_c08); + + // Test the label c4 + mln::image1d<float> chart_seed_c04(16*16+2); + + mln::data::fill(chart_seed_c04, mln::literal::zero); + + for (unsigned i = 1; i < 16+1; ++i) + { + influence_zone_front_2d(timer,build_input2d(i,256),mln::c4(),w2d_c04); + std::cout << "c04|256x256|" << i << " = " << timer.read() << std::endl; + mln::opt::at(chart_seed_c04, i*i) = timer.read(); + } + + mln::io::plot::save_image_sh(chart_seed_c04, "front.c04.2d.seed.sh"); + + // Test the label c8 + mln::image1d<float> chart_seed_c08(16*16+2); + + mln::data::fill(chart_seed_c08, mln::literal::zero); + + for (unsigned i = 1; i < 16+1; ++i) + { + influence_zone_front_2d(timer,build_input2d(i,256),mln::c8(),w2d_c08); + std::cout << "c08|256x256|" << i << " = " << timer.read() << std::endl; + mln::opt::at(chart_seed_c08, i*i) = timer.read(); + } + + mln::io::plot::save_image_sh(chart_seed_c08, "front.c08.2d.seed.sh"); + + // Test the size of the image + // 1, 2, 4, 8, 16, 32, 64, 128, 256 + mln::image1d<float> chart_size_c04(256+1); + + mln::data::fill(chart_size_c04, mln::literal::zero); + + for (unsigned i = 16; i < 256+1; ++i) + { + influence_zone_front_2d(timer, build_input2d(4,i),mln::c4(),w2d_c04); + std::cout << "c04|" << i << "x" << i << "|16 = " + << timer.read() << std::endl; + mln::opt::at(chart_size_c04, i) = timer.read(); + } + + mln::io::plot::save_image_sh(chart_size_c04, "front.c04.2d.size.sh"); + + // Test the size of the image + // 1, 2, 4, 8, 16, 32, 64, 128, 256 + mln::image1d<float> chart_size_c08(256+1); + + mln::data::fill(chart_size_c08, mln::literal::zero); + + for (unsigned i = 16; i < 256+1; ++i) + { + influence_zone_front_2d(timer, build_input2d(4,i),mln::c8(),w2d_c08); + std::cout << "c08|" << i << "x" << i << "|16 = " + << timer.read() << std::endl; + mln::opt::at(chart_size_c08, i) = timer.read(); + } + + mln::io::plot::save_image_sh(chart_size_c08, "front.c08.2d.size.sh"); +} +/// \} + + + +/// Benchmark euclidian distance. +/// \{ +/// \brief The euclidian material for the benchmark process. +/// +/// This part of the file contains all we need to benchmarck the +/// euclidian distance. First of all, we have the calling functions +/// that encapsulate the real call to geodesic routine. They bring us +/// a clean place where starting and stopping the timer without any +/// other code interference. Printing results could be done at this step. +/// At least, we have the test routine that call the previous functions +/// by passing arguments like different size of inputs and different +/// neighbouring. The test routines save their results in gnuplot script shell +/// file that enable to show charts. +void influence_zone_euclidian_2d(mln::util::timer& timer, + const mln::image2d<mln::value::label_8>& input, + const mln::util::array<mln::point2d>& seed) +{ + mln::image2d<mln::value::label_8> output; + + timer.start(); + + mln::initialize(output, input); + + mln_piter_(mln::image2d<mln::value::label_8>) p(output.domain()); + mln_eiter_(mln::util::array<mln::point2d>) e(seed); + + for_all(p) + { + unsigned d = 0; + unsigned min_d = mln_max(unsigned); + unsigned min_l = 0; + + for_all(e) + { + d = distance(p, seed(e.index_())); + + if (min_d > d) + { + min_d = d; + min_l = input(e); + } + } + + output(p) = min_l; + } + + timer.stop(); + + //mln::io::pgm::save(output, "output.pgm"); +} + + +void influence_zone_euclidian_3d(mln::util::timer& timer, + const mln::image3d<mln::value::label_8>& input, + const mln::util::array<mln::point3d>& seed) +{ + mln::image3d<mln::value::label_8> output; + + timer.start(); + + mln::initialize(output, input); + + mln_piter_(mln::image3d<mln::value::label_8>) p(output.domain()); + mln_eiter_(mln::util::array<mln::point3d>) e(seed); + + for_all(p) + { + unsigned d = 0; + unsigned min_d = mln_max(unsigned); + unsigned min_l = 0; + + for_all(e) + { + d = distance(p, seed(e.index_())); + + if (min_d > d) + { + min_d = d; + min_l = input(e); + } + } + + output(p) = min_l; + } + + timer.stop(); +} + +void test_influence_zone_euclidian_2d() +{ + mln::util::timer timer; +/* + // Global test + mln::image2d<float> chart(mln::box2d(mln::point2d(0,0), + mln::point2d(16*16+2,256+1))); + + mln::data::fill(chart, mln::literal::zero); + + for (unsigned i = 1; i < 256+1; ++i) // size + for (unsigned j = 1; j < i*i && j < 16+1; ++j) // seed + { + influence_zone_euclidian_2d(timer,build_input2d(j,i),build_seed2d(j,i)); + std::cout << "xxx|" << i << "x" << i << "|" << j << " = " + << timer.read() << std::endl; + mln::opt::at(chart, j*j,i) = timer.read(); + } + + mln::io::plot::save_image_sh(chart, "chart.sh"); +*/ + + // Test the number of labels + mln::image1d<float> chart_seed(16*16+2); + + mln::data::fill(chart_seed, mln::literal::zero); + + for (unsigned i = 1; i < 16+1; ++i) + { + influence_zone_euclidian_2d(timer,build_input2d(i,256),build_seed2d(i,256)); + std::cout << "xxx|256x256|" << i << " = " << timer.read() << std::endl; + mln::opt::at(chart_seed, i*i) = timer.read(); + } + + mln::io::plot::save_image_sh(chart_seed, "euclidian.2d.seed.sh"); + + // Test the size of the image + // 1, 2, 4, 8, 16, 32, 64, 128, 256 + mln::image1d<float> chart_size(256+1); + + mln::data::fill(chart_size, mln::literal::zero); + + for (unsigned i = 16; i < 256+1; ++i) + { + influence_zone_euclidian_2d(timer, build_input2d(4,i), build_seed2d(4,i)); + std::cout << "xxx|" << i << "x" << i << "|16 = " + << timer.read() << std::endl; + mln::opt::at(chart_size, i) = timer.read(); + } + + mln::io::plot::save_image_sh(chart_size, "euclidian.2d.size.sh"); +} + +void test_influence_zone_euclidian_3d() +{ + mln::util::timer timer; + + // Test the number of labels + mln::image1d<float> chart_seed(5*5*5+2); + + mln::data::fill(chart_seed, mln::literal::zero); + + for (unsigned i = 1; i < 5+1; ++i) + { + influence_zone_euclidian_3d(timer,build_input3d(i,128),build_seed3d(i,128)); + std::cout << "xxx|128x128x128|" << i << " = " << timer.read() << std::endl; + mln::opt::at(chart_seed, i*i*i) = timer.read(); + } + + mln::io::plot::save_image_sh(chart_seed, "euclidian.3d.seed.sh"); + + // Test the size of the image + // 1, 2, 4, 8, 16, 32, 64, 128, 256 + mln::image1d<float> chart_size(128+1); + + mln::data::fill(chart_size, mln::literal::zero); + + for (unsigned i = 6; i < 128+1; ++i) + { + influence_zone_euclidian_3d(timer, build_input3d(2,i), build_seed3d(2,i)); + std::cout << "xxx|" << i << "x" << i << "x" << i << "|8 = " + << timer.read() << std::endl; + mln::opt::at(chart_size, i) = timer.read(); + } + + mln::io::plot::save_image_sh(chart_size, "euclidian.3d.size.sh"); +} +/// \} + +//------------------------------------------------------------------------------ +// Main +// +// Point de fonctionnement du système [image de taille entre 1 et 256] +// Moins de 16 labels +// +//------------------------------------------------------------------------------ + +/// \brief The main routine that call all the benchmark tests. +/// +/// This benchmark aim at comparing different kind of distance. It +/// looks after the influence geodesic, the influence front and +/// euclidian distance. Many files are generated. Some rules exist to +/// build the name of the file: +/// distance.neighbouring.dimension.(size|seed). The distance could be +/// the front distance (front), the geodesic distance (geodesic) or +/// the euclidian distance (euclidian). The neighbouring could be c04 +/// or c08 in 2d, c06, c18 or c26 in 3d. The dimension could be 2d or 3d. +/// Finally, the flag size or seed precises the nature of that test, increasing +/// gradualy the size of the image or increasing gradualy the number of seeds. +/// The file contains the time benchmark of the distance studied. +/// +/// \fixme test_influence_zone_geodesic_3d doesn't compile. +int main() +{ + test_influence_zone_euclidian_2d(); + test_influence_zone_front_2d(); + test_influence_zone_geodesic_2d(); + + // FIXME : It doesn't compile because of a bad calling function at_ in + // FIXME : the influence_zone_geodesic.hh line 127. + // test_influence_zone_geodesic_3d(); + test_influence_zone_front_3d(); + test_influence_zone_euclidian_3d(); + + return 0; +} diff --git a/scribo/sandbox/green/demo/clustering/kmean1d/Makefile.am b/scribo/sandbox/green/demo/clustering/kmean1d/Makefile.am new file mode 100644 index 0000000..4455a07 --- /dev/null +++ b/scribo/sandbox/green/demo/clustering/kmean1d/Makefile.am @@ -0,0 +1,153 @@ +# +# Generic Makefile +# + +######### +# TOOLS # +######### + +#LOADLIBES= -lboost_filesystem +INCLUDES1= -I$(HOME)/git/olena/scribo/sandbox/green +INCLUDES2= -I$(HOME)/git/olena/milena +INCLUDES= $(INCLUDES1) $(INCLUDES2) +CXXFLAGS= -ggdb -O0 -Wall -W -pedantic -ansi -pipe $(INCLUDES) +#CXXFLAGS= -DNDEBUG -O1 -Wall -W -pedantic -ansi -pipe $(INCLUDES) +#CXXFLAGS= -DNDEBUG -O3 -Wall -W -pedantic -ansi -pipe $(INCLUDES) +ECHO= echo +RM= rm +MKDIR= mkdir -p +CP= cp + +SOURCE_PATTERN= green/demo +BUILD__PATTERN= green/build/demo + + +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/scribo/sandbox/green/demo/clustering/kmean1d/kmean1d.cc b/scribo/sandbox/green/demo/clustering/kmean1d/kmean1d.cc new file mode 100644 index 0000000..22eae91 --- /dev/null +++ b/scribo/sandbox/green/demo/clustering/kmean1d/kmean1d.cc @@ -0,0 +1,258 @@ +// Copyright (C) 2007,2008,2009,2010 EPITA 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. + +/// \file +/// +/// \brief This is a demonstrator for kmean1d. +/// +/// The demonstrator produces five kind of results. The file +/// "color.ppm" allow us to localize the different center in the +/// image. There is an equivalent file "label.pgm" that's do the same +/// thing but inplace of a specific color, it gives the label of each +/// center. It's quit easy with xv, to transform the label image in +/// the color one. The file "mean.pgm" replaces each label by the mean +/// of the points that contributate to their center. It is a kind of +/// abstraction of the reality of the image, of its complexity. In +/// file "variance_cnv.sh" abscissa axis stands for the convergence +/// evolution and the ordinate axis for each runs. The "mean_cnv.sh" +/// file shows the evolution of the centers, whatever the run. The +/// x-axis represents the id of the center, the y-axis the iteration +/// in the convergence process and the z-axis the id of the particular +/// run. The graphic is very bad, but textual interpretation is still +/// available. + +#include <iostream> +#include <sstream> + +#include <mln/img_path.hh> + +#include <mln/clustering/kmean1d.hh> + +#include <mln/core/image/image2d.hh> + +#include <mln/io/pgm/load.hh> +#include <mln/io/pgm/save.hh> +#include <mln/io/ppm/save.hh> +#include <mln/io/plot/save_image_sh.hh> + +#include <mln/value/int_u8.hh> + + +/// \brief The real code for launching the kmean optimised algorithm. +/// +/// \param[in] image : the 8 bits greylevel image. +/// \param[in] k_center : the number of centers. +/// \param[in] n_times : the number of launching. +/// \param[in] watch_dog : the number of iterations to manage the convergence. +/// +/// This is the real lauching code. In fact, the stuff consists in loading the +/// image, setting the parameters, calling the routine, extracting the results +/// and saving them for the user. +/// +/// \fixme The result is not safe because we don't test kmean.is_valid() + +void do_demo(const std::string& image, + const unsigned k_center, + const unsigned n_times, + const unsigned watch_dog) +{ + typedef mln::clustering::kmean1d<double,8> t_kmean; + typedef mln::value::int_u8 t_int_u8; + typedef mln::image2d<t_int_u8> t_image2d_int_u8; + + t_image2d_int_u8 img; + + mln::io::pgm::load(img, image.c_str()); + + t_kmean kmean(img, + k_center, + watch_dog, + n_times); + + //mln::trace::quiet = false; + + kmean.launch_n_times(); + + // FIXME : Not safe because we don't test kmean.is_valid() + + t_kmean::t_color_dbg color_img = kmean.get_color_dbg(); + t_kmean::t_mean_dbg mean_img = kmean.get_mean_dbg(); + t_kmean::t_label_dbg label_img = kmean.get_label_dbg(); + t_kmean::t_variance_cnv var_cnv = kmean.get_variance_cnv(); + t_kmean::t_mean_cnv mean_cnv = kmean.get_mean_cnv(); + + mln::io::pgm::save(mean_img, "mean.pgm"); + mln::io::ppm::save(color_img, "color.ppm"); + mln::io::pgm::save(label_img, "label.pgm"); + + mln::io::plot::save_image_sh(mean_cnv, "mean_cnv.sh"); + mln::io::plot::save_image_sh(var_cnv, "variance_cnv.sh"); +} + + +/// \brief Front hand for the demonstrator. +/// +/// \param[in] image : the 8 bits greylevel image. +/// \param[in] k_center : the number of centers. +/// \param[in] n_times : the number of launching. +/// \param[in] watch_dog : the number of iterations to manage the convergence. +/// +/// The front hand enables the setting of the default values for the +/// parameters. it allows us to print the real parameter set used by +/// the demonstrator. +void demo(const std::string& image = OLENA_IMG_PATH"/house.pgm", + const unsigned k_center = 3, + const unsigned n_times = 10, + const unsigned watch_dog = 10) +{ + std::cout << "----------------------------------------" << std::endl; + std::cout << "Launching the demo with these parameters" << std::endl; + std::cout << "image : " << image << std::endl; + std::cout << "k_center : " << k_center << std::endl; + std::cout << "n_times : " << n_times << std::endl; + std::cout << "watch_dog : " << watch_dog << std::endl; + std::cout << "----------------------------------------" << std::endl; + + do_demo(image, k_center, n_times, watch_dog); +} + + +/// \brief Convert character get in the input stream to unsigned integer. +/// +/// \param[in] status : the exiting flag tell us to exit without doing any job. +/// \param[in] arg : the input argument to convert. +/// \param[out] val : the converted value to output. +/// +/// \return a flag that tell us if every thing is ok, if the result can be used. +bool char_to_unsigned(const bool status, const char *arg, unsigned& val) +{ + bool result = false; + + if (status) + { + std::istringstream arg_stream(arg); + + arg_stream >> val; + + result = !arg_stream.fail(); + } + + return result; +} + + +/// \brief Convert character get in the input stream to string. +/// +/// \param[in] status : the exiting flag tell us to exit without doing any job. +/// \param[in] arg : the input argument to convert. +/// \param[out] val : the converted value to output. +/// +/// \return a flag that tell us if every thing is ok, if the result can be used. +bool char_to_string(const bool status, const char *arg, std::string& val) +{ + bool result = false; + + if (status) + { + std::istringstream arg_stream(arg); + + arg_stream >> val; + + return !arg_stream.fail(); + } + + return result; +} + + +/// \brief Print usage recommandation for this binary. +/// +/// \param[in] argc : the exiting flag tell us to exit without doing any job. +/// \param[in] arg : the input argument to convert. +void usage(const int argc, const char *args[]) +{ + std::cout << "----------------------------------------" << std::endl; + std::cout << "argc : " << argc << std::endl; + + for (int i = 0; i < argc; ++i) + std::cout << "args[" << i << "] : " << args[i] << std::endl; + + std::cout << "----------------------------------------" << std::endl; + std::cout << "usage: kmean1d [image [k_center [n_times [watch_dog]]]]" + << std::endl; + std::cout << "pbm image (points to work with)" << std::endl; + std::cout << "unsigned k_center (number of centers)" << std::endl; + std::cout << "unsigned n_times (number of launching)" << std::endl; + std::cout << "unsigned watch_dog (convergence loop)" << std::endl; + std::cout << "----------------------------------------" << std::endl; +} + + +/// \brief The main routine launchs the kmean optimised algoritm. +/// +/// \param[in] image : the 8 bits greylevel image. +/// \param[in] k_center : the number of centers. +/// \param[in] n_times : the number of launching. +/// \param[in] watch_dog : the number of iterations to manage the convergence. +/// +/// All the parameters are optional, but we must respect strictly a +/// specific order. In fact, we can launch five programs with some +/// default parameters: demo(), demo(image), demo(image,k_center), +/// demo(image,k_center,n_times) and +/// demo(image,k_center,n_times,watch_dog). +int main(const int argc, const char *args[]) +{ + std::string image("top"); + unsigned k_center; + unsigned watch_dog; + unsigned n_times; + bool status = true; + + switch (argc) + { + case 5: status = char_to_unsigned(status, args[4], watch_dog); + case 4: status = char_to_unsigned(status, args[3], n_times); + case 3: status = char_to_unsigned(status, args[2], k_center); + case 2: status = char_to_string(status, args[1], image); break; + case 1: status = true; break; + default: status = false; + } + + if (status) + { + switch (argc) + { + case 1: demo(); break; + case 2: demo(image); break; + case 3: demo(image, k_center); break; + case 4: demo(image, k_center, n_times); break; + case 5: demo(image, k_center, n_times, watch_dog); break; + } + } + else + usage(argc, args); + + return 0; +} diff --git a/scribo/sandbox/green/demo/clustering/kmean2d/Makefile.am b/scribo/sandbox/green/demo/clustering/kmean2d/Makefile.am new file mode 100644 index 0000000..4455a07 --- /dev/null +++ b/scribo/sandbox/green/demo/clustering/kmean2d/Makefile.am @@ -0,0 +1,153 @@ +# +# Generic Makefile +# + +######### +# TOOLS # +######### + +#LOADLIBES= -lboost_filesystem +INCLUDES1= -I$(HOME)/git/olena/scribo/sandbox/green +INCLUDES2= -I$(HOME)/git/olena/milena +INCLUDES= $(INCLUDES1) $(INCLUDES2) +CXXFLAGS= -ggdb -O0 -Wall -W -pedantic -ansi -pipe $(INCLUDES) +#CXXFLAGS= -DNDEBUG -O1 -Wall -W -pedantic -ansi -pipe $(INCLUDES) +#CXXFLAGS= -DNDEBUG -O3 -Wall -W -pedantic -ansi -pipe $(INCLUDES) +ECHO= echo +RM= rm +MKDIR= mkdir -p +CP= cp + +SOURCE_PATTERN= green/demo +BUILD__PATTERN= green/build/demo + + +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/scribo/sandbox/green/demo/clustering/kmean2d/kmean2d.cc b/scribo/sandbox/green/demo/clustering/kmean2d/kmean2d.cc new file mode 100644 index 0000000..2538dce --- /dev/null +++ b/scribo/sandbox/green/demo/clustering/kmean2d/kmean2d.cc @@ -0,0 +1,278 @@ +// Copyright (C) 2007,2008,2009,2010 EPITA 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. + +/// \file +/// +/// \brief This is a demonstrator for kmean2d. +/// +/// The demonstrator produces five kind of results. The file +/// "color.ppm" allow us to localize the different center in the +/// image. There is an equivalent file "label.pgm" that's do the same +/// thing but inplace of a specific color, it gives the label of each +/// center. It's quit easy with xv, to transform the label image in +/// the color one. The file "mean.pgm" replaces each label by the mean +/// of the points that contributate to their center. It is a kind of +/// abstraction of the reality of the image, of its complexity. The +/// "variance_cnv.sh" changes its representation and becomes more +/// readable. The "mean_cnv.sh" have got a generation problem. We can +/// bypass it by adding printing lines in the 'splot' +/// instruction. However, the graphic is correct and mainly shows the +/// convergence of the center value. Finally, as the work takes place in +/// the r/g space, the "point.ppm" file shows us the exact input space. + +#include <iostream> +#include <sstream> + +#include <mln/img_path.hh> + +#include <mln/clustering/kmean2d.hh> + +#include <mln/core/image/image2d.hh> + +#include <mln/data/transform.hh> + +#include <mln/fun/v2v/rgb_to_rg.hh> +#include <mln/fun/v2v/rg_to_rgb.hh> + +#include <mln/io/pgm/save.hh> +#include <mln/io/ppm/load.hh> +#include <mln/io/ppm/save.hh> +#include <mln/io/plot/save_image_sh.hh> + +#include <mln/value/int_u8.hh> +#include <mln/value/rg.hh> +#include <mln/value/rgb8.hh> + + +/// \brief The real code for launching the kmean optimised algorithm. +/// +/// \param[in] image : the color image. +/// \param[in] k_center : the number of centers. +/// \param[in] n_times : the number of launching. +/// \param[in] watch_dog : the number of iterations to manage the convergence. +/// +/// This is the real lauching code. In fact, the stuff consists in loading the +/// image, setting the parameters, calling the routine, extracting the results +/// and saving them for the user. +/// +/// \fixme The result is not safe because we don't test kmean.is_valid() +void do_demo(const std::string& image, + const unsigned k_center, + const unsigned n_times, + const unsigned watch_dog) +{ + typedef mln::clustering::kmean2d<double,8> t_kmean; + typedef mln::value::rg<8> t_rg8; + typedef mln::value::rgb8 t_rgb8; + typedef mln::image2d<t_rgb8> t_image2d_rgb8; + typedef mln::image2d<t_rg8> t_image2d_rg8; + typedef mln::fun::v2v::rgb_to_rg<8> t_rgb_to_rg; + typedef mln::fun::v2v::rg_to_rgb<8> t_rg_to_rgb; + + t_image2d_rgb8 img_rgb8; + t_image2d_rgb8 point_img_rgb8; + t_image2d_rgb8 mean_img_rgb8; + t_image2d_rgb8 mean_dbg_rgb8; + t_image2d_rg8 img_rg8; + + // Read input. + mln::io::ppm::load(img_rgb8, image.c_str()); + img_rg8 = mln::data::transform(img_rgb8, t_rgb_to_rg()); + + // Call kmean. + t_kmean kmean(img_rg8, k_center, watch_dog, n_times); + + mln::trace::quiet = false; + kmean.launch_n_times(); + + // FIXME : Not safe because we don't test kmean.is_valid() + + // Get outputs. + t_kmean::t_point_img point_img = kmean.get_point(); + t_kmean::t_color_dbg color_img = kmean.get_color_dbg(); + t_kmean::t_mean_dbg mean_img = kmean.get_mean_dbg(); + t_kmean::t_label_dbg label_img = kmean.get_label_dbg(); + t_kmean::t_variance_cnv variance_cnv = kmean.get_variance_cnv(); + t_kmean::t_mean_cnv mean_cnv = kmean.get_mean_cnv(); + + // Convert outputs. + point_img_rgb8 = mln::data::transform(point_img, t_rg_to_rgb()); + mean_img_rgb8 = mln::data::transform(mean_img, t_rg_to_rgb()); + + mln::io::ppm::save(mean_img_rgb8, "mean.ppm"); + mln::io::ppm::save(color_img, "color.ppm"); + mln::io::pgm::save(label_img, "label.pgm"); + mln::io::ppm::save(point_img_rgb8, "point.ppm"); + + mln::io::plot::save_image_sh(mean_cnv, "mean_cnv.sh"); + mln::io::plot::save_image_sh(variance_cnv, "variance_cnv.sh"); +} + + +/// \brief Front hand for the demonstrator. +/// +/// \param[in] image : the color image. +/// \param[in] k_center : the number of centers. +/// \param[in] n_times : the number of launching. +/// \param[in] watch_dog : the number of iterations to manage the convergence. +/// +/// The front hand enables the setting of the default values for the +/// parameters. it allows us to print the real parameter set used by +/// the demonstrator. +void demo(const std::string& image = OLENA_IMG_PATH"/house.ppm", + const unsigned k_center = 3, + const unsigned n_times = 10, + const unsigned watch_dog = 10) +{ + std::cout << "----------------------------------------" << std::endl; + std::cout << "Launching the demo with these parameters" << std::endl; + std::cout << "image : " << image << std::endl; + std::cout << "k_center : " << k_center << std::endl; + std::cout << "n_times : " << n_times << std::endl; + std::cout << "watch_dog : " << watch_dog << std::endl; + std::cout << "----------------------------------------" << std::endl; + + do_demo(image, k_center, n_times, watch_dog); +} + + +/// \brief Convert character get in the input stream to unsigned integer. +/// +/// \param[in] status : the exiting flag tell us to exit without doing any job. +/// \param[in] arg : the input argument to convert. +/// \param[out] val : the converted value to output. +/// +/// \return a flag that tell us if every thing is ok, if the result can be used. +bool char_to_unsigned(const bool status, const char *arg, unsigned& val) +{ + bool result = false; + + if (status) + { + std::istringstream arg_stream(arg); + + arg_stream >> val; + + result = !arg_stream.fail(); + } + + return result; +} + + +/// \brief Convert character get in the input stream to string. +/// +/// \param[in] status : the exiting flag tell us to exit without doing any job. +/// \param[in] arg : the input argument to convert. +/// \param[out] val : the converted value to output. +/// +/// \return a flag that tell us if every thing is ok, if the result can be used. +bool char_to_string(const bool status, const char *arg, std::string& val) +{ + bool result = false; + + if (status) + { + std::istringstream arg_stream(arg); + + arg_stream >> val; + + return !arg_stream.fail(); + } + + return result; +} + + +/// \brief Print usage recommandation for this binary. +/// +/// \param[in] argc : the exiting flag tell us to exit without doing any job. +/// \param[in] arg : the input argument to convert. +void usage(const int argc, const char *args[]) +{ + std::cout << "----------------------------------------" << std::endl; + std::cout << "argc : " << argc << std::endl; + + for (int i = 0; i < argc; ++i) + std::cout << "args[" << i << "] : " << args[i] << std::endl; + + std::cout << "----------------------------------------" << std::endl; + std::cout << "usage: kmean2d [image [k_center [n_times [watch_dog]]]]" + << std::endl; + std::cout << "ppm image (points to work with)" << std::endl; + std::cout << "unsigned k_center (number of centers)" << std::endl; + std::cout << "unsigned n_times (number of launching)" << std::endl; + std::cout << "unsigned watch_dog (convergence loop)" << std::endl; + std::cout << "----------------------------------------" << std::endl; +} + + +/// \brief The main routine launchs the kmean optimised algoritm. +/// +/// \param[in] image : the color image. +/// \param[in] k_center : the number of centers. +/// \param[in] n_times : the number of launching. +/// \param[in] watch_dog : the number of iterations to manage the convergence. +/// +/// All the parameters are optional, but we must respect strictly a +/// specific order. In fact, we can launch five programs with some +/// default parameters: demo(), demo(image), demo(image,k_center), +/// demo(image,k_center,n_times) and +/// demo(image,k_center,n_times,watch_dog). +int main(const int argc, const char *args[]) +{ + std::string image("top"); + unsigned k_center; + unsigned watch_dog; + unsigned n_times; + bool status = true; + + switch (argc) + { + case 5: status = char_to_unsigned(status, args[4], watch_dog); + case 4: status = char_to_unsigned(status, args[3], n_times); + case 3: status = char_to_unsigned(status, args[2], k_center); + case 2: status = char_to_string(status, args[1], image); break; + case 1: status = true; break; + default: status = false; + } + + if (status) + { + switch (argc) + { + case 1: demo(); break; + case 2: demo(image); break; + case 3: demo(image, k_center); break; + case 4: demo(image, k_center, n_times); break; + case 5: demo(image, k_center, n_times, watch_dog); break; + } + } + else + usage(argc, args); + + return 0; +} + diff --git a/scribo/sandbox/green/demo/clustering/kmean3d/Makefile.am b/scribo/sandbox/green/demo/clustering/kmean3d/Makefile.am new file mode 100644 index 0000000..4455a07 --- /dev/null +++ b/scribo/sandbox/green/demo/clustering/kmean3d/Makefile.am @@ -0,0 +1,153 @@ +# +# Generic Makefile +# + +######### +# TOOLS # +######### + +#LOADLIBES= -lboost_filesystem +INCLUDES1= -I$(HOME)/git/olena/scribo/sandbox/green +INCLUDES2= -I$(HOME)/git/olena/milena +INCLUDES= $(INCLUDES1) $(INCLUDES2) +CXXFLAGS= -ggdb -O0 -Wall -W -pedantic -ansi -pipe $(INCLUDES) +#CXXFLAGS= -DNDEBUG -O1 -Wall -W -pedantic -ansi -pipe $(INCLUDES) +#CXXFLAGS= -DNDEBUG -O3 -Wall -W -pedantic -ansi -pipe $(INCLUDES) +ECHO= echo +RM= rm +MKDIR= mkdir -p +CP= cp + +SOURCE_PATTERN= green/demo +BUILD__PATTERN= green/build/demo + + +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/scribo/sandbox/green/demo/clustering/kmean3d/kmean3d.cc b/scribo/sandbox/green/demo/clustering/kmean3d/kmean3d.cc new file mode 100644 index 0000000..0e2b16e --- /dev/null +++ b/scribo/sandbox/green/demo/clustering/kmean3d/kmean3d.cc @@ -0,0 +1,265 @@ +// Copyright (C) 2007,2008,2009,2010 EPITA 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. + +/// \file +/// +/// \brief This is a demonstrator for kmean3d. +/// +/// The demonstrator produces five kind of results. The file +/// "color.ppm" allow us to localize the different center in the +/// image. There is an equivalent file "label.pgm" that's do the same +/// thing but inplace of a specific color, it gives the label of each +/// center. It's quit easy with xv, to transform the label image in +/// the color one. The file "mean.pgm" replaces each label by the mean +/// of the points that contributate to their center. It is a kind of +/// abstraction of the reality of the image, of its complexity. The +/// "variance_cnv.sh" changes its representation and becomes more +/// readable. The "mean_cnv.sh" have got a generation problem. We can +/// bypass it by adding printing lines in the 'splot' +/// instruction. However, the graphic is correct and mainly shows the +/// convergence of the center value. + +#include <iostream> +#include <sstream> + +#include <mln/clustering/kmean3d.hh> + +#include <mln/core/macros.hh> +#include <mln/core/image/image2d.hh> + +#include <mln/data/transform.hh> + +#include <mln/fun/v2v/rgb8_to_rgbn.hh> + +#include <mln/io/ppm/load.hh> +#include <mln/io/pgm/load.hh> +#include <mln/io/pgm/save.hh> +#include <mln/io/ppm/save.hh> +#include <mln/io/plot/save_image_sh.hh> + +#include <mln/img_path.hh> + +#include <mln/value/int_u8.hh> +#include <mln/value/label_8.hh> +#include <mln/value/rgb8.hh> + + +/// \brief The real code for launching the kmean optimised algorithm. +/// +/// \param[in] image : the color image. +/// \param[in] k_center : the number of centers. +/// \param[in] n_times : the number of launching. +/// \param[in] watch_dog : the number of iterations to manage the convergence. +/// +/// This is the real lauching code. In fact, the stuff consists in loading the +/// image, setting the parameters, calling the routine, extracting the results +/// and saving them for the user. +/// +/// \fixme The result is not safe because we don't test kmean.is_valid() +void do_demo(const std::string& image, + const unsigned k_center, + const unsigned n_times, + const unsigned watch_dog) +{ + typedef mln::clustering::kmean3d<double,5> t_kmean; + typedef mln::value::label_8 t_label_8; + typedef mln::value::rgb8 t_rgb8; + typedef mln::value::rgb<5> t_rgb5; + typedef mln::image2d<t_rgb8> t_image2d_rgb8; + typedef mln::image2d<t_rgb5> t_image2d_rgb5; + + t_image2d_rgb8 house_rgb8; + t_image2d_rgb5 house_rgb5; + + mln::io::ppm::load(house_rgb8, image.c_str()); + house_rgb5=mln::data::transform(house_rgb8,mln::fun::v2v::rgb8_to_rgbn<5>()); + + t_kmean kmean(house_rgb5, k_center, watch_dog, n_times); + + mln::trace::quiet = false; + + kmean.launch_n_times(); + + // FIXME : Not safe because we don't test kmean.is_valid() + + t_kmean::t_color_dbg color_img = kmean.get_color_dbg(); + t_kmean::t_mean_dbg mean_img = kmean.get_mean_dbg(); + t_kmean::t_label_dbg label_img = kmean.get_label_dbg(); + t_kmean::t_variance_cnv variance_cnv = kmean.get_variance_cnv(); + t_kmean::t_mean_cnv mean_cnv = kmean.get_mean_cnv(); + + mln::io::ppm::save(mean_img, "mean.ppm"); + mln::io::ppm::save(color_img, "color.ppm"); + mln::io::pgm::save(label_img, "label.pgm"); + + mln::io::plot::save_image_sh(mean_img, "mean.sh"); + mln::io::plot::save_image_sh(mean_cnv, "mean_cnv.sh"); + mln::io::plot::save_image_sh(variance_cnv, "variance_cnv.sh"); +} + +/// \brief Front hand for the demonstrator. +/// +/// \param[in] image : the color image. +/// \param[in] k_center : the number of centers. +/// \param[in] n_times : the number of launching. +/// \param[in] watch_dog : the number of iterations to manage the convergence. +/// +/// The front hand enables the setting of the default values for the +/// parameters. it allows us to print the real parameter set used by +/// the demonstrator. +void demo(const std::string& image = OLENA_IMG_PATH"/house.ppm", + const unsigned k_center = 3, + const unsigned n_times = 10, + const unsigned watch_dog = 10) +{ + std::cout << "----------------------------------------" << std::endl; + std::cout << "Launching the demo with these parameters" << std::endl; + std::cout << "image : " << image << std::endl; + std::cout << "k_center : " << k_center << std::endl; + std::cout << "n_times : " << n_times << std::endl; + std::cout << "watch_dog : " << watch_dog << std::endl; + std::cout << "----------------------------------------" << std::endl; + + do_demo(image, k_center, n_times, watch_dog); +} + + +/// \brief Convert character get in the input stream to unsigned integer. +/// +/// \param[in] status : the exiting flag tell us to exit without doing any job. +/// \param[in] arg : the input argument to convert. +/// \param[out] val : the converted value to output. +/// +/// \return a flag that tell us if every thing is ok, if the result can be used. +bool char_to_unsigned(const bool status, const char *arg, unsigned& val) +{ + bool result = false; + + if (status) + { + std::istringstream arg_stream(arg); + + arg_stream >> val; + + result = !arg_stream.fail(); + } + + return result; +} + + +/// \brief Convert character get in the input stream to string. +/// +/// \param[in] status : the exiting flag tell us to exit without doing any job. +/// \param[in] arg : the input argument to convert. +/// \param[out] val : the converted value to output. +/// +/// \return a flag that tell us if every thing is ok, if the result can be used. +bool char_to_string(const bool status, const char *arg, std::string& val) +{ + bool result = false; + + if (status) + { + std::istringstream arg_stream(arg); + + arg_stream >> val; + + return !arg_stream.fail(); + } + + return result; +} + + +/// \brief Print usage recommandation for this binary. +/// +/// \param[in] argc : the exiting flag tell us to exit without doing any job. +/// \param[in] arg : the input argument to convert. +void usage(const int argc, const char *args[]) +{ + std::cout << "----------------------------------------" << std::endl; + std::cout << "argc : " << argc << std::endl; + + for (int i = 0; i < argc; ++i) + std::cout << "args[" << i << "] : " << args[i] << std::endl; + + std::cout << "----------------------------------------" << std::endl; + std::cout << "usage: kmean1d [image [k_center [n_times [watch_dog]]]]" + << std::endl; + std::cout << "pbm image (points to work with)" << std::endl; + std::cout << "unsigned k_center (number of centers)" << std::endl; + std::cout << "unsigned n_times (number of launching)" << std::endl; + std::cout << "unsigned watch_dog (convergence loop)" << std::endl; + std::cout << "----------------------------------------" << std::endl; +} + + +/// \brief The main routine launchs the kmean optimised algoritm. +/// +/// \param[in] image : the color image. +/// \param[in] k_center : the number of centers. +/// \param[in] n_times : the number of launching. +/// \param[in] watch_dog : the number of iterations to manage the convergence. +/// +/// All the parameters are optional, but we must respect strictly a +/// specific order. In fact, we can launch five programs with some +/// default parameters: demo(), demo(image), demo(image,k_center), +/// demo(image,k_center,n_times) and +/// demo(image,k_center,n_times,watch_dog). +int main(const int argc, const char *args[]) +{ + std::string image("top"); + unsigned k_center; + unsigned watch_dog; + unsigned n_times; + bool status = true; + + switch (argc) + { + case 5: status = char_to_unsigned(status, args[4], watch_dog); + case 4: status = char_to_unsigned(status, args[3], n_times); + case 3: status = char_to_unsigned(status, args[2], k_center); + case 2: status = char_to_string(status, args[1], image); break; + case 1: status = true; break; + default: status = false; + } + + if (status) + { + switch (argc) + { + case 1: demo(); break; + case 2: demo(image); break; + case 3: demo(image, k_center); break; + case 4: demo(image, k_center, n_times); break; + case 5: demo(image, k_center, n_times, watch_dog); break; + } + } + else + usage(argc, args); + + return 0; +} diff --git a/scribo/sandbox/green/demo/clustering/kmean_rgb/Makefile.am b/scribo/sandbox/green/demo/clustering/kmean_rgb/Makefile.am new file mode 100644 index 0000000..4455a07 --- /dev/null +++ b/scribo/sandbox/green/demo/clustering/kmean_rgb/Makefile.am @@ -0,0 +1,153 @@ +# +# Generic Makefile +# + +######### +# TOOLS # +######### + +#LOADLIBES= -lboost_filesystem +INCLUDES1= -I$(HOME)/git/olena/scribo/sandbox/green +INCLUDES2= -I$(HOME)/git/olena/milena +INCLUDES= $(INCLUDES1) $(INCLUDES2) +CXXFLAGS= -ggdb -O0 -Wall -W -pedantic -ansi -pipe $(INCLUDES) +#CXXFLAGS= -DNDEBUG -O1 -Wall -W -pedantic -ansi -pipe $(INCLUDES) +#CXXFLAGS= -DNDEBUG -O3 -Wall -W -pedantic -ansi -pipe $(INCLUDES) +ECHO= echo +RM= rm +MKDIR= mkdir -p +CP= cp + +SOURCE_PATTERN= green/demo +BUILD__PATTERN= green/build/demo + + +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/scribo/sandbox/green/demo/clustering/kmean_rgb/kmean_rgb.cc b/scribo/sandbox/green/demo/clustering/kmean_rgb/kmean_rgb.cc new file mode 100644 index 0000000..d02c497 --- /dev/null +++ b/scribo/sandbox/green/demo/clustering/kmean_rgb/kmean_rgb.cc @@ -0,0 +1,239 @@ +// Copyright (C) 2007,2008,2009,2010 EPITA 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. + +/// \file +/// +/// \brief This is a demonstrator for kmean_rgb. +/// +/// The code is provided as is. It is an alpha version, so very very +/// experimental. Take care !! + +#include <iostream> +#include <sstream> + +#include <mln/clustering/kmean_rgb.hh> + +#include <mln/core/macros.hh> +#include <mln/core/image/image2d.hh> + +#include <mln/data/transform.hh> + +#include <mln/fun/v2v/rgb8_to_rgbn.hh> + +#include <mln/io/ppm/load.hh> +#include <mln/io/pgm/load.hh> +#include <mln/io/pgm/save.hh> +#include <mln/io/ppm/save.hh> +#include <mln/io/plot/save_image_sh.hh> + +#include <mln/img_path.hh> + +#include <mln/value/int_u8.hh> +#include <mln/value/label_8.hh> +#include <mln/value/rgb8.hh> + + +/// \brief The real code for launching the kmean optimised algorithm. +/// +/// \param[in] image : the color image. +/// \param[in] k_center : the number of centers. +/// \param[in] n_times : the number of launching. +/// \param[in] watch_dog : the number of iterations to manage the convergence. +/// +/// This is the real lauching code. In fact, the stuff consists in loading the +/// image, setting the parameters, calling the routine, extracting the results +/// and saving them for the user. +/// +/// \fixme The result is not safe because we don't test kmean.is_valid() +void do_demo(const std::string& image, + const unsigned k_center, + const unsigned n_times, + const unsigned watch_dog) +{ + typedef mln::value::label_8 t_lbl8; + typedef mln::value::rgb8 t_rgb8; + typedef mln::value::rgb<5> t_rgb5; + typedef mln::image2d<t_rgb8> t_image2d_rgb8; + typedef mln::image2d<t_rgb5> t_image2d_rgb5; + typedef mln::image2d<t_lbl8> t_image2d_lbl8; + + t_image2d_rgb8 img_rgb8; + t_image2d_rgb5 img_rgb5; + t_image2d_lbl8 img_lbl8; + + mln::io::ppm::load(img_rgb8, image.c_str()); + img_rgb5 = mln::data::transform(img_rgb8,mln::fun::v2v::rgb8_to_rgbn<5>()); + img_lbl8 = mln::clustering::kmean_rgb<double,5>(img_rgb5, + k_center, + watch_dog, + n_times); + + mln::io::pgm::save(img_lbl8, "label.pgm"); +} + +/// \brief Front hand for the demonstrator. +/// +/// \param[in] image : the color image. +/// \param[in] k_center : the number of centers. +/// \param[in] n_times : the number of launching. +/// \param[in] watch_dog : the number of iterations to manage the convergence. +/// +/// The front hand enables the setting of the default values for the +/// parameters. it allows us to print the real parameter set used by +/// the demonstrator. +void demo(const std::string& image = OLENA_IMG_PATH"/house.ppm", + const unsigned k_center = 3, + const unsigned n_times = 3, + const unsigned watch_dog = 3) +{ + std::cout << "----------------------------------------" << std::endl; + std::cout << "Launching the demo with these parameters" << std::endl; + std::cout << "image : " << image << std::endl; + std::cout << "k_center : " << k_center << std::endl; + std::cout << "n_times : " << n_times << std::endl; + std::cout << "watch_dog : " << watch_dog << std::endl; + std::cout << "----------------------------------------" << std::endl; + + do_demo(image, k_center, n_times, watch_dog); +} + + +/// \brief Convert character get in the input stream to unsigned integer. +/// +/// \param[in] status : the exiting flag tell us to exit without doing any job. +/// \param[in] arg : the input argument to convert. +/// \param[out] val : the converted value to output. +/// +/// \return a flag that tell us if every thing is ok, if the result can be used. +bool char_to_unsigned(const bool status, const char *arg, unsigned& val) +{ + bool result = false; + + if (status) + { + std::istringstream arg_stream(arg); + + arg_stream >> val; + + result = !arg_stream.fail(); + } + + return result; +} + + +/// \brief Convert character get in the input stream to string. +/// +/// \param[in] status : the exiting flag tell us to exit without doing any job. +/// \param[in] arg : the input argument to convert. +/// \param[out] val : the converted value to output. +/// +/// \return a flag that tell us if every thing is ok, if the result can be used. +bool char_to_string(const bool status, const char *arg, std::string& val) +{ + bool result = false; + + if (status) + { + std::istringstream arg_stream(arg); + + arg_stream >> val; + + return !arg_stream.fail(); + } + + return result; +} + + +/// \brief Print usage recommandation for this binary. +/// +/// \param[in] argc : the exiting flag tell us to exit without doing any job. +/// \param[in] arg : the input argument to convert. +void usage(const int argc, const char *args[]) +{ + std::cout << "----------------------------------------" << std::endl; + std::cout << "argc : " << argc << std::endl; + + for (int i = 0; i < argc; ++i) + std::cout << "args[" << i << "] : " << args[i] << std::endl; + + std::cout << "----------------------------------------" << std::endl; + std::cout << "usage: kmean1d [image [k_center [n_times [watch_dog]]]]" + << std::endl; + std::cout << "pbm image (points to work with)" << std::endl; + std::cout << "unsigned k_center (number of centers)" << std::endl; + std::cout << "unsigned n_times (number of launching)" << std::endl; + std::cout << "unsigned watch_dog (convergence loop)" << std::endl; + std::cout << "----------------------------------------" << std::endl; +} + + +/// \brief The main routine launchs the kmean optimised algoritm. +/// +/// \param[in] image : the color image. +/// \param[in] k_center : the number of centers. +/// \param[in] n_times : the number of launching. +/// \param[in] watch_dog : the number of iterations to manage the convergence. +/// +/// All the parameters are optional, but we must respect strictly a +/// specific order. In fact, we can launch five programs with some +/// default parameters: demo(), demo(image), demo(image,k_center), +/// demo(image,k_center,n_times) and +/// demo(image,k_center,n_times,watch_dog). +int main(const int argc, const char *args[]) +{ + std::string image("top"); + unsigned k_center; + unsigned watch_dog; + unsigned n_times; + bool status = true; + + switch (argc) + { + case 5: status = char_to_unsigned(status, args[4], watch_dog); + case 4: status = char_to_unsigned(status, args[3], n_times); + case 3: status = char_to_unsigned(status, args[2], k_center); + case 2: status = char_to_string(status, args[1], image); break; + case 1: status = true; break; + default: status = false; + } + + if (status) + { + switch (argc) + { + case 1: demo(); break; + case 2: demo(image); break; + case 3: demo(image, k_center); break; + case 4: demo(image, k_center, n_times); break; + case 5: demo(image, k_center, n_times, watch_dog); break; + } + } + else + usage(argc, args); + + return 0; +} diff --git a/scribo/sandbox/green/mln/clustering/k_mean.hh b/scribo/sandbox/green/mln/clustering/k_mean.hh index db3f34c..74acda7 100644 --- a/scribo/sandbox/green/mln/clustering/k_mean.hh +++ b/scribo/sandbox/green/mln/clustering/k_mean.hh @@ -1,6 +1,4 @@ -// 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) +// Copyright (C) 2007,2008,2009,2010 EPITA LRDE // // This file is part of Olena. // @@ -26,43 +24,89 @@ // executable file might be covered by the GNU General Public License. #ifndef MLN_CLUSTERING_K_MEAN_HH -#define MLN_CLUSTERING_K_MEAN_HH +# define MLN_CLUSTERING_K_MEAN_HH /// \file /// -/// \brief Implements the K MEAN algorithm. -/// DO -/// - ASSIGNEMENT STEP -/// - UPDATE STEP -/// LOOP UNTIL CONVERGENCE +/// \brief Implement the K MEAN algorithm with matrix and vectors. /// -/// ASSIGNEMENT STEP +/// This is the first impementation of the kmean algorithm. There is no +/// specific optimisation but every part of the algorithm is here and +/// it works. As it used vectors and matrices, it is not very convenient to +/// work with this version. +/// +/// \verbatim +/// This is the main lines of the kmean algorithm: +/// +/// PROCEDURE MAIN +/// BEGIN +/// DO +/// - CALL ASSIGNEMENT STEP +/// - CALL UPDATE STEP +/// LOOP UNTIL CONVERGENCE +/// END +/// +/// PROCEDURE ASSIGNEMENT STEP /// BEGIN -/// - COMPUTE THE DISTANCE MATRIX FROM POINTS TO CENTERS -/// - COMPUTE GROUP MATRIX WHERE EACH POINT IS ASSIGNED TO NEAREST CENTER +/// - COMPUTE THE DISTANCE MATRIX FROM POINTS TO CENTERS +/// - COMPUTE GROUP MATRIX WHERE EACH POINT IS ASSIGNED TO THE NEAREST CENTER /// END /// -/// UPDATE STEP +/// PROCEDURE UPDATE STEP /// BEGIN -/// - COMPUTE THE MEAN OF THE GROUPS WHICH ARE THE NEW CENTERS +/// - COMPUTE THE MEAN OF THE GROUPS WHICH ARE NOW THE NEW CENTERS /// END +/// \endvarbitim +/// +/// The following sample is the standard use of this first +/// implementation. The number of centers is a decision left to the +/// final user. As the representation uses vectors and matices, size +/// of each objects must be known at compile time, and so NB_POINT must be +/// a constant expression (mln::geom::nsites couldn't be called). +/// +/// #include <mln/clustering/k_mean.hh> +/// #include <mln/core/image/image2d.hh> +/// #include <mln/img_path.hh> +/// #include <mln/io/ppm/load.hh> +/// #include <mln/trait/value_.hh> +/// #include <mln/value/rgb8.hh> +/// +/// #define NB_CENTER 9 +/// #define NB_POINT (128*128) +/// #define POINT_SIZE mln_dim(mln::value::rgb8) +/// #define POINT_TYPE double +/// +/// int main() +/// { +/// typedef mln::value::rgb8 t_rgb8; +/// mln::image2d<t_rgb8> img_rgb8; +/// +/// mln::io::ppm::load(img_ref, OLENA_IMG_PATH"/house.ppm"); +/// mln::clustering::k_mean<NB_POINT,NB_CENTER,POINT_SIZE,POINT_TYPE> kmean; +/// +/// kmean.init_point(img_rgb8); +/// kmean.loop(img_rgb8); +/// +/// return 0; +/// } + +# include <limits.h> +# include <iostream> -#include <limits.h> -#include <iostream> -#include <mln/trace/entering.hh> -#include <mln/trace/exiting.hh> +# include <mln/algebra/mat.hh> +# include <mln/algebra/vec.hh> -#include <mln/core/contract.hh> -#include <mln/trait/value_.hh> +# include <mln/core/concept/image.hh> +# include <mln/core/contract.hh> +# include <mln/core/macros.hh> -#include <mln/algebra/mat.hh> -#include <mln/algebra/vec.hh> +# include <mln/math/min.hh> +# include <mln/norm/l2.hh> -#include <mln/math/min.hh> -#include <mln/norm/l2.hh> +# include <mln/trace/entering.hh> +# include <mln/trace/exiting.hh> -#include <mln/core/concept/image.hh> -#include <mln/core/macros.hh> +# include <mln/trait/value_.hh> namespace mln { @@ -78,149 +122,221 @@ namespace mln namespace clustering { - - // - // PARAM : DIM VECTOR, NUMBER OF CLASSES - // INPUT : MATRIX 1..N (SAMPLE) - // WORK - // - - // n is the size of the sample. - // k is the number of centers. - // p is the number of attributes for a point. - // T is the type for computations. + + /// \brief Implements the K MEAN algorithm with matrix and vectors. + /// + /// Param n is the size of the sample (the number of point to be + /// classified). Param k is the number of centers, at the end, + /// each point is link to one the nearest center. Param p is the + /// number of attributes of a point, in fact its dimension (int_u8 + /// = 1, rgb8 = 3, etc ...). Param T is the type used for + /// computations, the type of the point, typiccaly float or + /// double. + /// + /// \ingroup modclustering template <unsigned n, unsigned k, unsigned p, typename T> struct k_mean { - //------------------------------------------------------------------------ - // Constructor and destructor - //------------------------------------------------------------------------ - + /// Constructors and destructors. + /// \{ + /// \brief Allocate or deallocate the data structure. + /// + /// Allocate or deallocate the _point, _distance, _group, + /// _center, _variance data structure with the correct size. k_mean(); ~k_mean(); + /// \} - //------------------------------------------------------------------------ - // Accessors - //------------------------------------------------------------------------ - + /// Accessors. + /// \{ + /// \brief Hack to view temporary results of the kmean algorithm. + /// + /// These methods are necessary for unitary testing and debugging. algebra::mat<n, p, T>& get_point(); algebra::mat<k, p, T>& get_center(); algebra::mat<n, k, T>& get_distance(); algebra::mat<n, k, T>& get_group(); algebra::vec<k, T>& get_variance(); + /// \} - - //------------------------------------------------------------------------ - // Tools - //------------------------------------------------------------------------ + /// Tools. + /// \{ + /// \brief Define elementary function that are not available from milena. + /// + /// These methods are not interesting from the kmean'point of + /// view but are required for the gluing process. - /// \brief Return the euclidian distance beetween vector x and vector y. + /// \brief Return the euclidian distance beetween two vectors x and y. /// /// Compute the f$\sqrt(\sum_{i=0}^P ((x_i - y_i)^2)$f /// - /// \param[in] x a vector of dimension 1xP. - /// \param[in] y a second vector of dimension 1xP. + /// \param[in] x a vector of dimension p. + /// \param[in] y a second vector of dimension p. /// \return the distance between x and y. - mln_sum_product(T,T) euclidian_distance(const algebra::vec<p,T>& x, const algebra::vec<p,T>& y) const; - /// \brief Return the ith column. - /// - /// \param[in] m a matrix of dimension {N or K}xP. - /// \return the ith column as a vector of dimension 1xP. - - /// \brief Return the ith column. + /// \brief Return a stack copy of the ith column. /// - /// \param[in] m a matrix of dimension {N or K}xP. - /// \return the ith column as a vector of dimension 1xP. + /// \param[in] m a matrix of dimension r x q. + /// \param[in] _col the index of the selected column. + /// \return a stack copy of the ith column as a vector of dimension q. template <unsigned q, unsigned r> algebra::vec<q,T> col(const algebra::mat<r, q, T>& m, const unsigned _col) const; + + /// \brief Return a heap copy of the ith col. + /// + /// \param[in] m a matrix of dimension r x q. + /// \param[in] _col the index of the selected column. + /// \return a heap copy of the ith column as a vector of dimension q. template <unsigned q, unsigned r> algebra::vec<q,T>* ptr_col(const algebra::mat<r, q, T>& m, const unsigned _col) const; + + /// \brief Return a stack copy of the ith row. + /// + /// \param[in] m a matrix of dimension r x q. + /// \param[in] _row the index of the selected row. + /// \return a stack copy of the ith row as a vector of dimension q. template <unsigned q, unsigned r> algebra::vec<r,T> row(const algebra::mat<r, q, T>& m, const unsigned _row) const; + + /// \brief Divide inplace a column of the matrix by a scalar. + /// + /// \param[in] m a matrix of dimension r x q. + /// \param[in] _col the index of the selected column. + /// \param[in] value the scalar by which dividing the column. template <unsigned q, unsigned r> void div_col(algebra::mat<r, q, T>& m, const unsigned _col, const T value); + + /// \brief Sum all the elements of one row. + /// + /// \param[in] m a matrix of dimension r x q. + /// \param[in] _row the index of the selected row. + /// \return the sum of every attributes of the row. template <unsigned q, unsigned r> mln_sum(T) sum_row(const algebra::mat<r, q, T>& m, const unsigned _row) const; + + /// \brief Return the minimum of a vector. + /// + /// \param[in] x a vector of dimension q. + /// \return the mininum of that input vector. template <unsigned q, typename M> M min_col(const algebra::vec<q, M>& x) const; + /// \} - //------------------------------------------------------------------------ - // Initializations of points and centers - //------------------------------------------------------------------------ - - /// \brief Initialize the matrix _point with the pixels of an image. + /// Initializations. + /// \{ + /// \brief Initialize the _point and _center data structure. /// - /// \param[in] input an image which contains the data points. + /// The _point data structure is fed with the value of the input + /// image. The _center data structure is fed with random points + /// taken from the input image. template <typename I> void init_point(const Image<I>& _input); void init_center(); + /// \} - - //------------------------------------------------------------------------ - // Computations of distance, group, center, within variance - //------------------------------------------------------------------------ + /// Computations. + /// \{ + /// \brief Define the core routines of the kmean algorithm. + /// + /// The update_distance, update_group, update_center and update_variance + /// define the core kmean routines. If some optimization muste be done, + /// one may looks here. + + + /// \brief Update the _distance data structure. + /// + /// Compute the square distance between each point of the data + /// cloud and each center. void update_distance(); + + /// \brief Update the _group data structure. + /// + /// For each point of the data cloud, find the group which has + /// the minimum distance from it. void update_group(); - void update_center(); - T update_variance(); + /// \brief Update the _center data structure. + /// + /// For each group, compute the center of mass in therm of + /// points of the data cloud. + void update_center(); - //------------------------------------------------------------------------ - // Main loop - //------------------------------------------------------------------------ + /// \brief Update the _variance. + /// + /// Compute the within variance. Sum every shortest distance. + T update_variance(); + /// \} + /// \brief Define the orchestration of the kmean core routines. + /// + /// \param[in] _input the initial image which initialize the data cloud. + /// + /// The orchestration is in a fact a loop which call one after + /// each other the core routines. Ending the loop means managing + /// the statistical convergence or having some clues of + /// divergence (watch_dog). template <typename I> void loop(const Image<I>& _input); - //void loop(); private: + /// \brief watch_dog define the maximum of iterations that can be done. + /// + /// That constant help us to decide if divergence has been + /// occurred or not. static const unsigned watch_dog = 100; - + + /// \brief _points contains the concatenation of every data points. /// - /// One data point is a vector 1xP where P is the number of attributes. - /// _points is a matrix NxP where N is the number of data points. + /// One data point is a vector 1 x p where p is the number of attributes. + /// So _points is a matrix n x P where n is the number of data points. algebra::mat<n, p, T>* _point; + /// \brief _distance contains all the euclidian distances between points /// and the centers. /// - /// _distance is a matrix NxK where N is the number of data points and - /// K the number of centers. + /// _distance is a matrix n x k where n is the number of data points and + /// k the number of centers. algebra::mat<n, k, mln_sum_product(T,T)>* _distance; + /// \brief _group contains the point assignement to one center. /// - /// _group is a boolean matrix NxK where N is the number of data points - /// and K the number of centers. + /// _group is a boolean matrix n x k where n is the number of data points + /// and k the number of centers. algebra::mat<n, k, T>* _group; - /// \brief _center contains the coordonnate of the K centers. + + /// \brief _center contains the coordonnate of the k centers. /// - /// _center is a matrix KxP where K is the number of centers and P is the - /// number of attributes. + /// _center is a matrix k x p where k is the number of centers + /// and p is the number of attributes. algebra::mat<k, p, T>* _center; + + /// \brief _variance contains the variance of each group. + /// + /// _variance is a vector 1 x k where k is the number of centers. algebra::vec<k, T>* _variance; }; @@ -234,7 +350,7 @@ namespace mln inline k_mean<n,k,p,T>::k_mean() { - trace::entering("mln::clustering::k_mean::k_mean"); + trace::entering("mln::clustering::k_mean::cstor"); _point = new algebra::mat<n, p, T>(); _distance = new algebra::mat<n, k, mln_sum_product(T,T)>(); @@ -248,14 +364,14 @@ namespace mln mln_postcondition(_center != 0); mln_postcondition(_variance != 0); - trace::exiting("mln::clustering::k_mean::k_mean"); + trace::exiting("mln::clustering::k_mean::cstor"); } template <unsigned n, unsigned k, unsigned p, typename T> inline k_mean<n,k,p,T>::~k_mean() { - trace::entering("mln::clustering::k_mean::~k_mean"); + trace::entering("mln::clustering::k_mean::dstor"); delete _point; delete _distance; @@ -263,7 +379,7 @@ namespace mln delete _center; delete _variance; - trace::exiting("mln::clustering::k_mean::~k_mean"); + trace::exiting("mln::clustering::k_mean::dstor"); } //-------------------------------------------------------------------------- @@ -350,7 +466,7 @@ namespace mln template <unsigned n, unsigned k, unsigned p, typename T> template <unsigned q, unsigned r> inline - algebra::vec<q,T> k_mean<n,k,p,T>::col(const algebra::mat<r, q, T>& m, + algebra::vec<q,T> k_mean<n,k,p,T>::col(const algebra::mat<r, q, T>& m, const unsigned _col) const { trace::entering("mln::clustering::k_mean::col"); @@ -368,7 +484,7 @@ namespace mln template <unsigned n, unsigned k, unsigned p, typename T> template <unsigned q, unsigned r> inline - algebra::vec<q,T>* k_mean<n,k,p,T>::ptr_col(const algebra::mat<r, q, T>& m, + algebra::vec<q,T>* k_mean<n,k,p,T>::ptr_col(const algebra::mat<r, q, T>& m, const unsigned _col) const { trace::entering("mln::clustering::k_mean::ptr_col"); @@ -386,7 +502,7 @@ namespace mln template <unsigned n, unsigned k, unsigned p, typename T> template <unsigned q, unsigned r> inline - mln_sum(T) k_mean<n,k,p,T>::sum_row(const algebra::mat<r, q, T>& m, + mln_sum(T) k_mean<n,k,p,T>::sum_row(const algebra::mat<r, q, T>& m, const unsigned _row) const { trace::entering("mln::clustering::k_mean::sum_row"); @@ -404,7 +520,7 @@ namespace mln template <unsigned n, unsigned k, unsigned p, typename T> template <unsigned q, unsigned r> inline - void k_mean<n,k,p,T>::div_col(algebra::mat<r, q, T>& m, + void k_mean<n,k,p,T>::div_col(algebra::mat<r, q, T>& m, const unsigned _col, const T value) { @@ -422,21 +538,21 @@ namespace mln inline M k_mean<n,k,p,T>::min_col(const algebra::vec<q, M>& x) const { - trace::entering("mln::clustering::k_mean<n,k,p,T>::min_col"); - + trace::entering("mln::clustering::k_mean::min_col"); + M result = x[0]; for (unsigned i = 1; i < q; ++i) result = math::min(result, x[i]); - trace::exiting("mln::clustering::k_mean<n,k,p,T>::min_col"); + trace::exiting("mln::clustering::k_mean::min_col"); return result; } template <unsigned n, unsigned k, unsigned p, typename T> inline mln_sum_product(T,T) - k_mean<n,k,p,T>::euclidian_distance(const algebra::vec<p, T>& x, + k_mean<n,k,p,T>::euclidian_distance(const algebra::vec<p, T>& x, const algebra::vec<p, T>& y) const { trace::entering("mln::clustering::k_mean::euclidian_distance"); @@ -458,8 +574,8 @@ namespace mln inline void k_mean<n,k,p,T>::init_point(const Image<I>& _input) { - trace::entering("mln::clustering::k_mean<n,k,p,T>::init"); - + trace::entering("mln::clustering::k_mean::init"); + const I& input = exact(_input); algebra::mat<n, p, T>& point = *_point; @@ -474,28 +590,28 @@ namespace mln for_all(pi) { //std::cout << pi << std::endl; - + ++i; for (unsigned j = 0; j < p; ++j) { - + point(i,j) = input(pi).comp(j); //point(i,j) = input(pi); } } - trace::exiting("mln::clustering::k_mean<n,k,p,T>::init"); + trace::exiting("mln::clustering::k_mean::init"); } template <unsigned n, unsigned k, unsigned p, typename T> inline void k_mean<n,k,p,T>::init_center() { - trace::entering("mln::clustering::k_mean<n,k,p,T>::init_center"); - + trace::entering("mln::clustering::k_mean::init_center"); + algebra::mat<n, p, T>& point = *_point; algebra::mat<k, p, T>& center = *_center; - + // A random point is choosen to be the initial value for a center. for (unsigned i = 0; i < k; ++i) { @@ -503,16 +619,16 @@ namespace mln for (unsigned j = 0; j < p; ++j) { - center(i,j) = point(random, j); + center(i,j) = point(random, j); } //std::cout << "center(" << i << ")" << col(center, i) << std::endl; } - trace::exiting("mln::clustering::k_mean<n,k,p,T>::init_center"); + trace::exiting("mln::clustering::k_mean::init_center"); } - + //-------------------------------------------------------------------------- // Computations of distance, group, center, within variance //-------------------------------------------------------------------------- @@ -528,7 +644,7 @@ namespace mln algebra::mat<n, p, T>& point = *_point; algebra::mat<n, k, T>& distance = *_distance; algebra::mat<k, p, T>& center = *_center; - + // for all points in the data cloud. for (unsigned i = 0; i < n; ++i) { @@ -546,7 +662,7 @@ namespace mln inline void k_mean<n,k,p,T>::update_group() { - trace::entering("mln::clustering::k_mean<n,k,p,T>::update_group"); + trace::entering("mln::clustering::k_mean::update_group"); algebra::mat<n, k, mln_sum_product(T,T)>& distance = *_distance; algebra::mat<n, k, T>& group = *_group; @@ -563,14 +679,14 @@ namespace mln } // mln_postcondition(sum(col(distance(i,j)) == 1) Vi - trace::exiting("mln::clustering::k_mean<n,k,p,T>::update_group"); + trace::exiting("mln::clustering::k_mean::update_group"); } template <unsigned n, unsigned k, unsigned p, typename T> inline void k_mean<n,k,p,T>::update_center() { - trace::entering("mln::clustering::k_mean<n,k,p,T>::update_center"); + trace::entering("mln::clustering::k_mean::update_center"); algebra::mat<n, p, T>& point = *_point; algebra::mat<k, p, T>& center = *_center; @@ -592,14 +708,14 @@ namespace mln for (unsigned i = 0; i < k; ++i) div_col(center, i, sum_row(group, i)); - trace::exiting("mln::clustering::k_mean<n,k,p,T>::update_center"); + trace::exiting("mln::clustering::k_mean::update_center"); } template <unsigned n, unsigned k, unsigned p, typename T> inline T k_mean<n,k,p,T>::update_variance() { - trace::entering("mln::clustering::k_mean<n,k,p,T>::update_variance"); + trace::entering("mln::clustering::k_mean::update_variance"); algebra::vec<k, T>& variance = *_variance; algebra::mat<n, k, T>& distance = *_distance; @@ -613,10 +729,10 @@ namespace mln result += variance[i]; } - trace::exiting("mln::clustering::k_mean<n,k,p,T>::update_variance"); + trace::exiting("mln::clustering::k_mean::update_variance"); return result; - } - + } + //-------------------------------------------------------------------------- // Main loop @@ -626,9 +742,8 @@ namespace mln template <typename I> inline void k_mean<n,k,p,T>::loop(const Image<I>& _input) - //void k_mean<n,k,p,T>::loop() { - trace::entering("mln::clustering::k_mean<n,k,p,T>::loop"); + trace::entering("mln::clustering::k_mean::loop"); T within_variance = INT_MAX-1; T old_variance = INT_MAX; @@ -658,12 +773,10 @@ namespace mln std::cout << i << " : " << within_variance << std::endl; } - trace::exiting("mln::clustering::k_mean<n,k,p,T>::loop"); - } - - + trace::exiting("mln::clustering::k_mean::loop"); + } -#endif // ! MLN_INCLUDE_ONLY +# endif // ! MLN_INCLUDE_ONLY } // end of namespace mln::clustering diff --git a/scribo/sandbox/green/mln/clustering/kmean1d.hh b/scribo/sandbox/green/mln/clustering/kmean1d.hh index c3c1add..57d246b 100644 --- a/scribo/sandbox/green/mln/clustering/kmean1d.hh +++ b/scribo/sandbox/green/mln/clustering/kmean1d.hh @@ -1,4 +1,4 @@ -// Copyright (C) 2008,2009 EPITA Research and Development Laboratory (LRDE) +// Copyright (C) 2007,2008,2009,2010 EPITA LRDE // // This file is part of Olena. // @@ -24,7 +24,7 @@ // executable file might be covered by the GNU General Public License. #ifndef MLN_CLUSTERING_KMEAN1D_HH -#define MLN_CLUSTERING_KMEAN1D_HH +# define MLN_CLUSTERING_KMEAN1D_HH /// \file /// @@ -34,36 +34,63 @@ /// the greylevel attribute inspite of the pixel attribute. The /// algorithm is independant from the image dimension. But, we have to /// compute one time the histogram. In fact, we move a recurrent cost -/// to a fix cost in the complexity. This version is very adapted to +/// by a fix cost in the complexity. This version is very adapted to /// images with small quantification. +/// +/// The following sample is a typical use of the new kmean implementation. +/// +/// #include <iostream> +/// #include <mln/clustering/kmean1d.hh> +/// #include <mln/core/image/image2d.hh> +/// #include <mln/img_path.hh> +/// #include <mln/io/pgm/load.hh> +/// #include <mln/value/int_u8.hh> +/// +/// int main() +/// { +/// typedef mln::value::int_u8 t_int_u8; +/// typedef mln::image2d<t_int_u8> t_image2d_int_u8; +/// t_image2d_int_u8 img_int_u8; +/// +/// mln::io::pgm::load(img_int_u8, OLENA_IMG_PATH"/house.pgm"); +/// mln::clustering::kmean1d<double, 8> kmean(img_int_u8, 3); +/// +/// kmean.launch_n_times(); +/// +/// return 0; +/// } + +# include <limits.h> +# include <iostream> -#include <limits.h> -#include <iostream> -#include <mln/trace/entering.hh> -#include <mln/trace/exiting.hh> +# include <mln/accu/stat/histo1d.hh> -#include <mln/core/contract.hh> -#include <mln/trait/value_.hh> -#include <mln/accu/stat/histo1d.hh> +# include <mln/core/contract.hh> +# include <mln/core/image/image2d.hh> +# include <mln/core/macros.hh> -#include <mln/math/min.hh> -#include <mln/math/sqr.hh> -#include <mln/norm/l2.hh> +# include <mln/data/compute.hh> +# include <mln/data/fill.hh> +# include <mln/debug/println.hh> -#include <mln/core/image/image2d.hh> -#include <mln/value/int_u.hh> -#include <mln/value/rgb8.hh> -#include <mln/core/macros.hh> +# include <mln/io/ppm/save.hh> +# include <mln/io/pgm/save.hh> -#include <mln/data/compute.hh> -#include <mln/debug/println.hh> -#include <mln/data/fill.hh> -#include <mln/literal/zero.hh> -#include <mln/labeling/colorize.hh> -#include <mln/labeling/mean_values.hh> +# include <mln/literal/zero.hh> +# include <mln/labeling/colorize.hh> +# include <mln/labeling/mean_values.hh> -#include <mln/io/ppm/save.hh> -#include <mln/io/pgm/save.hh> +# include <mln/math/min.hh> +# include <mln/math/sqr.hh> +# include <mln/norm/l2.hh> + +# include <mln/trace/entering.hh> +# include <mln/trace/exiting.hh> + +# include <mln/trait/value_.hh> + +# include <mln/value/int_u.hh> +# include <mln/value/rgb8.hh> namespace mln { @@ -85,8 +112,8 @@ namespace mln /// temporary images for computations and produces images as result. Images /// play the role of matrix or vector in standard statistic algoritm. /// - /// T is the type used for computations (float or double). - /// n is the quantification for the image grayscale. + /// Param T is the type used for computations (float or double). + /// Param n is the quantification for the image grayscale. template <typename T, unsigned n> struct kmean1d { @@ -117,32 +144,22 @@ namespace mln ///} - //------------------------------------------------------------------------ - // Constructor - //------------------------------------------------------------------------ - - /// \brief Constructor + /// \brief Constructor. /// \param[in] point : the image as the population of pixels. /// \param[in] k_center : the number of centers. /// \param[in] watch_dog : the limit to observe the convergence (10). /// \param[in] n_times : the number of times that we executed kmean(10). - kmean1d(const t_point_img& point, const unsigned k_center, const unsigned watch_dog = 10, const unsigned n_times = 10); - //------------------------------------------------------------------------ - // Accessors - //------------------------------------------------------------------------ - - /// Mutator and accessors. + /// Mutators and accessors. /// \{ /// \brief Mutator and accessors are required for debugging and testing. /// /// Testing needs to hack the kmean loop process in order to verify each /// step of the algorithm. - void set_point(t_point_img& point); void set_histo(t_histo_img& histo); void set_number(t_number_img& number); @@ -173,31 +190,21 @@ namespace mln /// \} - //------------------------------------------------------------------------ - // Initializations of centers - //------------------------------------------------------------------------ - /// Initialization of centers. /// \{ - /// \brief Two ways: Regular greylevel tick or random greylevel value or. + /// \brief Initialize centers by regular tick or random position. /// /// There is two way to proceed the initialization. First of all, we /// divide the greyscale in regular tick and we assigne them to the mean /// of the centers. Finaly, we can ask random initialization along the /// greyscale axis. The second process is needed to launch_n_times the /// kmean and converge to the best descent. - void init_mean(); void init_mean_regular(); void init_mean_random(); - /// \} - //------------------------------------------------------------------------ - // Computations of distance, group, center, within variance - //------------------------------------------------------------------------ - /// Computations of distance, group, center, within variance. /// \{ /// \brief Update the statistical information needed by the kmean process. @@ -206,36 +213,27 @@ namespace mln /// first compute. Then we assign the pixels to their nearest center. /// The new location of each center can then update. Finaly, hommogeneity /// in group is observed by the within variance. - void update_distance(); void update_group(); void update_mean(); void update_variance(); - /// \} - //------------------------------------------------------------------------ - // Main loop - //------------------------------------------------------------------------ /// kmean main loop /// \{ /// \brief User interface to launch the kmean process. /// - /// There are two ways to launch the kmean process. The first one allow to - /// run it one time until convergence. As the process is a descent, it - /// depends on the initial center locations. The second call allow us to - /// rerun the process many times and to keep the best result (the one - /// with the smallest within variance). - + /// There are two ways to launch the kmean process. The first + /// one allows to run it one time until convergence. As the + /// process is a descent, it depends on the initial center + /// location. The second call allow us to rerun the process + /// many times and to keep the best result (the one with the + /// smallest within variance). void launch_one_time(); void launch_n_times(); - /// \} - //------------------------------------------------------------------------ - // Checking the validiy of the results - //------------------------------------------------------------------------ /// Checking the validity of the results. /// \{ @@ -244,15 +242,10 @@ namespace mln /// After each launching the kmean process one time, we need to know if /// the descent was successfull or not. The method is_valid_descent do it /// for us. The method looks for a bad center (a class with no greylevel - /// associate to it) and a failure in the convergence. - + /// associate to it) or a failure in the convergence. bool is_descent_valid(); - /// \} - //------------------------------------------------------------------------ - // Debugging tools - //------------------------------------------------------------------------ /// Debugging tools /// \{ @@ -264,12 +257,10 @@ namespace mln /// greylevel image. The update_cnv and finalize_cnv methods are used to /// trace the convergence. They fill two images with the mean info and /// the within variance info along the convergence and the tries. - void build_label_dbg(); void build_all_dbg(); void update_cnv(); void finalize_cnv(); - /// \} @@ -279,20 +270,19 @@ namespace mln /// \brief These parameters control the convergence of the process. /// /// The first parameter, k_center, defines the number of center for kmean. - /// In fact, watch_dog limit the number of iteration that a simple kmean + /// In fact, watch_dog limits the number of iteration that a simple kmean /// loop can do. If the process reaches the watch_dog limit, it means /// that the process will not converge at all. The second parameter /// n_times is the number of times we launch again and again the simple /// kmean loop. As the kmean process is a descent, restarting the process /// from different location will confort us in that we found a global /// minima, not just a local one. - unsigned _k_center; unsigned _watch_dog; unsigned _n_times; - /// \} + /// Convergence information. /// \{ /// \brief This information is used to follow the convergence. @@ -300,26 +290,25 @@ namespace mln /// The within_variance is the homogeniety indicator for the /// kmean process. The ideal situation is to find the center /// with the minimum variance around them. The within variance - /// is just the sum of all variance around the centers. The - /// current_step variable allows us to remember the current - /// iteration in the kmean loop. This information is needed by - /// is_descent_valid routine which decide if convergence occurs - /// or not. The current_step info explicit where we are in the - /// kmean iteration. The last information, current_launching, - /// traces the progress while iterates kmean loop again and - /// again. The flag is_number_valid is set when a empty class - /// appears. This flag inhibit the process and force to restart - /// a try. - + /// is just the sum of all ponderated variances around the + /// centers. The current_step variable allows us to remember the + /// current iteration in the kmean loop. This information is + /// needed by is_descent_valid routine which decide if + /// convergence occurs or not. The current_step info explicit + /// where we are in the kmean iteration. The last information, + /// current_launching, traces the progress while iterates kmean + /// loop again and again. The flag is_number_valid is set when a + /// empty class appears. This flag inhibit the process and + /// force to restart a try. t_result _within_variance; unsigned _current_step; unsigned _current_launching; bool _is_number_valid; static const unsigned _N_TRIES = 3; - /// \} + /// Result of the kmean process. /// \{ /// \brief The center location are the major results of the kmean process. @@ -327,23 +316,23 @@ namespace mln /// The kmean process result is composed by three information. The best /// launching iteration, the best within variance obtained and the /// location of the centers associated. - unsigned _launching_min; t_result _variance_min; t_mean_img _mean_min; + /// \} + /// Inputs. /// \{ - /// \brief The inputs are the distribution of the values and the values. + /// \brief The inputs are the distribution of the values. /// /// The point image is a saving data for the real inputs. In fact, we use /// the histogram information in the optimized kmean process. - t_point_img _point; t_histo_img _histo; - ///\} + /// Centers description. /// \{ /// \brief Centers are described by the first moment of their group. @@ -354,13 +343,12 @@ namespace mln /// convergence. The number of pixels is used as integrity indicator. /// A center with no point is a non sense. Theses informations are updated /// after each kmean iteration. - t_number_img _number; // k x 1 t_mean_img _mean; // k x 1 t_variance_img _variance; // k x 1 within group - /// \} + /// Greylevels description. /// \{ /// \brief The information are concerned with the greylevel input image. @@ -369,15 +357,14 @@ namespace mln /// which pixel) is assigned to a center. The distance image give us a /// clue on how a greylevel could contribute to a center. The summation /// over the greylevels of a center give us the within variance. - t_group_img _group; // g x 1 because dim(t_value) = 1 t_distance_img _distance; // label x graylevel - /// \} + /// Debugging, calibrating and testing results. /// \{ - /// \brief Some exports information to control the results. + /// \brief Some information exports to control the results. /// /// We come back in the input space. Label is the image which associates /// each pixel to its center. Color is the image which gives a random rgb @@ -385,14 +372,13 @@ namespace mln /// label (assigned to the same center) in the image. The mean image /// associate the mean of each pixel center to each pixel. We obtain thus /// a rebuilded image. - t_label_dbg _label_dbg; t_color_dbg _color_dbg; t_mean_dbg _mean_dbg; - /// \} - /// Debugging, calibrating and testing convergence. + + /// Variance and center evolutions. /// \{ /// \brief Trace the variance and the center evolution. /// @@ -401,10 +387,8 @@ namespace mln /// kmean loop or along the different launch. The variance_cnv is a trace /// of the within variance along the kmean loop or along the different /// launch. - t_mean_cnv _mean_cnv; t_variance_cnv _variance_cnv; - /// \} }; @@ -803,8 +787,6 @@ namespace mln { trace::entering("mln::clustering::kmean1d::update_mean"); - /// FIXME VERIFIER QUE L'ON PEUT OBTENIR UNE IMAGE EN NDG SIGNE - // avec g le niveau de gris (signed or not signed) // w[g] la classe de g sous forme d'image // h[g] l'histogramme de l'image sous forme d'image @@ -872,7 +854,7 @@ namespace mln for_all(g) { - if (l.ind() == _group(g)) + if (static_cast<t_label>(l.ind()) == _group(g)) _variance(l) += _distance(point2d(g.ind(), l.ind())); } @@ -1091,7 +1073,7 @@ namespace mln trace::exiting("mln::clustering::kmean1d::launch_n_times"); } -#endif // ! MLN_INCLUDE_ONLY +# endif // ! MLN_INCLUDE_ONLY } // end of namespace mln::clustering diff --git a/scribo/sandbox/green/mln/clustering/kmean2d.hh b/scribo/sandbox/green/mln/clustering/kmean2d.hh index e4918db..51aaf49 100644 --- a/scribo/sandbox/green/mln/clustering/kmean2d.hh +++ b/scribo/sandbox/green/mln/clustering/kmean2d.hh @@ -1,4 +1,4 @@ -// Copyright (C) 2008,2009 EPITA Research and Development Laboratory (LRDE) +// Copyright (C) 2007,2008,2009,2010 EPITA LRDE // // This file is part of Olena. // @@ -24,52 +24,102 @@ // executable file might be covered by the GNU General Public License. #ifndef MLN_CLUSTERING_KMEAN2D_HH -#define MLN_CLUSTERING_KMEAN2D_HH +# define MLN_CLUSTERING_KMEAN2D_HH /// \file /// -/// \brief Implements the optimized kmean algorithm. +/// \brief Implements the optimized kmean algorithm in 2d. /// /// This algorithm is optimized in the way it proceeds directly with /// the greylevel attribute inspite of the pixel attribute. The /// algorithm is independant from the image dimension. But, we have to /// compute one time the histogram. In fact, we move a recurrent cost -/// to a fix cost in the complexity. This version is very adapted to -/// images with small quantification. - -#include <limits.h> -#include <iostream> -#include <mln/trace/entering.hh> -#include <mln/trace/exiting.hh> - -#include <mln/core/contract.hh> -#include <mln/trait/value_.hh> -#include <mln/accu/stat/histo2d.hh> - -#include <mln/math/min.hh> -#include <mln/math/sqr.hh> -#include <mln/norm/l2.hh> - -#include <mln/core/image/image2d.hh> -#include <mln/core/concept/image.hh> -#include <mln/value/int_u.hh> -#include <mln/value/rgb8.hh> -#include <mln/value/rg.hh> -#include <mln/core/macros.hh> - -#include <mln/data/compute.hh> -#include <mln/debug/println.hh> -#include <mln/data/fill.hh> -#include <mln/literal/zero.hh> -#include <mln/literal/one.hh> -#include <mln/labeling/colorize.hh> -#include <mln/labeling/mean_values.hh> - -#include <mln/io/ppm/save.hh> -#include <mln/io/pgm/save.hh> - -#include <mln/util/array.hh> -#include <mln/algebra/vec.hh> +/// by a fix cost in the complexity. This version is very adapted to +/// images with small quantification. But, in 2d, the execution +/// becomes very slow. It's just normal because the quantification is +/// 8 bits per axis. So the actual histogram is bigger than the image. +/// +/// Take care to the following point: The within variance is still a +/// scalar value because we take the distance between two points and +/// the result is a scalar from the geometrical point of view. An +/// alternative implementation could study the variance/covariance +/// matrix of each sub data clouds and works with the trace of the +/// within variance matrix (as we do for the fisher criteria in N-d). +/// +/// The following sample is a typical use of the new kmean implementation. +/// +/// #include <iostream> +/// #include <mln/clustering/kmean2d.hh> +/// #include <mln/core/image/image2d.hh> +/// #include <mln/data/transform.hh> +/// #include <mln/fun/v2v/rgb_to_rg.hh> +/// #include <mln/img_path.hh> +/// #include <mln/io/ppm/load.hh> +/// #include <mln/value/rg.hh> +/// #include <mln/value/rgb8.hh> +/// +/// int main() +/// { +/// typedef mln::value::rg<8> t_rg8; +/// typedef mln::value::rgb8 t_rgb8; +/// typedef mln::image2d<t_rgb8> t_image2d_rgb8; +/// typedef mln::image2d<t_rg8> t_image2d_rg8; +/// typedef mln::fun::v2v::rgb_to_rg<8> t_rgb_to_rg; +/// +/// t_image2d_rgb8 img_rgb8; +/// t_image2d_rg8 img_rg8; +/// +/// mln::io::ppm::load(img_rgb8, OLENA_IMG_PATH"/house.ppm"); +/// +/// img_rg8 = mln::data::transform(img_rgb8, t_rgb_to_rg()); +/// +/// mln::clustering::kmean2d<double, 8> kmean(img_rg8, 3); +/// +/// kmean.launch_n_times(); +/// +/// return 0; +/// } + +# include <limits.h> +# include <iostream> + +# include <mln/accu/stat/histo2d.hh> + +# include <mln/algebra/vec.hh> + +# include <mln/core/concept/image.hh> +# include <mln/core/contract.hh> +# include <mln/core/image/image2d.hh> +# include <mln/core/macros.hh> + +# include <mln/data/compute.hh> +# include <mln/data/fill.hh> + +# include <mln/debug/println.hh> + +# include <mln/io/pgm/save.hh> +# include <mln/io/ppm/save.hh> + +# include <mln/labeling/colorize.hh> +# include <mln/labeling/mean_values.hh> + +# include <mln/literal/one.hh> +# include <mln/literal/zero.hh> + +# include <mln/math/min.hh> +# include <mln/math/sqr.hh> +# include <mln/norm/l2.hh> + +# include <mln/trace/entering.hh> +# include <mln/trace/exiting.hh> + +# include <mln/trait/value_.hh> + +# include <mln/util/array.hh> + +# include <mln/value/int_u.hh> +# include <mln/value/rgb8.hh> +# include <mln/value/rg.hh> namespace mln { @@ -85,21 +135,22 @@ namespace mln namespace clustering { + /// \brief Implements the kmean algorithm in a specific way. /// - /// This version of the kmean algorithm uses a greyscale image as input, - /// temporary images for computations and produces images as result. Images - /// play the role of matrix or vector in standard statistic algoritm. + /// This version of the kmean algorithm uses a 2-channels + /// (red/green channel) image as input, temporary images for + /// computations and produces images as result. Images play the + /// role of matrix or vector in standard statistic algoritm. /// - /// T is the type used for computations (float or double). - /// n is the quantification for the image grayscale. + /// Param T is the type used for computations (float or double). + /// Param n is the quantification for the image grayscale. template <typename T, unsigned n> struct kmean2d { /// Type definitions. /// \brief A few type definitions to limit the refactoring impact. ///{ - typedef value::rgb<8> t_rgb; typedef value::label<8> t_label; typedef value::rg<n> t_value; @@ -108,7 +159,7 @@ namespace mln typedef T t_result1d; typedef algebra::vec<2,T> t_result2d; - /// FIXME t_point n'est pas forcément une image 2d, bien au contraire. + /// \fixme t_point_img is not an image2d ... but it works like this ... typedef image2d<t_value> t_point_img; typedef image2d<unsigned> t_histo_img; typedef util::array<t_result1d> t_number_img; @@ -128,35 +179,24 @@ namespace mln typedef util::array<t_mean_set> t_mean_cnv; typedef image1d<t_result1d> t_variance_val; typedef util::array<t_variance_val> t_variance_cnv; - ///} - //------------------------------------------------------------------------ - // Constructor - //------------------------------------------------------------------------ - - /// \brief Constructor + /// \brief Constructor. /// \param[in] point : the image as the population of pixels. /// \param[in] k_center : the number of centers. /// \param[in] watch_dog : the limit to observe the convergence (10). /// \param[in] n_times : the number of times that we executed kmean(10). - kmean2d(const t_point_img& point, const unsigned k_center, const unsigned watch_dog = 10, const unsigned n_times = 10); - //------------------------------------------------------------------------ - // Accessors - //------------------------------------------------------------------------ - - /// Mutator and accessors. + /// Mutators and accessors. /// \{ /// \brief Mutator and accessors are required for debugging and testing. /// /// Testing needs to hack the kmean loop process in order to verify each /// step of the algorithm. - void set_point(t_point_img& point); void set_histo(t_histo_img& histo); void set_number(t_number_img& number); @@ -187,10 +227,10 @@ namespace mln /// \} - //------------------------------------------------------------------------ - // Printing temporary results - //------------------------------------------------------------------------ - + /// Show temporary results. + /// \{ + /// \brief Formating temporary outputs for debugging. + /// void print_mean(); void print_number(); void print_variance(); @@ -198,32 +238,18 @@ namespace mln void print_group(); void print_point(); void print_histo(); - - //------------------------------------------------------------------------ - // Initializations of centers - //------------------------------------------------------------------------ + /// \} /// Initialization of centers. /// \{ - /// \brief Two ways: Regular greylevel tick or random greylevel value or. + /// \brief Initialize centers by random position. /// - /// There is two way to proceed the initialization. First of all, we - /// divide the greyscale in regular tick and we assigne them to the mean - /// of the centers. Finaly, we can ask random initialization along the - /// greyscale axis. The second process is needed to launch_n_times the - /// kmean and converge to the best descent. - + /// Assign a random position in the 2-channel space to each center. void init_mean(); - void init_mean_regular(); void init_mean_random(); - /// \} - //------------------------------------------------------------------------ - // Computations of distance, group, center, within variance - //------------------------------------------------------------------------ - /// Computations of distance, group, center, within variance. /// \{ /// \brief Update the statistical information needed by the kmean process. @@ -232,36 +258,27 @@ namespace mln /// first compute. Then we assign the pixels to their nearest center. /// The new location of each center can then update. Finaly, hommogeneity /// in group is observed by the within variance. - void update_distance(); void update_group(); void update_mean(); void update_variance(); - /// \} - //------------------------------------------------------------------------ - // Main loop - //------------------------------------------------------------------------ /// kmean main loop /// \{ /// \brief User interface to launch the kmean process. /// - /// There are two ways to launch the kmean process. The first one allow to - /// run it one time until convergence. As the process is a descent, it - /// depends on the initial center locations. The second call allow us to - /// rerun the process many times and to keep the best result (the one - /// with the smallest within variance). - + /// There are two ways to launch the kmean process. The first + /// one allows to run it one time until convergence. As the + /// process is a descent, it depends on the initial center + /// location. The second call allow us to rerun the process + /// many times and to keep the best result (the one with the + /// smallest within variance). void launch_one_time(); void launch_n_times(); - /// \} - //------------------------------------------------------------------------ - // Checking the validiy of the results - //------------------------------------------------------------------------ /// Checking the validity of the results. /// \{ @@ -269,16 +286,11 @@ namespace mln /// /// After each launching the kmean process one time, we need to know if /// the descent was successfull or not. The method is_valid_descent do it - /// for us. The method looks for a bad center (a class with no greylevel - /// associate to it) and a failure in the convergence. - + /// for us. The method looks for a bad center (a class with no r/g color + /// associate to it) or a failure in the convergence. bool is_descent_valid(); - /// \} - //------------------------------------------------------------------------ - // Debugging tools - //------------------------------------------------------------------------ /// Debugging tools /// \{ @@ -290,13 +302,11 @@ namespace mln /// greylevel image. The update_cnv and finalize_cnv methods are used to /// trace the convergence. They fill two images with the mean info and /// the within variance info along the convergence and the tries. - void build_label_dbg(); void build_mean_dbg(); void build_all_dbg(); void update_cnv(); void finalize_cnv(); - /// \} @@ -313,13 +323,12 @@ namespace mln /// kmean loop. As the kmean process is a descent, restarting the process /// from different location will confort us in that we found a global /// minima, not just a local one. - unsigned _k_center; unsigned _watch_dog; unsigned _n_times; - /// \} + /// Convergence information. /// \{ /// \brief This information is used to follow the convergence. @@ -337,16 +346,15 @@ namespace mln /// again. The flag is_number_valid is set when a empty class /// appears. This flag inhibit the process and force to restart /// a try. - t_result1d _within_variance; unsigned _current_step; unsigned _current_launching; bool _is_number_valid; static const unsigned _N_TRIES = 3; - /// \} + /// Result of the kmean process. /// \{ /// \brief The center location are the major results of the kmean process. @@ -354,10 +362,11 @@ namespace mln /// The kmean process result is composed by three information. The best /// launching iteration, the best within variance obtained and the /// location of the centers associated. - unsigned _launching_min; t_result1d _variance_min; t_mean_img _mean_min; + /// \} + /// Inputs. /// \{ @@ -365,12 +374,11 @@ namespace mln /// /// The point image is a saving data for the real inputs. In fact, we use /// the histogram information in the optimized kmean process. - t_point_img _point; t_histo_img _histo; - ///\} + /// Centers description. /// \{ /// \brief Centers are described by the first moment of their group. @@ -381,27 +389,25 @@ namespace mln /// convergence. The number of pixels is used as integrity indicator. /// A center with no point is a non sense. Theses informations are updated /// after each kmean iteration. - t_number_img _number; // k x 1 - t_mean_img _mean; // k x 1 + t_mean_img _mean; // k x 2 t_variance_img _variance; // k x 1 within group - /// \} + /// Greylevels description. /// \{ - /// \brief The information are concerned with the greylevel input image. + /// \brief The information are concerned with the 2-channel input image. /// - /// The group image allow us to decide which greylevel (and of course + /// The group image allow us to decide which r/g value (and of course /// which pixel) is assigned to a center. The distance image give us a - /// clue on how a greylevel could contribute to a center. The summation - /// over the greylevels of a center give us the within variance. - - t_group_img _group; // g x 1 because dim(t_value) = 1 - t_distance_img _distance; // label x graylevel - + /// clue on how a r/g value could contribute to a center. The summation + /// over the r/g values of a center give us the within variance. + t_group_img _group; // g x 2 because dim(t_value) = 2 + t_distance_img _distance; // label x r/g value /// \} + /// Debugging, calibrating and testing results. /// \{ /// \brief Some exports information to control the results. @@ -412,14 +418,13 @@ namespace mln /// label (assigned to the same center) in the image. The mean image /// associate the mean of each pixel center to each pixel. We obtain thus /// a rebuilded image. - t_label_dbg _label_dbg; t_color_dbg _color_dbg; t_mean_dbg _mean_dbg; - /// \} - /// Debugging, calibrating and testing convergence. + + /// Variance and center evolutions. /// \{ /// \brief Trace the variance and the center evolution. /// @@ -428,10 +433,8 @@ namespace mln /// kmean loop or along the different launch. The variance_cnv is a trace /// of the within variance along the kmean loop or along the different /// launch. - t_mean_cnv _mean_cnv; t_variance_cnv _variance_cnv; - /// \} }; @@ -448,7 +451,7 @@ namespace mln const unsigned watch_dog, const unsigned n_times) { - trace::entering("mln::clustering::kmean2d::kmean2d"); + trace::entering("mln::clustering::kmean2d::cstor"); mln_precondition(point.is_valid()); _k_center = k_center; @@ -516,7 +519,7 @@ namespace mln _mean_cnv.append(mean_set); } - trace::exiting("mln::clustering::kmean2d::kmean2d"); + trace::exiting("mln::clustering::kmean2d::cstor"); } //-------------------------------------------------------------------------- @@ -796,15 +799,15 @@ namespace mln { trace::entering("mln::clustering::kmean2d::print_histo"); - mln_piter(t_histo_img) rgb(_histo.domain()); + mln_piter(t_histo_img) rg(_histo.domain()); - for_all(rgb) + for_all(rg) { - if (0 < _histo(rgb)) + if (0 < _histo(rg)) { - std::cout << "histo(r=" << rgb.row(); - std::cout << ", g=" << rgb.col(); - std::cout << ")= " << _histo(rgb); + std::cout << "histo(r=" << rg.row(); + std::cout << ", g=" << rg.col(); + std::cout << ")= " << _histo(rg); std::cout << std::endl; } } @@ -818,15 +821,15 @@ namespace mln { trace::entering("mln::clustering::kmean2d::print_group"); - mln_piter(t_group_img) rgb(_group.domain()); + mln_piter(t_group_img) rg(_group.domain()); - for_all(rgb) + for_all(rg) { - if (0 < _histo(rgb)) + if (0 < _histo(rg)) { - std::cout << "group(r=" << rgb.row(); - std::cout << ", g=" << rgb.col(); - std::cout << ")= " << _group(rgb); + std::cout << "group(r=" << rg.row(); + std::cout << ", g=" << rg.col(); + std::cout << ")= " << _group(rg); std::cout << std::endl; } } @@ -844,16 +847,16 @@ namespace mln for_all(l) { - mln_piter(t_distance_val) rgb(_distance[l.index_()].domain()); + mln_piter(t_distance_val) rg(_distance[l.index_()].domain()); - for_all(rgb) + for_all(rg) { - if (0 < _histo(rgb)) + if (0 < _histo(rg)) { std::cout << "distance(l=" << l.index_(); - std::cout << ",r=" << rgb.row(); - std::cout << ", g=" << rgb.col(); - std::cout << ")= " << _distance[l.index_()](rgb); + std::cout << ",r=" << rg.row(); + std::cout << ", g=" << rg.col(); + std::cout << ")= " << _distance[l.index_()](rg); std::cout << std::endl; } } @@ -960,9 +963,9 @@ namespace mln { trace::entering("mln::clustering::kmean2d::update_group"); - mln_piter(t_group_img) rgb(_group.domain()); + mln_piter(t_group_img) rg(_group.domain()); - for_all(rgb) + for_all(rg) { mln_eiter(t_distance_img) l(_distance); t_result1d min = mln_max(t_result1d); @@ -972,9 +975,9 @@ namespace mln for_all(l) { - if (min > _distance[l.index_()](rgb)) + if (min > _distance[l.index_()](rg)) { - min = _distance[l.index_()](rgb); + min = _distance[l.index_()](rg); label = l.index_(); } @@ -984,7 +987,7 @@ namespace mln //std::cout << "g = " << g << std::endl; - _group(rgb) = label; + _group(rg) = label; //std::cout << "group = " << _group(g) << std::endl; //std::cout << "-----------" << std::endl; } @@ -998,8 +1001,6 @@ namespace mln { trace::entering("mln::clustering::kmean2d::update_mean"); - /// FIXME VERIFIER QUE L'ON PEUT OBTENIR UNE IMAGE EN NDG SIGNE - // avec g le niveau de gris (signed or not signed) // w[g] la classe de g sous forme d'image // h[g] l'histogramme de l'image sous forme d'image @@ -1021,14 +1022,14 @@ namespace mln _mean[em.index_()] = literal::zero; } - mln_piter(t_group_img) rgb(_group.domain()); + mln_piter(t_group_img) rg(_group.domain()); - for_all(rgb) + for_all(rg) { // peut être faut-il le decomposer par composantes - _mean[_group(rgb)][0] += rgb.row() * _histo(rgb); - _mean[_group(rgb)][1] += rgb.col() * _histo(rgb); - _number(_group(rgb)) += _histo(rgb); + _mean[_group(rg)][0] += rg.row() * _histo(rg); + _mean[_group(rg)][1] += rg.col() * _histo(rg); + _number(_group(rg)) += _histo(rg); } mln_eiter(t_mean_img) l(_mean); @@ -1072,12 +1073,12 @@ namespace mln { _variance[l.index_()] = literal::zero; - mln_piter(t_group_img) rgb(_group.domain()); + mln_piter(t_group_img) rg(_group.domain()); - for_all(rgb) + for_all(rg) { - if (l.index_() == _group(rgb)) - _variance[l.index_()] += _distance[l.index_()](rgb); + if (l.index_() == _group(rg)) + _variance[l.index_()] += _distance[l.index_()](rg); } _within_variance += _variance[l.index_()]; @@ -1334,7 +1335,7 @@ namespace mln trace::exiting("mln::clustering::kmean2d::launch_n_times"); } -#endif // ! MLN_INCLUDE_ONLY +# endif // ! MLN_INCLUDE_ONLY } // end of namespace mln::clustering diff --git a/scribo/sandbox/green/mln/clustering/kmean3d.hh b/scribo/sandbox/green/mln/clustering/kmean3d.hh index fb1a8df..c35d2a7 100644 --- a/scribo/sandbox/green/mln/clustering/kmean3d.hh +++ b/scribo/sandbox/green/mln/clustering/kmean3d.hh @@ -1,4 +1,4 @@ -// Copyright (C) 2008,2009 EPITA Research and Development Laboratory (LRDE) +// Copyright (C) 2007,2008,2009,2010 EPITA LRDE // // This file is part of Olena. // @@ -24,51 +24,102 @@ // executable file might be covered by the GNU General Public License. #ifndef MLN_CLUSTERING_KMEAN3D_HH -#define MLN_CLUSTERING_KMEAN3D_HH +# define MLN_CLUSTERING_KMEAN3D_HH /// \file /// -/// \brief Implements the optimized kmean algorithm. +/// \brief Implements the optimized kmean algorithm in 3d. /// /// This algorithm is optimized in the way it proceeds directly with -/// the rgb values inspite of the pixel attribute. The +/// the rgb value inspite of the pixel attribute. The /// algorithm is independant from the image dimension. But, we have to /// compute one time the histogram. In fact, we move a recurrent cost -/// to a fix cost in the complexity. This version is adapted to -/// image with small quantification. - -#include <limits.h> -#include <iostream> -#include <mln/trace/entering.hh> -#include <mln/trace/exiting.hh> - -#include <mln/core/contract.hh> -#include <mln/trait/value_.hh> -#include <mln/accu/stat/histo3d_rgb.hh> - -#include <mln/math/min.hh> -#include <mln/math/sqr.hh> -#include <mln/norm/l2.hh> - -#include <mln/core/image/image2d.hh> -#include <mln/core/concept/image.hh> -#include <mln/value/int_u.hh> -#include <mln/value/rgb8.hh> -#include <mln/core/macros.hh> - -#include <mln/data/compute.hh> -#include <mln/debug/println.hh> -#include <mln/data/fill.hh> -#include <mln/literal/zero.hh> -#include <mln/literal/one.hh> -#include <mln/labeling/colorize.hh> -#include <mln/labeling/mean_values.hh> - -#include <mln/io/ppm/save.hh> -#include <mln/io/pgm/save.hh> - -#include <mln/util/array.hh> -#include <mln/algebra/vec.hh> +/// by a fix cost in the complexity. This version is very adapted to +/// images with small quantification. But, in 3d, the execution +/// becomes very slow. It's just normal because the quantification is +/// n bits per axis. So the actual histogram may be bigger than the image. +/// +/// Take care to the following point: The within variance is still a +/// scalar value because we take the distance between two points and +/// the result is a scalar from the geometrical point of view. An +/// alternative implementation could study the variance/covariance +/// matrix of each sub data clouds and works with the trace of the +/// within variance matrix (as we do for the fisher criteria in N-d). +/// +/// The following sample is a typical use of the new kmean implementation. +/// +/// #include <iostream> +/// #include <mln/clustering/kmean3d.hh> +/// #include <mln/core/image/image2d.hh> +/// #include <mln/data/transform.hh> +/// #include <mln/fun/v2v/rgb8_to_rgbn.hh> +/// #include <mln/img_path.hh> +/// #include <mln/io/ppm/load.hh> +/// #include <mln/value/rgb.hh> +/// #include <mln/value/rgb8.hh> +/// +/// int main() +/// { +/// typedef mln::clustering::kmean3d<double,5> t_kmean; +/// typedef mln::value::rgb8 t_rgb8; +/// typedef mln::value::rgb<5> t_rgb5; +/// typedef mln::image2d<t_rgb8> t_image2d_rgb8; +/// typedef mln::image2d<t_rgb5> t_image2d_rgb5; +/// typedef mln::fun::v2v::rgb8_to_rgbn<5> t_rgb8_to_rgb5; +/// +/// t_image2d_rgb8 img_rgb8; +/// t_image2d_rgb5 img_rgb5; +/// +/// mln::io::ppm::load(img_rgb8, OLENA_IMG_PATH"/house.ppm"); +/// +/// img_rgb5=mln::data::transform(img_rgb8, t_rgb8_to_rgb5()); +/// +/// t_kmean kmean(img_rgb5, 3); +/// +/// kmean.launch_n_times(); +/// +/// return 0; +/// } + +# include <limits.h> +# include <iostream> + +# include <mln/accu/stat/histo3d_rgb.hh> + +# include <mln/algebra/vec.hh> + +# include <mln/math/min.hh> +# include <mln/math/sqr.hh> +# include <mln/norm/l2.hh> + +# include <mln/core/concept/image.hh> +# include <mln/core/contract.hh> +# include <mln/core/image/image2d.hh> +# include <mln/core/macros.hh> + +# include <mln/data/compute.hh> +# include <mln/data/fill.hh> +# include <mln/debug/println.hh> + +# include <mln/labeling/colorize.hh> +# include <mln/labeling/mean_values.hh> + +# include <mln/literal/one.hh> +# include <mln/literal/zero.hh> + +# include <mln/io/ppm/save.hh> +# include <mln/io/pgm/save.hh> + +# include <mln/trace/entering.hh> +# include <mln/trace/exiting.hh> + +# include <mln/trait/value_.hh> + +# include <mln/util/array.hh> + +# include <mln/value/int_u.hh> +# include <mln/value/rgb8.hh> + namespace mln { @@ -98,7 +149,6 @@ namespace mln /// Type definitions. /// \brief A few type definitions to limit the refactoring impact. ///{ - typedef value::rgb<8> t_rgb; typedef value::label<8> t_label; typedef value::rgb<n> t_value; @@ -108,7 +158,7 @@ namespace mln typedef T t_result1d; typedef algebra::vec<3,T> t_result3d; - /// FIXME t_point n'est pas forcément une image 2d, bien au contraire. + /// \fixme t_point is not an image2d, it may be something else ... typedef image2d<t_value> t_point_img; typedef image3d<unsigned> t_histo_img; typedef util::array<t_result1d> t_number_img; @@ -128,35 +178,26 @@ namespace mln typedef util::array<t_mean_set> t_mean_cnv; typedef image1d<t_result1d> t_variance_val; typedef util::array<t_variance_val> t_variance_cnv; - ///} - //------------------------------------------------------------------------ - // Constructor - //------------------------------------------------------------------------ - /// \brief Constructor + /// \brief Constructor. + /// /// \param[in] point : the image as the population of pixels. /// \param[in] k_center : the number of centers. /// \param[in] watch_dog : the limit to observe the convergence (10). /// \param[in] n_times : the number of times that we executed kmean(10). - kmean3d(const t_point_img& point, const unsigned k_center, const unsigned watch_dog = 10, const unsigned n_times = 10); - //------------------------------------------------------------------------ - // Accessors - //------------------------------------------------------------------------ - - /// Mutator and accessors. + /// Mutators and accessors. /// \{ /// \brief Mutator and accessors are required for debugging and testing. /// /// Testing needs to hack the kmean loop process in order to verify each /// step of the algorithm. - void set_point(t_point_img& point); void set_histo(t_histo_img& histo); void set_number(t_number_img& number); @@ -184,13 +225,13 @@ namespace mln // Normal outputs t_mean_img& to_result(); - /// \} - //------------------------------------------------------------------------ - // Printing temporary results - //------------------------------------------------------------------------ + /// Show temporary results. + /// \{ + /// \brief Formating temporary outputs for debugging. + /// void print_mean(); void print_number(); void print_variance(); @@ -198,32 +239,19 @@ namespace mln void print_group(); void print_point(); void print_histo(); + /// \} - //------------------------------------------------------------------------ - // Initializations of centers - //------------------------------------------------------------------------ /// Initialization of centers. /// \{ - /// \brief Two ways: Regular greylevel tick or random greylevel value or. + /// \brief Initialize centers by random position. /// - /// There is two way to proceed the initialization. First of all, we - /// divide the rgb space in regular tick and we assigne them to the mean - /// of the centers. Finaly, we can ask random initialization along the - /// greyscale axis. The second process is needed to launch_n_times the - /// kmean and converge to the best descent. - + /// Assign a random position in the rgb space to each center. void init_mean(); - void init_mean_regular(); void init_mean_random(); - /// \} - //------------------------------------------------------------------------ - // Computations of distance, group, center, within variance - //------------------------------------------------------------------------ - /// Computations of distance, group, center, within variance. /// \{ /// \brief Update the statistical information needed by the kmean process. @@ -232,36 +260,27 @@ namespace mln /// first compute. Then we assign the pixels to their nearest center. /// The new location of each center can then update. Finaly, hommogeneity /// in group is observed by the within variance. - void update_distance(); void update_group(); void update_mean(); void update_variance(); - /// \} - //------------------------------------------------------------------------ - // Main loop - //------------------------------------------------------------------------ /// kmean main loop /// \{ /// \brief User interface to launch the kmean process. /// - /// There are two ways to launch the kmean process. The first one allow to - /// run it one time until convergence. As the process is a descent, it - /// depends on the initial center locations. The second call allow us to - /// rerun the process many times and to keep the best result (the one - /// with the smallest within variance). - + /// There are two ways to launch the kmean process. The first + /// one allows to run it one time until convergence. As the + /// process is a descent, it depends on the initial center + /// location. The second call allow us to rerun the process + /// many times and to keep the best result (the one with the + /// smallest within variance). void launch_one_time(); void launch_n_times(); - /// \} - //------------------------------------------------------------------------ - // Checking the validiy of the results - //------------------------------------------------------------------------ /// Checking the validity of the results. /// \{ @@ -271,32 +290,22 @@ namespace mln /// the descent was successfull or not. The method is_valid_descent do it /// for us. The method looks for a bad center (a class with no greylevel /// associate to it) and a failure in the convergence. - bool is_descent_valid(); - /// \} - //------------------------------------------------------------------------ - // Debugging tools - //------------------------------------------------------------------------ - - /// Debugging tools + /// Checking the validity of the results. /// \{ - /// \brief These methods help to interpret results. + /// \brief These methods help us to determine the validity of the results. /// - /// The methods build_label_dbg and build_all_dbg work in the input data - /// space. The first one build the 2d image of labels. The second call the - /// first one and then builds the colorize label' image and the mean - /// greylevel image. The update_cnv and finalize_cnv methods are used to - /// trace the convergence. They fill two images with the mean info and - /// the within variance info along the convergence and the tries. - + /// After each launching the kmean process one time, we need to know if + /// the descent was successfull or not. The method is_valid_descent do it + /// for us. The method looks for a bad center (a class with no color + /// associate to it) or a failure in the convergence. void build_label_dbg(); void build_mean_dbg(); void build_all_dbg(); void update_cnv(); void finalize_cnv(); - /// \} @@ -313,13 +322,12 @@ namespace mln /// kmean loop. As the kmean process is a descent, restarting the process /// from different location will confort us in that we found a global /// minima, not just a local one. - unsigned _k_center; unsigned _watch_dog; unsigned _n_times; - /// \} + /// Convergence information. /// \{ /// \brief This information is used to follow the convergence. @@ -337,14 +345,12 @@ namespace mln /// again. The flag is_number_valid is set when a empty class /// appears. This flag inhibit the process and force to restart /// a try. - t_result1d _within_variance; unsigned _current_step; unsigned _current_launching; bool _is_number_valid; static const unsigned _N_TRIES = 3; - /// \} /// Result of the kmean process. @@ -354,10 +360,10 @@ namespace mln /// The kmean process result is composed by three information. The best /// launching iteration, the best within variance obtained and the /// location of the centers associated. - unsigned _launching_min; t_result1d _variance_min; t_mean_img _mean_min; + /// \} /// Inputs. /// \{ @@ -365,12 +371,11 @@ namespace mln /// /// The point image is a saving data for the real inputs. In fact, we use /// the histogram information in the optimized kmean process. - t_point_img _point; t_histo_img _histo; - ///\} + /// Centers description. /// \{ /// \brief Centers are described by the first moment of their group. @@ -381,11 +386,9 @@ namespace mln /// convergence. The number of pixels is used as integrity indicator. /// A center with no point is a non sense. Theses informations are updated /// after each kmean iteration. - t_number_img _number; // k x 1 - t_mean_img _mean; // k x 1 + t_mean_img _mean; // k x 3 t_variance_img _variance; // k x 1 within group - /// \} /// rgb image description. @@ -396,12 +399,11 @@ namespace mln /// which pixel) is assigned to a center. The distance image give us a /// clue on how a greylevel could contribute to a center. The summation /// over the rgb space of a center give us the within variance. - t_group_img _group; // g x 3 because dim(t_value) = 3 t_distance_img _distance; // label x rgb space - /// \} + /// Debugging, calibrating and testing results. /// \{ /// \brief Some exports information to control the results. @@ -412,14 +414,12 @@ namespace mln /// label (assigned to the same center) in the image. The mean image /// associate the mean of each pixel center to each pixel. We obtain thus /// a rebuilded image. - t_label_dbg _label_dbg; t_color_dbg _color_dbg; t_mean_dbg _mean_dbg; - /// \} - /// Debugging, calibrating and testing convergence. + /// Variance and center evolutions. /// \{ /// \brief Trace the variance and the center evolution. /// @@ -428,10 +428,8 @@ namespace mln /// kmean loop or along the different launch. The variance_cnv is a trace /// of the within variance along the kmean loop or along the different /// launch. - t_mean_cnv _mean_cnv; t_variance_cnv _variance_cnv; - /// \} }; @@ -448,7 +446,7 @@ namespace mln const unsigned watch_dog, const unsigned n_times) { - trace::entering("mln::clustering::kmean3d::kmean3d"); + trace::entering("mln::clustering::kmean3d::cstor"); mln_precondition(point.is_valid()); _k_center = k_center; @@ -520,7 +518,7 @@ namespace mln _mean_cnv.append(mean_set); } - trace::exiting("mln::clustering::kmean3d::kmean3d"); + trace::exiting("mln::clustering::kmean3d::cstor"); } //-------------------------------------------------------------------------- @@ -1338,7 +1336,7 @@ namespace mln trace::exiting("mln::clustering::kmean3d::launch_n_times"); } -#endif // ! MLN_INCLUDE_ONLY +# endif // ! MLN_INCLUDE_ONLY } // end of namespace mln::clustering diff --git a/scribo/sandbox/green/mln/clustering/kmean_rgb.hh b/scribo/sandbox/green/mln/clustering/kmean_rgb.hh index 253745b..544066b 100644 --- a/scribo/sandbox/green/mln/clustering/kmean_rgb.hh +++ b/scribo/sandbox/green/mln/clustering/kmean_rgb.hh @@ -1,4 +1,4 @@ -// Copyright (C) 2008,2009 EPITA Research and Development Laboratory (LRDE) +// Copyright (C) 2007,2008,2009,2010 EPITA LRDE // // This file is part of Olena. // @@ -28,16 +28,68 @@ /// \file /// -/// \brief Implements the optimized kmean algorithm. +/// \brief Implements the optimized kmean algorithm in the 3d-RGB space. /// /// This algorithm is optimized in the way it proceeds directly with -/// the rgb values inspite of the pixel attribute. The +/// the rgb value inspite of the pixel attribute. The /// algorithm is independant from the image dimension. But, we have to /// compute one time the histogram. In fact, we move a recurrent cost -/// to a fix cost in the complexity. This version is adapted to -/// image with small quantification. - -/// APLATISSEMENT DES KMEAN3D +/// by a fix cost in the complexity. This version is very adapted to +/// images with small quantification. But, in 3d, the execution +/// becomes very slow. It's just normal because the quantification is +/// n bits per axis. So the actual histogram may be bigger than the image. +/// +/// Take care to the following point: The within variance is still a +/// scalar value because we take the distance between two points and +/// the result is a scalar from the geometrical point of view. An +/// alternative implementation could study the variance/covariance +/// matrix of each sub data clouds and works with the trace of the +/// within variance matrix (as we do for the fisher criteria in N-d). +/// +/// The following sample is a typical use of the functional (versus +/// object) kmean implementation. +/// +/// #include <iostream> +/// #include <mln/clustering/kmean_rgb.hh> +/// #include <mln/core/image/image2d.hh> +/// #include <mln/data/transform.hh> +/// #include <mln/fun/v2v/rgb8_to_rgbn.hh> +/// #include <mln/img_path.hh> +/// #include <mln/io/ppm/load.hh> +/// #include <mln/value/label_8.hh> +/// #include <mln/value/rgb.hh> +/// #include <mln/value/rgb8.hh> +/// +/// int main() +/// { +/// typedef mln::value::label_8 t_lbl8; +/// typedef mln::value::rgb8 t_rgb8; +/// typedef mln::value::rgb<5> t_rgb5; +/// typedef mln::image2d<t_rgb8> t_image2d_rgb8; +/// typedef mln::image2d<t_rgb5> t_image2d_rgb5; +/// typedef mln::image2d<t_lbl8> t_image2d_lbl8; +/// typedef mln::fun::v2v::rgb8_to_rgbn<5> t_rgb8_to_rgb5; +/// +/// t_image2d_rgb8 img_rgb8; +/// t_image2d_rgb5 img_rgb5; +/// t_image2d_lbl8 img_lbl8; +/// +/// mln::io::ppm::load(img_rgb8, OLENA_IMG_PATH"/house.ppm"); +/// +/// img_rgb5 = mln::data::transform(img_rgb8, t_rgb8_to_rgb5()); +/// img_lbl8 = mln::clustering::kmean_rgb<double,5>(img_rgb5, 3); +/// +/// return 0; +/// } +/// +/// \fixme The execution shows a bug in printing outputs and it seems severe. +/// +/// The last execution with the following set of parameters +/// {house.ppm,3,10,10} shows that if the binary starts correctly, it +/// ends before returning the label image and with disturbing outputs. +/// Dumping the outputs in a file reveals that the number of +/// trace::entering differs from the number of trace::exiting. May the +/// program exit from a loop without ending a trace ??? # include <limits.h> # include <iostream> @@ -86,7 +138,7 @@ //-------------------------------------------------------------------------- -// CODE APLATI +// FUNCTIONAL CODE //-------------------------------------------------------------------------- @@ -95,7 +147,24 @@ namespace mln namespace clustering { - + /// \brief Implements the functional kmean algorithm. + /// + /// This functional version of the kmean is very specific. All the + /// code is view as a one-block function. This code is provided as + /// is. I (YJ) don't know where i stopped this version. It may not + /// work. Debugging tools are not yet provided. This code is just + /// the functional transcription of the kmean3d version. The code + /// has the very experimental status. + /// + /// T is the type used for computations (float or double). + /// n is the quantification for the rgb image. + /// + /// \param[in] point : the image as the population of pixels. + /// \param[in] k_center : the number of centers. + /// \param[in] watch_dog : the limit to observe the convergence (10). + /// \param[in] n_times : the number of times that we executed kmean(10). + /// + /// \return an image which represents the pixel classification. template <typename T, unsigned n, typename I> inline image2d<value::label_8> diff --git a/scribo/sandbox/green/mln/fun/v2v/rg_to_rgb.hh b/scribo/sandbox/green/mln/fun/v2v/rg_to_rgb.hh index ca7ba51..e89edad 100644 --- a/scribo/sandbox/green/mln/fun/v2v/rg_to_rgb.hh +++ b/scribo/sandbox/green/mln/fun/v2v/rg_to_rgb.hh @@ -1,6 +1,4 @@ -// 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) +// Copyright (C) 2007,2008,2009,2010 EPITA LRDE // // This file is part of Olena. // @@ -34,7 +32,51 @@ /// \file /// -/// \brief Convert rg value to rgb +/// \brief Convert a rg value to a rgb value. +/// +/// This source implements the conversion between rg space and rgb space. +/// +/// The following sample is a typical use of the rg/rgb conversion function. +/// +/// #include <iostream> +/// #include <mln/clustering/kmean2d.hh> +/// #include <mln/core/image/image2d.hh> +/// #include <mln/data/transform.hh> +/// #include <mln/fun/v2v/rgb_to_rg.hh> +/// #include <mln/fun/v2v/rg_to_rgb.hh> +/// #include <mln/img_path.hh> +/// #include <mln/io/ppm/load.hh> +/// #include <mln/value/rg.hh> +/// #include <mln/value/rgb8.hh> +/// +/// int main() +/// { +/// typedef mln::value::rg<8> t_rg8; +/// typedef mln::value::rgb8 t_rgb8; +/// typedef mln::image2d<t_rgb8> t_image2d_rgb8; +/// typedef mln::image2d<t_rg8> t_image2d_rg8; +/// typedef mln::fun::v2v::rgb_to_rg<8> t_rgb_to_rg; +/// typedef mln::fun::v2v::rg_to_rgb<8> t_rg_to_rgb; +/// +/// t_image2d_rgb8 img_rgb8; +/// t_image2d_rgb8 point_img_rgb8; +/// t_image2d_rg8 img_rg8; +/// +/// mln::io::ppm::load(img_rgb8, OLENA_IMG_PATH"/house.ppm"); +/// +/// img_rg8 = mln::data::transform(img_rgb8, t_rgb_to_rg()); +/// +/// mln::clustering::kmean2d<double, 8> kmean(img_rg8, 3); +/// +/// kmean.launch_n_times(); +/// +/// mln::clustering::kmean2d<double,8>::t_point_img point_img = +/// kmean.get_point(); +/// +/// point_img_rgb8 = mln::data::transform(point_img, t_rg_to_rgb()); +/// +/// return 0; +/// } namespace mln { @@ -47,14 +89,21 @@ namespace mln /// \brief Convert rg value to rgb. /// + /// Param n defines the quantification used for rgb space and rg space. + /// /// \ingroup modfunv2v - template <unsigned n> struct rg_to_rgb : Function_v2v< rg_to_rgb<n> > { typedef value::rg<n> argument; typedef value::rgb<n> result; + /// \brief Convert rg value to rgb value. + /// + /// \param[in] v the rg value to convert. + /// + /// Conversion is done by calling the rgb constructor and fill + /// the empty attirbute by 127. result operator()(const argument& v) const { return value::rgb<n>(v.red(), v.green(), 127); diff --git a/scribo/sandbox/green/tests/clustering/k_mean/Makefile.am b/scribo/sandbox/green/tests/clustering/k_mean/Makefile.am index 5f00678..77f9015 100644 --- a/scribo/sandbox/green/tests/clustering/k_mean/Makefile.am +++ b/scribo/sandbox/green/tests/clustering/k_mean/Makefile.am @@ -6,8 +6,13 @@ # TOOLS # ######### -INCLUDES= -I$(HOME)/svn/oln/trunk/milena/sandbox/green +#LOADLIBES= -lboost_filesystem +INCLUDES1= -I$(HOME)/git/olena/scribo/sandbox/green +INCLUDES2= -I$(HOME)/git/olena/milena +INCLUDES= $(INCLUDES1) $(INCLUDES2) CXXFLAGS= -ggdb -O0 -Wall -W -pedantic -ansi -pipe $(INCLUDES) +#CXXFLAGS= -DNDEBUG -O1 -Wall -W -pedantic -ansi -pipe $(INCLUDES) +#CXXFLAGS= -DNDEBUG -O3 -Wall -W -pedantic -ansi -pipe $(INCLUDES) ECHO= echo RM= rm MKDIR= mkdir -p @@ -20,10 +25,10 @@ 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) +BUILD__DIR= $(PWD)/ else # Case where make is done from source directory. -SOURCE_DIR= $(PWD) +SOURCE_DIR= $(PWD)/ BUILD__DIR= $(subst $(SOURCE_PATTERN),$(BUILD__PATTERN),$(PWD)) endif @@ -89,7 +94,7 @@ $(OBJ_F_PATH):$(SRC_F_PATH) ######### # Force every time the deletion -clean: print clean_target clean_obj clean_dst clean_old #clean_make +clean: clean_target clean_obj clean_dst clean_old #clean_make clean_target: diff --git a/scribo/sandbox/green/tests/clustering/k_mean/k_mean.cc b/scribo/sandbox/green/tests/clustering/k_mean/k_mean.cc index 27751fd..a839ece 100644 --- a/scribo/sandbox/green/tests/clustering/k_mean/k_mean.cc +++ b/scribo/sandbox/green/tests/clustering/k_mean/k_mean.cc @@ -1,34 +1,68 @@ -// UNARY TESTS ON K_MEAN - -#include <mln/clustering/k_mean.hh> +// Copyright (C) 2007, 2008, 2009, 2010 EPITA 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. + +/// \file +/// +/// \brief This source manages unitary testing on the kmean implementation. +/// +/// Tests are performed from 2 bits up to 8 bits quantification. The goal +/// is to go through each programmatic flow to verify the conformity of the +/// code. It sounds like a theoritic model of unitary testing for milena. +/// The last test enables statistic computations on that component. #include <iostream> -#include <mln/pw/value.hh> - -#include <mln/value/int_u8.hh> -#include <mln/value/rgb8.hh> - #include <mln/literal/colors.hh> #include <mln/algebra/vec.hh> #include <mln/algebra/mat.hh> +#include <mln/clustering/k_mean.hh> + #include <mln/core/macros.hh> #include <mln/core/contract.hh> #include <mln/core/image/image2d.hh> #include <mln/core/image/dmorph/image_if.hh> +#include <mln/data/transform.hh> + +#include <mln/img_path.hh> + #include <mln/io/ppm/load.hh> #include <mln/io/pgm/load.hh> #include <mln/io/pgm/save.hh> #include <mln/io/ppm/save.hh> -#include <mln/data/transform.hh> - #include <mln/trait/value/print.hh> #include <mln/trait/image/print.hh> +#include <mln/pw/value.hh> + +#include <mln/value/int_u8.hh> +#include <mln/value/rgb8.hh> + #define SIZE_IMAGE 512 #define SIZE_SAMPLE1 (512*512) #define SIZE_SAMPLE2 4 @@ -44,20 +78,18 @@ #define MAT_GROUP2 mln::algebra::mat<SIZE_SAMPLE2, NB_CENTER, TYPE_POINT> #define VEC_VAR mln::algebra::vec<NB_CENTER, TYPE_POINT> - -void test_instantiation() -{ - mln::clustering::k_mean<SIZE_SAMPLE2,NB_CENTER, DIM_POINT, TYPE_POINT> kmean; - - // test the compilation - - std::cout << "test instantiation : ok" << std::endl; -} +/// Tools. +/// \{ +/// \brief Define some tools which are used in unitary testing. +/// +/// This kind of tools help to fill an image with only 4 tons or +/// computing a distance between two colors. Just keep an eye, nothing +/// really difficult in this code. struct rgb8_to_4colors : mln::Function_v2v<rgb8_to_4colors> { typedef mln::value::rgb8 result; - + mln::value::rgb8 operator()(const mln::value::rgb8& color) const { mln::value::rgb8 result; @@ -78,11 +110,12 @@ struct rgb8_to_4colors : mln::Function_v2v<rgb8_to_4colors> void print_color(const mln::value::rgb8& color) { - std::cout << "{r=" << color.red() << ", "; + std::cout << "{r=" << color.red() << ", "; std::cout << "g=" << color.green() << ", "; std::cout << "b=" << color.blue() << "}" << std::endl; } + void fill_image_with_4colors(mln::image2d<mln::value::rgb8>& img) { const mln::value::rgb8 lime = mln::literal::lime; @@ -98,6 +131,140 @@ void fill_image_with_4colors(mln::image2d<mln::value::rgb8>& img) //print_color(purple); } + +double dist(mln::value::rgb8 color1, mln::value::rgb8 color2) +{ + double red = color1.red() - color2.red(); + double green = color1.green() - color2.green(); + double blue = color1.blue() - color2.blue(); + double result= red * red + green * green + blue * blue; + + return result; +} + +/// \} + + +/// External mutators. +/// \{ +/// \brief Replace the kmean data structure values. +/// +/// This is a hack that provides low level routines to access key data +/// structure like point, center, distance and group. + +void set_point(MAT_POINT2& point, + const unsigned index, + const mln::value::rgb8& color) +{ + point(index,0) = color.red(); + point(index,1) = color.green(); + point(index,2) = color.blue(); +} + +void set_center(MAT_CENTER& center, + const unsigned index, + const mln::value::rgb8& color) +{ + center(index,0) = color.red(); + center(index,1) = color.green(); + center(index,2) = color.blue(); +} + +void set_distance(MAT_DISTANCE2& distance, + const unsigned index, + const double d1, + const double d2) +{ + distance(index,0) = d1; + distance(index,1) = d2; +} + +void set_group(MAT_GROUP2& group, + const unsigned index, + const unsigned min) +{ + group(index, min) = 1.0; + group(index, 1-min) = 0.0; +} + +/// \} + +/// Fake states. +/// \{ +/// \brief Help to build from scratch temporary states for the kmean algorithm. +/// +/// This hack allow us to build temporary results used in the previous step to +/// make us very the behaviour of the current step. There is a fake state for +/// every key data structure (point, group, center and distance). + +void fake_init_point(MAT_POINT2& point, + const mln::value::rgb8& point1, + const mln::value::rgb8& point2, + const mln::value::rgb8& point3, + const mln::value::rgb8& point4) +{ + set_point(point, 0, point1); + set_point(point, 1, point2); + set_point(point, 2, point3); + set_point(point, 3, point4); +} + + +void fake_update_group(MAT_GROUP2& group, + const unsigned& point1_min, + const unsigned& point2_min, + const unsigned& point3_min, + const unsigned& point4_min) +{ + set_group(group, 0, point1_min); + set_group(group, 1, point2_min); + set_group(group, 2, point3_min); + set_group(group, 3, point4_min); +} + + +void fake_init_center(MAT_CENTER& center, + const mln::value::rgb8 center1, + const mln::value::rgb8 center2) +{ + + set_center(center, 0, center1); + set_center(center, 1, center2); +} + + + + +void fake_update_distance(MAT_DISTANCE2& distance, + const mln::value::rgb8& point1, + const mln::value::rgb8& point2, + const mln::value::rgb8& point3, + const mln::value::rgb8& point4, + const mln::value::rgb8& center1, + const mln::value::rgb8& center2) +{ + set_distance(distance, 0, dist(point1, center1), dist(point1, center2)); + set_distance(distance, 1, dist(point2, center1), dist(point2, center2)); + set_distance(distance, 2, dist(point3, center1), dist(point3, center2)); + set_distance(distance, 3, dist(point4, center1), dist(point4, center2)); + + /* + for (int i = 0; i < SIZE_SAMPLE2; ++i) + for (int j = 0; j < NB_CENTER; ++j) + std::cout << "d(" << i << "," << j << ") = " << distance(i,j) <<std::endl; + */ +} + +/// \} + +/// Equivalence. +/// \{ +/// \brief Test equivalence between point and image, center and color. +/// +/// Two kinds of equivalence are defined here. The first one tests the +/// equality between the data cloud and the initial image, while the +/// second one tests the equality between a center and a color. + bool is_equivalent(const mln::image2d<mln::value::rgb8>& img, const MAT_POINT1& point) { @@ -118,11 +285,11 @@ bool is_equivalent(const mln::image2d<mln::value::rgb8>& img, if (!test) { std::cout << pi; - std::cout << "{r=" << img(pi).red() << ", "; + std::cout << "{r=" << img(pi).red() << ", "; std::cout << "g=" << img(pi).green() << ", "; std::cout << "b=" << img(pi).blue() << "}"; std::cout << index; - std::cout << "[r=" << point(index,0) << ", "; + std::cout << "[r=" << point(index,0) << ", "; std::cout << "g=" << point(index,1) << ", "; std::cout << "b=" << point(index,2) << "]" << std::endl; @@ -135,6 +302,44 @@ bool is_equivalent(const mln::image2d<mln::value::rgb8>& img, return result; } +bool is_equal(const mln::value::rgb8& ref, + const MAT_CENTER& center, + const unsigned i) +{ + bool result = true; + + result = result && (center(i, 0) - ref.red() < 1.0); + result = result && (center(i, 1) - ref.green() < 1.0); + result = result && (center(i, 2) - ref.blue() < 1.0); + + return result; +} + +/// \} + + +/// kmean unitary testing +/// \{ +/// \brief This part of the code manages the unitary testing. +/// +/// Many tests are performed and new kind of unitary testing +/// appears. In fact, we must simulate the previous steps of the line +/// currently testing and so making some fake steps. Bad and deep +/// hacking in data structure are required. We test the instantiation +/// of the kmean object, its initialization (points and centers), its +/// core routines (update_center, update_group, update_distance, +/// update_variance) and the final loop. + +void test_instantiation() +{ + mln::clustering::k_mean<SIZE_SAMPLE2,NB_CENTER, DIM_POINT, TYPE_POINT> kmean; + + // test the compilation + + std::cout << "test instantiation : ok" << std::endl; +} + + void test_init_point() { typedef mln::value::rgb8 rgb8; @@ -147,45 +352,12 @@ void test_init_point() fill_image_with_4colors(img_ref); kmean.init_point(img_ref); - + mln_assertion(true == is_equivalent(img_ref, kmean.get_point())); std::cout << "Test init point : ok" << std::endl; } -void set_point(MAT_POINT2& point, - const unsigned index, - const mln::value::rgb8& color) -{ - point(index,0) = color.red(); - point(index,1) = color.green(); - point(index,2) = color.blue(); -} - -void fake_init_point(MAT_POINT2& point, - const mln::value::rgb8& point1, - const mln::value::rgb8& point2, - const mln::value::rgb8& point3, - const mln::value::rgb8& point4) -{ - set_point(point, 0, point1); - set_point(point, 1, point2); - set_point(point, 2, point3); - set_point(point, 3, point4); -} - -bool is_equal(const mln::value::rgb8& ref, - const MAT_CENTER& center, - const unsigned i) -{ - bool result = true; - - result = result && (center(i, 0) - ref.red() < 1.0); - result = result && (center(i, 1) - ref.green() < 1.0); - result = result && (center(i, 2) - ref.blue() < 1.0); - - return result; -} void test_init_center() { @@ -195,10 +367,10 @@ void test_init_center() const mln::value::rgb8 brown = mln::literal::brown; const mln::value::rgb8 teal = mln::literal::teal; const mln::value::rgb8 purple = mln::literal::purple; - + fake_init_point(kmean.get_point(), lime, brown, teal, purple); kmean.init_center(); - + mln_assertion(is_equal(lime, kmean.get_center(), 0) || is_equal(brown, kmean.get_center(), 0) || is_equal(teal, kmean.get_center(), 0) || @@ -212,34 +384,6 @@ void test_init_center() std::cout << "Test init center : ok" << std::endl; } -void set_center(MAT_CENTER& center, - const unsigned index, - const mln::value::rgb8& color) -{ - center(index,0) = color.red(); - center(index,1) = color.green(); - center(index,2) = color.blue(); -} - -void fake_init_center(MAT_CENTER& center, - const mln::value::rgb8 center1, - const mln::value::rgb8 center2) -{ - - set_center(center, 0, center1); - set_center(center, 1, center2); -} - - -double dist(mln::value::rgb8 color1, mln::value::rgb8 color2) -{ - double red = color1.red() - color2.red(); - double green = color1.green() - color2.green(); - double blue = color1.blue() - color2.blue(); - double result= red * red + green * green + blue * blue; - - return result; -} void test_update_distance() { @@ -269,34 +413,6 @@ void test_update_distance() std::cout << "Test update distance : ok" << std::endl; } -void set_distance(MAT_DISTANCE2& distance, - const unsigned index, - const double d1, - const double d2) -{ - distance(index,0) = d1; - distance(index,1) = d2; -} - -void fake_update_distance(MAT_DISTANCE2& distance, - const mln::value::rgb8& point1, - const mln::value::rgb8& point2, - const mln::value::rgb8& point3, - const mln::value::rgb8& point4, - const mln::value::rgb8& center1, - const mln::value::rgb8& center2) -{ - set_distance(distance, 0, dist(point1, center1), dist(point1, center2)); - set_distance(distance, 1, dist(point2, center1), dist(point2, center2)); - set_distance(distance, 2, dist(point3, center1), dist(point3, center2)); - set_distance(distance, 3, dist(point4, center1), dist(point4, center2)); - - /* - for (int i = 0; i < SIZE_SAMPLE2; ++i) - for (int j = 0; j < NB_CENTER; ++j) - std::cout << "d(" << i << "," << j << ") = " << distance(i,j) <<std::endl; - */ -} void test_update_group() { @@ -331,26 +447,6 @@ void test_update_group() std::cout << "Test update group : ok" << std::endl; } -void set_group(MAT_GROUP2& group, - const unsigned index, - const unsigned min) -{ - group(index, min) = 1.0; - group(index, 1-min) = 0.0; -} - - -void fake_update_group(MAT_GROUP2& group, - const unsigned& point1_min, - const unsigned& point2_min, - const unsigned& point3_min, - const unsigned& point4_min) -{ - set_group(group, 0, point1_min); - set_group(group, 1, point2_min); - set_group(group, 2, point3_min); - set_group(group, 3, point4_min); -} void test_update_center() { @@ -374,13 +470,14 @@ void test_update_center() fake_update_distance(kmean.get_distance(), lime, brown, teal, purple, c1, c2); fake_update_group(kmean.get_group(), pt1_min, pt2_min, pt3_min, pt4_min); kmean.update_center(); - + mln_assertion(is_equal(mean_c1, kmean.get_center(), 0)); mln_assertion(is_equal(mean_c2, kmean.get_center(), 1)); std::cout << "Test update center : ok" << std::endl; } + void test_update_variance() { mln::clustering::k_mean<SIZE_SAMPLE2, NB_CENTER, DIM_POINT, TYPE_POINT> kmean; @@ -405,13 +502,15 @@ void test_update_variance() fake_update_distance(kmean.get_distance(), lime, brown, teal, purple, c1, c2); fake_update_group(kmean.get_group(), pt1_min, pt2_min, pt3_min, pt4_min); kmean.update_variance(); - + mln_assertion(v1 == var[0]); mln_assertion(v2 == var[1]); std::cout << "Test update variance : ok" << std::endl; } + +/// \fixme this procedure tests actually nothing. void test_loop() { typedef mln::value::rgb8 rgb8; @@ -426,24 +525,22 @@ void test_loop() kmean.init_point(img_ref); kmean.loop(img_ref); - - // std::cout << "Test update variance: ok" << std::endl; + // \FIXME: Which assertion must we define ? + // std::cout << "Test loop : ok" << std::endl; } +/// \} int main() { - //test_instantiation(); - //test_init_point(); - //test_init_center(); - //test_update_distance(); - //test_update_group(); - //test_update_center(); - //test_update_variance(); - - // mln::trace::quiet = false; - + test_instantiation(); + test_init_point(); + test_init_center(); + test_update_distance(); + test_update_group(); + test_update_center(); + test_update_variance(); test_loop(); return 0; diff --git a/scribo/sandbox/green/use/accu/stat/histo1d/Makefile.am b/scribo/sandbox/green/use/clustering/k_mean/Makefile.am similarity index 100% copy from scribo/sandbox/green/use/accu/stat/histo1d/Makefile.am copy to scribo/sandbox/green/use/clustering/k_mean/Makefile.am diff --git a/scribo/sandbox/green/use/clustering/k_mean/k_mean.cc b/scribo/sandbox/green/use/clustering/k_mean/k_mean.cc new file mode 100644 index 0000000..9b00037 --- /dev/null +++ b/scribo/sandbox/green/use/clustering/k_mean/k_mean.cc @@ -0,0 +1,55 @@ +// Copyright (C) 2007, 2008, 2009, 2010 EPITA 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. + +/// \file +/// +/// \brief Minimal code to use the first implementation of the kmean algorithm. +/// + +#include <mln/clustering/k_mean.hh> +#include <mln/core/image/image2d.hh> +#include <mln/img_path.hh> +#include <mln/io/ppm/load.hh> +#include <mln/trait/value_.hh> +#include <mln/value/rgb8.hh> + +#define NB_CENTER 9 +#define NB_POINT (128*128) +#define POINT_SIZE mln_dim(mln::value::rgb8) +#define POINT_TYPE double + +int main() +{ + typedef mln::value::rgb8 t_rgb8; + mln::image2d<t_rgb8> img_rgb8; + + mln::io::ppm::load(img_rgb8, OLENA_IMG_PATH"/house.ppm"); + mln::clustering::k_mean<NB_POINT, NB_CENTER, POINT_SIZE, POINT_TYPE> kmean; + + kmean.init_point(img_rgb8); + kmean.loop(img_rgb8); + + return 0; +} diff --git a/scribo/sandbox/green/use/accu/stat/histo1d/Makefile.am b/scribo/sandbox/green/use/clustering/kmean1d/Makefile.am similarity index 100% copy from scribo/sandbox/green/use/accu/stat/histo1d/Makefile.am copy to scribo/sandbox/green/use/clustering/kmean1d/Makefile.am diff --git a/scribo/sandbox/green/use/clustering/kmean1d/kmean1d.cc b/scribo/sandbox/green/use/clustering/kmean1d/kmean1d.cc new file mode 100644 index 0000000..82b13c9 --- /dev/null +++ b/scribo/sandbox/green/use/clustering/kmean1d/kmean1d.cc @@ -0,0 +1,50 @@ +// Copyright (C) 2007, 2008, 2009, 2010 EPITA 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. + +/// \file +/// +/// \brief Minimal code to use the second implementation of the kmean algorithm. +/// + +#include <iostream> +#include <mln/clustering/kmean1d.hh> +#include <mln/core/image/image2d.hh> +#include <mln/img_path.hh> +#include <mln/io/pgm/load.hh> +#include <mln/value/int_u8.hh> + +int main() +{ + typedef mln::value::int_u8 t_int_u8; + typedef mln::image2d<t_int_u8> t_image2d_int_u8; + t_image2d_int_u8 img_int_u8; + + mln::io::pgm::load(img_int_u8, OLENA_IMG_PATH"/house.pgm"); + mln::clustering::kmean1d<double, 8> kmean(img_int_u8, 3); + + kmean.launch_n_times(); + + return 0; +} diff --git a/scribo/sandbox/green/use/accu/stat/histo1d/Makefile.am b/scribo/sandbox/green/use/clustering/kmean2d/Makefile.am similarity index 100% copy from scribo/sandbox/green/use/accu/stat/histo1d/Makefile.am copy to scribo/sandbox/green/use/clustering/kmean2d/Makefile.am diff --git a/scribo/sandbox/green/use/clustering/kmean2d/kmean2d.cc b/scribo/sandbox/green/use/clustering/kmean2d/kmean2d.cc new file mode 100644 index 0000000..d6bf05b --- /dev/null +++ b/scribo/sandbox/green/use/clustering/kmean2d/kmean2d.cc @@ -0,0 +1,61 @@ +// Copyright (C) 2007, 2008, 2009, 2010 EPITA 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. + +/// \file +/// +/// \brief Minimal code to use the optimized version of the kmean2d algorithm. +/// + +#include <iostream> +#include <mln/clustering/kmean2d.hh> +#include <mln/core/image/image2d.hh> +#include <mln/data/transform.hh> +#include <mln/fun/v2v/rgb_to_rg.hh> +#include <mln/img_path.hh> +#include <mln/io/ppm/load.hh> +#include <mln/value/rg.hh> +#include <mln/value/rgb8.hh> + +int main() +{ + typedef mln::value::rg<8> t_rg8; + typedef mln::value::rgb8 t_rgb8; + typedef mln::image2d<t_rgb8> t_image2d_rgb8; + typedef mln::image2d<t_rg8> t_image2d_rg8; + typedef mln::fun::v2v::rgb_to_rg<8> t_rgb_to_rg; + + t_image2d_rgb8 img_rgb8; + t_image2d_rg8 img_rg8; + + mln::io::ppm::load(img_rgb8, OLENA_IMG_PATH"/house.ppm"); + + img_rg8 = mln::data::transform(img_rgb8, t_rgb_to_rg()); + + mln::clustering::kmean2d<double, 8> kmean(img_rg8, 3); + + kmean.launch_n_times(); + + return 0; +} diff --git a/scribo/sandbox/green/use/accu/stat/histo1d/Makefile.am b/scribo/sandbox/green/use/clustering/kmean3d/Makefile.am similarity index 100% copy from scribo/sandbox/green/use/accu/stat/histo1d/Makefile.am copy to scribo/sandbox/green/use/clustering/kmean3d/Makefile.am diff --git a/scribo/sandbox/green/use/clustering/kmean3d/kmean3d.cc b/scribo/sandbox/green/use/clustering/kmean3d/kmean3d.cc new file mode 100644 index 0000000..c57d48a --- /dev/null +++ b/scribo/sandbox/green/use/clustering/kmean3d/kmean3d.cc @@ -0,0 +1,63 @@ +// Copyright (C) 2007, 2008, 2009, 2010 EPITA 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. + +/// \file +/// +/// \brief Minimal code to use the optimized version of the kmean3d algorithm. +/// + +#include <iostream> +#include <mln/clustering/kmean3d.hh> +#include <mln/core/image/image2d.hh> +#include <mln/data/transform.hh> +#include <mln/fun/v2v/rgb8_to_rgbn.hh> +#include <mln/img_path.hh> +#include <mln/io/ppm/load.hh> +#include <mln/value/rgb.hh> +#include <mln/value/rgb8.hh> + + +int main() +{ + typedef mln::clustering::kmean3d<double,5> t_kmean; + typedef mln::value::rgb8 t_rgb8; + typedef mln::value::rgb<5> t_rgb5; + typedef mln::image2d<t_rgb8> t_image2d_rgb8; + typedef mln::image2d<t_rgb5> t_image2d_rgb5; + typedef mln::fun::v2v::rgb8_to_rgbn<5> t_rgb8_to_rgb5; + + t_image2d_rgb8 img_rgb8; + t_image2d_rgb5 img_rgb5; + + mln::io::ppm::load(img_rgb8, OLENA_IMG_PATH"/house.ppm"); + + img_rgb5=mln::data::transform(img_rgb8, t_rgb8_to_rgb5()); + + t_kmean kmean(img_rgb5, 3); + + kmean.launch_n_times(); + + return 0; +} diff --git a/scribo/sandbox/green/use/accu/stat/histo1d/Makefile.am b/scribo/sandbox/green/use/clustering/kmean_rgb/Makefile.am similarity index 100% copy from scribo/sandbox/green/use/accu/stat/histo1d/Makefile.am copy to scribo/sandbox/green/use/clustering/kmean_rgb/Makefile.am diff --git a/scribo/sandbox/green/use/clustering/kmean_rgb/kmean_rgb.cc b/scribo/sandbox/green/use/clustering/kmean_rgb/kmean_rgb.cc new file mode 100644 index 0000000..3bf2241 --- /dev/null +++ b/scribo/sandbox/green/use/clustering/kmean_rgb/kmean_rgb.cc @@ -0,0 +1,63 @@ +// Copyright (C) 2007, 2008, 2009, 2010 EPITA 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. + +/// \file +/// +/// \brief Minimal code to use the the functional (versus object) kmean code. +/// + +#include <iostream> +#include <mln/clustering/kmean_rgb.hh> +#include <mln/core/image/image2d.hh> +#include <mln/data/transform.hh> +#include <mln/fun/v2v/rgb8_to_rgbn.hh> +#include <mln/img_path.hh> +#include <mln/io/ppm/load.hh> +#include <mln/value/label_8.hh> +#include <mln/value/rgb.hh> +#include <mln/value/rgb8.hh> + + +int main() +{ + typedef mln::value::label_8 t_lbl8; + typedef mln::value::rgb8 t_rgb8; + typedef mln::value::rgb<5> t_rgb5; + typedef mln::image2d<t_rgb8> t_image2d_rgb8; + typedef mln::image2d<t_rgb5> t_image2d_rgb5; + typedef mln::image2d<t_lbl8> t_image2d_lbl8; + typedef mln::fun::v2v::rgb8_to_rgbn<5> t_rgb8_to_rgb5; + + t_image2d_rgb8 img_rgb8; + t_image2d_rgb5 img_rgb5; + t_image2d_lbl8 img_lbl8; + + mln::io::ppm::load(img_rgb8, OLENA_IMG_PATH"/house.ppm"); + + img_rgb5 = mln::data::transform(img_rgb8, t_rgb8_to_rgb5()); + img_lbl8 = mln::clustering::kmean_rgb<double,5>(img_rgb5, 3, 10, 10); + + return 0; +} diff --git a/scribo/sandbox/green/use/accu/stat/histo1d/Makefile.am b/scribo/sandbox/green/use/fun/v2v/rg_to_rgb/Makefile.am similarity index 100% copy from scribo/sandbox/green/use/accu/stat/histo1d/Makefile.am copy to scribo/sandbox/green/use/fun/v2v/rg_to_rgb/Makefile.am diff --git a/scribo/sandbox/green/use/fun/v2v/rg_to_rgb/rg_to_rgb.cc b/scribo/sandbox/green/use/fun/v2v/rg_to_rgb/rg_to_rgb.cc new file mode 100644 index 0000000..84ae33f --- /dev/null +++ b/scribo/sandbox/green/use/fun/v2v/rg_to_rgb/rg_to_rgb.cc @@ -0,0 +1,68 @@ +// Copyright (C) 2007, 2008, 2009, 2010 EPITA 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. + +/// \file +/// +/// \brief Example of using rg_t_rgb transformation used with kmean2d. +/// + +#include <iostream> +#include <mln/clustering/kmean2d.hh> +#include <mln/core/image/image2d.hh> +#include <mln/data/transform.hh> +#include <mln/fun/v2v/rgb_to_rg.hh> +#include <mln/fun/v2v/rg_to_rgb.hh> +#include <mln/img_path.hh> +#include <mln/io/ppm/load.hh> +#include <mln/value/rg.hh> +#include <mln/value/rgb8.hh> + +int main() +{ + typedef mln::value::rg<8> t_rg8; + typedef mln::value::rgb8 t_rgb8; + typedef mln::image2d<t_rgb8> t_image2d_rgb8; + typedef mln::image2d<t_rg8> t_image2d_rg8; + typedef mln::fun::v2v::rgb_to_rg<8> t_rgb_to_rg; + typedef mln::fun::v2v::rg_to_rgb<8> t_rg_to_rgb; + + t_image2d_rgb8 img_rgb8; + t_image2d_rgb8 point_img_rgb8; + t_image2d_rg8 img_rg8; + + mln::io::ppm::load(img_rgb8, OLENA_IMG_PATH"/house.ppm"); + + img_rg8 = mln::data::transform(img_rgb8, t_rgb_to_rg()); + + mln::clustering::kmean2d<double, 8> kmean(img_rg8, 3); + + kmean.launch_n_times(); + + mln::clustering::kmean2d<double,8>::t_point_img point_img = kmean.get_point(); + + point_img_rgb8 = mln::data::transform(point_img, t_rg_to_rgb()); + + return 0; +} -- 1.5.6.5
14Â years, 2Â months
1
0
0
0
last-svn-commit-46-gc87f968 Add some futur materials on regional maxima.
by Yann Jacquelet
* test_labelling_2.cc: New file. * test_labelling_3.cc: New file. --- scribo/sandbox/green/ChangeLog | 7 + .../sandbox/green/test_labelling_2.cc | 318 +++++++------------- .../sandbox/green/test_labelling_3.cc | 25 ++- 3 files changed, 141 insertions(+), 209 deletions(-) copy milena/sandbox/green/demo/clustering/kmean2d/kmean2d.cc => scribo/sandbox/green/test_labelling_2.cc (64%) copy milena/sandbox/green/demo/clustering/kmean2d/kmean2d.cc => scribo/sandbox/green/test_labelling_3.cc (92%) diff --git a/scribo/sandbox/green/ChangeLog b/scribo/sandbox/green/ChangeLog index 4ddaa54..9e9b7d6 100644 --- a/scribo/sandbox/green/ChangeLog +++ b/scribo/sandbox/green/ChangeLog @@ -1,3 +1,10 @@ +2010-06-30 Yann Jacquelet <jacquelet(a)lrde.epita.fr> + + Add some futur materials on regional maxima. + + * test_labelling_2.cc: New file. + * test_labelling_3.cc: New file. + 2010-06-28 Yann Jacquelet <jacquelet(a)lrde.epita.fr> Implement the kmean algorithh and start to optimize it. diff --git a/milena/sandbox/green/demo/clustering/kmean2d/kmean2d.cc b/scribo/sandbox/green/test_labelling_2.cc similarity index 64% copy from milena/sandbox/green/demo/clustering/kmean2d/kmean2d.cc copy to scribo/sandbox/green/test_labelling_2.cc index 30e68b1..28129f1 100644 --- a/milena/sandbox/green/demo/clustering/kmean2d/kmean2d.cc +++ b/scribo/sandbox/green/test_labelling_2.cc @@ -1,4 +1,29 @@ -// DEMO ON KMEAN2D +// Copyright (C) 2007,2008,2009,2010 EPITA 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. + +/// \file #include <mln/clustering/kmean2d.hh> @@ -53,10 +78,10 @@ // Ok pour la convergence. // demander à Théo pour le temps (45 sec pour chaque launching [house,3 cl.]) // -void do_demo_kmean(const std::string& image, - const unsigned k_center, - const unsigned n_times, - const unsigned watch_dog) +void do_demo(const std::string& image, + const unsigned k_center, + const unsigned n_times, + const unsigned watch_dog) { typedef mln::clustering::kmean2d<double,8> t_kmean; typedef mln::value::rg<8> t_rg8; @@ -104,6 +129,21 @@ void do_demo_kmean(const std::string& image, } +void demo(const std::string& image = OLENA_IMG_PATH"/house.ppm", + const unsigned k_center = 3, + const unsigned n_times = 10, + const unsigned watch_dog = 10) +{ + std::cout << "----------------------------------------" << std::endl; + std::cout << "Launching the demo with these parameters" << std::endl; + std::cout << "image : " << image << std::endl; + std::cout << "k_center : " << k_center << std::endl; + std::cout << "n_times : " << n_times << std::endl; + std::cout << "watch_dog : " << watch_dog << std::endl; + std::cout << "----------------------------------------" << std::endl; + + do_demo(image, k_center, n_times, watch_dog); +} mln::image2d<mln::value::rgb<8> > merge(const mln::image2d<mln::value::rg<8> >& input, @@ -134,124 +174,91 @@ merge(const mln::image2d<mln::value::rg<8> >& input, } -// -// Watershed image processing chain. -// -void do_demo_watershed(const std::string& image, - const unsigned k_center, - const unsigned n_times, - const unsigned watch_dog) -{ - typedef mln::value::label_8 t_lbl8; - typedef mln::value::rg<8> t_rg8; - typedef mln::value::rgb8 t_rgb8; - typedef mln::value::int_u8 t_int_u8; - typedef mln::image2d<t_lbl8> t_image2d_lbl8; - typedef mln::image2d<t_rgb8> t_image2d_rgb8; - typedef mln::image2d<t_int_u8> t_image2d_int_u8; - typedef mln::image2d<t_rg8> t_image2d_rg8; - typedef mln::image2d<unsigned> t_histo2d; - typedef mln::fun::v2v::rgb_to_rg<8> t_rgb_to_rg; - typedef mln::fun::v2v::rg_to_rgb<8> t_rg_to_rgb; - - t_image2d_rgb8 img_rgb8; - t_image2d_rgb8 output; - t_image2d_rgb8 img_cast; - t_image2d_rg8 img_rg8; - t_histo2d histo; - t_image2d_lbl8 label; - t_lbl8 n_labels; - t_histo2d reverted; - - // IMAGE LOADING PHASE - mln::io::ppm::load(house_rgb8, image.c_str()); - img_rg8 = mln::data::transform(img_rgb8, t_rgb_to_rg()); - img_cast = mln::data::transform(img_rg8, t_rg_to_rgb()); - mln::io::ppm::save(img_cast, "red_green.ppm"); - - // HISTO COMPUTING AND FILTERING PHASE - histo = mln::data::compute(mln::accu::meta::stat::histo2d(), img_rg8); - mln::io::plot::save_image_sh(histo, "histo.sh"); - - //histo = mln::morpho::elementary::opening(histo, mln::c4()); - - mln::io::plot::save_image_sh(histo, "histo.sh"); - - // LABELING PHASE - reverted = mln::arith::revert(histo); - label = mln::morpho::watershed::flooding(reverted, mln::c4(), n_labels); - mln::io::pgm::save(label, "label.pgm"); +void usage(const int argc, const char *args[]) +{ + std::cout << "----------------------------------------" << std::endl; + std::cout << "argc : " << argc << std::endl; - // OUTPUT PHASE - output = merge(house_rg8, label); + for (int i = 0; i < argc; ++i) + std::cout << "args[" << i << "] : " << args[i] << std::endl; - mln::io::ppm::save(output, "merge.ppm"); + std::cout << "----------------------------------------" << std::endl; + std::cout << "usage: kmean2d [image [k_center [n_times [watch_dog]]]]" + << std::endl; + std::cout << "pbm image (points to work with)" << std::endl; + std::cout << "unsigned k_center (number of centers)" << std::endl; + std::cout << "unsigned n_times (number of launching)" << std::endl; + std::cout << "unsigned watch_dog (convergence loop)" << std::endl; + std::cout << "----------------------------------------" << std::endl; } - -// -// Regional maxima image processing chain. -// -void do_demo_regional1(const std::string& image, - const unsigned k_center, - const unsigned n_times, - const unsigned watch_dog) +bool char_to_unsigned(const bool status, const char *arg, unsigned& val) { - typedef mln::value::label_8 t_lbl8; - typedef mln::value::rg<8> t_rg8; - typedef mln::value::rgb8 t_rgb8; - typedef mln::value::int_u8 t_int_u8; - typedef mln::image2d<t_lbl8> t_image2d_lbl8; - typedef mln::image2d<t_rgb8> t_image2d_rgb8; - typedef mln::image2d<t_int_u8> t_image2d_int_u8; - typedef mln::image2d<t_rg8> t_image2d_rg8; - typedef mln::image2d<unsigned> t_histo2d; - typedef mln::fun::v2v::rgb_to_rg<8> t_rgb_to_rg; - typedef mln::fun::v2v::rg_to_rgb<8> t_rg_to_rgb; + bool result = false; - t_image2d_rgb8 img_rgb8; - t_image2d_rgb8 output; - t_image2d_rgb8 img_cast; - t_image2d_rg8 img_rg8; - t_histo2d histo; - t_histo2d opened; - t_image2d_lbl8 label; - t_image2d_lbl8 dilated; - t_lbl8 n_labels; + if (status) + { + std::istringstream arg_stream(arg); + arg_stream >> val; - // IMAGE LOADING PHASE - mln::io::ppm::load(img_rgb8, image.c_str()); - img_rg8 = mln::data::transform(img_rgb8, t_rgb_to_rg()); - img_cast = mln::data::transform(img_rg8, t_rg_to_rgb()); - mln::io::ppm::save(img_cast, "red_green.ppm"); + result = !arg_stream.fail(); + } + return result; +} - // HISTO COMPUTING PHASE - histo = mln::data::compute(mln::accu::meta::stat::histo2d(), img_rg8); - mln::io::plot::save_image_sh(histo, "histo.sh"); +bool char_to_string(const bool status, const char *arg, std::string& val) +{ + bool result = false; + if (status) + { + std::istringstream arg_stream(arg); - // HISTO FILTERING PHASE - opened = mln::morpho::elementary::opening(histo, mln::c8()); - mln::io::plot::save_image_sh(opened, "opened.sh"); + arg_stream >> val; + return !arg_stream.fail(); + } - // HISTO LABELING PHASE - label = mln::labeling::regional_maxima(opened, mln::c8(), n_labels); - mln::io::pgm::save(label, "label.pgm"); + return result; +} +int main(const int argc, const char *args[]) +{ + std::string image("top"); + unsigned k_center; + unsigned watch_dog; + unsigned n_times; + bool status = true; - // HISTO FUZZY PHASE - dilated = mln::morpho::elementary::dilation(label, mln::c8()); - mln::io::pgm::save(dilated, "dilated.pgm"); + switch (argc) + { + case 5: status = char_to_unsigned(status, args[4], watch_dog); + case 4: status = char_to_unsigned(status, args[3], n_times); + case 3: status = char_to_unsigned(status, args[2], k_center); + case 2: status = char_to_string(status, args[1], image); break; + case 1: status = true; break; + default: status = false; + } + if (status) + { + switch (argc) + { + case 1: demo(); break; + case 2: demo(image); break; + case 3: demo(image, k_center); break; + case 4: demo(image, k_center, n_times); break; + case 5: demo(image, k_center, n_times, watch_dog); break; + } + } + else + usage(argc, args); - // OUTPUT PHASE - output = merge(img_rg8, dilated); - mln::io::ppm::save(output, "merge.ppm"); + return 0; } // @@ -333,108 +340,3 @@ void do_demo_regional2(const std::string& image, -void demo(const std::string& image = SCRIBO_PPM_IMG_PATH"/mp00082c_50p.ppm", - //const std::string& image = OLENA_IMG_PATH"/house.ppm", - const unsigned k_center = 2, - //const unsigned k_center = 3, - const unsigned n_times = 10, - const unsigned watch_dog = 10) -{ - std::cout << "----------------------------------------" << std::endl; - std::cout << "Launching the demo with these parameters" << std::endl; - std::cout << "image : " << image << std::endl; - std::cout << "k_center : " << k_center << std::endl; - std::cout << "n_times : " << n_times << std::endl; - std::cout << "watch_dog : " << watch_dog << std::endl; - std::cout << "----------------------------------------" << std::endl; - -// do_demo_kmean(image, k_center, n_times, watch_dog); -// do_demo_watershed(image, k_center, n_times, watch_dog); - do_demo_regional1(image, k_center, n_times, watch_dog); - //do_demo_regional2(image, k_center, n_times, watch_dog); -} - -void usage(const int argc, const char *args[]) -{ - std::cout << "----------------------------------------" << std::endl; - std::cout << "argc : " << argc << std::endl; - - for (int i = 0; i < argc; ++i) - std::cout << "args[" << i << "] : " << args[i] << std::endl; - - std::cout << "----------------------------------------" << std::endl; - std::cout << "usage: kmean2d [image [k_center [n_times [watch_dog]]]]" - << std::endl; - std::cout << "pbm image (points to work with)" << std::endl; - std::cout << "unsigned k_center (number of centers)" << std::endl; - std::cout << "unsigned n_times (number of launching)" << std::endl; - std::cout << "unsigned watch_dog (convergence loop)" << std::endl; - std::cout << "----------------------------------------" << std::endl; -} - -bool char_to_unsigned(const bool status, const char *arg, unsigned& val) -{ - bool result = false; - - if (status) - { - std::istringstream arg_stream(arg); - - arg_stream >> val; - - result = !arg_stream.fail(); - } - - return result; -} - -bool char_to_string(const bool status, const char *arg, std::string& val) -{ - bool result = false; - - if (status) - { - std::istringstream arg_stream(arg); - - arg_stream >> val; - - return !arg_stream.fail(); - } - - return result; -} - -int main(const int argc, const char *args[]) -{ - std::string image("top"); - unsigned k_center; - unsigned watch_dog; - unsigned n_times; - bool status = true; - - switch (argc) - { - case 5: status = char_to_unsigned(status, args[4], watch_dog); - case 4: status = char_to_unsigned(status, args[3], n_times); - case 3: status = char_to_unsigned(status, args[2], k_center); - case 2: status = char_to_string(status, args[1], image); break; - case 1: status = true; break; - default: status = false; - } - - if (status) - { - switch (argc) - { - case 1: demo(); break; - case 2: demo(image); break; - case 3: demo(image, k_center); break; - case 4: demo(image, k_center, n_times); break; - case 5: demo(image, k_center, n_times, watch_dog); break; - } - } - else - usage(argc, args); - - return 0; -} diff --git a/milena/sandbox/green/demo/clustering/kmean2d/kmean2d.cc b/scribo/sandbox/green/test_labelling_3.cc similarity index 92% copy from milena/sandbox/green/demo/clustering/kmean2d/kmean2d.cc copy to scribo/sandbox/green/test_labelling_3.cc index 30e68b1..317832b 100644 --- a/milena/sandbox/green/demo/clustering/kmean2d/kmean2d.cc +++ b/scribo/sandbox/green/test_labelling_3.cc @@ -1,4 +1,27 @@ -// DEMO ON KMEAN2D +// Copyright (C) 2007,2008,2009,2010 EPITA 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. #include <mln/clustering/kmean2d.hh> -- 1.5.6.5
14Â years, 2Â months
1
0
0
0
last-svn-commit-21-gabdea30 Write the opening volume thresholds for the scribo image mp00082c.ppm.
by green
* green/demo/labeling/regional_maxima/thresholds.txt: New documentation. --- milena/sandbox/ChangeLog | 6 ++++ .../demo/labeling/regional_maxima/thresholds.txt | 27 ++++++++++++++++++++ 2 files changed, 33 insertions(+), 0 deletions(-) create mode 100644 milena/sandbox/green/demo/labeling/regional_maxima/thresholds.txt diff --git a/milena/sandbox/ChangeLog b/milena/sandbox/ChangeLog index 8a92218..9c7bef7 100644 --- a/milena/sandbox/ChangeLog +++ b/milena/sandbox/ChangeLog @@ -1,5 +1,11 @@ 2009-12-23 Yann Jacquelet <jacquelet(a)lrde.epita.fr> + Write the opening volume thresholds for the scribo image mp00082c.ppm. + + * green/demo/labeling/regional_maxima/thresholds.txt: New documentation. + +2009-12-23 Yann Jacquelet <jacquelet(a)lrde.epita.fr> + Experiment variation on regional maxima labeling. * green/demo/labeling/regional_maxima/regional_maxima.cc diff --git a/milena/sandbox/green/demo/labeling/regional_maxima/thresholds.txt b/milena/sandbox/green/demo/labeling/regional_maxima/thresholds.txt new file mode 100644 index 0000000..ddf5ca7 --- /dev/null +++ b/milena/sandbox/green/demo/labeling/regional_maxima/thresholds.txt @@ -0,0 +1,27 @@ +image = 1169 x 1567 = 1831823 + + +% image | min_volume +----------------------- + 0.05 % | 1000.00 + 1.00 % | 18318.23 + 5.00 % | 91591.15 + 10.00 % | 183182.30 + 15.00 % | 274773.45 + 20.00 % | 366364.60 + 25.00 % | 457955.75 + 30.00 % | 549546.90 + 35.00 % | 641138.05 + 40.00 % | 732729.20 + 45.00 % | 824320.35 + 50.00 % | 915911.50 + 55.00 % | 1007502.65 + 60.00 % | 1099093.80 + 65.00 % | 1190684.95 + 70.00 % | 1282276.10 + 75.00 % | 1373867.25 + 80.00 % | 1465458.40 + 85.00 % | 1557049.55 + 90.00 % | 1648640.70 + 95.00 % | 1740231.85 +100.00 % | 1831823.00 -- 1.5.6.5
14Â years, 2Â months
1
0
0
0
last-svn-commit-22-ge7dcb79 Split the regional maxima binary in small atomic binaries.
by green
* green/tools/annotating/histo: New directory. * green/tools/annotating/histo/Makefile.am: New Makefile. * green/tools/annotating/histo/histo.cc: New source file. * green/tools/annotating/opening: New directory. * green/tools/annotating/opening/Makefile.am: New Makefile. * green/tools/annotating/opening/opening.cc: New source file. * green/tools/annotating/regmax: New directory. * green/tools/annotating/regmax/Makefile.am: New Makefile. * green/tools/annotating/regmax/regmax.cc: New source file. --- milena/sandbox/ChangeLog | 14 ++ .../annotating/histo}/Makefile.am | 9 +- .../sandbox/green/tools/annotating/histo/histo.cc | 121 ++++++++++++++++++ .../annotating/opening}/Makefile.am | 9 +- .../green/tools/annotating/opening/opening.cc | 79 ++++++++++++ .../annotating/regmax}/Makefile.am | 9 +- .../green/tools/annotating/regmax/regmax.cc | 133 ++++++++++++++++++++ 7 files changed, 359 insertions(+), 15 deletions(-) copy milena/sandbox/green/{exp/annotating/nb_color => tools/annotating/histo}/Makefile.am (96%) create mode 100644 milena/sandbox/green/tools/annotating/histo/histo.cc copy milena/sandbox/green/{exp/annotating/nb_color => tools/annotating/opening}/Makefile.am (96%) create mode 100644 milena/sandbox/green/tools/annotating/opening/opening.cc copy milena/sandbox/green/{exp/annotating/nb_color => tools/annotating/regmax}/Makefile.am (96%) create mode 100644 milena/sandbox/green/tools/annotating/regmax/regmax.cc diff --git a/milena/sandbox/ChangeLog b/milena/sandbox/ChangeLog index 9c7bef7..6b0a1ac 100644 --- a/milena/sandbox/ChangeLog +++ b/milena/sandbox/ChangeLog @@ -1,3 +1,17 @@ +2010-01-05 Yann Jacquelet <jacquelet(a)lrde.epita.fr> + + Split the regional maxima binary in small atomic binaries. + + * green/tools/annotating/histo: New directory. + * green/tools/annotating/histo/Makefile.am: New Makefile. + * green/tools/annotating/histo/histo.cc: New source file. + * green/tools/annotating/opening: New directory. + * green/tools/annotating/opening/Makefile.am: New Makefile. + * green/tools/annotating/opening/opening.cc: New source file. + * green/tools/annotating/regmax: New directory. + * green/tools/annotating/regmax/Makefile.am: New Makefile. + * green/tools/annotating/regmax/regmax.cc: New source file. + 2009-12-23 Yann Jacquelet <jacquelet(a)lrde.epita.fr> Write the opening volume thresholds for the scribo image mp00082c.ppm. diff --git a/milena/sandbox/green/exp/annotating/nb_color/Makefile.am b/milena/sandbox/green/tools/annotating/histo/Makefile.am similarity index 96% copy from milena/sandbox/green/exp/annotating/nb_color/Makefile.am copy to milena/sandbox/green/tools/annotating/histo/Makefile.am index 8e204c6..8cd7511 100644 --- a/milena/sandbox/green/exp/annotating/nb_color/Makefile.am +++ b/milena/sandbox/green/tools/annotating/histo/Makefile.am @@ -6,7 +6,6 @@ # TOOLS # ######### -LOADLIBES= -lboost_filesystem INCLUDES= -I$(HOME)/svn/oln/trunk/milena/sandbox/green #CXXFLAGS= -ggdb -O0 -Wall -W -pedantic -ansi -pipe $(INCLUDES) #CXXFLAGS= -DNDEBUG -O1 -Wall -W -pedantic -ansi -pipe $(INCLUDES) @@ -16,17 +15,17 @@ RM= rm MKDIR= mkdir -p CP= cp -SOURCE_PATTERN= green/exp -BUILD__PATTERN= green/build/exp +SOURCE_PATTERN= green/tools +BUILD__PATTERN= green/build/tools 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)/ +BUILD__DIR= $(PWD) else # Case where make is done from source directory. -SOURCE_DIR= $(PWD)/ +SOURCE_DIR= $(PWD) BUILD__DIR= $(subst $(SOURCE_PATTERN),$(BUILD__PATTERN),$(PWD)) endif diff --git a/milena/sandbox/green/tools/annotating/histo/histo.cc b/milena/sandbox/green/tools/annotating/histo/histo.cc new file mode 100644 index 0000000..ab0b8af --- /dev/null +++ b/milena/sandbox/green/tools/annotating/histo/histo.cc @@ -0,0 +1,121 @@ +// TOOLS ==> Color histogram + +#include <iostream> + +#include <mln/accu/stat/histo3d_rgb.hh> + +#include <mln/core/macros.hh> +#include <mln/core/image/image2d.hh> +#include <mln/core/image/image3d.hh> +#include <mln/core/image/dmorph/image_if.hh> + +#include <mln/data/compute.hh> +#include <mln/data/transform.hh> + +#include <mln/display/display_histo.hh> + +#include <mln/fun/v2v/rgb8_to_rgbn.hh> + +#include <mln/io/dump/save.hh> +#include <mln/io/pbm/load.hh> +#include <mln/io/pbm/save.hh> +#include <mln/io/pgm/load.hh> +#include <mln/io/pgm/save.hh> +#include <mln/io/ppm/load.hh> +#include <mln/io/ppm/save.hh> + +#include <mln/opt/at.hh> + +#include <mln/pw/value.hh> + +#include <mln/value/rgb8.hh> +#include <mln/value/rgb.hh> + + +template <unsigned n> +void mk_histo(const std::string& input, + const std::string& output, + const std::string& histo, + const std::string& mask) +{ + typedef mln::value::int_u8 t_int_u8; + typedef mln::value::rgb8 t_rgb8; + typedef mln::value::rgb<n> t_rgbn; + typedef mln::image2d<t_int_u8> t_image2d_int_u8; + typedef mln::image2d<t_rgb8> t_image2d_rgb8; + typedef mln::image2d<t_rgbn> t_image2d_rgbn; + typedef mln::image2d<bool> t_image2d_bool; + typedef mln::image3d<unsigned> t_histo3d; + typedef mln::fun::v2v::rgb8_to_rgbn<n> t_rgb8_to_rgbn; + typedef mln::accu::meta::stat::histo3d_rgb t_histo3d_fun; + + // START OF IMAGE PROCESSING CHAIN + t_image2d_rgb8 i0_input; // input rgb8 + t_image2d_rgbn i1_input; // input rgbn + t_image2d_bool m0_input; // mask input + t_histo3d h1_input; // histo input + t_image2d_int_u8 p1_histo; // histo proj + + mln::io::ppm::load(i0_input, input.c_str()); + i1_input = mln::data::transform(i0_input, t_rgb8_to_rgbn()); + + if (0 < mask.size()) + { + mln::io::pbm::load(m0_input, mask.c_str()); + h1_input = mln::data::compute(t_histo3d_fun(), + (i1_input | mln::pw::value(m0_input)).rw()); + } + else + { + h1_input = mln::data::compute(t_histo3d_fun(), i1_input); + } + // END OF IMAGE PROCESSING CHAIN + + // BEGIN DUMPING + p1_histo = mln::display::display_histo3d_unsigned(h1_input); + mln::io::dump::save(h1_input, histo.c_str()); + mln::io::pgm::save(p1_histo, output.c_str()); + // END DUMPING +} + + +void usage() +{ + std::cout << std::endl; + std::cout << "histo input.ppm q out.ppm histo.dump [msk.pbm]" << std::endl; + std::cout << "where" << std::endl; + std::cout << "input.ppm is the 8 bits color ppm image" << std::endl; + std::cout << "q is the degree of quanification {2,3,4,5,6,7,8}" << std::endl; + std::cout << "out.pgm is the r/g projection of the histogram" << std::endl; + std::cout << "out.dump is the quantified color histogram" << std::endl; + std::cout << "msk.pbm is the mask which select the pixels" << std::endl; + std::cout << std::endl; +} + +int main(int argc, char* args[]) +{ + if (5 == argc || 6 == argc) + { + const std::string input(args[1]); + const char q = args[2][0]; + const std::string output(args[3]); + const std::string histo(args[4]); + const std::string mask(6 == argc? args[5] : ""); + + switch(q) + { + case '2': mk_histo<2>(input, output, histo, mask); break; + case '3': mk_histo<3>(input, output, histo, mask); break; + case '4': mk_histo<4>(input, output, histo, mask); break; + case '5': mk_histo<5>(input, output, histo, mask); break; + case '6': mk_histo<6>(input, output, histo, mask); break; + case '7': mk_histo<7>(input, output, histo, mask); break; + case '8': mk_histo<8>(input, output, histo, mask); break; + default: usage(); break; + } + } + else + usage(); + + return 0; +} diff --git a/milena/sandbox/green/exp/annotating/nb_color/Makefile.am b/milena/sandbox/green/tools/annotating/opening/Makefile.am similarity index 96% copy from milena/sandbox/green/exp/annotating/nb_color/Makefile.am copy to milena/sandbox/green/tools/annotating/opening/Makefile.am index 8e204c6..8cd7511 100644 --- a/milena/sandbox/green/exp/annotating/nb_color/Makefile.am +++ b/milena/sandbox/green/tools/annotating/opening/Makefile.am @@ -6,7 +6,6 @@ # TOOLS # ######### -LOADLIBES= -lboost_filesystem INCLUDES= -I$(HOME)/svn/oln/trunk/milena/sandbox/green #CXXFLAGS= -ggdb -O0 -Wall -W -pedantic -ansi -pipe $(INCLUDES) #CXXFLAGS= -DNDEBUG -O1 -Wall -W -pedantic -ansi -pipe $(INCLUDES) @@ -16,17 +15,17 @@ RM= rm MKDIR= mkdir -p CP= cp -SOURCE_PATTERN= green/exp -BUILD__PATTERN= green/build/exp +SOURCE_PATTERN= green/tools +BUILD__PATTERN= green/build/tools 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)/ +BUILD__DIR= $(PWD) else # Case where make is done from source directory. -SOURCE_DIR= $(PWD)/ +SOURCE_DIR= $(PWD) BUILD__DIR= $(subst $(SOURCE_PATTERN),$(BUILD__PATTERN),$(PWD)) endif diff --git a/milena/sandbox/green/tools/annotating/opening/opening.cc b/milena/sandbox/green/tools/annotating/opening/opening.cc new file mode 100644 index 0000000..3e1dbf2 --- /dev/null +++ b/milena/sandbox/green/tools/annotating/opening/opening.cc @@ -0,0 +1,79 @@ +// TOOLS ==> histogram filtering + +#include <iostream> + +#include <mln/accu/stat/histo3d_rgb.hh> + +#include <mln/core/macros.hh> +#include <mln/core/alias/neighb3d.hh> +#include <mln/core/image/image2d.hh> +#include <mln/core/image/image3d.hh> + +#include <mln/data/compute.hh> + +#include <mln/display/display_histo.hh> + +#include <mln/io/dump/load.hh> +#include <mln/io/dump/save.hh> +#include <mln/io/pgm/load.hh> +#include <mln/io/pgm/save.hh> + +#include <mln/morpho/opening/volume.hh> + +#include <mln/value/int_u8.hh> + +void mk_opening(const std::string& input, + const unsigned min_vol, + const std::string& output, + const std::string& opened) +{ + typedef mln::value::int_u8 t_int_u8; + typedef mln::image2d<t_int_u8> t_image2d_int_u8; + typedef mln::image3d<unsigned> t_histo3d; + typedef mln::accu::meta::stat::histo3d_rgb t_histo3d_fun; + + // START OF IMAGE PROCESSING CHAIN + t_histo3d h1_input; // histo input + t_histo3d h2_input; // histo input + t_image2d_int_u8 p1_histo; // histo proj + + mln::io::dump::load(h1_input, input.c_str()); + h2_input = mln::morpho::opening::volume(h1_input, mln::c6(), min_vol); + // END OF IMAGE PROCESSING CHAIN + + // BEGIN DUMPING + p1_histo = mln::display::display_histo3d_unsigned(h2_input); + mln::io::dump::save(h2_input, opened.c_str()); + mln::io::pgm::save(p1_histo, output.c_str()); + // END DUMPING +} + + +void usage() +{ + std::cout << std::endl; + std::cout << "opening input.dump v out.dump out.ppm" << std::endl; + std::cout << "where" << std::endl; + std::cout << "input.dump is the 3d color input histo" << std::endl; + std::cout << "v is the minimum size of each composant" << std::endl; + std::cout << "out.pgm is the r/g proj of the opened histogram" << std::endl; + std::cout << "out.dump is the opened histogram" << std::endl; + std::cout << std::endl; +} + +int main(int argc, char* args[]) +{ + if (5 == argc) + { + const std::string input(args[1]); + const unsigned min_vol = atoi(args[2]); + const std::string output(args[3]); + const std::string opened(args[4]); + + mk_opening(input, min_vol, output, opened); + } + else + usage(); + + return 0; +} diff --git a/milena/sandbox/green/exp/annotating/nb_color/Makefile.am b/milena/sandbox/green/tools/annotating/regmax/Makefile.am similarity index 96% copy from milena/sandbox/green/exp/annotating/nb_color/Makefile.am copy to milena/sandbox/green/tools/annotating/regmax/Makefile.am index 8e204c6..8cd7511 100644 --- a/milena/sandbox/green/exp/annotating/nb_color/Makefile.am +++ b/milena/sandbox/green/tools/annotating/regmax/Makefile.am @@ -6,7 +6,6 @@ # TOOLS # ######### -LOADLIBES= -lboost_filesystem INCLUDES= -I$(HOME)/svn/oln/trunk/milena/sandbox/green #CXXFLAGS= -ggdb -O0 -Wall -W -pedantic -ansi -pipe $(INCLUDES) #CXXFLAGS= -DNDEBUG -O1 -Wall -W -pedantic -ansi -pipe $(INCLUDES) @@ -16,17 +15,17 @@ RM= rm MKDIR= mkdir -p CP= cp -SOURCE_PATTERN= green/exp -BUILD__PATTERN= green/build/exp +SOURCE_PATTERN= green/tools +BUILD__PATTERN= green/build/tools 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)/ +BUILD__DIR= $(PWD) else # Case where make is done from source directory. -SOURCE_DIR= $(PWD)/ +SOURCE_DIR= $(PWD) BUILD__DIR= $(subst $(SOURCE_PATTERN),$(BUILD__PATTERN),$(PWD)) endif diff --git a/milena/sandbox/green/tools/annotating/regmax/regmax.cc b/milena/sandbox/green/tools/annotating/regmax/regmax.cc new file mode 100644 index 0000000..2079bc4 --- /dev/null +++ b/milena/sandbox/green/tools/annotating/regmax/regmax.cc @@ -0,0 +1,133 @@ +// TOOLS ==> regmax on histo + +#include <iostream> + +#include <mln/accu/stat/histo3d_rgb.hh> + +#include <mln/core/macros.hh> +#include <mln/core/alias/neighb3d.hh> +#include <mln/core/image/image2d.hh> +#include <mln/core/image/image3d.hh> + +#include <mln/data/compute.hh> + +#include <mln/debug/println.hh> +#include <mln/display/display_histo.hh> + +#include <mln/io/dump/load.hh> +#include <mln/io/dump/save.hh> +#include <mln/io/pgm/load.hh> +#include <mln/io/pgm/save.hh> +#include <mln/io/ppm/save.hh> + +#include <mln/labeling/regional_maxima.hh> + +#include <mln/morpho/opening/volume.hh> + +#include <mln/value/label_8.hh> +#include <mln/value/int_u8.hh> +#include <mln/value/rgb8.hh> + +template <unsigned n> +struct t_labeling_rgbn : mln::Function_v2v< t_labeling_rgbn<n> > +{ + typedef mln::value::rgb<n> t_rgbn; + typedef mln::value::label_8 t_lbl8; + typedef t_rgbn argument; + typedef t_lbl8 result; + typedef mln::image3d<t_lbl8> t_label; + + const t_label& _label; + + t_labeling_rgbn(const t_label& label) : _label(label) {} + + result operator()(const argument& c) const + { + t_lbl8 tmp = mln::opt::at(_label, c.blue(), c.red(), c.green()); + + return tmp; + } +}; + +void mk_regmax(const std::string& input, + const std::string& quant, + const std::string& histo, + const std::string& label, + const std::string& output) +{ + typedef mln::value::label_8 t_lbl8; + typedef mln::value::rgb8 t_rgb8; + typedef mln::value::rgbn t_rgbn; + typedef mln::value::int_u8 t_int_u8; + typedef mln::algebra::vec<3,float> t_v3f; + typedef mln::image2d<t_int_u8> t_image2d_int_u8; + typedef mln::image2d<t_rgb8> t_image2d_rgb8; + typedef mln::image3d<t_lbl8> t_image3d_lbl8; + typedef mln::image2d<t_lbl8> t_image2d_lbl8; + typedef mln::image3d<unsigned> t_histo3d; + typedef mln::accu::meta::stat::histo3d_rgb t_histo3d_fun; + typedef mln::accu::stat::mean<t_v3f,t_v3f,t_v3f> t_mean; + typedef mln::util::array<t_v3f> t_mean_array; + + t_image2d_rgb8 i0_input; // input img + t_image2d_rgbn i1_input; // quant img + t_histo3d h2_input; // opened histo +// t_image2d_int_u8 p2_label; // histo proj + t_image2d_lbl8 p2_label; // histo proj +// t_image2d_rgb8 p2_label; // histo proj + t_image3d_lbl8 l2_histo; // label histo + t_mean_array m2_label; // palette + + t_lbl8 n_lbl; // nb class + + // BEGIN LOADING + mln::io::ppm::load(i0_input, input.c_str()); + mln::io::ppm::load(i1_input, quant.c_str()); + mln::io::dump::load(h2_input, histo.c_str()); + // END LOADING + + // BEGIN IMAGE PROCESSING + l2_histo = mln::labeling::regional_maxima(h2_input, mln::c6(), n_lbl); + // END IMAGE PROCESSING + + // BEGIN SAVING + mln::debug::println(h2_input); + mln::io::dump::save(l2_histo, labeled.c_str()); + + l2_input = mln::data::transform(i1_input, t_labeling_rgbn<n>(l2_histo)); + m2_label = mln::labeling::compute(t_mean(), i0_input, l2_input, n_labels); + p2_label =mln::display::display3_histo3d_unsigned(h2_input,l2_histo,m2_label); + +// mln::io::pgm::save(p2_label, output.c_str()); + mln::io::ppm::save(p2_label, output.c_str()); + std::cout << "Nb classes : " << n_lbl << std::endl; + // END SAVING +} + + +void usage() +{ + std::cout << std::endl; + std::cout << "regmax input.dump out.dump out.ppm" << std::endl; + std::cout << "where" << std::endl; + std::cout << "input.dump is opened histo" << std::endl; + std::cout << "out.pgm is the r/g proj of the opened histogram" << std::endl; + std::cout << "out.dump is the labeled histogram" << std::endl; + std::cout << std::endl; +} + +int main(int argc, char* args[]) +{ + if (4 == argc) + { + const std::string input(args[1]); + const std::string output(args[2]); + const std::string labeled(args[3]); + + mk_regmax(input, output, labeled); + } + else + usage(); + + return 0; +} -- 1.5.6.5
14Â years, 2Â months
1
0
0
0
last-svn-commit-23-gccd6711 Build translation table between number of pixels and percentage of pixels in image for the scribo database.
by green
* green/demo/labeling/regional_maxima/threshold.txt: New translation table. --- milena/sandbox/ChangeLog | 8 ++++++++ .../demo/labeling/regional_maxima/thresholds.txt | 15 +++++++++++++++ 2 files changed, 23 insertions(+), 0 deletions(-) diff --git a/milena/sandbox/ChangeLog b/milena/sandbox/ChangeLog index 6b0a1ac..d6aa439 100644 --- a/milena/sandbox/ChangeLog +++ b/milena/sandbox/ChangeLog @@ -1,5 +1,13 @@ 2010-01-05 Yann Jacquelet <jacquelet(a)lrde.epita.fr> + Build translation table between number of pixels and percentage of + pixels in image for the scribo database. + + * green/demo/labeling/regional_maxima/threshold.txt: New translation + table. + +2010-01-05 Yann Jacquelet <jacquelet(a)lrde.epita.fr> + Split the regional maxima binary in small atomic binaries. * green/tools/annotating/histo: New directory. diff --git a/milena/sandbox/green/demo/labeling/regional_maxima/thresholds.txt b/milena/sandbox/green/demo/labeling/regional_maxima/thresholds.txt index ddf5ca7..58f3e6a 100644 --- a/milena/sandbox/green/demo/labeling/regional_maxima/thresholds.txt +++ b/milena/sandbox/green/demo/labeling/regional_maxima/thresholds.txt @@ -5,9 +5,24 @@ image = 1169 x 1567 = 1831823 ----------------------- 0.05 % | 1000.00 1.00 % | 18318.23 + 2.00 % | 36636.46 + 3.00 % | 54954.69 + 4.00 % | 73272.92 5.00 % | 91591.15 + 6.00 % | 109909.38 + 7.00 % | 128227.61 + 8.00 % | 146545.84 + 9.00 % | 164864.07 10.00 % | 183182.30 + 11.00 % | 201500.53 + 12.00 % | 219818.76 + 13.00 % | 238136.99 + 14.00 % | 256455.22 15.00 % | 274773.45 + 16.00 % | 293091.68 + 17.00 % | 311409.91 + 18.00 % | 329728.14 + 19.00 % | 348046.37 20.00 % | 366364.60 25.00 % | 457955.75 30.00 % | 549546.90 -- 1.5.6.5
14Â years, 2Â months
1
0
0
0
last-svn-commit-24-g17b0492 Extend the histogram visualization tools for new projection concept.
by green
* green/mln/display/project_histo.hh (project2_histo): New functions that keep the max of the histogram or the class associate to it while projecting along a direction. * green/mln/display/project_histo.hh (project3_histo): New functions that keep the color of the class associate to the histogram maximum while projecting along a direction. * green/mln/display/display_histo.hh: New interface functions for project2_histo and project3_histo. --- milena/sandbox/ChangeLog | 13 + milena/sandbox/green/mln/display/display_histo.hh | 50 +++ milena/sandbox/green/mln/display/project_histo.hh | 344 +++++++++++++++++++++ 3 files changed, 407 insertions(+), 0 deletions(-) diff --git a/milena/sandbox/ChangeLog b/milena/sandbox/ChangeLog index d6aa439..ed75bd1 100644 --- a/milena/sandbox/ChangeLog +++ b/milena/sandbox/ChangeLog @@ -1,5 +1,18 @@ 2010-01-05 Yann Jacquelet <jacquelet(a)lrde.epita.fr> + Extend the histogram visualization tools for new projection concept. + + * green/mln/display/project_histo.hh (project2_histo): New functions + that keep the max of the histogram or the class associate to it while + projecting along a direction. + * green/mln/display/project_histo.hh (project3_histo): New functions + that keep the color of the class associate to the histogram maximum + while projecting along a direction. + * green/mln/display/display_histo.hh: New interface functions for + project2_histo and project3_histo. + +2010-01-05 Yann Jacquelet <jacquelet(a)lrde.epita.fr> + Build translation table between number of pixels and percentage of pixels in image for the scribo database. diff --git a/milena/sandbox/green/mln/display/display_histo.hh b/milena/sandbox/green/mln/display/display_histo.hh index 1fd5da4..2ba0b61 100644 --- a/milena/sandbox/green/mln/display/display_histo.hh +++ b/milena/sandbox/green/mln/display/display_histo.hh @@ -33,6 +33,8 @@ # include <mln/display/project_histo.hh> # include <mln/fun/v2v/log.hh> # include <mln/value/int_u8.hh> +# include <mln/value/rgb8.hh> +# include <mln/value/label_8.hh> /// \file @@ -55,6 +57,20 @@ namespace mln image2d<value::int_u8> display_histo3d_unsigned(const image3d<unsigned>& histo); + image2d<value::int_u8> + display2_histo3d_unsigned(const image3d<unsigned>& histo); + + image2d<value::label_8> + display2_histo3d_unsigned(const image3d<unsigned>& histo, + const image3d<value::label_8>& label); + + image2d<value::rgb8> + display3_histo3d_unsigned(const image3d<unsigned>& histo); + + image2d<value::rgb8> + display3_histo3d_unsigned(const image3d<unsigned>& histo, + const image3d<value::label_8>& label); + #ifndef MLN_INCLUDE_ONLY /// \brief Allow the visualization of a 3d histogram by projection. @@ -86,6 +102,40 @@ namespace mln return proj_int; } + image2d<value::int_u8> + display2_histo3d_unsigned(const image3d<unsigned>& histo) + { + image2d<value::int_u8> proj = project2_histo<0>(histo); + + return proj; + } + + image2d<value::label_8> + display2_histo3d_unsigned(const image3d<unsigned>& histo, + const image3d<value::label_8>& label) + { + image2d<value::label_8> proj = project2_histo<0>(histo, label); + + return proj; + } + + image2d<value::rgb8> + display3_histo3d_unsigned(const image3d<unsigned>& histo) + { + image2d<value::rgb8> proj = project3_histo<0>(histo); + + return proj; + } + + image2d<value::rgb8> + display3_histo3d_unsigned(const image3d<unsigned>& histo, + const image3d<value::label_8>& label) + { + image2d<value::rgb8> proj = project3_histo<0>(histo, label); + + return proj; + } + #endif // ! MLN_INCLUDE_ONLY diff --git a/milena/sandbox/green/mln/display/project_histo.hh b/milena/sandbox/green/mln/display/project_histo.hh index f0e6858..d842c70 100644 --- a/milena/sandbox/green/mln/display/project_histo.hh +++ b/milena/sandbox/green/mln/display/project_histo.hh @@ -37,6 +37,12 @@ # include <mln/accu/image/take.hh> # include <mln/accu/image/to_result.hh> +# include <mln/opt/at.hh> + +# include <mln/value/int_u8.hh> +# include <mln/value/rgb8.hh> +# include <mln/value/label_8.hh> + /// \file /// /// \brief Allow the visualization of 3d histogram. @@ -54,6 +60,10 @@ namespace mln image2d<mln_result(A)> project_histo(const image3d<V>& histo); + template <typename A, unsigned direction, typename V> + image2d<mln_result(A)> + project2_histo(const image3d<V>& histo); + # ifndef MLN_INCLUDE_ONLY /// \brief Allow the visualization of 3d histogram. @@ -86,6 +96,340 @@ namespace mln return accu::image::to_result(histo_accu); } + template <unsigned direction> + image2d<value::int_u8> + project2_histo(const image3d<unsigned>& histo) + { + image2d<value::int_u8> result; + + if (0 == direction) // blue + { + image2d<value::int_u8> arg_max(histo.ncols(), histo.nslices()); + + for (unsigned j = 0; j < histo.ncols(); ++j) + for (unsigned i = 0; i < histo.nslices(); ++i) + { + unsigned max = 0; // minimum as possible + signed pos = -1; + + for (unsigned k = 0; k < histo.nrows(); ++k) + { + if (max <= opt::at(histo,i,j,k)) + { + max = opt::at(histo,i,j,k); + pos = k; + } + } + + opt::at(arg_max,i,j) = pos; + } + + result = arg_max; + } + else if (1 == direction) // red + { + image2d<value::int_u8> arg_max(histo.nrows(), histo.nslices()); + + for (unsigned j = 0; j < histo.nslices(); ++j) + for (unsigned i = 0; i < histo.nrows(); ++i) + { + unsigned max = 0; // minimum as possible + signed pos = -1; + + for (unsigned k = 0; k < histo.ncols(); ++k) + { + if (max <= opt::at(histo,i,j,k)) + { + max = opt::at(histo,i,j,k); + pos = k; + } + } + + opt::at(arg_max,i,j) = pos; + } + + result = arg_max; + } + else // 2 == direction // green + { + image2d<value::int_u8> arg_max(histo.nrows(), histo.ncols()); + + for (unsigned j = 0; j < histo.ncols(); ++j) + for (unsigned i = 0; i < histo.nrows(); ++i) + { + unsigned max = 0; // minimum as possible + signed pos = -1; + + for (unsigned k = 0; k < histo.nslices(); ++k) + { + if (max <= opt::at(histo,i,j,k)) + { + max = opt::at(histo,i,j,k); + pos = k; + } + } + + opt::at(arg_max,i,j) = pos; + } + + result = arg_max; + } + + return result; + } + + template <unsigned direction> + image2d<value::label_8> + project2_histo(const image3d<unsigned>& histo, + const image3d<value::label_8>& label) + { + image2d<value::label_8> result; + + if (0 == direction) // blue + { + image2d<value::label_8> arg_max(histo.ncols(), histo.nslices()); + + for (unsigned j = 0; j < histo.ncols(); ++j) + for (unsigned i = 0; i < histo.nslices(); ++i) + { + unsigned max = 0; // minimum as possible + signed pos = -1; + + for (unsigned k = 0; k < histo.nrows(); ++k) + { + if (max <= opt::at(histo,i,j,k)) + { + max = opt::at(histo,i,j,k); + pos = k; + } + } + + opt::at(arg_max,i,j) = opt::at(label,i,j,pos); + } + + result = arg_max; + } + else if (1 == direction) // red + { + image2d<value::label_8> arg_max(histo.nrows(), histo.nslices()); + + for (unsigned j = 0; j < histo.nslices(); ++j) + for (unsigned i = 0; i < histo.nrows(); ++i) + { + unsigned max = 0; // minimum as possible + signed pos = -1; + + for (unsigned k = 0; k < histo.ncols(); ++k) + { + if (max <= opt::at(histo,i,j,k)) + { + max = opt::at(histo,i,j,k); + pos = k; + } + } + + opt::at(arg_max,i,j) = opt::at(label,pos,i,j); + } + + result = arg_max; + } + else // 2 == direction // green + { + image2d<value::label_8> arg_max(histo.nrows(), histo.ncols()); + + for (unsigned j = 0; j < histo.ncols(); ++j) + for (unsigned i = 0; i < histo.nrows(); ++i) + { + unsigned max = 0; // minimum as possible + signed pos = -1; + + for (unsigned k = 0; k < histo.nslices(); ++k) + { + if (max <= opt::at(histo,i,j,k)) + { + max = opt::at(histo,i,j,k); + pos = k; + } + } + + opt::at(arg_max,i,j) = opt::at(label,i,pos,j); + } + + result = arg_max; + } + + return result; + } + + + // FIXME ... determine the color of each class. + template <unsigned direction> + image2d<value::rgb8> + project3_histo(const image3d<unsigned>& histo, + const image3d<value::label_8>& label) + { + image2d<value::rgb8> result; + + if (0 == direction) // blue + { + image2d<value::rgb8> arg_max(histo.ncols(), histo.nslices()); + + for (unsigned j = 0; j < histo.ncols(); ++j) + for (unsigned i = 0; i < histo.nslices(); ++i) + { + unsigned max = 0; // minimum as possible + signed pos = -1; + + for (unsigned k = 0; k < histo.nrows(); ++k) + { + if (max <= opt::at(histo,i,j,k)) + { + max = opt::at(histo,i,j,k); + pos = k; + } + } + + opt::at(arg_max,i,j) = value::rgb8(i,j,pos); + } + + result = arg_max; + } + else if (1 == direction) // red + { + image2d<value::rgb8> arg_max(histo.nrows(), histo.nslices()); + + for (unsigned j = 0; j < histo.nslices(); ++j) + for (unsigned i = 0; i < histo.nrows(); ++i) + { + unsigned max = 0; // minimum as possible + signed pos = -1; + + for (unsigned k = 0; k < histo.ncols(); ++k) + { + if (max <= opt::at(histo,i,j,k)) + { + max = opt::at(histo,i,j,k); + pos = k; + } + } + + opt::at(arg_max,i,j) = value::rgb8(pos,i,j); + } + + result = arg_max; + } + else // 2 == direction // green + { + image2d<value::rgb8> arg_max(histo.nrows(), histo.ncols()); + + for (unsigned j = 0; j < histo.ncols(); ++j) + for (unsigned i = 0; i < histo.nrows(); ++i) + { + unsigned max = 0; // minimum as possible + signed pos = -1; + + for (unsigned k = 0; k < histo.nslices(); ++k) + { + if (max <= opt::at(histo,i,j,k)) + { + max = opt::at(histo,i,j,k); + pos = k; + } + } + + // FIXME ... how to fix the n of rgb + opt::at(arg_max,i,j) = value::rgb8(i,pos,j); + } + + result = arg_max; + } + + return result; + } + + template <unsigned direction> + image2d<value::rgb8> + project3_histo(const image3d<unsigned>& histo) + { + image2d<value::rgb8> result; + + if (0 == direction) // blue + { + image2d<value::rgb8> arg_max(histo.ncols(), histo.nslices()); + + for (unsigned j = 0; j < histo.ncols(); ++j) + for (unsigned i = 0; i < histo.nslices(); ++i) + { + unsigned max = 0; // minimum as possible + signed pos = -1; + + for (unsigned k = 0; k < histo.nrows(); ++k) + { + if (max <= opt::at(histo,i,j,k)) + { + max = opt::at(histo,i,j,k); + pos = k; + } + } + + opt::at(arg_max,i,j) = value::rgb8(i,j,pos); + } + + result = arg_max; + } + else if (1 == direction) // red + { + image2d<value::rgb8> arg_max(histo.nrows(), histo.nslices()); + + for (unsigned j = 0; j < histo.nslices(); ++j) + for (unsigned i = 0; i < histo.nrows(); ++i) + { + unsigned max = 0; // minimum as possible + signed pos = -1; + + for (unsigned k = 0; k < histo.ncols(); ++k) + { + if (max <= opt::at(histo,i,j,k)) + { + max = opt::at(histo,i,j,k); + pos = k; + } + } + + opt::at(arg_max,i,j) = value::rgb8(pos,i,j); + } + + result = arg_max; + } + else // 2 == direction // green + { + image2d<value::rgb8> arg_max(histo.nrows(), histo.ncols()); + + for (unsigned j = 0; j < histo.ncols(); ++j) + for (unsigned i = 0; i < histo.nrows(); ++i) + { + unsigned max = 0; // minimum as possible + signed pos = -1; + + for (unsigned k = 0; k < histo.nslices(); ++k) + { + if (max <= opt::at(histo,i,j,k)) + { + max = opt::at(histo,i,j,k); + pos = k; + } + } + + // FIXME ... how to fix the n of rgb + opt::at(arg_max,i,j) = value::rgb8(i,pos,j); + } + + result = arg_max; + } + + return result; + } + # endif // ! MLN_INCLUDE_ONLY -- 1.5.6.5
14Â years, 2Â months
1
0
0
0
last-svn-commit-25-ga3fa356 Fix last details in the image processing chain.
by green
* green/tools/annotating/histo/histo.cc: Manage new inputs/outputs. * green/tools/annotating/opening/opening.cc: Manage new inputs/outputs. * green/tools/annotating/iz/Makefile.am: New Makefile. * green/tools/annotating/iz/iz.cc: New file. * green/tools/annotating/regmax/regmax.cc: Manage new inputs/outputs. --- milena/sandbox/ChangeLog | 10 + .../sandbox/green/tools/annotating/histo/histo.cc | 84 +++-- .../tools/annotating/{histo => iz}/Makefile.am | 0 milena/sandbox/green/tools/annotating/iz/iz.cc | 373 ++++++++++++++++++++ .../green/tools/annotating/opening/opening.cc | 76 +++-- .../green/tools/annotating/regmax/regmax.cc | 253 ++++++++++++-- 6 files changed, 714 insertions(+), 82 deletions(-) copy milena/sandbox/green/tools/annotating/{histo => iz}/Makefile.am (100%) create mode 100644 milena/sandbox/green/tools/annotating/iz/iz.cc diff --git a/milena/sandbox/ChangeLog b/milena/sandbox/ChangeLog index ed75bd1..0968186 100644 --- a/milena/sandbox/ChangeLog +++ b/milena/sandbox/ChangeLog @@ -1,3 +1,13 @@ +2010-02-10 Yann Jacquelet <jacquelet(a)lrde.epita.fr> + + Fix last details in the image processing chain. + + * green/tools/annotating/histo/histo.cc: Manage new inputs/outputs. + * green/tools/annotating/opening/opening.cc: Manage new inputs/outputs. + * green/tools/annotating/iz/Makefile.am: New Makefile. + * green/tools/annotating/iz/iz.cc: New file. + * green/tools/annotating/regmax/regmax.cc: Manage new inputs/outputs. + 2010-01-05 Yann Jacquelet <jacquelet(a)lrde.epita.fr> Extend the histogram visualization tools for new projection concept. diff --git a/milena/sandbox/green/tools/annotating/histo/histo.cc b/milena/sandbox/green/tools/annotating/histo/histo.cc index ab0b8af..8037e1a 100644 --- a/milena/sandbox/green/tools/annotating/histo/histo.cc +++ b/milena/sandbox/green/tools/annotating/histo/histo.cc @@ -16,14 +16,14 @@ #include <mln/fun/v2v/rgb8_to_rgbn.hh> -#include <mln/io/dump/save.hh> #include <mln/io/pbm/load.hh> -#include <mln/io/pbm/save.hh> -#include <mln/io/pgm/load.hh> -#include <mln/io/pgm/save.hh> #include <mln/io/ppm/load.hh> +#include <mln/io/dump/save.hh> +#include <mln/io/pgm/save.hh> #include <mln/io/ppm/save.hh> +#include <mln/literal/colors.hh> + #include <mln/opt/at.hh> #include <mln/pw/value.hh> @@ -33,15 +33,19 @@ template <unsigned n> -void mk_histo(const std::string& input, - const std::string& output, - const std::string& histo, - const std::string& mask) +void mk_histo(const std::string& input, // in + const std::string& quant, // in + const std::string& histo, // out + const std::string& proj1, // out + const std::string& proj2, // out + const std::string& mask) // [in] { typedef mln::value::int_u8 t_int_u8; + typedef mln::value::int_u<n> t_int_un; typedef mln::value::rgb8 t_rgb8; typedef mln::value::rgb<n> t_rgbn; typedef mln::image2d<t_int_u8> t_image2d_int_u8; + typedef mln::image2d<t_int_un> t_image2d_int_un; typedef mln::image2d<t_rgb8> t_image2d_rgb8; typedef mln::image2d<t_rgbn> t_image2d_rgbn; typedef mln::image2d<bool> t_image2d_bool; @@ -54,7 +58,9 @@ void mk_histo(const std::string& input, t_image2d_rgbn i1_input; // input rgbn t_image2d_bool m0_input; // mask input t_histo3d h1_input; // histo input - t_image2d_int_u8 p1_histo; // histo proj + t_image2d_int_u8 p1_histo1;// histo proj1 + t_image2d_rgbn p1_histo2;// histo proj2 + t_rgbn red(mln::literal::red); mln::io::ppm::load(i0_input, input.c_str()); i1_input = mln::data::transform(i0_input, t_rgb8_to_rgbn()); @@ -72,9 +78,13 @@ void mk_histo(const std::string& input, // END OF IMAGE PROCESSING CHAIN // BEGIN DUMPING - p1_histo = mln::display::display_histo3d_unsigned(h1_input); + p1_histo1 = mln::display::display_histo3d_unsigned(h1_input); + p1_histo2 = mln::display::display3_histo3d_unsigned(h1_input, red); + + mln::io::ppm::save(i1_input, quant.c_str()); mln::io::dump::save(h1_input, histo.c_str()); - mln::io::pgm::save(p1_histo, output.c_str()); + mln::io::pgm::save(p1_histo1, proj1.c_str()); + mln::io::ppm::save(p1_histo2, proj2.c_str()); // END DUMPING } @@ -82,35 +92,47 @@ void mk_histo(const std::string& input, void usage() { std::cout << std::endl; - std::cout << "histo input.ppm q out.ppm histo.dump [msk.pbm]" << std::endl; - std::cout << "where" << std::endl; - std::cout << "input.ppm is the 8 bits color ppm image" << std::endl; - std::cout << "q is the degree of quanification {2,3,4,5,6,7,8}" << std::endl; - std::cout << "out.pgm is the r/g projection of the histogram" << std::endl; - std::cout << "out.dump is the quantified color histogram" << std::endl; - std::cout << "msk.pbm is the mask which select the pixels" << std::endl; + std::cout << "histo input.ppm q quant.ppm histo.dump proj.pgm" + << " proj.ppm [msk.pbm]" << std::endl; + std::cout << std::endl; + std::cout << "where :" << std::endl; + std::cout << "* [ in] input.ppm is the 8 bits color ppm image" << std::endl; + std::cout << "* [ in] q is the degree of quantification" + << " {2,3,4,5,6,7,8}" << std::endl; + std::cout << "* [out] quant.ppm is the q bits quantified input" + << " image" << std::endl; + std::cout << "* [out] histo.dump is the quantified color" + << " histogram" << std::endl; + std::cout << "* [out] proj.pgm is the r/g projection of the" + << " histogram (summing along the blue axe)" << std::endl; + std::cout << "* [out] proj.ppm is the r/g projection of the" + << " histogram with maxima plot on" << std::endl; + std::cout << "* [ in] msk.pbm is the mask which selects the" + << " pixels" << std::endl; std::cout << std::endl; } int main(int argc, char* args[]) { - if (5 == argc || 6 == argc) + if (7 == argc || 8 == argc) { - const std::string input(args[1]); - const char q = args[2][0]; - const std::string output(args[3]); - const std::string histo(args[4]); - const std::string mask(6 == argc? args[5] : ""); + const std::string input(args[1]); // in + const char q = args[2][0]; // in + const std::string quant(args[3]); // out + const std::string histo(args[4]); // out + const std::string proj1(args[5]); // out + const std::string proj2(args[6]); // out + const std::string mask(8 == argc? args[7] : ""); // [in] switch(q) { - case '2': mk_histo<2>(input, output, histo, mask); break; - case '3': mk_histo<3>(input, output, histo, mask); break; - case '4': mk_histo<4>(input, output, histo, mask); break; - case '5': mk_histo<5>(input, output, histo, mask); break; - case '6': mk_histo<6>(input, output, histo, mask); break; - case '7': mk_histo<7>(input, output, histo, mask); break; - case '8': mk_histo<8>(input, output, histo, mask); break; + case '2': mk_histo<2>(input, quant, histo, proj1, proj2, mask); break; + case '3': mk_histo<3>(input, quant, histo, proj1, proj2, mask); break; + case '4': mk_histo<4>(input, quant, histo, proj1, proj2, mask); break; + case '5': mk_histo<5>(input, quant, histo, proj1, proj2, mask); break; + case '6': mk_histo<6>(input, quant, histo, proj1, proj2, mask); break; + case '7': mk_histo<7>(input, quant, histo, proj1, proj2, mask); break; + case '8': mk_histo<8>(input, quant, histo, proj1, proj2, mask); break; default: usage(); break; } } diff --git a/milena/sandbox/green/tools/annotating/histo/Makefile.am b/milena/sandbox/green/tools/annotating/iz/Makefile.am similarity index 100% copy from milena/sandbox/green/tools/annotating/histo/Makefile.am copy to milena/sandbox/green/tools/annotating/iz/Makefile.am diff --git a/milena/sandbox/green/tools/annotating/iz/iz.cc b/milena/sandbox/green/tools/annotating/iz/iz.cc new file mode 100644 index 0000000..07e5dd9 --- /dev/null +++ b/milena/sandbox/green/tools/annotating/iz/iz.cc @@ -0,0 +1,373 @@ +// TOOLS ==> influence zone transformation + +#include <iostream> +#include <fstream> +#include <boost/format.hpp> + +#include <mln/accu/stat/histo3d_rgb.hh> + +#include <mln/core/macros.hh> +#include <mln/core/alias/neighb3d.hh> +#include <mln/core/image/image2d.hh> +#include <mln/core/image/image3d.hh> + +#include <mln/data/compute.hh> + +#include <mln/display/display_histo.hh> + +#include <mln/io/dump/load.hh> +#include <mln/io/dump/save.hh> +#include <mln/io/ppm/load.hh> +#include <mln/io/ppm/save.hh> +#include <mln/io/pgm/load.hh> +#include <mln/io/pgm/save.hh> + +#include <mln/literal/colors.hh> + +#include <mln/labeling/compute.hh> +#include <mln/labeling/mean_values.hh> + +#include <mln/transform/influence_zone_geodesic.hh> + +#include <mln/value/int_u8.hh> + +template <unsigned n> +struct t_labeling_rgbn : mln::Function_v2v< t_labeling_rgbn<n> > +{ + typedef mln::value::rgb<n> t_rgbn; + typedef mln::value::label_8 t_lbl8; + typedef t_rgbn argument; + typedef t_lbl8 result; + typedef mln::image3d<t_lbl8> t_label; + + const t_label& _label; + + t_labeling_rgbn(const t_label& label) : _label(label) {} + + result operator()(const argument& c) const + { + t_lbl8 tmp = mln::opt::at(_label, c.blue(), c.red(), c.green()); + + return tmp; + } +}; + +void compute_stats(const mln::image2d<mln::value::rgb8>& i_input_rgb8, + const mln::image2d<mln::value::label_8>& l_input_lbl8, + const mln::image3d<unsigned>& h_histo_rgbn, + const mln::image3d<mln::value::label_8>& l_histo_lbl8, + const mln::value::label_8& n_labels, + const std::string& log) +{ + typedef mln::algebra::vec<3,float> t_vec3f; + typedef mln::accu::math::sum<unsigned,unsigned> t_sum; + typedef mln::accu::stat::mean<t_vec3f,t_vec3f,t_vec3f> t_mean; + typedef mln::util::array<unsigned> t_count_array; + typedef mln::util::array<t_vec3f> t_mean_array; + + mln::util::array<float> abs((unsigned)(n_labels)+1); + mln::util::array<float> rel((unsigned)(n_labels)+1); + unsigned nb = 0; + + for (unsigned i = 0; i <= n_labels; ++i) + { + abs[i] = 0.0; + rel[i] = 0.0; + } + + // COMPUTE THE SUM + t_count_array count = mln::labeling::compute(t_sum(), + h_histo_rgbn, + l_histo_lbl8, + n_labels); + + // COMPUTE THE TOTAL + for (unsigned i = 0; i <= n_labels; ++i) + { + unsigned c = count[i]; + nb += c; + } + + // COMPUTE THE PERCENTAGES + for (unsigned i = 0; i <= n_labels; ++i) + if (0 < count[i]) + { + abs[i] = ((float)count[i] / nb)*100.0; + rel[i] = ((float)count[i] / (nb - count[0]))*100.0; + } + + // COMPUTE THE MEAN + + t_mean_array mean = mln::labeling::compute(t_mean(), + i_input_rgb8, + l_input_lbl8, + n_labels); + + // CORRECT 0 LABEL STATS + rel[0] = 0; + mean[0][0] = 255.0; + mean[0][1] = 255.0; + mean[0][2] = 0.0; + + // PRINT STATS + std::ofstream log_stream(log.c_str()); + + for (unsigned i = 0; i <= n_labels; ++i) + { + const t_vec3f& mean_v = mean[i]; + + log_stream << boost::format("%2i|" + "r = %6.2f, g = %6.2f, b = %6.2f |" + "c = %7i, %%i = %5.2f, %%c = %5.2f") + % i + % mean_v[0] + % mean_v[1] + % mean_v[2] + % count[i] + % abs[i] + % rel[i] + << std::endl; + } + + log_stream << std::endl << std::endl; + log_stream.flush(); + log_stream.close(); +} + +bool expect(std::istream& stream, const std::string expected) +{ + bool result; + std::string got; + + stream >> got; + + result = (got == expected); + + return result; +} + +std::istream& operator>>(std::istream& stream, + mln::algebra::vec<3,float>& color) +{ + unsigned lbl; + + stream >> lbl; + if (expect(stream, std::string("|")) && + expect(stream, std::string("r")) && + expect(stream, std::string("="))) + { + stream >> color[0]; + + if (expect(stream, std::string(",")) && + expect(stream, std::string("g")) && + expect(stream, std::string("="))) + { + stream >> color[1]; + + if (expect(stream, std::string(",")) && + expect(stream, std::string("b")) && + expect(stream, std::string("="))) + { + stream >> color[2]; + } + } + } + + return stream; +} + +void load(mln::util::array< mln::algebra::vec<3,float> >& m2_label, + const char *colormap) +{ + typedef mln::algebra::vec<3,float> t_vec3f; + typedef mln::util::array<t_vec3f> t_mean_array; + + std::ifstream stream(colormap); + std::string buffer; + + getline(stream, buffer); + + while (0 < buffer.size()) + { + std::stringstream line(buffer); + t_vec3f mean_v; + + line >> mean_v; + + m2_label.append(mean_v); + + getline(stream, buffer); + } + + stream.close(); +} + +template<unsigned n> +void mk_iz(const std::string& labeled, // in + const unsigned d, // in + const mln::neighb3d& nbh, // in + const std::string& input, // in + const std::string& quant, // in + const std::string& histo, // in + const std::string& colormap,// in + const std::string& iz, // out + const std::string& proj, // out + const std::string& mean, // out + const std::string& stats) // [out] +{ + typedef mln::value::int_u8 t_int_u8; + typedef mln::value::label_8 t_lbl8; + typedef mln::value::rgb8 t_rgb8; + typedef mln::value::rgb<n> t_rgbn; + typedef mln::algebra::vec<3,float> t_v3f; + typedef mln::image2d<t_int_u8> t_image2d_int_u8; + typedef mln::image2d<t_rgb8> t_image2d_rgb8; + typedef mln::image2d<t_rgbn> t_image2d_rgbn; + typedef mln::image2d<t_lbl8> t_image2d_lbl8; + typedef mln::image3d<unsigned> t_histo3d; + typedef mln::image3d<t_lbl8> t_image3d_lbl8; + typedef mln::accu::meta::stat::histo3d_rgb t_histo3d_fun; + typedef mln::accu::stat::mean<t_v3f,t_v3f,t_v3f> t_mean; + typedef mln::util::array<t_v3f> t_mean_array; + + // START OF IMAGE PROCESSING CHAIN + t_image2d_rgb8 i0_input; // input img + t_image2d_rgbn i1_input; // quant img + t_histo3d h1_input; // histo input + t_histo3d h2_input; // histo input + t_image2d_int_u8 p1_histo; // histo proj + t_image2d_rgb8 p3_histo; // histo proj + t_image3d_lbl8 l2_histo; // label histo + t_image3d_lbl8 l3_histo; // iz label hist + t_mean_array m2_label; // colormap + t_mean_array m3_label; // colormap + t_image2d_lbl8 l3_input; // label input + t_image2d_rgb8 i3_mean; // reconstructed + + t_lbl8 n_lbl; // nb labels + t_rgb8 red(mln::literal::red); + + mln::io::dump::load(l2_histo, labeled.c_str()); + mln::io::ppm::load(i0_input, input.c_str()); + mln::io::ppm::load(i1_input, quant.c_str()); + mln::io::dump::load(h1_input, histo.c_str()); + load(m2_label, colormap.c_str()); + + if (0 == d) + { + l3_histo = mln::transform::influence_zone_geodesic(l2_histo, nbh); + } + else + { + l3_histo = mln::transform::influence_zone_geodesic(l2_histo, nbh, d); + } + // END OF IMAGE PROCESSING CHAIN + + // BEGIN DUMPING + + n_lbl = (t_lbl8)(m2_label.size()-1); + + l3_input = mln::data::transform(i1_input, t_labeling_rgbn<n>(l3_histo)); + i3_mean = mln::labeling::mean_values(i0_input, l3_input, n_lbl); + m3_label = mln::labeling::compute(t_mean(), i0_input, l3_input, n_lbl); + + // CORRECT 0 LABEL STATS + m3_label[0][0] = 255.0; + m3_label[0][1] = 255.0; + m3_label[0][2] = 0.0; + + p3_histo = mln::display::display3_histo3d_unsigned<n>(h1_input, + l3_histo, + m3_label, + red); + mln::io::dump::save(l3_input, iz.c_str()); + mln::io::ppm::save(p3_histo, proj.c_str()); + mln::io::ppm::save(i3_mean, mean.c_str()); + + if (0 < stats.size()) + compute_stats(i0_input, l3_input, h1_input, l3_histo, n_lbl, stats); + + // END DUMPING +} + + +void usage() +{ + std::cout << std::endl; + std::cout << "iz labeled.dump d nbh input.ppm q quant.ppm" + << " histo.dump colormap.txt iz.dump proj.ppm" + << " mean.ppm [stats.txt]" << std::endl; + std::cout << std::endl; + std::cout << "where :" << std::endl; + std::cout << "* [ in] labeled.dump is the labeled 3d histogram" << std::endl; + std::cout << "* [ in] d is the depth for the zone influence" + << " transformation (0 means infinite)" << std::endl; + std::cout << "* [ in] nbh is the 3d neighbourhood {6,18,26}" << std::endl; + std::cout << "* [ in] input.ppm is the 8 bits color ppm image" << std::endl; + std::cout << "* [ in] q is the degree of quantification" + << " {2,3,4,5,6,7,8}" << std::endl; + std::cout << "* [ in] quant.ppm is the q bits quantified input" + << " image" << std::endl; + std::cout << "* [ in] histo.dump is the quantified color" + << " histogram" << std::endl; + std::cout << "* [ in] colormap.txt is the colormap for labels" << std::endl; + std::cout << "* [out] iz.dump is the iz labeled 3d histogram" << std::endl; + std::cout << "* [out] proj.ppm is the r/g projection of the" + << " histogram with maxima label plot on" << std::endl; + std::cout << "* [out] mean.ppm is the mean reconstructed image" << std::endl; + std::cout << "* [out] stats.txt is the statistical label report"<< std::endl; + std::cout << std::endl; +} + +int main(int argc, char* args[]) +{ + if (12 == argc || 13 == argc) + { + const std::string labeled(args[1]); // in + const unsigned d = atoi(args[2]); // in + const char nbh = args[3][0]; // in + const std::string input(args[4]); // in + const char q = args[5][0]; // in + const std::string quant(args[6]); // in + const std::string histo(args[7]); // in + const std::string colormap(args[8]); // in + const std::string iz(args[9]); // out + const std::string proj(args[10]); // out + const std::string mean(args[11]); // out + const std::string stats(13 == argc? args[12] : ""); // [out] + + + mln::neighb3d neighbourhood; + + switch (nbh) + { + case '6': neighbourhood = mln::c6(); break; + case '1': neighbourhood = mln::c18(); break; + case '2': neighbourhood = mln::c26(); break; + default: usage(); return 0; // force usage and quit + } + + switch (q) + { + case '2' : mk_iz<2>(labeled,d,neighbourhood,input,quant, + histo,colormap,iz,proj,mean,stats);break; + case '3' : mk_iz<3>(labeled,d,neighbourhood,input,quant, + histo,colormap,iz,proj,mean,stats);break; + case '4' : mk_iz<4>(labeled,d,neighbourhood,input,quant, + histo,colormap,iz,proj,mean,stats);break; + case '5' : mk_iz<5>(labeled,d,neighbourhood,input,quant, + histo,colormap,iz,proj,mean,stats);break; + case '6' : mk_iz<6>(labeled,d,neighbourhood,input,quant, + histo,colormap,iz,proj,mean,stats);break; + case '7' : mk_iz<7>(labeled,d,neighbourhood,input,quant, + histo,colormap,iz,proj,mean,stats);break; + case '8' : mk_iz<8>(labeled,d,neighbourhood,input,quant, + histo,colormap,iz,proj,mean,stats);break; + default: usage(); break; + } + } + else + usage(); + + return 0; +} diff --git a/milena/sandbox/green/tools/annotating/opening/opening.cc b/milena/sandbox/green/tools/annotating/opening/opening.cc index 3e1dbf2..cdd37fb 100644 --- a/milena/sandbox/green/tools/annotating/opening/opening.cc +++ b/milena/sandbox/green/tools/annotating/opening/opening.cc @@ -15,36 +15,47 @@ #include <mln/io/dump/load.hh> #include <mln/io/dump/save.hh> -#include <mln/io/pgm/load.hh> +#include <mln/io/ppm/save.hh> #include <mln/io/pgm/save.hh> +#include <mln/literal/colors.hh> + #include <mln/morpho/opening/volume.hh> +#include <mln/value/rgb.hh> #include <mln/value/int_u8.hh> -void mk_opening(const std::string& input, - const unsigned min_vol, - const std::string& output, - const std::string& opened) +template <unsigned n> +void mk_opening(const std::string& histo, // in + const unsigned min_vol, // in + const std::string& opened, // out + const std::string& proj1, // out + const std::string& proj2) // out { typedef mln::value::int_u8 t_int_u8; + typedef mln::value::rgb<n> t_rgbn; typedef mln::image2d<t_int_u8> t_image2d_int_u8; + typedef mln::image2d<t_rgbn> t_image2d_rgbn; typedef mln::image3d<unsigned> t_histo3d; typedef mln::accu::meta::stat::histo3d_rgb t_histo3d_fun; // START OF IMAGE PROCESSING CHAIN t_histo3d h1_input; // histo input t_histo3d h2_input; // histo input - t_image2d_int_u8 p1_histo; // histo proj + t_image2d_int_u8 p1_histo1;// histo proj1 + t_image2d_rgbn p1_histo2;// histo proj2 + t_rgbn red(mln::literal::red); - mln::io::dump::load(h1_input, input.c_str()); + mln::io::dump::load(h1_input, histo.c_str()); h2_input = mln::morpho::opening::volume(h1_input, mln::c6(), min_vol); // END OF IMAGE PROCESSING CHAIN // BEGIN DUMPING - p1_histo = mln::display::display_histo3d_unsigned(h2_input); + p1_histo1 = mln::display::display_histo3d_unsigned(h2_input); + p1_histo2 = mln::display::display3_histo3d_unsigned(h2_input, red); mln::io::dump::save(h2_input, opened.c_str()); - mln::io::pgm::save(p1_histo, output.c_str()); + mln::io::pgm::save(p1_histo1, proj1.c_str()); + mln::io::ppm::save(p1_histo2, proj2.c_str()); // END DUMPING } @@ -52,25 +63,46 @@ void mk_opening(const std::string& input, void usage() { std::cout << std::endl; - std::cout << "opening input.dump v out.dump out.ppm" << std::endl; - std::cout << "where" << std::endl; - std::cout << "input.dump is the 3d color input histo" << std::endl; - std::cout << "v is the minimum size of each composant" << std::endl; - std::cout << "out.pgm is the r/g proj of the opened histogram" << std::endl; - std::cout << "out.dump is the opened histogram" << std::endl; + std::cout << "opening q histo.dump v opened.dump proj.pgm" + << " proj.ppm" << std::endl; + std::cout << std::endl; + std::cout << "where :" << std::endl; + std::cout << "* [ in] q is the degree of quantification" + << " {2,3,4,5,6,7,8}" << std::endl; + std::cout << "* [ in] histo.dump is the quantified color" + << " histogram" << std::endl; + std::cout << "* [ in] v is the minimum size (in pixels) of" + << " each composant" << std::endl; + std::cout << "* [out] opened.dump is the filtered histogram" << std::endl; + std::cout << "* [out] proj.pgm is the r/g projection of the" + << " histogram (summing along the blue axe)" << std::endl; + std::cout << "* [out] proj.ppm is the r/g projection of the" + << " histogram with maxima plot on" << std::endl; std::cout << std::endl; } int main(int argc, char* args[]) { - if (5 == argc) + if (7 == argc) { - const std::string input(args[1]); - const unsigned min_vol = atoi(args[2]); - const std::string output(args[3]); - const std::string opened(args[4]); - - mk_opening(input, min_vol, output, opened); + const char q = args[1][0]; // in + const std::string histo(args[2]); // in + const unsigned min_vol = atoi(args[3]); // in + const std::string opened(args[4]); // out + const std::string proj1(args[5]); // out + const std::string proj2(args[6]); // out + + switch(q) + { + case '2': mk_opening<2>(histo, min_vol, opened, proj1, proj2); break; + case '3': mk_opening<3>(histo, min_vol, opened, proj1, proj2); break; + case '4': mk_opening<4>(histo, min_vol, opened, proj1, proj2); break; + case '5': mk_opening<5>(histo, min_vol, opened, proj1, proj2); break; + case '6': mk_opening<6>(histo, min_vol, opened, proj1, proj2); break; + case '7': mk_opening<7>(histo, min_vol, opened, proj1, proj2); break; + case '8': mk_opening<8>(histo, min_vol, opened, proj1, proj2); break; + default: usage(); break; + } } else usage(); diff --git a/milena/sandbox/green/tools/annotating/regmax/regmax.cc b/milena/sandbox/green/tools/annotating/regmax/regmax.cc index 2079bc4..0ff4d2e 100644 --- a/milena/sandbox/green/tools/annotating/regmax/regmax.cc +++ b/milena/sandbox/green/tools/annotating/regmax/regmax.cc @@ -1,8 +1,13 @@ // TOOLS ==> regmax on histo #include <iostream> +#include <fstream> +#include <boost/format.hpp> #include <mln/accu/stat/histo3d_rgb.hh> +#include <mln/accu/stat/mean.hh> + +#include <mln/algebra/vec.hh> #include <mln/core/macros.hh> #include <mln/core/alias/neighb3d.hh> @@ -18,9 +23,14 @@ #include <mln/io/dump/save.hh> #include <mln/io/pgm/load.hh> #include <mln/io/pgm/save.hh> +#include <mln/io/ppm/load.hh> #include <mln/io/ppm/save.hh> #include <mln/labeling/regional_maxima.hh> +#include <mln/labeling/compute.hh> +#include <mln/labeling/mean_values.hh> + +#include <mln/literal/colors.hh> #include <mln/morpho/opening/volume.hh> @@ -28,6 +38,8 @@ #include <mln/value/int_u8.hh> #include <mln/value/rgb8.hh> +#include <mln/util/array.hh> + template <unsigned n> struct t_labeling_rgbn : mln::Function_v2v< t_labeling_rgbn<n> > { @@ -49,19 +61,134 @@ struct t_labeling_rgbn : mln::Function_v2v< t_labeling_rgbn<n> > } }; -void mk_regmax(const std::string& input, - const std::string& quant, - const std::string& histo, - const std::string& label, - const std::string& output) +void compute_stats(const mln::image2d<mln::value::rgb8>& i_input_rgb8, + const mln::image2d<mln::value::label_8>& l_input_lbl8, + const mln::image3d<unsigned>& h_histo_rgbn, + const mln::image3d<mln::value::label_8>& l_histo_lbl8, + const mln::value::label_8& n_labels, + const std::string& log) +{ + typedef mln::algebra::vec<3,float> t_vec3f; + typedef mln::accu::math::sum<unsigned,unsigned> t_sum; + typedef mln::accu::stat::mean<t_vec3f,t_vec3f,t_vec3f> t_mean; + typedef mln::util::array<unsigned> t_count_array; + typedef mln::util::array<t_vec3f> t_mean_array; + + mln::util::array<float> abs((unsigned)(n_labels)+1); + mln::util::array<float> rel((unsigned)(n_labels)+1); + unsigned nb = 0; + + for (unsigned i = 0; i <= n_labels; ++i) + { + abs[i] = 0.0; + rel[i] = 0.0; + } + + // COMPUTE THE SUM + t_count_array count = mln::labeling::compute(t_sum(), + h_histo_rgbn, + l_histo_lbl8, + n_labels); + + // COMPUTE THE TOTAL + for (unsigned i = 0; i <= n_labels; ++i) + { + unsigned c = count[i]; + nb += c; + } + + // COMPUTE THE PERCENTAGES + for (unsigned i = 0; i <= n_labels; ++i) + if (0 < count[i]) + { + abs[i] = ((float)count[i] / nb)*100.0; + rel[i] = ((float)count[i] / (nb - count[0]))*100.0; + } + + // COMPUTE THE MEAN + + t_mean_array mean = mln::labeling::compute(t_mean(), + i_input_rgb8, + l_input_lbl8, + n_labels); + + // CORRECT 0 LABEL STATS + rel[0] = 0; + mean[0][0] = 255.0; + mean[0][1] = 255.0; + mean[0][2] = 0.0; + + // PRINT STATS + std::ofstream log_stream(log.c_str()); + + for (unsigned i = 0; i <= n_labels; ++i) + { + const t_vec3f& mean_v = mean[i]; + + log_stream << boost::format("%2i|" + "r = %6.2f, g = %6.2f, b = %6.2f |" + "c = %7i, %%i = %5.2f, %%c = %5.2f") + % i + % mean_v[0] + % mean_v[1] + % mean_v[2] + % count[i] + % abs[i] + % rel[i] + << std::endl; + } + + log_stream << std::endl << std::endl; + log_stream.flush(); + log_stream.close(); +} + +void save(mln::util::array< mln::algebra::vec<3,float> >& m2_label, + const char *colormap) +{ + typedef mln::algebra::vec<3,float> t_vec3f; + typedef mln::util::array<t_vec3f> t_mean_array; + + std::ofstream stream(colormap); + + for (unsigned i = 0; i < m2_label.size(); ++i) + { + const t_vec3f& mean_v = m2_label[i]; + + stream << boost::format("%2i | r = %6.2f, g = %6.2f, b = %6.2f") + % i + % mean_v[0] + % mean_v[1] + % mean_v[2] + << std::endl; + } + + stream.flush(); + stream.close(); +} + +template <unsigned n> +void mk_regmax(const std::string& input, // in + const std::string& quant, // in + const std::string& histo, // in + const std::string& opened, // in + const mln::neighb3d& nbh, // in + const std::string& labeled, // out + const std::string& proj, // out + const std::string& colormap,// out + const std::string& mean, // out + const std::string& stats) // [out] { typedef mln::value::label_8 t_lbl8; typedef mln::value::rgb8 t_rgb8; - typedef mln::value::rgbn t_rgbn; + typedef mln::value::rgb<n> t_rgbn; typedef mln::value::int_u8 t_int_u8; + typedef mln::value::int_u<n> t_int_un; typedef mln::algebra::vec<3,float> t_v3f; typedef mln::image2d<t_int_u8> t_image2d_int_u8; + typedef mln::image2d<t_int_un> t_image2d_int_un; typedef mln::image2d<t_rgb8> t_image2d_rgb8; + typedef mln::image2d<t_rgbn> t_image2d_rgbn; typedef mln::image3d<t_lbl8> t_image3d_lbl8; typedef mln::image2d<t_lbl8> t_image2d_lbl8; typedef mln::image3d<unsigned> t_histo3d; @@ -71,60 +198,128 @@ void mk_regmax(const std::string& input, t_image2d_rgb8 i0_input; // input img t_image2d_rgbn i1_input; // quant img + t_histo3d h1_input; // input histo t_histo3d h2_input; // opened histo -// t_image2d_int_u8 p2_label; // histo proj - t_image2d_lbl8 p2_label; // histo proj -// t_image2d_rgb8 p2_label; // histo proj + t_image2d_rgb8 p2_label; // histo proj t_image3d_lbl8 l2_histo; // label histo - t_mean_array m2_label; // palette + t_image2d_lbl8 l2_input; // label input + t_mean_array m2_label; // colormap + t_image2d_rgb8 i2_mean; // reconstructed t_lbl8 n_lbl; // nb class + t_rgb8 red(mln::literal::red); + // BEGIN LOADING mln::io::ppm::load(i0_input, input.c_str()); mln::io::ppm::load(i1_input, quant.c_str()); - mln::io::dump::load(h2_input, histo.c_str()); + mln::io::dump::load(h1_input, histo.c_str()); + mln::io::dump::load(h2_input, opened.c_str()); // END LOADING // BEGIN IMAGE PROCESSING - l2_histo = mln::labeling::regional_maxima(h2_input, mln::c6(), n_lbl); + l2_histo = mln::labeling::regional_maxima(h2_input, nbh, n_lbl); // END IMAGE PROCESSING // BEGIN SAVING - mln::debug::println(h2_input); mln::io::dump::save(l2_histo, labeled.c_str()); l2_input = mln::data::transform(i1_input, t_labeling_rgbn<n>(l2_histo)); - m2_label = mln::labeling::compute(t_mean(), i0_input, l2_input, n_labels); - p2_label =mln::display::display3_histo3d_unsigned(h2_input,l2_histo,m2_label); + i2_mean = mln::labeling::mean_values(i0_input, l2_input, n_lbl); + m2_label = mln::labeling::compute(t_mean(), i0_input, l2_input, n_lbl); + + // CORRECT 0 LABEL STATS + m2_label[0][0] = 255.0; + m2_label[0][1] = 255.0; + m2_label[0][2] = 0.0; + + p2_label =mln::display::display3_histo3d_unsigned<n>(h1_input, + l2_histo, + m2_label, + red); + + mln::io::ppm::save(p2_label, proj.c_str()); + save(m2_label, colormap.c_str()); + mln::io::ppm::save(i2_mean, mean.c_str()); + + if (0 < stats.size()) + compute_stats(i0_input, l2_input, h1_input, l2_histo, n_lbl, stats); -// mln::io::pgm::save(p2_label, output.c_str()); - mln::io::ppm::save(p2_label, output.c_str()); - std::cout << "Nb classes : " << n_lbl << std::endl; // END SAVING } - void usage() { std::cout << std::endl; - std::cout << "regmax input.dump out.dump out.ppm" << std::endl; - std::cout << "where" << std::endl; - std::cout << "input.dump is opened histo" << std::endl; - std::cout << "out.pgm is the r/g proj of the opened histogram" << std::endl; - std::cout << "out.dump is the labeled histogram" << std::endl; + std::cout << "regmax input.ppm q quant.ppm histo.dump" + << " opened.dump nbh labeled.dump proj.ppm" + << " colormap.txt mean.ppm [stats.txt]" << std::endl; + std::cout << std::endl; + std::cout << "where :" << std::endl; + std::cout << "* [ in] input.ppm is the 8 bits color ppm image" << std::endl; + std::cout << "* [ in] q is the degree of quantification" + << " {2,3,4,5,6,7,8}" << std::endl; + std::cout << "* [ in] quant.ppm is the q bits quantified input" + << " image" << std::endl; + std::cout << "* [ in] histo.dump is the quantified color" + << " histogram" << std::endl; + std::cout << "* [ in] opened.dump is the filtered histogram" << std::endl; + std::cout << "* [ in] nbh is the 3d neighbourhood {6,18,26}" << std::endl; + std::cout << "* [out] labeled.dump is the labeled 3d histogram" << std::endl; + std::cout << "* [out] proj.ppm is the r/g projection of the" + << " histogram with maxima label plot on" << std::endl; + std::cout << "* [out] colormap.txt is the colormap for labels" << std::endl; + std::cout << "* [out] mean.ppm is the mean reconstructed image" << std::endl; + std::cout << "* [out] stats.txt is the statistical label report"<< std::endl; std::cout << std::endl; } int main(int argc, char* args[]) { - if (4 == argc) + if (11 == argc || 12 == argc) { - const std::string input(args[1]); - const std::string output(args[2]); - const std::string labeled(args[3]); + const std::string input(args[1]); // in + const char q = args[2][0]; // in + const std::string quant(args[3]); // in + const std::string histo(args[4]); // in + const std::string opened(args[5]); // in + const char nbh = args[6][0]; // in + const std::string labeled(args[7]); // out + const std::string proj(args[8]); // out + const std::string colormap(args[9]);// out + const std::string mean(args[10]); // out + const std::string stats(12 == argc? args[11] : ""); // [out] + + + mln::neighb3d neighbourhood; + + switch (nbh) + { + case '6': neighbourhood = mln::c6(); break; + case '1': neighbourhood = mln::c18(); break; + case '2': neighbourhood = mln::c26(); break; + default: usage(); return 0; // force usage and quit + } + + switch (q) + { - mk_regmax(input, output, labeled); + case '2': mk_regmax<2>(input,quant,histo,opened,neighbourhood, + labeled,proj,colormap,mean,stats); break; + case '3': mk_regmax<3>(input,quant,histo,opened,neighbourhood, + labeled,proj,colormap,mean,stats); break; + case '4': mk_regmax<4>(input,quant,histo,opened,neighbourhood, + labeled,proj,colormap,mean,stats); break; + case '5': mk_regmax<5>(input,quant,histo,opened,neighbourhood, + labeled,proj,colormap,mean,stats); break; + case '6': mk_regmax<6>(input,quant,histo,opened,neighbourhood, + labeled,proj,colormap,mean,stats); break; + case '7': mk_regmax<7>(input,quant,histo,opened,neighbourhood, + labeled,proj,colormap,mean,stats); break; + case '8': mk_regmax<8>(input,quant,histo,opened,neighbourhood, + labeled,proj,colormap,mean,stats); break; + default: usage(); break; + } } else usage(); -- 1.5.6.5
14Â years, 2Â months
1
0
0
0
last-svn-commit-26-g25ef511 Fix bugs in the histogram visualization tools.
by green
* green/mln/display/display_histo.cc: Add new vizualisations. * green/mln/display/project_histo.cc: Add new color projections. --- milena/sandbox/ChangeLog | 7 + milena/sandbox/green/mln/display/display_histo.hh | 75 ++++-- milena/sandbox/green/mln/display/project_histo.hh | 341 +++++++++++++-------- 3 files changed, 279 insertions(+), 144 deletions(-) diff --git a/milena/sandbox/ChangeLog b/milena/sandbox/ChangeLog index 0968186..6f08caf 100644 --- a/milena/sandbox/ChangeLog +++ b/milena/sandbox/ChangeLog @@ -1,5 +1,12 @@ 2010-02-10 Yann Jacquelet <jacquelet(a)lrde.epita.fr> + Fix bugs in the histogram visualization tools. + + * green/mln/display/display_histo.cc: Add new vizualisations. + * green/mln/display/project_histo.cc: Add new color projections. + +2010-02-10 Yann Jacquelet <jacquelet(a)lrde.epita.fr> + Fix last details in the image processing chain. * green/tools/annotating/histo/histo.cc: Manage new inputs/outputs. diff --git a/milena/sandbox/green/mln/display/display_histo.hh b/milena/sandbox/green/mln/display/display_histo.hh index 2ba0b61..ef47182 100644 --- a/milena/sandbox/green/mln/display/display_histo.hh +++ b/milena/sandbox/green/mln/display/display_histo.hh @@ -29,12 +29,14 @@ # define MLN_DISPLAY_DISPLAY_HISTO_HH # include <mln/accu/math/sum.hh> +# include <mln/algebra/vec.hh> # include <mln/data/stretch.hh> # include <mln/display/project_histo.hh> # include <mln/fun/v2v/log.hh> # include <mln/value/int_u8.hh> # include <mln/value/rgb8.hh> # include <mln/value/label_8.hh> +# include <mln/util/array.hh> /// \file @@ -57,19 +59,28 @@ namespace mln image2d<value::int_u8> display_histo3d_unsigned(const image3d<unsigned>& histo); - image2d<value::int_u8> - display2_histo3d_unsigned(const image3d<unsigned>& histo); + template <unsigned n> + image2d< value::int_u<n> > + display2_histo3d_unsigned(const image3d<unsigned>& histo, + const value::int_u<n> ambiguous_color); + template <unsigned n> image2d<value::label_8> display2_histo3d_unsigned(const image3d<unsigned>& histo, - const image3d<value::label_8>& label); + const image3d<value::label_8>& label, + const value::label_8 ambiguous_label); - image2d<value::rgb8> - display3_histo3d_unsigned(const image3d<unsigned>& histo); + template <unsigned n> + image2d< value::rgb<n> > + display3_histo3d_unsigned(const image3d<unsigned>& histo, + const value::rgb<n> ambiguous_color); - image2d<value::rgb8> - display3_histo3d_unsigned(const image3d<unsigned>& histo, - const image3d<value::label_8>& label); + template <unsigned n> + image2d< value::rgb8 > + display3_histo3d_unsigned(const image3d<unsigned>& histo, + const image3d<value::label_8>& label, + const util::array< algebra::vec<3,float> >& pal, + const value::rgb8 ambiguous_color); #ifndef MLN_INCLUDE_ONLY @@ -87,7 +98,7 @@ namespace mln /// \parameter[in] histo the histogram in 3d. /// \result return a equivalent 2d image. - + // FIXME : display_shape [in int_u8] image2d<value::int_u8> display_histo3d_unsigned(const image3d<unsigned>& histo) { @@ -102,40 +113,62 @@ namespace mln return proj_int; } - image2d<value::int_u8> - display2_histo3d_unsigned(const image3d<unsigned>& histo) + // FIXME : display_color [in int_un] + template <unsigned n> + image2d< value::int_u<n> > + display2_histo3d_unsigned(const image3d<unsigned>& histo, + const value::int_u<n> ambiguous_color) { - image2d<value::int_u8> proj = project2_histo<0>(histo); + image2d< value::int_u<n> > proj = project2_histo<n,0>(histo, + ambiguous_color); return proj; } + // FIXME : display_label [in label] + template <unsigned n> image2d<value::label_8> display2_histo3d_unsigned(const image3d<unsigned>& histo, - const image3d<value::label_8>& label) + const image3d<value::label_8>& label, + const value::label_8 ambiguous_label) { - image2d<value::label_8> proj = project2_histo<0>(histo, label); + image2d<value::label_8> proj = project2_histo<n,0>(histo, + label, + ambiguous_label); return proj; } - image2d<value::rgb8> - display3_histo3d_unsigned(const image3d<unsigned>& histo) + // FIXME : display_color [in color] + template <unsigned n> + image2d< value::rgb<n> > + display3_histo3d_unsigned(const image3d<unsigned>& histo, + const value::rgb<n> ambiguous_color) { - image2d<value::rgb8> proj = project3_histo<0>(histo); + image2d< value::rgb<n> > proj = project3_histo<n,0>(histo, + ambiguous_color); return proj; } - image2d<value::rgb8> - display3_histo3d_unsigned(const image3d<unsigned>& histo, - const image3d<value::label_8>& label) + + // FIXME : display_label [in color] + template <unsigned n> + image2d< value::rgb8 > + display3_histo3d_unsigned(const image3d<unsigned>& histo, + const image3d<value::label_8>& label, + const util::array<algebra::vec<3,float> >& pal, + const value::rgb8 ambiguous_color) { - image2d<value::rgb8> proj = project3_histo<0>(histo, label); + image2d< value::rgb8 > proj = project3_histo<n,0>(histo, + label, + pal, + ambiguous_color); return proj; } + #endif // ! MLN_INCLUDE_ONLY diff --git a/milena/sandbox/green/mln/display/project_histo.hh b/milena/sandbox/green/mln/display/project_histo.hh index d842c70..30bcd6d 100644 --- a/milena/sandbox/green/mln/display/project_histo.hh +++ b/milena/sandbox/green/mln/display/project_histo.hh @@ -37,12 +37,16 @@ # include <mln/accu/image/take.hh> # include <mln/accu/image/to_result.hh> +# include <mln/algebra/vec.hh> + # include <mln/opt/at.hh> # include <mln/value/int_u8.hh> # include <mln/value/rgb8.hh> # include <mln/value/label_8.hh> +# include <mln/util/array.hh> + /// \file /// /// \brief Allow the visualization of 3d histogram. @@ -60,9 +64,30 @@ namespace mln image2d<mln_result(A)> project_histo(const image3d<V>& histo); - template <typename A, unsigned direction, typename V> + template <typename A, unsigned n, unsigned direction, typename V> image2d<mln_result(A)> - project2_histo(const image3d<V>& histo); + project2_histo(const image3d<V>& histo, + const value::int_u<n>& ambiguous_color); + + template <unsigned n, unsigned direction, typename V> + image2d<V> + project2_histo(const image3d<unsigned>& histo, + const image3d<V>& label); + + template <unsigned n, unsigned direction> + image2d< value::rgb<n> > + project3_histo(const image3d<unsigned>& histo, + const value::rgb<n> ambiguous_color); + + template <unsigned n, unsigned direction> + image2d< value::rgb8 > + project3_histo(const image3d<unsigned>& histo, + const image3d<value::label_8>& label, + const util::array<algebra::vec<3, float> >& pal, + const value::rgb8 ambiguous_color); + // FIXME ==> palette must be 1d-image not an array !! + + # ifndef MLN_INCLUDE_ONLY @@ -96,80 +121,96 @@ namespace mln return accu::image::to_result(histo_accu); } - template <unsigned direction> - image2d<value::int_u8> - project2_histo(const image3d<unsigned>& histo) + // 0 ==> blue + // 1 ==> red + // 2 ==> green + + // mln::opt::at(histo, blue, red, green) + + template <unsigned n, unsigned direction> + image2d< value::int_u<n> > + project2_histo(const image3d<unsigned>& histo, + const value::int_u<n>& ambiguous_color) { - image2d<value::int_u8> result; + image2d< value::int_u<n> > result; if (0 == direction) // blue { - image2d<value::int_u8> arg_max(histo.ncols(), histo.nslices()); + image2d< value::int_u<n> > arg_max(histo.nrows(), histo.ncols()); - for (unsigned j = 0; j < histo.ncols(); ++j) - for (unsigned i = 0; i < histo.nslices(); ++i) + for (def::coord green = 0; green < (signed)histo.ncols(); ++green) + for (def::coord red = 0; red < (signed)histo.nrows(); ++red) { - unsigned max = 0; // minimum as possible - signed pos = -1; + unsigned max = 0; // minimum as possible + def::coord pos = -1; - for (unsigned k = 0; k < histo.nrows(); ++k) + for (def::coord blue = 0; blue < (signed)histo.nslices(); ++blue) { - if (max <= opt::at(histo,i,j,k)) + if (max < opt::at(histo,blue,red,green)) { - max = opt::at(histo,i,j,k); - pos = k; + max = opt::at(histo,blue,red,green); + pos = blue; } } - opt::at(arg_max,i,j) = pos; + if (-1 == pos) + opt::at(arg_max,red,green) = ambiguous_color; + else + opt::at(arg_max,red,green) = pos; } result = arg_max; } else if (1 == direction) // red { - image2d<value::int_u8> arg_max(histo.nrows(), histo.nslices()); + image2d< value::int_u<n> > arg_max(histo.ncols(), histo.nslices()); - for (unsigned j = 0; j < histo.nslices(); ++j) - for (unsigned i = 0; i < histo.nrows(); ++i) + for (def::coord blue = 0; blue < (signed)histo.nslices(); ++blue) + for (def::coord green = 0; green < (signed)histo.ncols(); ++green) { unsigned max = 0; // minimum as possible signed pos = -1; - for (unsigned k = 0; k < histo.ncols(); ++k) + for (def::coord red = 0; red < (signed)histo.nrows(); ++red) { - if (max <= opt::at(histo,i,j,k)) + if (max < opt::at(histo,blue,red,green)) { - max = opt::at(histo,i,j,k); - pos = k; + max = opt::at(histo,blue,red,green); + pos = red; } } - opt::at(arg_max,i,j) = pos; + if (-1 == pos) + opt::at(arg_max,green,blue) = ambiguous_color; + else + opt::at(arg_max,green,blue) = pos; } result = arg_max; } else // 2 == direction // green { - image2d<value::int_u8> arg_max(histo.nrows(), histo.ncols()); + image2d< value::int_u<n> > arg_max(histo.nrows(), histo.nslices()); - for (unsigned j = 0; j < histo.ncols(); ++j) - for (unsigned i = 0; i < histo.nrows(); ++i) + for (def::coord blue = 0; blue < (signed)histo.nslices(); ++blue) + for (def::coord red = 0; red < (signed)histo.nrows(); ++red) { unsigned max = 0; // minimum as possible signed pos = -1; - for (unsigned k = 0; k < histo.nslices(); ++k) + for (def::coord green = 0; green < (signed)histo.ncols(); ++green) { - if (max <= opt::at(histo,i,j,k)) + if (max < opt::at(histo,blue,red,green)) { - max = opt::at(histo,i,j,k); - pos = k; + max = opt::at(histo,blue,red,green); + pos = green; } } - opt::at(arg_max,i,j) = pos; + if (-1 == pos) + opt::at(arg_max,red,blue) = ambiguous_color; + else + opt::at(arg_max,red,blue) = pos; } result = arg_max; @@ -178,81 +219,91 @@ namespace mln return result; } - template <unsigned direction> + template <unsigned n, unsigned direction> image2d<value::label_8> project2_histo(const image3d<unsigned>& histo, - const image3d<value::label_8>& label) + const image3d<value::label_8>& label, + const value::label_8 ambiguous_label) { image2d<value::label_8> result; if (0 == direction) // blue { - image2d<value::label_8> arg_max(histo.ncols(), histo.nslices()); + image2d<value::label_8> arg_max(histo.nrows(), histo.ncols()); - for (unsigned j = 0; j < histo.ncols(); ++j) - for (unsigned i = 0; i < histo.nslices(); ++i) + for (def::coord green = 0; green < (signed)histo.ncols(); ++green) + for (def::coord red = 0; red < (signed)histo.nrows(); ++red) { - unsigned max = 0; // minimum as possible - signed pos = -1; + unsigned max = 0; // minimum as possible + def::coord pos = -1; - for (unsigned k = 0; k < histo.nrows(); ++k) + for (def::coord blue = 0; blue < (signed)histo.nslices(); ++blue) { - if (max <= opt::at(histo,i,j,k)) + if (max < opt::at(histo,blue,red,green)) { - max = opt::at(histo,i,j,k); - pos = k; + max = opt::at(histo,blue,red,green); + pos = blue; } } - opt::at(arg_max,i,j) = opt::at(label,i,j,pos); + if (-1 == pos) + opt::at(arg_max,red,green) = ambiguous_label; + else + opt::at(arg_max,red,green) = opt::at(label, pos, red, green); } result = arg_max; } else if (1 == direction) // red { - image2d<value::label_8> arg_max(histo.nrows(), histo.nslices()); + image2d<value::label_8> arg_max(histo.ncols(), histo.nslices()); - for (unsigned j = 0; j < histo.nslices(); ++j) - for (unsigned i = 0; i < histo.nrows(); ++i) + for (def::coord blue = 0; blue < (signed)histo.nslices(); ++blue) + for (def::coord green = 0; green < (signed)histo.ncols(); ++green) { unsigned max = 0; // minimum as possible signed pos = -1; - for (unsigned k = 0; k < histo.ncols(); ++k) + for (def::coord red = 0; red < (signed)histo.nrows(); ++red) { - if (max <= opt::at(histo,i,j,k)) + if (max < opt::at(histo,blue,red,green)) { - max = opt::at(histo,i,j,k); - pos = k; + max = opt::at(histo,blue,red,green); + pos = red; } } - opt::at(arg_max,i,j) = opt::at(label,pos,i,j); + if (-1 == pos) + opt::at(arg_max,green,blue) = ambiguous_label; + else + opt::at(arg_max,green,blue) = opt::at(label, blue, pos, green); } result = arg_max; } else // 2 == direction // green { - image2d<value::label_8> arg_max(histo.nrows(), histo.ncols()); + image2d<value::label_8> arg_max(histo.nrows(), histo.nslices()); - for (unsigned j = 0; j < histo.ncols(); ++j) - for (unsigned i = 0; i < histo.nrows(); ++i) + for (def::coord blue = 0; blue < (signed)histo.nslices(); ++blue) + for (def::coord red = 0; red < (signed)histo.nrows(); ++red) { unsigned max = 0; // minimum as possible signed pos = -1; - for (unsigned k = 0; k < histo.nslices(); ++k) + for (def::coord green = 0; green < (signed)histo.ncols(); ++green) { - if (max <= opt::at(histo,i,j,k)) + if (max < opt::at(histo,blue,red,green)) { - max = opt::at(histo,i,j,k); - pos = k; + max = opt::at(histo,blue,red,green); + pos = green; } } - opt::at(arg_max,i,j) = opt::at(label,i,pos,j); + if (-1 == pos) + opt::at(arg_max,red,blue) = ambiguous_label; + else + opt::at(arg_max,red,blue) = opt::at(label, blue, red, pos); } result = arg_max; @@ -262,83 +313,117 @@ namespace mln } + + // FIXME ... determine the color of each class. - template <unsigned direction> - image2d<value::rgb8> - project3_histo(const image3d<unsigned>& histo, - const image3d<value::label_8>& label) + // FIXME la palette est supposée en 8 bits + template <unsigned n, unsigned direction> + image2d< value::rgb8 > + project3_histo(const image3d<unsigned>& histo, + const image3d<value::label_8>& label, + const util::array<algebra::vec<3,float> >& pal, + const value::rgb8 ambiguous_color) { - image2d<value::rgb8> result; + image2d< value::rgb8 > result; if (0 == direction) // blue { - image2d<value::rgb8> arg_max(histo.ncols(), histo.nslices()); + image2d< value::rgb8 > arg_max(histo.nrows(), histo.ncols()); - for (unsigned j = 0; j < histo.ncols(); ++j) - for (unsigned i = 0; i < histo.nslices(); ++i) + for (def::coord green = 0; green < (signed)histo.ncols(); ++green) + for (def::coord red = 0; red < (signed)histo.nrows(); ++red) { - unsigned max = 0; // minimum as possible - signed pos = -1; + unsigned max = 0; // minimum as possible + def::coord pos = -1; - for (unsigned k = 0; k < histo.nrows(); ++k) + for (def::coord blue = 0; blue < (signed)histo.nslices(); ++blue) { - if (max <= opt::at(histo,i,j,k)) + if (max < opt::at(histo,blue,red,green)) { - max = opt::at(histo,i,j,k); - pos = k; + max = opt::at(histo,blue,red,green); + pos = blue; } } - opt::at(arg_max,i,j) = value::rgb8(i,j,pos); + if (-1 == pos) + opt::at(arg_max,red,green) = ambiguous_color; + else + { + value::int_u8 r = pal[opt::at(label,pos,red,green)][0]; + value::int_u8 g = pal[opt::at(label,pos,red,green)][1]; + value::int_u8 b = pal[opt::at(label,pos,red,green)][2]; + value::rgb8 color(r,g,b); + + opt::at(arg_max,red,green) = color; + } } result = arg_max; } else if (1 == direction) // red { - image2d<value::rgb8> arg_max(histo.nrows(), histo.nslices()); + image2d< value::rgb8 > arg_max(histo.ncols(), histo.nslices()); - for (unsigned j = 0; j < histo.nslices(); ++j) - for (unsigned i = 0; i < histo.nrows(); ++i) + for (def::coord blue = 0; blue < (signed)histo.nslices(); ++blue) + for (def::coord green = 0; green < (signed)histo.ncols(); ++green) { unsigned max = 0; // minimum as possible signed pos = -1; - for (unsigned k = 0; k < histo.ncols(); ++k) + for (def::coord red = 0; red < (signed)histo.nrows(); ++red) { - if (max <= opt::at(histo,i,j,k)) + if (max < opt::at(histo,blue,red,green)) { - max = opt::at(histo,i,j,k); - pos = k; + max = opt::at(histo,blue,red,green); + pos = red; } } - opt::at(arg_max,i,j) = value::rgb8(pos,i,j); + if (-1 == pos) + opt::at(arg_max,green,blue) = ambiguous_color; + else + { + value::int_u8 r = pal[opt::at(label,blue,pos,green)][0]; + value::int_u8 g = pal[opt::at(label,blue,pos,green)][1]; + value::int_u8 b = pal[opt::at(label,blue,pos,green)][2]; + value::rgb8 color(r,g,b); + + opt::at(arg_max,green,blue) = color; + } } result = arg_max; } else // 2 == direction // green { - image2d<value::rgb8> arg_max(histo.nrows(), histo.ncols()); + image2d< value::rgb8 > arg_max(histo.nrows(), histo.nslices()); - for (unsigned j = 0; j < histo.ncols(); ++j) - for (unsigned i = 0; i < histo.nrows(); ++i) + for (def::coord blue = 0; blue < (signed)histo.nslices(); ++blue) + for (def::coord red = 0; red < (signed)histo.nrows(); ++red) { unsigned max = 0; // minimum as possible signed pos = -1; - for (unsigned k = 0; k < histo.nslices(); ++k) + for (def::coord green = 0; green < (signed)histo.ncols(); ++green) { - if (max <= opt::at(histo,i,j,k)) + if (max < opt::at(histo,blue,red,green)) { - max = opt::at(histo,i,j,k); - pos = k; + max = opt::at(histo,blue,red,green); + pos = green; } } - // FIXME ... how to fix the n of rgb - opt::at(arg_max,i,j) = value::rgb8(i,pos,j); + if (-1 == pos) + opt::at(arg_max,red,blue) = ambiguous_color; + else + { + value::int_u8 r = pal[opt::at(label,blue,red,pos)][0]; + value::int_u8 g = pal[opt::at(label,blue,red,pos)][1]; + value::int_u8 b = pal[opt::at(label,blue,red,pos)][2]; + value::rgb8 color(r,g,b); + + opt::at(arg_max,red,blue) = color; + } } result = arg_max; @@ -347,81 +432,91 @@ namespace mln return result; } - template <unsigned direction> - image2d<value::rgb8> - project3_histo(const image3d<unsigned>& histo) + + template <unsigned n, unsigned direction> + image2d< value::rgb<n> > + project3_histo(const image3d<unsigned>& histo, + const value::rgb<n> ambiguous_color) { - image2d<value::rgb8> result; + image2d< value::rgb<n> > result; if (0 == direction) // blue { - image2d<value::rgb8> arg_max(histo.ncols(), histo.nslices()); + image2d< value::rgb<n> > arg_max(histo.nrows(), histo.ncols()); - for (unsigned j = 0; j < histo.ncols(); ++j) - for (unsigned i = 0; i < histo.nslices(); ++i) + for (def::coord green = 0; green < (signed)histo.ncols(); ++green) + for (def::coord red = 0; red < (signed)histo.nrows(); ++red) { - unsigned max = 0; // minimum as possible - signed pos = -1; + unsigned max = 0; // minimum as possible + def::coord pos = -1; - for (unsigned k = 0; k < histo.nrows(); ++k) + for (def::coord blue = 0; blue < (signed)histo.nslices(); ++blue) { - if (max <= opt::at(histo,i,j,k)) + if (max < opt::at(histo,blue,red,green)) { - max = opt::at(histo,i,j,k); - pos = k; + max = opt::at(histo,blue,red,green); + pos = blue; } } - opt::at(arg_max,i,j) = value::rgb8(i,j,pos); + if (-1 == pos) + opt::at(arg_max,red,green) = ambiguous_color; + else + opt::at(arg_max,red,green) = value::rgb<n>(red,green,pos); } result = arg_max; } else if (1 == direction) // red { - image2d<value::rgb8> arg_max(histo.nrows(), histo.nslices()); + image2d< value::rgb<n> > arg_max(histo.ncols(), histo.nslices()); - for (unsigned j = 0; j < histo.nslices(); ++j) - for (unsigned i = 0; i < histo.nrows(); ++i) + for (def::coord blue = 0; blue < (signed)histo.nslices(); ++blue) + for (def::coord green = 0; green < (signed)histo.ncols(); ++green) { unsigned max = 0; // minimum as possible signed pos = -1; - for (unsigned k = 0; k < histo.ncols(); ++k) + for (def::coord red = 0; red < (signed)histo.nrows(); ++red) { - if (max <= opt::at(histo,i,j,k)) + if (max < opt::at(histo,blue,red,green)) { - max = opt::at(histo,i,j,k); - pos = k; + max = opt::at(histo,blue,red,green); + pos = red; } } - opt::at(arg_max,i,j) = value::rgb8(pos,i,j); + if (-1 == pos) + opt::at(arg_max,green,blue) = ambiguous_color; + else + opt::at(arg_max,green,blue) = value::rgb<n>(pos,green,blue);; } result = arg_max; } else // 2 == direction // green { - image2d<value::rgb8> arg_max(histo.nrows(), histo.ncols()); + image2d< value::rgb<n> > arg_max(histo.nrows(), histo.nslices()); - for (unsigned j = 0; j < histo.ncols(); ++j) - for (unsigned i = 0; i < histo.nrows(); ++i) + for (def::coord blue = 0; blue < (signed)histo.nslices(); ++blue) + for (def::coord red = 0; red < (signed)histo.nrows(); ++red) { unsigned max = 0; // minimum as possible signed pos = -1; - for (unsigned k = 0; k < histo.nslices(); ++k) + for (def::coord green = 0; green < (signed)histo.ncols(); ++green) { - if (max <= opt::at(histo,i,j,k)) + if (max < opt::at(histo,blue,red,green)) { - max = opt::at(histo,i,j,k); - pos = k; + max = opt::at(histo,blue,red,green); + pos = green; } } - // FIXME ... how to fix the n of rgb - opt::at(arg_max,i,j) = value::rgb8(i,pos,j); + if (-1 == pos) + opt::at(arg_max,red,blue) = ambiguous_color; + else + opt::at(arg_max,red,blue) = value::rgb<n>(red,pos,blue); } result = arg_max; -- 1.5.6.5
14Â years, 2Â months
1
0
0
0
← Newer
1
...
334
335
336
337
338
339
340
...
963
Older →
Jump to page:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
Results per page:
10
25
50
100
200