Olena-patches
Threads by month
- ----- 2025 -----
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- 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
- 9625 discussions
last-svn-commit-193-g8adc201 2009-12-15 Yann Jacquelet <jacquelet@lrde.epita.fr>
by green 30 Jun '10
by green 30 Jun '10
30 Jun '10
Introduce clipart operators described by Millet.
* green/demo/annoting/nb_color: New demonstration directory.
* green/demo/annoting/nb_color/Makefile.am: New Makefile.
* green/demo/annoting/nb_color/nb_color.cc: New source file.
* green/demo/annoting/stddev_color: New demonstration directory.
* green/demo/annoting/stddev_color/Makefile.am: New Makefile.
* green/demo/annoting/stddev_color/stddev_color.cc: New source file.
---
milena/sandbox/ChangeLog | 13 ++
.../demo/annoting/{bic => nb_color}/Makefile.am | 0
.../green/demo/annoting/nb_color/nb_color.cc | 101 ++++++++++++++++
.../annoting/{bic => stddev_color}/Makefile.am | 0
.../demo/annoting/stddev_color/stddev_color.cc | 124 ++++++++++++++++++++
5 files changed, 238 insertions(+), 0 deletions(-)
copy milena/sandbox/green/demo/annoting/{bic => nb_color}/Makefile.am (100%)
create mode 100644 milena/sandbox/green/demo/annoting/nb_color/nb_color.cc
copy milena/sandbox/green/demo/annoting/{bic => stddev_color}/Makefile.am (100%)
create mode 100644 milena/sandbox/green/demo/annoting/stddev_color/stddev_color.cc
diff --git a/milena/sandbox/ChangeLog b/milena/sandbox/ChangeLog
index 89443b8..ac48ee2 100644
--- a/milena/sandbox/ChangeLog
+++ b/milena/sandbox/ChangeLog
@@ -75,6 +75,19 @@
* bin/pgm_to_pbm.cc,
* bin/ppm_negate.cc: New.
+2009-12-15 Yann Jacquelet <jacquelet(a)lrde.epita.fr>
+
+ Introduce clipart operators described by Millet.
+
+ * green/demo/annoting/nb_color: New demonstration directory.
+ * green/demo/annoting/nb_color/Makefile.am: New Makefile.
+ * green/demo/annoting/nb_color/nb_color.cc: New source file.
+
+ * green/demo/annoting/stddev_color: New demonstration directory.
+ * green/demo/annoting/stddev_color/Makefile.am: New Makefile.
+ * green/demo/annoting/stddev_color/stddev_color.cc: New source file.
+
+
2009-12-02 Yann Jacquelet <jacquelet(a)lrde.epita.fr>
Optimize regional maxima processing for statistical counts and outputs.
diff --git a/milena/sandbox/green/demo/annoting/bic/Makefile.am b/milena/sandbox/green/demo/annoting/nb_color/Makefile.am
similarity index 100%
copy from milena/sandbox/green/demo/annoting/bic/Makefile.am
copy to milena/sandbox/green/demo/annoting/nb_color/Makefile.am
diff --git a/milena/sandbox/green/demo/annoting/nb_color/nb_color.cc b/milena/sandbox/green/demo/annoting/nb_color/nb_color.cc
new file mode 100644
index 0000000..9ad5666
--- /dev/null
+++ b/milena/sandbox/green/demo/annoting/nb_color/nb_color.cc
@@ -0,0 +1,101 @@
+// COUNTING THE IMAGE COLORS
+
+#include <iostream>
+#include <sstream>
+
+#include <mln/img_path.hh>
+
+#include <mln/accu/math/sum.hh>
+#include <mln/accu/math/count.hh>
+#include <mln/accu/stat/histo3d_rgb.hh>
+#include <mln/accu/stat/mean.hh>
+#include <mln/accu/stat/variance.hh>
+
+#include <mln/algebra/vec.hh>
+
+#include <mln/arith/diff_abs.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/core/image/dmorph/image_if.hh>
+#include <mln/core/routine/initialize.hh>
+
+#include <mln/data/compute.hh>
+#include <mln/data/fill.hh>
+#include <mln/data/transform.hh>
+
+#include <mln/fun/v2v/rgb8_to_rgbn.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/mean_values.hh>
+#include <mln/labeling/compute.hh>
+
+#include <mln/literal/colors.hh>
+
+#include <mln/morpho/opening/volume.hh>
+#include <mln/morpho/elementary/dilation.hh>
+
+#include <mln/opt/at.hh>
+
+#include <mln/pw/cst.hh>
+
+#include <mln/util/array.hh>
+#include <mln/util/timer.hh>
+
+#include <mln/value/label_8.hh>
+#include <mln/value/rgb8.hh>
+#include <mln/value/rgb.hh>
+#include <mln/value/int_u.hh>
+
+
+// n < 8, n is the degree of quantification
+template <unsigned n>
+unsigned count_image_color(const std::string& image)
+{
+ 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_rgb8> t_image2d_rgb8;
+ typedef mln::image2d<t_rgbn> t_image2d_rgbn;
+ 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;
+ typedef mln::accu::meta::math::count t_count_fun;
+
+ t_image2d_rgb8 input_rgb8;
+ t_image2d_rgbn input_rgbn;
+ t_image2d_rgbn output_rgbn;
+ t_histo3d histo;
+ t_histo3d opened;
+
+ mln::io::ppm::load(input_rgb8, image.c_str());
+
+ unsigned nb_pixel = input_rgb8.ncols() * input_rgb8.nrows();
+// unsigned min_volume = (unsigned)(nb_pixel * 0.054);
+ unsigned nb_color = 0;
+
+ input_rgbn = mln::data::transform(input_rgb8, t_rgb8_to_rgbn());
+ histo = mln::data::compute(t_histo3d_fun(), input_rgbn);
+ nb_color = mln::data::compute(t_count_fun(),
+ (histo | (mln::pw::value(histo) != 0)).rw());
+
+ return nb_color;
+}
+
+
+int main()
+{
+ unsigned val = count_image_color<8>(ANNOTING_PHOTO_IMG_PATH "/photo01.ppm");
+
+ std::cout << "nb color : " << val << std::endl;
+
+ return 0;
+}
+
diff --git a/milena/sandbox/green/demo/annoting/bic/Makefile.am b/milena/sandbox/green/demo/annoting/stddev_color/Makefile.am
similarity index 100%
copy from milena/sandbox/green/demo/annoting/bic/Makefile.am
copy to milena/sandbox/green/demo/annoting/stddev_color/Makefile.am
diff --git a/milena/sandbox/green/demo/annoting/stddev_color/stddev_color.cc b/milena/sandbox/green/demo/annoting/stddev_color/stddev_color.cc
new file mode 100644
index 0000000..0782e9c
--- /dev/null
+++ b/milena/sandbox/green/demo/annoting/stddev_color/stddev_color.cc
@@ -0,0 +1,124 @@
+// COMPUTING THE STDEV OF THE COLORS
+
+#include <iostream>
+#include <sstream>
+
+#include <mln/img_path.hh>
+
+#include <mln/accu/max_site.hh>
+#include <mln/accu/stat/histo1d.hh>
+
+#include <mln/core/macros.hh>
+#include <mln/core/image/image1d.hh>
+#include <mln/core/image/image2d.hh>
+#include <mln/core/image/image3d.hh>
+
+#include <mln/debug/println.hh>
+
+#include <mln/data/compute.hh>
+#include <mln/data/fill.hh>
+#include <mln/data/transform.hh>
+
+#include <mln/fun/v2v/rgb8_to_int_u8.hh>
+
+#include <mln/io/ppm/load.hh>
+#include <mln/io/pgm/save.hh>
+#include <mln/io/plot/save_image_sh.hh>
+
+#include <mln/math/sqr.hh>
+
+#include <mln/opt/at.hh>
+
+#include <mln/value/rgb8.hh>
+#include <mln/value/int_u.hh>
+
+
+// FIXME REPARER L'ACCUMULATEUR MAX_SITE
+// FIXME PENSER LA VARIANCE SUR UN HISTOGRAMME NORMALISE, VOIR LES RESULTATS
+
+float r(short p, unsigned histo_p, short x, unsigned histo_x)
+{
+ float result = mln::math::sqr(((float)histo_x / histo_p) * (x-p));
+
+ return result;
+}
+
+unsigned stddev_color(const std::string& image)
+{
+ typedef mln::point1d t_point1d;
+ typedef mln::value::rgb8 t_rgb8;
+ typedef mln::value::int_u8 t_int_u8;
+ typedef mln::image2d<t_rgb8> t_image2d_rgb8;
+ typedef mln::image2d<t_int_u8> t_image2d_int_u8;
+ typedef mln::image1d<unsigned> t_histo1d;
+ typedef mln::fun::v2v::rgb8_to_int_u8 t_rgb8_to_int_u8;
+ typedef mln::accu::meta::stat::histo1d t_histo1d_fun;
+ typedef mln::accu::max_site<t_histo1d> t_max_site_fun;
+
+ t_image2d_rgb8 input_rgb8;
+ t_image2d_int_u8 input_int_u8;
+ t_histo1d histo;
+ t_point1d max_site;
+
+ mln::io::ppm::load(input_rgb8, image.c_str());
+ input_int_u8 = mln::data::transform(input_rgb8, t_rgb8_to_int_u8());
+ histo = mln::data::compute(t_histo1d_fun(), input_int_u8);
+
+ mln::io::pgm::save(input_int_u8, "tmp.pgm");
+ mln::io::plot::save_image_sh(histo, "histo.sh");
+ mln::debug::println(histo);
+
+ // Find the peak of the histogram
+ unsigned v_max = mln::opt::at(histo, 0);
+ short p_max = 0;
+
+ mln_piter_(t_histo1d) p(histo.domain());
+
+ for_all(p)
+ {
+ if (v_max < histo(p))
+ {
+ v_max = histo(p);
+ p_max = p.ind();
+ }
+ }
+
+ // Compute the specific stddev
+
+ float stddev_low = 0.0;
+ float stddev_up = 0.0;
+ float stddev = 0.0;
+
+ if (250 > p_max)
+ for (short i = p_max+1; i < p_max+6; ++i)
+ stddev_up += r(p_max, mln::opt::at(histo,p_max),
+ i, mln::opt::at(histo,i));
+
+ if (5 < p_max)
+ for (short i = p_max-1; i > p_max-6; --i)
+ stddev_low += r(p_max, mln::opt::at(histo,p_max),
+ i, mln::opt::at(histo,i));
+
+ stddev = (250 < p_max)? stddev_low : (5 > p_max)? stddev_up :
+ (stddev_low + stddev_up)/2;
+
+ std::cout << "max_site : " << p_max << std::endl;
+ std::cout << "h(max_site) : " << v_max << std::endl;
+ std::cout << "stddev_up : " << stddev_up << std::endl;
+ std::cout << "stddev_low : " << stddev_low << std::endl;
+ std::cout << "stddev : " << stddev << std::endl;
+
+ return 0;
+}
+
+
+int main()
+{
+// unsigned val = stdev_color(ANNOTING_PHOTO_IMG_PATH "/photo01.ppm");
+ unsigned val = stddev_color(ANNOTING_LOGO_IMG_PATH "/logo06.ppm");
+
+// std::cout << "nb color : " << val << std::endl;
+
+ return 0;
+}
+
--
1.5.6.5
1
0
30 Jun '10
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Olena, a generic and efficient image processing platform".
The branch exp/scribo-z has been updated
via 58e82cd9f7d25b6aafb2085c4ace86d1819b5e1f (commit)
via 218a6951a1b0d51f35faf440a0938ffc57e6fc69 (commit)
via 2290b5c217d1aff34973686b4ca20ac907b088b1 (commit)
via 3586ef11c3c314352893a9239f16679657d12d5f (commit)
via 681f2578cf36e5d15de8744b5a7dd92bfdc4fc4c (commit)
via 1307e9db8d14cfc6dff52604e561b71388e44f58 (commit)
via 71f26fd56cb0b4ce501d5b268110a7cba2580c26 (commit)
via ad5614ea5041d342b336310eb72fc632e85d92fe (commit)
via 125df33ea1757903b9ae2078ff37cda45ab1fc0c (commit)
via b9a5b97f58655d268aea57a5b3d625f8fedae6ee (commit)
via d169338813844bac2932789235e76482922b0d5e (commit)
via 241c2467d08dc42b87d25a93f2606c1d46d835d2 (commit)
via f5c0ae5a9385033e13a8f7d639f26f7c3114854e (commit)
via 7e1a2f88f9f363580adf64244448a04b2fed8588 (commit)
via 31925d2882a55285b496a5efb040875eeceee85e (commit)
via b15c1b6b4c6eb9cb7dda58a28bb93695feb7c463 (commit)
via 288d44d51e20f1d602c0b6b2f2d3cadb5cc4ba1d (commit)
via 4d87541b98ba8e496d125c80c83ad20fbfbb8fb3 (commit)
via b57d26e949bf2f7993b86a1df34d12c0e27f581d (commit)
via 17304c0d1e2e0f089a7fba4a319c85c401b78a71 (commit)
via 5179913a9ef7ad087e49b617e185ea77bef3bd4e (commit)
via 7c558b5f8ddad2675f221439e6cc05c131c41306 (commit)
via fe92959d0b991dc4af32354a5aaecebe4a2496e7 (commit)
via 5fa09b417ceab47852ce77832d504474b37911c0 (commit)
via b4195d21051065f1793d03ac2fc8473979eb3d85 (commit)
via f3987ed3d3aa9063ae36e632d59f56c0fed6ef71 (commit)
via 7570d066d5b6867ec467c65577b856552eb7959f (commit)
via b98887a266675d0408c9a5e206e01e8c05141350 (commit)
via 07b0d845a4695de07897a0550f3cf88e90bf71ba (commit)
via e9bf3efcc6957e3e0d0b37228e0060cee5315c66 (commit)
via 26fd960b08963a21dcc2b55b6618bc0fb03f1721 (commit)
via f8c67ca6812d33f6e758d02b52306be5337357ec (commit)
via 34bcc24494086059cddc9563bfc74d7d41c92062 (commit)
via 00152b7b89d4690e7e1fe0ac252096d834360917 (commit)
via 53630924d3586513a4979ad9ba76ec975a7d4d6f (commit)
via 65586d1b604614ab2072306198b2418b222901e6 (commit)
via 8adc20194128cd40b88e9d531541067d9c07f90a (commit)
via e6a836cee6c68ad1fb50e38754ac5c0a0a7c6236 (commit)
via 993461bf6f0e721d96fd483df3c461a7f37c7ea5 (commit)
via 60fefaa2e97f9a9dac00d2404fa4ce730cd171b0 (commit)
via 4b0e1fb92f24d116e8df227786eae369f1b8f615 (commit)
via 2f0e11309514214cd1be0c8c565183bd001cc1b6 (commit)
via 224e84a64d1844494f71173a154fbec87927da4b (commit)
via 81d685024b4321859625cf173903e176cbf6ecbe (commit)
from 543d805e7b099357ba92802493be73e39a71687c (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
58e82cd Add some futur materials on regional maxima.
218a695 Implement the kmean algorithh and start to optimize it.
2290b5c Import files from milena/sandbox/green.
3586ef1 Simple integration test.
681f257 Fix the way to convert unsigned to float.
1307e9d Add milena library components.
71f26fd Work on Millet value descriptor.
ad5614e Work on Millet saturation descriptor.
125df33 Work on Millet saturation descriptor.
b9a5b97 Work on Millet hsv descriptors.
d169338 Work on histograms view as density.
241c246 Test error quantification as a color descriptor in our database.
f5c0ae5 Benchmark few descriptors.
7e1a2f8 Test on image database the achromatism descriptor.
31925d2 Turn around Millet 2008 hsv descriptors.
b15c1b6 Delete BUG image file in milena/img.
288d44d Save Theo's exhaustive demonstration results.
4d87541 Fix bugs in the histogram visualization tools.
b57d26e Fix last details in the image processing chain.
17304c0 Extend the histogram visualization tools for new projection concept.
5179913 Build translation table between number of pixels and percentage of
7c558b5 Split the regional maxima binary in small atomic binaries.
fe92959 Write the opening volume thresholds for the scribo image mp00082c.ppm.
5fa09b4 Experiment various quantifications on regional maxima labeling.
b4195d2 Experiment variation on regional maxima labeling.
f3987ed Fix the right behaviour of the regmax software.
7570d06 Fix bug in the direction of projection.
b98887a Fix bugs in regional_maxima routine, work with rgb8 for stats.
07b0d84 Test the local deviation operator (Millet2008) on the annotating base.
e9bf3ef Introduce the local deviation operator (Millet2008) which
26fd960 Group Millet2008 documentation files.
f8c67ca Correct typo into directories.
34bcc24 2009-12-15 green <jacquelet(a)lrde.epita.fr>
00152b7 2009-12-15 green <jacquelet(a)lrde.epita.fr>
5363092 2009-12-15 Yann Jacquelet <jacquelet(a)lrde.epita.fr>
65586d1 Test clipart operators described by Millet on annoting database.
8adc201 2009-12-15 Yann Jacquelet <jacquelet(a)lrde.epita.fr>
e6a836c 2009-12-02 Yann Jacquelet <jacquelet(a)lrde.epita.fr>
993461b Test experimentation with regmax code on annoting database.
60fefaa Transform kmean object in a big function and then a canvas.
4b0e1fb Benchmark on distance, preliminary work before optimizing kmean.
2f0e113 Works on Millet2008 descriptors.
224e84a Extend the test image database.
81d6850 Fix the outside template use case for the convolve macros.
-----------------------------------------------------------------------
Summary of changes:
milena/ChangeLog | 15 +
milena/img/BUG_lean_ascii.pgm.gz | Bin 75726 -> 0 bytes
milena/mln/convert/from_to.hxx | 4 +
milena/mln/convert/impl/from_unsigned_to_value.hh | 10 +
milena/mln/linear/ch_convolve.hh | 9 +-
milena/sandbox/ChangeLog | 524 +++++++++
.../green/bench/transform/distance/Makefile.am | 150 +++
.../green/bench/transform/distance/distance.cc | 775 +++++++++++++
.../sandbox/green/demo/annotating/bic/Makefile.am | 150 +++
milena/sandbox/green/demo/annotating/bic/bic.cc | 87 ++
.../sandbox/green/demo/annotating/hsv/Makefile.am | 152 +++
milena/sandbox/green/demo/annotating/hsv/hsv.cc | 607 ++++++++++
.../sandbox/green/demo/annotating/lep/Makefile.am | 150 +++
milena/sandbox/green/demo/annotating/lep/lep.cc | 92 ++
.../green/demo/annotating/nb_color/Makefile.am | 150 +++
.../green/demo/annotating/nb_color/nb_color.cc | 101 ++
.../green/demo/annotating/project/Makefile.am | 150 +++
.../green/demo/annotating/project/project.cc | 210 ++++
.../green/demo/annotating/rgb_64/Makefile.am | 150 +++
.../sandbox/green/demo/annotating/rgb_64/rgb_64.cc | 47 +
.../green/demo/annotating/rgb_64_9/Makefile.am | 150 +++
.../green/demo/annotating/rgb_64_9/rgb_64_9.cc | 97 ++
.../green/demo/annotating/stddev_color/Makefile.am | 150 +++
.../demo/annotating/stddev_color/stddev_color.cc | 124 ++
.../demo/annotating/stddev_color_16/Makefile.am | 150 +++
.../annotating/stddev_color_16/stddev_color_16.cc | 178 +++
.../histo2d => clustering/kmean_rgb}/Makefile.am | 0
.../green/demo/clustering/kmean_rgb/kmean_rgb.cc | 91 ++
.../demo/labeling/regional_maxima/Makefile.am | 2 +
.../labeling/regional_maxima/regional_maxima.cc | 906 +++++++++++----
.../demo/labeling/regional_maxima/thresholds.txt | 42 +
milena/sandbox/green/doc/annotating/class.txt | 42 +
.../green/doc/annotating/syntheseMillet2008.txt | 283 +++++
milena/sandbox/green/doc/annotating/testMillet2008 | 69 ++
.../doc/regional_maxima/cmp_method/h0_input.pgm.gz | Bin 0 -> 18078 bytes
.../doc/regional_maxima/cmp_method/h2_mean.pgm.gz | Bin 0 -> 374 bytes
.../doc/regional_maxima/cmp_method/h2_merge.pgm.gz | Bin 0 -> 4491 bytes
.../doc/regional_maxima/cmp_method/h3_mean.pgm.gz | Bin 0 -> 391 bytes
.../doc/regional_maxima/cmp_method/h3_merge.pgm.gz | Bin 0 -> 10188 bytes
.../doc/regional_maxima/cmp_method/h4_mean.pgm.gz | Bin 0 -> 367 bytes
.../doc/regional_maxima/cmp_method/h4_merge.pgm.gz | Bin 0 -> 18078 bytes
.../doc/regional_maxima/cmp_method/h5_mean.pgm.gz | Bin 0 -> 372 bytes
.../doc/regional_maxima/cmp_method/h5_merge.pgm.gz | Bin 0 -> 12777 bytes
.../doc/regional_maxima/cmp_method/i2_mean.ppm.gz | Bin 0 -> 566650 bytes
.../doc/regional_maxima/cmp_method/i2_merge.ppm.gz | Bin 0 -> 1586150 bytes
.../doc/regional_maxima/cmp_method/i3_mean.ppm.gz | Bin 0 -> 573407 bytes
.../doc/regional_maxima/cmp_method/i3_merge.ppm.gz | Bin 0 -> 3050979 bytes
.../doc/regional_maxima/cmp_method/i4_mean.ppm.gz | Bin 0 -> 663621 bytes
.../doc/regional_maxima/cmp_method/i4_merge.ppm.gz | Bin 0 -> 3387044 bytes
.../doc/regional_maxima/cmp_method/i5_mean.ppm.gz | Bin 0 -> 653140 bytes
.../doc/regional_maxima/cmp_method/i5_merge.ppm.gz | Bin 0 -> 3217839 bytes
.../doc/regional_maxima/cmp_method/l2_input.pgm.gz | Bin 0 -> 423612 bytes
.../doc/regional_maxima/cmp_method/l3_input.pgm.gz | Bin 0 -> 420801 bytes
.../doc/regional_maxima/cmp_method/l4_input.pgm.gz | Bin 0 -> 486206 bytes
.../doc/regional_maxima/cmp_method/l5_input.pgm.gz | Bin 0 -> 479055 bytes
.../regional_maxima/cmp_method/reponse_theo.eml | 106 ++
.../doc/regional_maxima/cmp_method/s2_histo.txt | 31 +
.../doc/regional_maxima/cmp_method/s3_histo.txt | 31 +
.../doc/regional_maxima/cmp_method/s4_histo.txt | 31 +
.../doc/regional_maxima/cmp_method/s5_histo.txt | 31 +
.../doc/regional_maxima/cmp_method/synthese.txt | 223 ++++
.../doc/regional_maxima/cmp_quant/h0_input.pgm.gz | Bin 0 -> 18078 bytes
.../regional_maxima/cmp_quant/h5_mean_q2.pgm.gz | Bin 0 -> 247 bytes
.../regional_maxima/cmp_quant/h5_mean_q3.pgm.gz | Bin 0 -> 280 bytes
.../regional_maxima/cmp_quant/h5_mean_q4.pgm.gz | Bin 0 -> 319 bytes
.../regional_maxima/cmp_quant/h5_mean_q5.pgm.gz | Bin 0 -> 375 bytes
.../regional_maxima/cmp_quant/h5_mean_q6.pgm.gz | Bin 0 -> 392 bytes
.../regional_maxima/cmp_quant/h5_mean_q7.pgm.gz | Bin 0 -> 383 bytes
.../regional_maxima/cmp_quant/h5_mean_q8.pgm.gz | Bin 0 -> 470 bytes
.../regional_maxima/cmp_quant/h5_merge_q2.pgm.gz | Bin 0 -> 18081 bytes
.../regional_maxima/cmp_quant/h5_merge_q3.pgm.gz | Bin 0 -> 18081 bytes
.../regional_maxima/cmp_quant/h5_merge_q4.pgm.gz | Bin 0 -> 16358 bytes
.../regional_maxima/cmp_quant/h5_merge_q5.pgm.gz | Bin 0 -> 12780 bytes
.../regional_maxima/cmp_quant/h5_merge_q6.pgm.gz | Bin 0 -> 9694 bytes
.../regional_maxima/cmp_quant/h5_merge_q7.pgm.gz | Bin 0 -> 6211 bytes
.../regional_maxima/cmp_quant/h5_merge_q8.pgm.gz | Bin 0 -> 1564 bytes
.../regional_maxima/cmp_quant/i5_mean_q2.ppm.gz | Bin 0 -> 112779 bytes
.../regional_maxima/cmp_quant/i5_mean_q3.ppm.gz | Bin 0 -> 191264 bytes
.../regional_maxima/cmp_quant/i5_mean_q4.ppm.gz | Bin 0 -> 298062 bytes
.../regional_maxima/cmp_quant/i5_mean_q5.ppm.gz | Bin 0 -> 653143 bytes
.../regional_maxima/cmp_quant/i5_mean_q6.ppm.gz | Bin 0 -> 807617 bytes
.../regional_maxima/cmp_quant/i5_mean_q7.ppm.gz | Bin 0 -> 813222 bytes
.../regional_maxima/cmp_quant/i5_mean_q8.ppm.gz | Bin 0 -> 861711 bytes
.../regional_maxima/cmp_quant/i5_merge_q2.ppm.gz | Bin 0 -> 3387047 bytes
.../regional_maxima/cmp_quant/i5_merge_q3.ppm.gz | Bin 0 -> 3387047 bytes
.../regional_maxima/cmp_quant/i5_merge_q4.ppm.gz | Bin 0 -> 3355365 bytes
.../regional_maxima/cmp_quant/i5_merge_q5.ppm.gz | Bin 0 -> 3217842 bytes
.../regional_maxima/cmp_quant/i5_merge_q6.ppm.gz | Bin 0 -> 3033730 bytes
.../regional_maxima/cmp_quant/i5_merge_q7.ppm.gz | Bin 0 -> 2295150 bytes
.../regional_maxima/cmp_quant/i5_merge_q8.ppm.gz | Bin 0 -> 1319396 bytes
.../regional_maxima/cmp_quant/l5_input_q2.pgm.gz | Bin 0 -> 83951 bytes
.../regional_maxima/cmp_quant/l5_input_q3.pgm.gz | Bin 0 -> 143817 bytes
.../regional_maxima/cmp_quant/l5_input_q4.pgm.gz | Bin 0 -> 220346 bytes
.../regional_maxima/cmp_quant/l5_input_q5.pgm.gz | Bin 0 -> 479058 bytes
.../regional_maxima/cmp_quant/l5_input_q6.pgm.gz | Bin 0 -> 593359 bytes
.../regional_maxima/cmp_quant/l5_input_q7.pgm.gz | Bin 0 -> 600121 bytes
.../regional_maxima/cmp_quant/l5_input_q8.pgm.gz | Bin 0 -> 630760 bytes
.../doc/regional_maxima/cmp_quant/s5_histo_q2.txt | 3 +
.../doc/regional_maxima/cmp_quant/s5_histo_q3.txt | 8 +
.../doc/regional_maxima/cmp_quant/s5_histo_q4.txt | 18 +
.../doc/regional_maxima/cmp_quant/s5_histo_q5.txt | 33 +
.../doc/regional_maxima/cmp_quant/s5_histo_q6.txt | 33 +
.../doc/regional_maxima/cmp_quant/s5_histo_q7.txt | 32 +
.../doc/regional_maxima/cmp_quant/s5_histo_q8.txt | 75 ++
.../doc/regional_maxima/cmp_quant/synthese.txt | 205 ++++
.../mp00411c/colormap_all_q4.txt.gz | Bin 0 -> 187 bytes
.../mp00411c/colormap_all_q5.txt.gz | Bin 0 -> 420 bytes
.../mp00411c/colormap_thick_q4.txt.gz | Bin 0 -> 159 bytes
.../mp00411c/colormap_thick_q5.txt.gz | Bin 0 -> 352 bytes
.../mp00411c/colormap_thin_q4.txt.gz | Bin 0 -> 173 bytes
.../mp00411c/colormap_thin_q5.txt.gz | Bin 0 -> 366 bytes
.../regional_maxima/mp00411c/histo_all_q4.dump.gz | Bin 0 -> 1233 bytes
.../regional_maxima/mp00411c/histo_all_q5.dump.gz | Bin 0 -> 4779 bytes
.../mp00411c/histo_thick_q4.dump.gz | Bin 0 -> 781 bytes
.../mp00411c/histo_thick_q5.dump.gz | Bin 0 -> 2532 bytes
.../regional_maxima/mp00411c/histo_thin_q4.dump.gz | Bin 0 -> 901 bytes
.../regional_maxima/mp00411c/histo_thin_q5.dump.gz | Bin 0 -> 2976 bytes
.../doc/regional_maxima/mp00411c/iz_all_q4.dump.gz | Bin 0 -> 659040 bytes
.../doc/regional_maxima/mp00411c/iz_all_q5.dump.gz | Bin 0 -> 1505619 bytes
.../regional_maxima/mp00411c/iz_thick_q4.dump.gz | Bin 0 -> 482831 bytes
.../regional_maxima/mp00411c/iz_thick_q5.dump.gz | Bin 0 -> 1414258 bytes
.../regional_maxima/mp00411c/iz_thin_q4.dump.gz | Bin 0 -> 647722 bytes
.../regional_maxima/mp00411c/iz_thin_q5.dump.gz | Bin 0 -> 1458415 bytes
.../mp00411c/labeled_all_q4.dump.gz | Bin 0 -> 149 bytes
.../mp00411c/labeled_all_q5.dump.gz | Bin 0 -> 343 bytes
.../mp00411c/labeled_thick_q4.dump.gz | Bin 0 -> 149 bytes
.../mp00411c/labeled_thick_q5.dump.gz | Bin 0 -> 309 bytes
.../mp00411c/labeled_thin_q4.dump.gz | Bin 0 -> 149 bytes
.../mp00411c/labeled_thin_q5.dump.gz | Bin 0 -> 308 bytes
.../regional_maxima/mp00411c/mean3_all_q4.ppm.gz | Bin 0 -> 985276 bytes
.../regional_maxima/mp00411c/mean3_all_q5.ppm.gz | Bin 0 -> 1961577 bytes
.../regional_maxima/mp00411c/mean3_thick_q4.ppm.gz | Bin 0 -> 865034 bytes
.../regional_maxima/mp00411c/mean3_thick_q5.ppm.gz | Bin 0 -> 1831699 bytes
.../regional_maxima/mp00411c/mean3_thin_q4.ppm.gz | Bin 0 -> 958289 bytes
.../regional_maxima/mp00411c/mean3_thin_q5.ppm.gz | Bin 0 -> 1872271 bytes
.../regional_maxima/mp00411c/mean4_all_q4.ppm.gz | Bin 0 -> 772605 bytes
.../regional_maxima/mp00411c/mean4_all_q5.ppm.gz | Bin 0 -> 1852455 bytes
.../regional_maxima/mp00411c/mean4_thick_q4.ppm.gz | Bin 0 -> 559850 bytes
.../regional_maxima/mp00411c/mean4_thick_q5.ppm.gz | Bin 0 -> 1727247 bytes
.../regional_maxima/mp00411c/mean4_thin_q4.ppm.gz | Bin 0 -> 760428 bytes
.../regional_maxima/mp00411c/mean4_thin_q5.ppm.gz | Bin 0 -> 1781495 bytes
.../doc/regional_maxima/mp00411c/mp00411c.ppm.gz | Bin 0 -> 5316204 bytes
.../doc/regional_maxima/mp00411c/mp00411c.sh.gz | Bin 0 -> 636 bytes
.../regional_maxima/mp00411c/mp00411c_thick.pbm.gz | Bin 0 -> 190478 bytes
.../regional_maxima/mp00411c/mp00411c_thin.pbm.gz | Bin 0 -> 248730 bytes
.../regional_maxima/mp00411c/opened_all_q4.dump.gz | Bin 0 -> 1159 bytes
.../regional_maxima/mp00411c/opened_all_q5.dump.gz | Bin 0 -> 4531 bytes
.../mp00411c/opened_thick_q4.dump.gz | Bin 0 -> 747 bytes
.../mp00411c/opened_thick_q5.dump.gz | Bin 0 -> 2351 bytes
.../mp00411c/opened_thin_q4.dump.gz | Bin 0 -> 848 bytes
.../mp00411c/opened_thin_q5.dump.gz | Bin 0 -> 2772 bytes
.../regional_maxima/mp00411c/proj1_all_q4.pgm.gz | Bin 0 -> 343 bytes
.../regional_maxima/mp00411c/proj1_all_q5.pgm.gz | Bin 0 -> 779 bytes
.../regional_maxima/mp00411c/proj1_thick_q4.pgm.gz | Bin 0 -> 312 bytes
.../regional_maxima/mp00411c/proj1_thick_q5.pgm.gz | Bin 0 -> 612 bytes
.../regional_maxima/mp00411c/proj1_thin_q4.pgm.gz | Bin 0 -> 339 bytes
.../regional_maxima/mp00411c/proj1_thin_q5.pgm.gz | Bin 0 -> 718 bytes
.../regional_maxima/mp00411c/proj2_all_q4.pgm.gz | Bin 0 -> 338 bytes
.../regional_maxima/mp00411c/proj2_all_q5.pgm.gz | Bin 0 -> 750 bytes
.../regional_maxima/mp00411c/proj2_thick_q4.pgm.gz | Bin 0 -> 315 bytes
.../regional_maxima/mp00411c/proj2_thick_q5.pgm.gz | Bin 0 -> 606 bytes
.../regional_maxima/mp00411c/proj2_thin_q4.pgm.gz | Bin 0 -> 331 bytes
.../regional_maxima/mp00411c/proj2_thin_q5.pgm.gz | Bin 0 -> 693 bytes
.../regional_maxima/mp00411c/proj3_all_q4.ppm.gz | Bin 0 -> 230 bytes
.../regional_maxima/mp00411c/proj3_all_q5.ppm.gz | Bin 0 -> 401 bytes
.../regional_maxima/mp00411c/proj3_thick_q4.ppm.gz | Bin 0 -> 224 bytes
.../regional_maxima/mp00411c/proj3_thick_q5.ppm.gz | Bin 0 -> 343 bytes
.../regional_maxima/mp00411c/proj3_thin_q4.ppm.gz | Bin 0 -> 229 bytes
.../regional_maxima/mp00411c/proj3_thin_q5.ppm.gz | Bin 0 -> 359 bytes
.../regional_maxima/mp00411c/proj4_all_q4.ppm.gz | Bin 0 -> 252 bytes
.../regional_maxima/mp00411c/proj4_all_q5.ppm.gz | Bin 0 -> 447 bytes
.../regional_maxima/mp00411c/proj4_thick_q4.ppm.gz | Bin 0 -> 221 bytes
.../regional_maxima/mp00411c/proj4_thick_q5.ppm.gz | Bin 0 -> 369 bytes
.../regional_maxima/mp00411c/proj4_thin_q4.ppm.gz | Bin 0 -> 234 bytes
.../regional_maxima/mp00411c/proj4_thin_q5.ppm.gz | Bin 0 -> 415 bytes
.../doc/regional_maxima/mp00411c/quant_q4.ppm.gz | Bin 0 -> 2590062 bytes
.../doc/regional_maxima/mp00411c/quant_q5.ppm.gz | Bin 0 -> 3775184 bytes
.../regional_maxima/mp00411c/stats3_all_q4.txt.gz | Bin 0 -> 292 bytes
.../regional_maxima/mp00411c/stats3_all_q5.txt.gz | Bin 0 -> 701 bytes
.../mp00411c/stats3_thick_q4.txt.gz | Bin 0 -> 244 bytes
.../mp00411c/stats3_thick_q5.txt.gz | Bin 0 -> 584 bytes
.../regional_maxima/mp00411c/stats3_thin_q4.txt.gz | Bin 0 -> 262 bytes
.../regional_maxima/mp00411c/stats3_thin_q5.txt.gz | Bin 0 -> 606 bytes
.../regional_maxima/mp00411c/stats4_all_q4.txt.gz | Bin 0 -> 284 bytes
.../regional_maxima/mp00411c/stats4_all_q5.txt.gz | Bin 0 -> 704 bytes
.../mp00411c/stats4_thick_q4.txt.gz | Bin 0 -> 234 bytes
.../mp00411c/stats4_thick_q5.txt.gz | Bin 0 -> 580 bytes
.../regional_maxima/mp00411c/stats4_thin_q4.txt.gz | Bin 0 -> 255 bytes
.../regional_maxima/mp00411c/stats4_thin_q5.txt.gz | Bin 0 -> 591 bytes
.../doc/regional_maxima/mp00411c/synthese.txt.gz | Bin 0 -> 4062 bytes
.../green/exp/annotating/achromastism/Makefile.am | 153 +++
.../exp/annotating/achromastism/achromastism.cc | 113 ++
.../exp/annotating/achromastism/text-color.txt | 15 +
.../green/exp/annotating/achromastism/text-img.txt | 40 +
.../exp/annotating/achromastism/text-only.txt | 8 +
.../sandbox/green/exp/annotating/bench/Makefile.am | 153 +++
milena/sandbox/green/exp/annotating/bench/bench.cc | 1213 ++++++++++++++++++++
.../sandbox/green/exp/annotating/error/Makefile.am | 153 +++
milena/sandbox/green/exp/annotating/error/error.cc | 700 +++++++++++
.../sandbox/green/exp/annotating/histo/Makefile.am | 153 +++
milena/sandbox/green/exp/annotating/histo/histo.cc | 306 +++++
.../sandbox/green/exp/annotating/hsv/Makefile.am | 153 +++
milena/sandbox/green/exp/annotating/hsv/hsv.cc | 652 +++++++++++
.../sandbox/green/exp/annotating/hue/Makefile.am | 153 +++
milena/sandbox/green/exp/annotating/hue/hue.cc | 291 +++++
.../green/exp/annotating/hue/text-color.txt | 15 +
.../sandbox/green/exp/annotating/hue/text-img.txt | 40 +
.../sandbox/green/exp/annotating/hue/text-only.txt | 8 +
.../green/exp/annotating/nb_color/Makefile.am | 151 +++
.../green/exp/annotating/nb_color/nb_color.cc | 131 +++
.../green/exp/annotating/saturation/Makefile.am | 153 +++
.../green/exp/annotating/saturation/saturation.cc | 119 ++
.../green/exp/annotating/saturation/text-color.txt | 15 +
.../green/exp/annotating/saturation/text-img.txt | 40 +
.../green/exp/annotating/saturation/text-only.txt | 8 +
.../green/exp/annotating/stddev_color/Makefile.am | 151 +++
.../exp/annotating/stddev_color/stddev_color.cc | 153 +++
.../exp/annotating/stddev_color_16/Makefile.am | 151 +++
.../annotating/stddev_color_16/stddev_color_16.cc | 195 ++++
.../sandbox/green/exp/annotating/value/Makefile.am | 153 +++
.../green/exp/annotating/value/text-color.txt | 15 +
.../green/exp/annotating/value/text-img.txt | 40 +
.../green/exp/annotating/value/text-only.txt | 8 +
milena/sandbox/green/exp/annotating/value/value.cc | 316 +++++
.../green/exp/labeling/regional_maxima/Makefile.am | 151 +++
.../labeling/regional_maxima/regional_maxima.cc | 156 +++
milena/sandbox/green/mln/accu/stat/histo1d.hh | 66 +-
.../sandbox/green/mln/clustering/kmean_rgb.hh | 0
milena/sandbox/green/mln/display/display_histo.hh | 98 ++-
milena/sandbox/green/mln/display/project_histo.hh | 443 +++++++-
.../sandbox/green/mln/fun/p2b/achromatic.hh | 0
.../sandbox/green/mln/fun/p2b/component_equals.hh | 0
.../sandbox/green/mln/fun/v2v/achromatism.hh | 0
.../sandbox/green/mln/fun/v2v/hue_concentration.hh | 0
.../sandbox/green/mln/fun/v2v/rgb8_to_int_u8.hh | 0
.../green/mln/fun/v2v/rgb_to_achromatism_map.hh | 0
.../sandbox/green/mln/fun/v2v/rgb_to_hsv.hh | 0
.../sandbox/green/mln/fun/v2v/rgb_to_hue_map.hh | 0
.../green/mln/fun/v2v/rgb_to_saturation_map.hh | 0
.../sandbox/green/mln/fun/v2v/rgb_to_value_map.hh | 0
milena/sandbox/green/mln/img_path.hh | 221 ++++-
{scribo => milena}/sandbox/green/mln/math/ceil.hh | 0
{scribo => milena}/sandbox/green/mln/math/floor.hh | 0
{scribo => milena}/sandbox/green/mln/value/hsv.hh | 0
.../green/tools/annotating/histo/Makefile.am | 150 +++
.../sandbox/green/tools/annotating/histo/histo.cc | 143 +++
.../sandbox/green/tools/annotating/iz/Makefile.am | 150 +++
milena/sandbox/green/tools/annotating/iz/iz.cc | 373 ++++++
.../green/tools/annotating/opening/Makefile.am | 150 +++
.../green/tools/annotating/opening/opening.cc | 111 ++
.../green/tools/annotating/regmax/Makefile.am | 150 +++
.../green/tools/annotating/regmax/regmax.cc | 328 ++++++
scribo/sandbox/green/ChangeLog | 93 ++
scribo/sandbox/green/README | 219 ++++
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/accu/stat/histo1d.hh | 1 -
scribo/sandbox/green/mln/accu/stat/histo2d.hh | 9 +-
scribo/sandbox/green/mln/accu/stat/histo3d_hsl.hh | 1 +
scribo/sandbox/green/mln/accu/stat/histo3d_rgb.hh | 2 +
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 +-
scribo/sandbox/green/ok/mln/accu/histo/histo1d.hh | 334 ++++++
.../sandbox/green/ok/mln/accu/histo}/histo2d.hh | 0
.../sandbox/green/ok/mln/accu/histo/histo3d.hh | 0
scribo/sandbox/green/{ => ok}/mln/img_path.hh | 0
.../sandbox/green/ok/test/accu/histo}/gaussian.sh | 0
scribo/sandbox/green/ok/test/accu/histo/histo1d | Bin 0 -> 802920 bytes
scribo/sandbox/green/ok/test/accu/histo/histo1d.cc | 726 ++++++++++++
scribo/sandbox/green/test_labelling_2.cc | 342 ++++++
scribo/sandbox/green/test_labelling_3.cc | 463 ++++++++
.../green/tests/clustering/k_mean/Makefile.am | 13 +-
.../green/tests/clustering/k_mean/k_mean.cc | 395 ++++---
.../sandbox/green/use/accu/stat/histo1d/histo1d.cc | 2 -
.../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 ++
299 files changed, 21557 insertions(+), 965 deletions(-)
delete mode 100644 milena/img/BUG_lean_ascii.pgm.gz
create mode 100644 milena/sandbox/green/bench/transform/distance/Makefile.am
create mode 100644 milena/sandbox/green/bench/transform/distance/distance.cc
create mode 100644 milena/sandbox/green/demo/annotating/bic/Makefile.am
create mode 100644 milena/sandbox/green/demo/annotating/bic/bic.cc
create mode 100644 milena/sandbox/green/demo/annotating/hsv/Makefile.am
create mode 100644 milena/sandbox/green/demo/annotating/hsv/hsv.cc
create mode 100644 milena/sandbox/green/demo/annotating/lep/Makefile.am
create mode 100644 milena/sandbox/green/demo/annotating/lep/lep.cc
create mode 100644 milena/sandbox/green/demo/annotating/nb_color/Makefile.am
create mode 100644 milena/sandbox/green/demo/annotating/nb_color/nb_color.cc
create mode 100644 milena/sandbox/green/demo/annotating/project/Makefile.am
create mode 100644 milena/sandbox/green/demo/annotating/project/project.cc
create mode 100644 milena/sandbox/green/demo/annotating/rgb_64/Makefile.am
create mode 100644 milena/sandbox/green/demo/annotating/rgb_64/rgb_64.cc
create mode 100644 milena/sandbox/green/demo/annotating/rgb_64_9/Makefile.am
create mode 100644 milena/sandbox/green/demo/annotating/rgb_64_9/rgb_64_9.cc
create mode 100644 milena/sandbox/green/demo/annotating/stddev_color/Makefile.am
create mode 100644 milena/sandbox/green/demo/annotating/stddev_color/stddev_color.cc
create mode 100644 milena/sandbox/green/demo/annotating/stddev_color_16/Makefile.am
create mode 100644 milena/sandbox/green/demo/annotating/stddev_color_16/stddev_color_16.cc
copy milena/sandbox/green/demo/{accu/stat/histo2d => clustering/kmean_rgb}/Makefile.am (100%)
create mode 100644 milena/sandbox/green/demo/clustering/kmean_rgb/kmean_rgb.cc
create mode 100644 milena/sandbox/green/demo/labeling/regional_maxima/thresholds.txt
create mode 100644 milena/sandbox/green/doc/annotating/class.txt
create mode 100644 milena/sandbox/green/doc/annotating/syntheseMillet2008.txt
create mode 100644 milena/sandbox/green/doc/annotating/testMillet2008
create mode 100644 milena/sandbox/green/doc/regional_maxima/cmp_method/h0_input.pgm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/cmp_method/h2_mean.pgm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/cmp_method/h2_merge.pgm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/cmp_method/h3_mean.pgm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/cmp_method/h3_merge.pgm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/cmp_method/h4_mean.pgm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/cmp_method/h4_merge.pgm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/cmp_method/h5_mean.pgm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/cmp_method/h5_merge.pgm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/cmp_method/i2_mean.ppm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/cmp_method/i2_merge.ppm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/cmp_method/i3_mean.ppm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/cmp_method/i3_merge.ppm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/cmp_method/i4_mean.ppm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/cmp_method/i4_merge.ppm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/cmp_method/i5_mean.ppm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/cmp_method/i5_merge.ppm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/cmp_method/l2_input.pgm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/cmp_method/l3_input.pgm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/cmp_method/l4_input.pgm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/cmp_method/l5_input.pgm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/cmp_method/reponse_theo.eml
create mode 100644 milena/sandbox/green/doc/regional_maxima/cmp_method/s2_histo.txt
create mode 100644 milena/sandbox/green/doc/regional_maxima/cmp_method/s3_histo.txt
create mode 100644 milena/sandbox/green/doc/regional_maxima/cmp_method/s4_histo.txt
create mode 100644 milena/sandbox/green/doc/regional_maxima/cmp_method/s5_histo.txt
create mode 100644 milena/sandbox/green/doc/regional_maxima/cmp_method/synthese.txt
create mode 100644 milena/sandbox/green/doc/regional_maxima/cmp_quant/h0_input.pgm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/cmp_quant/h5_mean_q2.pgm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/cmp_quant/h5_mean_q3.pgm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/cmp_quant/h5_mean_q4.pgm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/cmp_quant/h5_mean_q5.pgm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/cmp_quant/h5_mean_q6.pgm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/cmp_quant/h5_mean_q7.pgm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/cmp_quant/h5_mean_q8.pgm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/cmp_quant/h5_merge_q2.pgm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/cmp_quant/h5_merge_q3.pgm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/cmp_quant/h5_merge_q4.pgm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/cmp_quant/h5_merge_q5.pgm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/cmp_quant/h5_merge_q6.pgm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/cmp_quant/h5_merge_q7.pgm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/cmp_quant/h5_merge_q8.pgm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/cmp_quant/i5_mean_q2.ppm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/cmp_quant/i5_mean_q3.ppm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/cmp_quant/i5_mean_q4.ppm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/cmp_quant/i5_mean_q5.ppm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/cmp_quant/i5_mean_q6.ppm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/cmp_quant/i5_mean_q7.ppm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/cmp_quant/i5_mean_q8.ppm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/cmp_quant/i5_merge_q2.ppm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/cmp_quant/i5_merge_q3.ppm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/cmp_quant/i5_merge_q4.ppm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/cmp_quant/i5_merge_q5.ppm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/cmp_quant/i5_merge_q6.ppm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/cmp_quant/i5_merge_q7.ppm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/cmp_quant/i5_merge_q8.ppm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/cmp_quant/l5_input_q2.pgm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/cmp_quant/l5_input_q3.pgm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/cmp_quant/l5_input_q4.pgm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/cmp_quant/l5_input_q5.pgm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/cmp_quant/l5_input_q6.pgm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/cmp_quant/l5_input_q7.pgm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/cmp_quant/l5_input_q8.pgm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/cmp_quant/s5_histo_q2.txt
create mode 100644 milena/sandbox/green/doc/regional_maxima/cmp_quant/s5_histo_q3.txt
create mode 100644 milena/sandbox/green/doc/regional_maxima/cmp_quant/s5_histo_q4.txt
create mode 100644 milena/sandbox/green/doc/regional_maxima/cmp_quant/s5_histo_q5.txt
create mode 100644 milena/sandbox/green/doc/regional_maxima/cmp_quant/s5_histo_q6.txt
create mode 100644 milena/sandbox/green/doc/regional_maxima/cmp_quant/s5_histo_q7.txt
create mode 100644 milena/sandbox/green/doc/regional_maxima/cmp_quant/s5_histo_q8.txt
create mode 100644 milena/sandbox/green/doc/regional_maxima/cmp_quant/synthese.txt
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/colormap_all_q4.txt.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/colormap_all_q5.txt.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/colormap_thick_q4.txt.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/colormap_thick_q5.txt.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/colormap_thin_q4.txt.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/colormap_thin_q5.txt.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/histo_all_q4.dump.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/histo_all_q5.dump.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/histo_thick_q4.dump.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/histo_thick_q5.dump.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/histo_thin_q4.dump.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/histo_thin_q5.dump.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/iz_all_q4.dump.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/iz_all_q5.dump.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/iz_thick_q4.dump.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/iz_thick_q5.dump.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/iz_thin_q4.dump.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/iz_thin_q5.dump.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/labeled_all_q4.dump.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/labeled_all_q5.dump.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/labeled_thick_q4.dump.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/labeled_thick_q5.dump.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/labeled_thin_q4.dump.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/labeled_thin_q5.dump.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/mean3_all_q4.ppm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/mean3_all_q5.ppm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/mean3_thick_q4.ppm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/mean3_thick_q5.ppm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/mean3_thin_q4.ppm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/mean3_thin_q5.ppm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/mean4_all_q4.ppm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/mean4_all_q5.ppm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/mean4_thick_q4.ppm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/mean4_thick_q5.ppm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/mean4_thin_q4.ppm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/mean4_thin_q5.ppm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/mp00411c.ppm.gz
create mode 100755 milena/sandbox/green/doc/regional_maxima/mp00411c/mp00411c.sh.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/mp00411c_thick.pbm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/mp00411c_thin.pbm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/opened_all_q4.dump.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/opened_all_q5.dump.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/opened_thick_q4.dump.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/opened_thick_q5.dump.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/opened_thin_q4.dump.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/opened_thin_q5.dump.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/proj1_all_q4.pgm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/proj1_all_q5.pgm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/proj1_thick_q4.pgm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/proj1_thick_q5.pgm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/proj1_thin_q4.pgm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/proj1_thin_q5.pgm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/proj2_all_q4.pgm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/proj2_all_q5.pgm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/proj2_thick_q4.pgm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/proj2_thick_q5.pgm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/proj2_thin_q4.pgm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/proj2_thin_q5.pgm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/proj3_all_q4.ppm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/proj3_all_q5.ppm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/proj3_thick_q4.ppm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/proj3_thick_q5.ppm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/proj3_thin_q4.ppm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/proj3_thin_q5.ppm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/proj4_all_q4.ppm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/proj4_all_q5.ppm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/proj4_thick_q4.ppm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/proj4_thick_q5.ppm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/proj4_thin_q4.ppm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/proj4_thin_q5.ppm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/quant_q4.ppm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/quant_q5.ppm.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/stats3_all_q4.txt.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/stats3_all_q5.txt.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/stats3_thick_q4.txt.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/stats3_thick_q5.txt.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/stats3_thin_q4.txt.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/stats3_thin_q5.txt.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/stats4_all_q4.txt.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/stats4_all_q5.txt.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/stats4_thick_q4.txt.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/stats4_thick_q5.txt.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/stats4_thin_q4.txt.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/stats4_thin_q5.txt.gz
create mode 100644 milena/sandbox/green/doc/regional_maxima/mp00411c/synthese.txt.gz
create mode 100644 milena/sandbox/green/exp/annotating/achromastism/Makefile.am
create mode 100644 milena/sandbox/green/exp/annotating/achromastism/achromastism.cc
create mode 100644 milena/sandbox/green/exp/annotating/achromastism/text-color.txt
create mode 100644 milena/sandbox/green/exp/annotating/achromastism/text-img.txt
create mode 100644 milena/sandbox/green/exp/annotating/achromastism/text-only.txt
create mode 100644 milena/sandbox/green/exp/annotating/bench/Makefile.am
create mode 100644 milena/sandbox/green/exp/annotating/bench/bench.cc
create mode 100644 milena/sandbox/green/exp/annotating/error/Makefile.am
create mode 100644 milena/sandbox/green/exp/annotating/error/error.cc
create mode 100644 milena/sandbox/green/exp/annotating/histo/Makefile.am
create mode 100644 milena/sandbox/green/exp/annotating/histo/histo.cc
create mode 100644 milena/sandbox/green/exp/annotating/hsv/Makefile.am
create mode 100644 milena/sandbox/green/exp/annotating/hsv/hsv.cc
create mode 100644 milena/sandbox/green/exp/annotating/hue/Makefile.am
create mode 100644 milena/sandbox/green/exp/annotating/hue/hue.cc
create mode 100644 milena/sandbox/green/exp/annotating/hue/text-color.txt
create mode 100644 milena/sandbox/green/exp/annotating/hue/text-img.txt
create mode 100644 milena/sandbox/green/exp/annotating/hue/text-only.txt
create mode 100644 milena/sandbox/green/exp/annotating/nb_color/Makefile.am
create mode 100644 milena/sandbox/green/exp/annotating/nb_color/nb_color.cc
create mode 100644 milena/sandbox/green/exp/annotating/saturation/Makefile.am
create mode 100644 milena/sandbox/green/exp/annotating/saturation/saturation.cc
create mode 100644 milena/sandbox/green/exp/annotating/saturation/text-color.txt
create mode 100644 milena/sandbox/green/exp/annotating/saturation/text-img.txt
create mode 100644 milena/sandbox/green/exp/annotating/saturation/text-only.txt
create mode 100644 milena/sandbox/green/exp/annotating/stddev_color/Makefile.am
create mode 100644 milena/sandbox/green/exp/annotating/stddev_color/stddev_color.cc
create mode 100644 milena/sandbox/green/exp/annotating/stddev_color_16/Makefile.am
create mode 100644 milena/sandbox/green/exp/annotating/stddev_color_16/stddev_color_16.cc
create mode 100644 milena/sandbox/green/exp/annotating/value/Makefile.am
create mode 100644 milena/sandbox/green/exp/annotating/value/text-color.txt
create mode 100644 milena/sandbox/green/exp/annotating/value/text-img.txt
create mode 100644 milena/sandbox/green/exp/annotating/value/text-only.txt
create mode 100644 milena/sandbox/green/exp/annotating/value/value.cc
create mode 100644 milena/sandbox/green/exp/labeling/regional_maxima/Makefile.am
create mode 100644 milena/sandbox/green/exp/labeling/regional_maxima/regional_maxima.cc
copy {scribo => milena}/sandbox/green/mln/clustering/kmean_rgb.hh (100%)
copy {scribo => milena}/sandbox/green/mln/fun/p2b/achromatic.hh (100%)
copy {scribo => milena}/sandbox/green/mln/fun/p2b/component_equals.hh (100%)
copy {scribo => milena}/sandbox/green/mln/fun/v2v/achromatism.hh (100%)
copy {scribo => milena}/sandbox/green/mln/fun/v2v/hue_concentration.hh (100%)
copy {scribo => milena}/sandbox/green/mln/fun/v2v/rgb8_to_int_u8.hh (100%)
copy {scribo => milena}/sandbox/green/mln/fun/v2v/rgb_to_achromatism_map.hh (100%)
copy {scribo => milena}/sandbox/green/mln/fun/v2v/rgb_to_hsv.hh (100%)
copy {scribo => milena}/sandbox/green/mln/fun/v2v/rgb_to_hue_map.hh (100%)
copy {scribo => milena}/sandbox/green/mln/fun/v2v/rgb_to_saturation_map.hh (100%)
copy {scribo => milena}/sandbox/green/mln/fun/v2v/rgb_to_value_map.hh (100%)
copy {scribo => milena}/sandbox/green/mln/math/ceil.hh (100%)
copy {scribo => milena}/sandbox/green/mln/math/floor.hh (100%)
copy {scribo => milena}/sandbox/green/mln/value/hsv.hh (100%)
create mode 100644 milena/sandbox/green/tools/annotating/histo/Makefile.am
create mode 100644 milena/sandbox/green/tools/annotating/histo/histo.cc
create mode 100644 milena/sandbox/green/tools/annotating/iz/Makefile.am
create mode 100644 milena/sandbox/green/tools/annotating/iz/iz.cc
create mode 100644 milena/sandbox/green/tools/annotating/opening/Makefile.am
create mode 100644 milena/sandbox/green/tools/annotating/opening/opening.cc
create mode 100644 milena/sandbox/green/tools/annotating/regmax/Makefile.am
create mode 100644 milena/sandbox/green/tools/annotating/regmax/regmax.cc
create mode 100644 scribo/sandbox/green/README
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
create mode 100644 scribo/sandbox/green/ok/mln/accu/histo/histo1d.hh
copy {milena/sandbox/green/mln/accu/stat => scribo/sandbox/green/ok/mln/accu/histo}/histo2d.hh (100%)
copy milena/sandbox/green/mln/accu/stat/histo3d_rgb.hh => scribo/sandbox/green/ok/mln/accu/histo/histo3d.hh (100%)
copy scribo/sandbox/green/{ => ok}/mln/img_path.hh (100%)
copy {milena/sandbox/green/tests/accu/stat/histo1d => scribo/sandbox/green/ok/test/accu/histo}/gaussian.sh (100%)
create mode 100755 scribo/sandbox/green/ok/test/accu/histo/histo1d
create mode 100644 scribo/sandbox/green/ok/test/accu/histo/histo1d.cc
create mode 100644 scribo/sandbox/green/test_labelling_2.cc
create mode 100644 scribo/sandbox/green/test_labelling_3.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
hooks/post-receive
--
Olena, a generic and efficient image processing platform
1
0
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Olena, a generic and efficient image processing platform".
The branch exp/green has been updated
via 6db793f7e1bba8cde5c975d2a9fb6521265f551b (commit)
via 456226224a7c2fd96932e9dce71e92bf734ead9c (commit)
from cfc3ef76083def2e08adf726a633919cfd86bd9d (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
6db793f Add some futur materials on regional maxima.
4562262 Implement the kmean algorithh and start to optimize it.
-----------------------------------------------------------------------
Summary of changes:
scribo/sandbox/green/ChangeLog | 84 ++
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 ++-
scribo/sandbox/green/test_labelling_2.cc | 342 ++++++++
scribo/sandbox/green/test_labelling_3.cc | 463 +++++++++++
.../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 ++
34 files changed, 5036 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
create mode 100644 scribo/sandbox/green/test_labelling_2.cc
create mode 100644 scribo/sandbox/green/test_labelling_3.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
hooks/post-receive
--
Olena, a generic and efficient image processing platform
1
0
last-svn-commit-48-g6db793f Add some futur materials on regional maxima.
by Yann Jacquelet 30 Jun '10
by Yann Jacquelet 30 Jun '10
30 Jun '10
* 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
1
0
last-svn-commit-229-g58e82cd Add some futur materials on regional maxima.
by Yann Jacquelet 30 Jun '10
by Yann Jacquelet 30 Jun '10
30 Jun '10
* 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 7106b22..81749fe 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
1
0
last-svn-commit-47-g4562262 Implement the kmean algorithh and start to optimize it.
by Yann Jacquelet 30 Jun '10
by Yann Jacquelet 30 Jun '10
30 Jun '10
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
1
0
last-svn-commit-228-g218a695 Implement the kmean algorithh and start to optimize it.
by Yann Jacquelet 30 Jun '10
by Yann Jacquelet 30 Jun '10
30 Jun '10
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 b557ccf..7106b22 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
1
0
30 Jun '10
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Olena, a generic and efficient image processing platform".
The branch exp/scribo-z has been updated
via 543d805e7b099357ba92802493be73e39a71687c (commit)
from 2f5f4a438accd7aa52c3ac8d3550b70cef778c0e (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
543d805 Extended XML mode support.
-----------------------------------------------------------------------
Summary of changes:
scribo/ChangeLog | 23 +++-
scribo/demo/viewer/Makefile.am | 9 +-
scribo/demo/viewer/common.hh | 26 ++--
scribo/demo/viewer/image_region.cc | 23 ++-
scribo/demo/viewer/image_region.hh | 2 +
scribo/demo/viewer/image_region.hxx | 15 +-
scribo/demo/viewer/image_scene.cc | 72 +++++---
scribo/demo/viewer/image_scene.hh | 2 +
scribo/demo/viewer/key_widget.cc | 29 +++-
scribo/demo/viewer/key_widget.hh | 3 +-
scribo/demo/viewer/viewer.cc | 346 +++++++++++++++++++++++++++--------
scribo/demo/viewer/viewer.hh | 10 +-
12 files changed, 434 insertions(+), 126 deletions(-)
hooks/post-receive
--
Olena, a generic and efficient image processing platform
1
0
30 Jun '10
* scribo/demo/viewer/Makefile.am
* demo/viewer/image_region.cc,
* viewer/image_region.hh,
* viewer/image_region.hxx: Change regions depths to have a hierarchy.
* demo/viewer/image_scene.cc,
* demo/viewer/image_scene.hh: Change mouse click behaviour.
* demo/viewer/key_widget.cc,
* demo/viewer/key_widget.hh: Add new items (text line and paragraph)
* demo/viewer/viewer.cc,
* demo/viewer/viewer.hh: Chnage XML parsing to support extended format.
* scribo/demo/viewer/common.hh: Add new RegionId's.
---
scribo/ChangeLog | 23 +++-
scribo/demo/viewer/Makefile.am | 9 +-
scribo/demo/viewer/common.hh | 26 ++--
scribo/demo/viewer/image_region.cc | 23 ++-
scribo/demo/viewer/image_region.hh | 2 +
scribo/demo/viewer/image_region.hxx | 15 +-
scribo/demo/viewer/image_scene.cc | 72 +++++---
scribo/demo/viewer/image_scene.hh | 2 +
scribo/demo/viewer/key_widget.cc | 29 +++-
scribo/demo/viewer/key_widget.hh | 3 +-
scribo/demo/viewer/viewer.cc | 346 +++++++++++++++++++++++++++--------
scribo/demo/viewer/viewer.hh | 10 +-
12 files changed, 434 insertions(+), 126 deletions(-)
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index 9b8392e..6cab6a1 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,9 +1,30 @@
2010-06-30 Arthur Crepin-Leblond <crepin(a)stockholm.lrde.epita.fr>
+ Extended XML mode support.
+
+ * scribo/demo/viewer/Makefile.am
+
+ * demo/viewer/image_region.cc,
+ * viewer/image_region.hh,
+ * viewer/image_region.hxx: Change regions depths to have a hierarchy.
+
+ * demo/viewer/image_scene.cc,
+ * demo/viewer/image_scene.hh: Change mouse click behaviour.
+
+ * demo/viewer/key_widget.cc,
+ * demo/viewer/key_widget.hh: Add new items (text line and paragraph)
+
+ * demo/viewer/viewer.cc,
+ * demo/viewer/viewer.hh: Chnage XML parsing to support extended format.
+
+ * scribo/demo/viewer/common.hh: Add new RegionId's.
+
+2010-06-30 Arthur Crepin-Leblond <crepin(a)stockholm.lrde.epita.fr>
+
New features in Qt interface.
* demo/viewer/browser_widget.hh: Improve picture browser.
- * demo/viewer/step_widget.cc Add a "step chooser" to load several XML files related to one picture.
+ * demo/viewer/step_widget.cc: Add a "step chooser" to load several XML files related to one picture.
2010-06-30 Arthur Crepin-Leblond <crepin(a)stockholm.lrde.epita.fr>
diff --git a/scribo/demo/viewer/Makefile.am b/scribo/demo/viewer/Makefile.am
index 0a6213a..a0112c6 100644
--- a/scribo/demo/viewer/Makefile.am
+++ b/scribo/demo/viewer/Makefile.am
@@ -28,7 +28,8 @@ viewer_SOURCES = $(BUILT_SOURCES) \
dommodel.cc \
domitem.cc \
image_region.cc \
- help_dialog.cc
+ help_dialog.cc \
+ step_widget.cc
viewer_CPPFLAGS = $(QT_CPPFLAGS) $(AM_CPPFLAGS) -I$(srcdir)
viewer_CXXFLAGS = $(QT_CXXFLAGS) $(AM_CXXFLAGS) -O3
@@ -46,7 +47,8 @@ BUILT_SOURCES = viewer.moc.cc \
dommodel.moc.cc \
domitem.moc.cc \
image_region.moc.cc \
- help_dialog.moc.cc
+ help_dialog.moc.cc \
+ step_widget.moc.cc
include_HEADERS = viewer.hh \
viewer.hxx \
@@ -62,6 +64,7 @@ include_HEADERS = viewer.hh \
image_region.hh \
image_region.hxx \
common.hh \
- help_dialog.hh
+ help_dialog.hh \
+ step_widget.hh
EXTRA_DIST = README
diff --git a/scribo/demo/viewer/common.hh b/scribo/demo/viewer/common.hh
index ba4f3b1..346ea51 100644
--- a/scribo/demo/viewer/common.hh
+++ b/scribo/demo/viewer/common.hh
@@ -20,17 +20,19 @@ namespace region
typedef QVector<QPair<QString, QColor> > KeyMap;
enum RegionId
- {
- Text = 0,
- Image,
- Noise,
- Separator,
- Table,
- LineDrawing,
- Graphic,
- Chart,
- Maths
- };
-};
+ {
+ Text = 0,
+ Paragraph,
+ Line,
+ Image,
+ Noise,
+ Separator,
+ Table,
+ LineDrawing,
+ Graphic,
+ Chart,
+ Maths
+ };
+}
#endif /* !COMMON_HH_ */
diff --git a/scribo/demo/viewer/image_region.cc b/scribo/demo/viewer/image_region.cc
index f2e9970..04e3c9b 100644
--- a/scribo/demo/viewer/image_region.cc
+++ b/scribo/demo/viewer/image_region.cc
@@ -35,10 +35,15 @@ ImageRegion::ImageRegion(region::RegionId id,
fill_(fill),
draw_(draw),
selected_(false),
- alpha_(30)
+ alpha_(50)
{
setCursor(Qt::ArrowCursor);
- setZValue(1);
+ if (id_ == region::Paragraph)
+ setZValue(2);
+ else if (id_ == region::Line)
+ setZValue(3);
+ else
+ setZValue(1);
if (points.size() == 0)
return;
@@ -57,6 +62,11 @@ ImageRegion::~ImageRegion()
{
}
+region::RegionId ImageRegion::id()
+{
+ return id_;
+}
+
void
ImageRegion::paint(QPainter* painter,
const QStyleOptionGraphicsItem*,
@@ -103,7 +113,7 @@ ImageRegion::select()
if (!selected_)
{
selected_ = true;
- setZValue(2);
+ setZValue(4);
prepareGeometryChange();
scene()->invalidate();
update();
@@ -116,7 +126,12 @@ ImageRegion::deselect()
if (selected_)
{
selected_ = false;
- setZValue(1);
+ if (id_ == region::Paragraph)
+ setZValue(2);
+ else if (id_ == region::Line)
+ setZValue(3);
+ else
+ setZValue(1);
prepareGeometryChange();
scene()->invalidate();
update();
diff --git a/scribo/demo/viewer/image_region.hh b/scribo/demo/viewer/image_region.hh
index 7f65c02..38aecb4 100644
--- a/scribo/demo/viewer/image_region.hh
+++ b/scribo/demo/viewer/image_region.hh
@@ -36,6 +36,7 @@ public:
~ImageRegion();
+ region::RegionId id();
void paint(QPainter* painter,
const QStyleOptionGraphicsItem* option,
QWidget* widget = 0);
@@ -43,6 +44,7 @@ public:
const QModelIndex& index() const;
QRectF boundingRect() const;
QPainterPath shape() const;
+ QString name() { return name_; }
public slots:
void setOutline(bool outline);
diff --git a/scribo/demo/viewer/image_region.hxx b/scribo/demo/viewer/image_region.hxx
index de8ec11..50dc93d 100644
--- a/scribo/demo/viewer/image_region.hxx
+++ b/scribo/demo/viewer/image_region.hxx
@@ -56,9 +56,14 @@ void
ImageRegion::setDrawIfSameId(int id, bool draw)
{
if (id == id_)
- draw_ = draw;
- scene()->invalidate();
- update();
+ {
+ draw_ = draw;
+ if (scene())
+ {
+ scene()->invalidate();
+ update();
+ }
+ }
}
inline
@@ -73,8 +78,8 @@ inline
QRectF
ImageRegion::boundingRect() const
{
- if (selected_)
- return mapFromScene(scene()->sceneRect()).boundingRect();
+// if (selected_)
+// return mapFromScene(scene()->sceneRect()).boundingRect();
return rect_;
}
diff --git a/scribo/demo/viewer/image_scene.cc b/scribo/demo/viewer/image_scene.cc
index 14eac76..bbc75c3 100644
--- a/scribo/demo/viewer/image_scene.cc
+++ b/scribo/demo/viewer/image_scene.cc
@@ -31,30 +31,58 @@ void
ImageScene::mousePressEvent(QGraphicsSceneMouseEvent* event)
{
QGraphicsScene::mousePressEvent(event);
- ImageRegion* item = dynamic_cast<ImageRegion*>(itemAt(event->pos()));
- if (item)
- {
- if (item != selected_)
- {
- if (selected_)
- {
- selected_->deselect();
- emit deselected(selected_->index());
- }
- selected_ = item;
- item->select();
- emit selected(item->index());
- }
- }
- else
- {
- if (selected_)
+ QList<QGraphicsItem *> items_list = items(event->pos()); // includes both ImageRegions and the picture.
+
+ // Selection is under the mouse click (at event->pos()).
+ bool selection_is_clicked = items_list.contains(selected_);
+
+ foreach(QGraphicsItem* elt, items_list)
{
- selected_->deselect();
- emit deselected(selected_->index());
- selected_ = 0;
+ ImageRegion* item = dynamic_cast<ImageRegion*>(elt);
+ if (item)
+ {
+ if (item != selected_)
+ {
+ if (selected_)
+ {
+ if ( (item->boundingRect().intersects(selected_->boundingRect())))
+ {
+ int item_area = item->boundingRect().size().height() * item->boundingRect().size().width();
+ int selected_area = selected_->boundingRect().size().height() * selected_->boundingRect().size().width();
+
+ if (selected_area < item_area && selection_is_clicked)
+ return;
+ else
+ {
+ selected_->deselect();
+ emit deselected(selected_->index());
+ selected_ = 0;
+ }
+ }
+ else
+ {
+ selected_->deselect();
+ emit deselected(selected_->index());
+ selected_ = 0;
+ }
+ }
+ selected_ = item;
+ item->select();
+ emit selected(item->index());
+ return;
+ }
+ }
+ else
+ {
+ if ( (selected_)
+ && (items_list.size() == 1) )// no ImageRegion, only the picture
+ {
+ selected_->deselect();
+ emit deselected(selected_->index());
+ selected_ = 0;
+ }
+ }
}
- }
}
ImageScene::~ImageScene()
diff --git a/scribo/demo/viewer/image_scene.hh b/scribo/demo/viewer/image_scene.hh
index eb95462..64ab590 100644
--- a/scribo/demo/viewer/image_scene.hh
+++ b/scribo/demo/viewer/image_scene.hh
@@ -1,3 +1,4 @@
+
//
// Document layout viewer.
//
@@ -37,6 +38,7 @@ signals:
private:
ImageRegion* selected_;
+ QVector<ImageRegion*> region_vector_;
};
#endif /* !IMAGE_SCENE_HH_ */
diff --git a/scribo/demo/viewer/key_widget.cc b/scribo/demo/viewer/key_widget.cc
index af817b3..93c2cf0 100644
--- a/scribo/demo/viewer/key_widget.cc
+++ b/scribo/demo/viewer/key_widget.cc
@@ -26,7 +26,9 @@ KeyWidget::KeyWidget(const region::KeyMap& key_map)
layout->addWidget(items_);
for (int i = 0; i < key_map.size(); ++i)
- add_item_(key_map[i].first, key_map[i].second);
+ add_item_(key_map[i].first, key_map[i].second,
+ (i == region::Paragraph) ||
+ (i == region::Line) );
setLayout(layout);
@@ -34,8 +36,29 @@ KeyWidget::KeyWidget(const region::KeyMap& key_map)
this, SLOT(update(QListWidgetItem*)));
}
+void
+KeyWidget::change_mode(bool b)
+{
+ int id_region = region::Paragraph;
+ int id_line = region::Line;
+ if (b)
+ {
+ items_->item(id_region)->setCheckState(Qt::Checked);
+ items_->item(id_region)->setHidden(false);
+ items_->item(id_line)->setCheckState(Qt::Checked);
+ items_->item(id_line)->setHidden(false);
+ }
+ else
+ {
+ items_->item(id_region)->setCheckState(Qt::Unchecked);
+ items_->item(id_region)->setHidden(true);
+ items_->item(id_line)->setCheckState(Qt::Unchecked);
+ items_->item(id_line)->setHidden(true);
+ }
+}
+
void
-KeyWidget::add_item_(QString text, QColor color)
+KeyWidget::add_item_(QString text, QColor color, bool b)
{
QListWidgetItem* item = new QListWidgetItem(text);
QPixmap pixmap(10, 6);
@@ -44,6 +67,8 @@ KeyWidget::add_item_(QString text, QColor color)
item->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled);
item->setCheckState(Qt::Checked);
items_->addItem(item);
+ int id = items_->row(item);
+ items_->item(id)->setHidden(b);
}
bool
diff --git a/scribo/demo/viewer/key_widget.hh b/scribo/demo/viewer/key_widget.hh
index 2f8a8c6..e5259e2 100644
--- a/scribo/demo/viewer/key_widget.hh
+++ b/scribo/demo/viewer/key_widget.hh
@@ -34,9 +34,10 @@ signals:
private slots:
void update(QListWidgetItem* slot);
+ void change_mode(bool b);
private:
- void add_item_(QString text, QColor color);
+ void add_item_(QString text, QColor color, bool b);
QListWidget* items_;
};
diff --git a/scribo/demo/viewer/viewer.cc b/scribo/demo/viewer/viewer.cc
index 622a805..8bafc39 100644
--- a/scribo/demo/viewer/viewer.cc
+++ b/scribo/demo/viewer/viewer.cc
@@ -18,6 +18,7 @@
#include "browser_widget.hh"
#include "image_widget.hh"
#include "xml_widget.hh"
+#include "step_widget.hh"
#include "image_scene.hh"
#include "image_region.hh"
#include "help_dialog.hh"
@@ -33,12 +34,16 @@ Viewer::Viewer(int &argc, char** argv)
scene_(new ImageScene()),
files_(new QDirModel()),
doc_layout_(0),
- key_map_(9),
- no_cache_(false)
+ key_map_(11),
+ no_cache_(false),
+ extended_mode_(false),
+ xml_file_(QString(""))
{
// Key map
- key_map_[region::Text] = qMakePair(tr("Text"), QColor(0, 200, 0));
+ key_map_[region::Text] = qMakePair(tr("Text Region"), QColor(0, 200, 0));
+ key_map_[region::Paragraph] = qMakePair(tr("Paragraph"), QColor(0, 0, 255));
+ key_map_[region::Line] = qMakePair(tr("Text line"), QColor(255, 0, 0));
key_map_[region::Image] = qMakePair(tr("Image"), QColor(255, 120, 0));
key_map_[region::Noise] = qMakePair(tr("Noise"), QColor(43, 39, 128));
key_map_[region::Separator] = qMakePair(tr("Separator"), QColor(0, 0, 255));
@@ -52,6 +57,8 @@ Viewer::Viewer(int &argc, char** argv)
// Region ids
region_ids_["text_region"] = region::Text;
+ region_ids_["paragraph"] = region::Paragraph;
+ region_ids_["line"] = region::Line;
region_ids_["image_region"] = region::Image;
region_ids_["noise_region"] = region::Noise;
region_ids_["separator_region"] = region::Separator;
@@ -96,6 +103,7 @@ Viewer::Viewer(int &argc, char** argv)
connect(fill_action_, SIGNAL(toggled(bool)),
this, SIGNAL(setFill(bool)));
option_menu->addAction(fill_action_);
+
QAction* cache_action = new QAction(tr("Disable cache"), file_menu);
cache_action->setStatusTip(tr("Disable the image cache (useful for"
" large images)."));
@@ -105,6 +113,15 @@ Viewer::Viewer(int &argc, char** argv)
this, SLOT(useCache(bool)));
option_menu->addAction(cache_action);
+ QAction* extended_action = new QAction(tr("Extended mode"), file_menu);
+ extended_action->setStatusTip(tr("If enabled, some features not supported by ICDAR"
+ " are added such as text regions or text lines"));
+ extended_action->setCheckable(true);
+ extended_action->setChecked(false);
+ connect(extended_action, SIGNAL(toggled(bool)),
+ this, SLOT(useExtended(bool)));
+ option_menu->addAction(extended_action);
+
QMenu* help_menu = win_->menuBar()->addMenu(tr("Help"));
QAction* about_action = new QAction(tr("About"), help_menu);
about_action->setStatusTip(tr("About this program."));
@@ -116,6 +133,7 @@ Viewer::Viewer(int &argc, char** argv)
QSplitter* v_splitter = new QSplitter(Qt::Vertical);
QSplitter* v_splitter2 = new QSplitter(Qt::Vertical);
+ StepWidget* step_widget = new StepWidget();
PropertyWidget* property_wgt = new PropertyWidget();
XmlWidget* xml_wgt = new XmlWidget();
BrowserWidget* browser_wgt =
@@ -126,6 +144,7 @@ Viewer::Viewer(int &argc, char** argv)
scene_->setBackgroundBrush(scene_->palette().window());
v_splitter->addWidget(property_wgt);
+ v_splitter->addWidget(step_widget);
v_splitter->addWidget(key_wgt_);
v_splitter->addWidget(browser_wgt);
@@ -138,7 +157,7 @@ Viewer::Viewer(int &argc, char** argv)
win_->setCentralWidget(h_splitter);
QList<int> v_sizes;
- v_sizes << 300 << 200 << 500;
+ v_sizes << 300 << 200 << 200 << 300;
v_splitter->setSizes(v_sizes);
QList<int> v_sizes2;
@@ -150,15 +169,25 @@ Viewer::Viewer(int &argc, char** argv)
h_splitter->setSizes(h_sizes);
connect(browser_wgt, SIGNAL(activated(QString)),
+ step_widget, SLOT(fill_steps(QString)));
+
+ connect(step_widget, SIGNAL(load_image(QString)),
this, SLOT(load(QString)));
+ connect(step_widget, SIGNAL(load_xml(QString)),
+ this, SLOT(load_xml(QString)));
+
connect(this, SIGNAL(updated(DomModel*)),
property_wgt, SLOT(update(DomModel*)));
+ connect(this, SIGNAL(mode_changed(bool)),
+ key_wgt_, SLOT(change_mode(bool)));
connect(this, SIGNAL(updated(DomModel*)),
xml_wgt, SLOT(update(DomModel*)));
connect(this, SIGNAL(updated(DomModel*)),
image_wgt, SLOT(update()));
+
connect(key_wgt_, SIGNAL(updated(int, bool)),
this, SIGNAL(key_updated(int, bool)));
+
connect(scene_, SIGNAL(selected(QModelIndex)),
property_wgt, SLOT(select(QModelIndex)));
connect(scene_, SIGNAL(deselected(QModelIndex)),
@@ -167,36 +196,33 @@ Viewer::Viewer(int &argc, char** argv)
xml_wgt, SLOT(select(QModelIndex)));
connect(scene_, SIGNAL(deselected(QModelIndex)),
xml_wgt, SLOT(deselect(QModelIndex)));
+
connect(image_wgt, SIGNAL(scaleUpdated(qreal)),
this, SLOT(maybeChangeCacheMode(qreal)));
}
void
-Viewer::load(QString filename)
+Viewer::load_xml(QString filename)
{
+ QString xml_file = filename;
+ xml_file_ = filename;
+
app_->setOverrideCursor(QCursor(Qt::WaitCursor));
- scene_->clear();
- image_ = 0;
- // Load the image in a pixmap that is directly shown on screen.
- // This is very slow when used with the normal rendering system.
- // OpenGL might speed up things a bit.
- image_ = new QGraphicsPixmapItem(QPixmap(filename));
- image_->setShapeMode(QGraphicsPixmapItem::BoundingRectShape);
- image_->setZValue(0);
+ scene_->removeItem(image_);
+ scene_->clear();
scene_->addItem(image_);
+
+ scene_->update();
if (doc_layout_)
- {
- doc_layout_->deleteLater();
- doc_layout_ = 0;
- }
-
- // FIXME: Ugly
- QString xml_file = filename;
- xml_file.chop(4);
- xml_file += ".xml";
-
+ {
+ doc_layout_->deleteLater();
+ doc_layout_ = 0;
+ }
+
+ emit updated(doc_layout_);
+
if (QFile::exists(xml_file))
{
QFile file(xml_file);
@@ -207,70 +233,223 @@ Viewer::load(QString filename)
{
doc_layout_ = new DomModel(document, this);
}
+ else
+ {
+ app_->restoreOverrideCursor();
+ QMessageBox msgBox;
+ msgBox.setText("Error while loading the XML file, please choose another.");
+ msgBox.exec();
+ }
file.close();
}
}
+ xml_to_layout();
+
+ app_->restoreOverrideCursor();
+}
+
+void
+Viewer::xml_to_layout()
+{
// Add layout info to the scene.
if (doc_layout_)
- {
- QModelIndex pgGts = doc_layout_->index(1, 0);
- QModelIndex page = doc_layout_->index(1, 0, pgGts);
- QModelIndex region;
- QModelIndex attributes;
- QModelIndex coords;
- QModelIndex point;
- for (int i = 0; true; ++i)
{
- region = doc_layout_->index(i, 0, page);
- attributes = doc_layout_->index(i, 1, page);
- QString name = doc_layout_->data(region, Qt::DisplayRole).toString();
- region::RegionId id = static_cast<region::RegionId>(region_ids_[name]);
+ QModelIndex pgGts = doc_layout_->index(1, 0);
+ QModelIndex page = doc_layout_->index(1, 0, pgGts);
+ QModelIndex region;
+ QModelIndex attributes;
+ QModelIndex coords;
+ QModelIndex point;
+ for (int i = 0; true; ++i)
+ {
+ region = doc_layout_->index(i, 0, page);
+ attributes = doc_layout_->index(i, 1, page);
+ QString name = doc_layout_->data(region, Qt::DisplayRole).toString();
+ region::RegionId id = static_cast<region::RegionId>(region_ids_[name]);
+
+ coords = doc_layout_->index(0, 0, region);
+ if (!region.isValid() || !coords.isValid())
+ break;
+
+ QVector<QPoint> points;
+ for (int j = 0; true; ++j)
+ {
+ // Navigate to the coordinate list
+ point = doc_layout_->index(j, 1, coords);
+ if (!point.isValid())
+ break;
+
+ QMap<QString, QVariant> data =
+ doc_layout_->data(point, Qt::UserRole).toMap();
+ int x = data["x"].toInt();
+ int y = data["y"].toInt();
+ points << QPoint(x, y);
+ }
+
+ // Create region
+ ImageRegion* r = new ImageRegion(id,
+ key_map_[id].first,
+ key_map_[id].second,
+ attributes, points,
+ outline_action_->isChecked(),
+ fill_action_->isChecked(),
+ precise_action_->isChecked(),
+ key_wgt_->isChecked(id));
+
+ connect(this, SIGNAL(key_updated(int, bool)),
+ r, SLOT(setDrawIfSameId(int, bool)));
+ connect(this, SIGNAL(setOutline(bool)),
+ r, SLOT(setOutline(bool)));
+ connect(this, SIGNAL(setPrecise(bool)),
+ r, SLOT(setPrecise(bool)));
+ connect(this, SIGNAL(setFill(bool)),
+ r, SLOT(setFill(bool)));
+
+ scene_->addItem(r);
+
+ // EXTENDED MODE
+ if (extended_mode_)
+ {
+ for (int k = 1; true; ++k)
+ {
+ QModelIndex paragraph = doc_layout_->index(k, 0, region);
+ QModelIndex attributes_par = doc_layout_->index(k, 1, region);
+ if (!paragraph.isValid())
+ break;
+
+ QString name_par = doc_layout_->data(paragraph, Qt::DisplayRole).toString();
+ region::RegionId id_par = static_cast<region::RegionId>(region_ids_[name_par]);
+
+ QDebug(&name_par) << name_par;
+
+ QModelIndex par_coords = doc_layout_->index(0, 0, paragraph);
+ QModelIndex point_par;
+ QVector<QPoint> points_par;
+ for (int m = 0; true; ++m)
+ {
+ // Navigate to the coordinate list
+ point_par = doc_layout_->index(m, 1, par_coords);
+ if (!point_par.isValid())
+ break;
+
+ QMap<QString, QVariant> data_par =
+ doc_layout_->data(point_par, Qt::UserRole).toMap();
+ int x = data_par["x"].toInt();
+ int y = data_par["y"].toInt();
+ points_par << QPoint(x, y);
+ }
+
+ // Create region
+ ImageRegion* r_par = new ImageRegion(id_par,
+ key_map_[id_par].first,
+ key_map_[id_par].second,
+ attributes_par, points_par,
+ outline_action_->isChecked(),
+ fill_action_->isChecked(),
+ precise_action_->isChecked(),
+ key_wgt_->isChecked(id_par));
+
+ connect(this, SIGNAL(key_updated(int, bool)),
+ r_par, SLOT(setDrawIfSameId(int, bool)));
+ connect(this, SIGNAL(setOutline(bool)),
+ r_par, SLOT(setOutline(bool)));
+ connect(this, SIGNAL(setPrecise(bool)),
+ r_par, SLOT(setPrecise(bool)));
+ connect(this, SIGNAL(setFill(bool)),
+ r_par, SLOT(setFill(bool)));
+
+ scene_->addItem(r_par);
+
+ for (int l = 1; true; ++l)
+ {
+ QModelIndex line = doc_layout_->index(l, 0, paragraph);
+ QModelIndex attributes_line = doc_layout_->index(l, 1, paragraph);
+ if (!line.isValid())
+ break;
+
+ QString name_line = doc_layout_->data(line, Qt::DisplayRole).toString();
+ region::RegionId id_line = static_cast<region::RegionId>(region_ids_[name_line]);
+
+ QModelIndex line_coords = doc_layout_->index(0, 0, line);
+ QModelIndex point_line;
+ QVector<QPoint> points_line;
+ for (int n = 0; true; ++n)
+ {
+ // Navigate to the coordinate list
+ point_line = doc_layout_->index(n, 1, line_coords);
+ if (!point_line.isValid())
+ break;
+
+ QMap<QString, QVariant> data_line =
+ doc_layout_->data(point_line, Qt::UserRole).toMap();
+ int x = data_line["x"].toInt();
+ int y = data_line["y"].toInt();
+ points_line << QPoint(x, y);
+ }
+
+ // Create region
+ ImageRegion* r_line = new ImageRegion(id_line,
+ key_map_[id_line].first,
+ key_map_[id_line].second,
+ attributes_line, points_line,
+ outline_action_->isChecked(),
+ fill_action_->isChecked(),
+ precise_action_->isChecked(),
+ key_wgt_->isChecked(id_line));
+
+ connect(this, SIGNAL(key_updated(int, bool)),
+ r_line, SLOT(setDrawIfSameId(int, bool)));
+ connect(this, SIGNAL(setOutline(bool)),
+ r_line, SLOT(setOutline(bool)));
+ connect(this, SIGNAL(setPrecise(bool)),
+ r_line, SLOT(setPrecise(bool)));
+ connect(this, SIGNAL(setFill(bool)),
+ r_line, SLOT(setFill(bool)));
+
+ scene_->addItem(r_line);
+ }
+ }
+ }
+ // END OF EXTENDED MODE
+
+ }
+
+ emit updated(doc_layout_);
+ }
+}
- coords = doc_layout_->index(0, 0, region);
- if (!region.isValid() || !coords.isValid())
- break;
+void
+Viewer::load(QString filename)
+{
+ app_->setOverrideCursor(QCursor(Qt::WaitCursor));
+ scene_->clear();
+ scene_->update();
+ image_ = 0;
+ xml_file_ = "";
- QVector<QPoint> points;
- for (int j = 0; true; ++j)
- {
- // Navigate to the coordinate list
- point = doc_layout_->index(j, 1, coords);
- if (!point.isValid())
- break;
-
- QMap<QString, QVariant> data =
- doc_layout_->data(point, Qt::UserRole).toMap();
- int x = data["x"].toInt();
- int y = data["y"].toInt();
- points << QPoint(x, y);
- }
+ // Load the image in a pixmap that is directly shown on screen.
+ // This is very slow when used with the normal rendering system.
+ // OpenGL might speed up things a bit.
+ image_ = new QGraphicsPixmapItem(QPixmap(filename));
+ image_->setShapeMode(QGraphicsPixmapItem::BoundingRectShape);
+ image_->setZValue(0);
+ scene_->addItem(image_);
- // Create region
- ImageRegion* r = new ImageRegion(id,
- key_map_[id].first,
- key_map_[id].second,
- attributes, points,
- outline_action_->isChecked(),
- fill_action_->isChecked(),
- precise_action_->isChecked(),
- key_wgt_->isChecked(id));
-
- connect(this, SIGNAL(key_updated(int, bool)),
- r, SLOT(setDrawIfSameId(int, bool)));
- connect(this, SIGNAL(setOutline(bool)),
- r, SLOT(setOutline(bool)));
- connect(this, SIGNAL(setPrecise(bool)),
- r, SLOT(setPrecise(bool)));
- connect(this, SIGNAL(setFill(bool)),
- r, SLOT(setFill(bool)));
- scene_->addItem(r);
- }
- }
+ if (no_cache_)
+ image_->setCacheMode(QGraphicsItem::NoCache);
+ else
+ image_->setCacheMode(QGraphicsItem::DeviceCoordinateCache);
- emit updated(doc_layout_);
+ if (doc_layout_)
+ {
+ doc_layout_->deleteLater();
+ doc_layout_ = 0;
+ }
app_->restoreOverrideCursor();
+
+ emit updated(doc_layout_);
}
int
@@ -299,10 +478,27 @@ Viewer::maybeChangeCacheMode(qreal scale)
}
}
+void Viewer::useExtended(bool b)
+{
+ extended_mode_ = b;
+ if (xml_file_ != QString(""))
+ load_xml(xml_file_);
+
+ emit mode_changed (b);
+}
+
void
Viewer::useCache(bool b)
{
no_cache_ = b;
if (b)
- image_->setCacheMode(QGraphicsItem::NoCache);
+ {
+ if (image_)
+ image_->setCacheMode(QGraphicsItem::NoCache);
+ }
+ else
+ if (image_)
+ image_->setCacheMode(QGraphicsItem::DeviceCoordinateCache);
}
+
+// LocalWords: hh
diff --git a/scribo/demo/viewer/viewer.hh b/scribo/demo/viewer/viewer.hh
index d579847..d13ef91 100644
--- a/scribo/demo/viewer/viewer.hh
+++ b/scribo/demo/viewer/viewer.hh
@@ -21,6 +21,7 @@
class ImageScene;
class DomModel;
class KeyWidget;
+class ImageRegion;
class Viewer
: public QObject
@@ -39,21 +40,26 @@ public slots:
// name is found.
void load(QString filename);
void help();
-
+ void load_xml(QString filename);
void maybeChangeCacheMode(qreal scale);
void useCache(bool b);
+ void useExtended(bool b);
signals:
void updated(DomModel* model);
+ void loaded(DomModel* model);
void key_updated(int key, bool checked);
void setOutline(bool b);
void setPrecise(bool b);
void setFill(bool b);
+ void mode_changed(bool b);
private:
Viewer(int &argc, char** argv);
Viewer();
+ void xml_to_layout();
+
QApplication* app_;
QMainWindow* win_;
@@ -73,6 +79,8 @@ private:
region::KeyMap key_map_;
bool no_cache_;
+ bool extended_mode_;
+ QString xml_file_;
};
#include "viewer.hxx"
--
1.5.6.5
1
0
30 Jun '10
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Olena, a generic and efficient image processing platform".
The branch exp/scribo-z has been updated
via 2f5f4a438accd7aa52c3ac8d3550b70cef778c0e (commit)
from 6b6d1440369b9cb9fc31c4453723e179d91ba842 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
2f5f4a4 Modified Changelog in accordance to commit 55a5c8.
-----------------------------------------------------------------------
Summary of changes:
scribo/ChangeLog | 7 +++++++
1 files changed, 7 insertions(+), 0 deletions(-)
hooks/post-receive
--
Olena, a generic and efficient image processing platform
1
0