Olena-patches
Threads by month
- ----- 2025 -----
- 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
branch green-regional-maxima updated: last-svn-commit-41-g67b295e
by lazzaraï¼ lrde.epita.fr 15 Nov '10
by lazzaraï¼ lrde.epita.fr 15 Nov '10
15 Nov '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 green-regional-maxima has been updated
discards 9ea8474bbe3fbdcfdeba74a7cf2ea602687768ab (commit)
discards 861abf27dc8e90c590b515c5cf0f05111a696220 (commit)
discards 57573abae5803df09f5af2c5fcb15ad4d5a7a397 (commit)
discards 0a1cbd3506e4153a104682280e0bb12d5042613c (commit)
discards 7bc32d5ed6f18ffd43b8512b5a7de4cc26a358ff (commit)
discards a502be9d78730bac9e286324386f0ae4b5f11b88 (commit)
discards ddb6f8cfa75d114ac584c5eabbee8c722fda54d8 (commit)
discards 72bad6e9e8187ee9870f40286db8d4fe4e453425 (commit)
discards 20909f49c35d22b79de8df44915aacca06e71ae0 (commit)
discards 49aaec032034188ccf7694494cddb425bcc352d2 (commit)
discards 110656234b315d15df8617333019265340089d34 (commit)
discards c920529afe338d1120cbc9043394f827a328c368 (commit)
discards 36d40e5b46524d05cfe9d6b8d328cbae09c7e779 (commit)
discards 8c049974295cee70d9d2f235c069f9ed01df30ca (commit)
discards b70dff23b7d1974e60b22b3cb7a196acc3d84946 (commit)
discards 1086f4ed0bec9037a9cff4176b18e49d218bfa6e (commit)
discards d3e640b6eba0ee6d8c52ae1e433ebe7c0be3b15e (commit)
discards 9028f28f51a0a9133e5006917253d386df93ef66 (commit)
discards 34f317bf7800516d03ba9d5cea0f224cca3b9668 (commit)
discards f628029dbf93d9ac7490ea499a64b9794a8168a3 (commit)
discards 8959d2ae95c16fbb28b2a4e98788bdb6463add0f (commit)
discards fe69f742dba2a232cb2f49807ba2879e2325c3b2 (commit)
discards fc278a9509a401b2f9275fa6f39092e77315acd0 (commit)
discards 7af9ecdc4c1b1ed33122c4146f05c55d33e4c5c0 (commit)
discards c6ff97e1bc8ef0e059e1228a3004690f13e2bd56 (commit)
discards d0783cebdffb4c8d8fbcf934bae458684639e325 (commit)
discards 047c90824ecef770ebe8553606bcd2f265c2fa9e (commit)
discards 45cefb4a2e0dd60490e558ca9d04ecac98b2a615 (commit)
discards b5caa8de0eeed69a23d459663fa6dbe0a45980b1 (commit)
discards 7abe6d3e6ecd5341f8b613c072213f454398086c (commit)
discards f2adc9125d01a421487347e72d387488c50fcfce (commit)
discards 988bdbbdf6fe96847ebd00dcced6f8cd4e5682bc (commit)
discards 4e56a00784e19e8e7a2a984aab4f809ec6aee220 (commit)
discards 03c3d97828462c3a070ebb51acc56cded2809b29 (commit)
discards 0c4e1cb4947d09f720a2134c0f8a8702e2bfcd49 (commit)
discards c121636371613a2edb38cb1073e9992833ac5009 (commit)
discards 9e772c65245f643261142cdb7987ed346bfc1a46 (commit)
discards fd0947d2453d62e92681d4a1f0026b42fd5c8024 (commit)
discards 2c3f552813a8b6a51692e8ef4c40a4f8dba933bf (commit)
discards 8c92a3be8ae8f2738b584580b4e39031d6243bcf (commit)
discards 4ee2f2a9467f7ed2ca24c68ac5ef35e12f4faf86 (commit)
via 67b295ee221ad90e1abc475854375a7bc06d7954 (commit)
via 2cfa144eb3d4bb1b1f12655c2e4708771138d23b (commit)
via c670b7e781b64e3e8b4d0b17b5d6fef31d6a8bc6 (commit)
via 49b8dc22e8f9664f7f385496080c06ab80096171 (commit)
via d4f2e4917b95cb92762f0fc82498050789ead89c (commit)
via e9328a0605c308aea46d70abbb73402593b9eb65 (commit)
via 485f8dec942fd56ba950c33c539f7803dfa281d0 (commit)
via 1d23bfaf3e648f96ca2321da52bfc4e7b6f8420c (commit)
via 2c26e604d0e939535f7dff1bfdf0925825b9f307 (commit)
via 174b91703414bb8df7c9fb0922c51aef32c38cb2 (commit)
via ba99cc211570e5854fc6b910a3a634f6d15f1f86 (commit)
via acb2f3dbabfa00da20a7e8e1160fbbd051a1b652 (commit)
via a85f46a9568f5085ca32662e59a545675b70905c (commit)
via a2d33697a1ffc22679540af9cdf899bebf0e5167 (commit)
via 18d1a4203f6577a0602e4c4578dbae57a11a0f02 (commit)
via 3849ff557b11d1542cc38263fae5ea5163899678 (commit)
via 1dff8cf61b25a32a64186ea346ceb14c97f3f63a (commit)
via 40063b84e2132755bb7982fb86f6cd8527399ebd (commit)
via fdf0f76c54e847f00553092d355f752d10a1b835 (commit)
via a3cbabff4529a013fa40dddebbfc63d2eb3667aa (commit)
via 88906972b5285dbd4bff41f6645d09fb182aed1b (commit)
via 444245a639e02fd0ebdfb083c8c551b459a56fb1 (commit)
via 16fbbef7db27689c3728436e7035a5a6549826de (commit)
via 1835af00071ea4e14e1641cb87d118d3ba511f4b (commit)
via 0625137ef6694e51353ea04db9cb62365188c67c (commit)
via c325629baf82f376924de68f8d43133e77c934c1 (commit)
via 1a823f73b8f232149a0e953624d895a29f706a2d (commit)
via 58801223f73cb532e43fac2ca8065a43c8fa6985 (commit)
via 607075682b6992513805c0f5cafd95ded370efab (commit)
via 60307833a3b3ff5e7b5da1e9b333a8404c0040f2 (commit)
via 31f0f731e35d208e89a812ebadddcfcf90ebc667 (commit)
via 6c0fa46bdaaf8619358568aabfcf8a20c6c21ee1 (commit)
via cadda529593468fcd00d0750fda70d4648d3badd (commit)
via 256de5f3eed935fc8229a3800be8cb71937b70ee (commit)
via 00ab9ddbdd78e06f7ebd01c57f5e6f490254fa2c (commit)
via 19825009a7bc9c638226dd2963f1a56679d31757 (commit)
via b6641d4b0fe6550d26d15b837ba65e7279f2298b (commit)
via b1afad461fa1621d1b6c98ae81bcbfc23248f6dd (commit)
via 7404579567f626734d6de94fb6cb62072d97553b (commit)
via 00da4238932f0410315ed16fb7be6869f4d0b381 (commit)
via 59ebeab82ed59260c238a59478a79c30c090584b (commit)
This update added new revisions after undoing existing revisions. That is
to say, the old revision is not a strict subset of the new revision. This
situation occurs when you --force push a change and generate a repository
containing something like this:
* -- * -- B -- O -- O -- O (9ea8474bbe3fbdcfdeba74a7cf2ea602687768ab)
\
N -- N -- N (67b295ee221ad90e1abc475854375a7bc06d7954)
When this happens we assume that you've already had alert emails for all
of the O revisions, and so we here report only the revisions in the N
branch from the common base, B.
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 -----------------------------------------------------------------
67b295e Simple integration test.
2cfa144 Fix the way to convert unsigned to float.
c670b7e Add milena library components.
49b8dc2 Work on Millet value descriptor.
d4f2e49 Work on Millet saturation descriptor.
e9328a0 Work on Millet saturation descriptor.
485f8de Work on Millet hsv descriptors.
1d23bfa Work on histograms view as density.
2c26e60 Test error quantification as a color descriptor in our database.
174b917 Benchmark few descriptors.
ba99cc2 Test on image database the achromatism descriptor.
acb2f3d Turn around Millet 2008 hsv descriptors.
a85f46a Delete BUG image file in milena/img.
a2d3369 Save Theo's exhaustive demonstration results.
18d1a42 Fix bugs in the histogram visualization tools.
3849ff5 Fix last details in the image processing chain.
1dff8cf Extend the histogram visualization tools for new projection concept.
40063b8 Build translation table between number of pixels and percentage of
fdf0f76 Split the regional maxima binary in small atomic binaries.
a3cbabf Write the opening volume thresholds for the scribo image mp00082c.ppm.
8890697 Experiment various quantifications on regional maxima labeling.
444245a Experiment variation on regional maxima labeling.
-----------------------------------------------------------------------
Summary of changes:
hooks/post-receive
--
Olena, a generic and efficient image processing platform
1
0
* green/exp/annotating/bench: New directory.
* green/exp/annotating/bench/Makefile.am: New Makefile.
* green/exp/annotating/bench/bench.cc: New source.
---
milena/sandbox/ChangeLog | 8 +
.../annotating/{achromastism => bench}/Makefile.am | 0
milena/sandbox/green/exp/annotating/bench/bench.cc | 1213 ++++++++++++++++++++
3 files changed, 1221 insertions(+), 0 deletions(-)
copy milena/sandbox/green/exp/annotating/{achromastism => bench}/Makefile.am (100%)
create mode 100644 milena/sandbox/green/exp/annotating/bench/bench.cc
diff --git a/milena/sandbox/ChangeLog b/milena/sandbox/ChangeLog
index 0086d22..7489f70 100644
--- a/milena/sandbox/ChangeLog
+++ b/milena/sandbox/ChangeLog
@@ -1,5 +1,13 @@
2010-06-21 Yann Jacquelet <jacquelet(a)lrde.epita.fr>
+ Benchmark few descriptors.
+
+ * green/exp/annotating/bench: New directory.
+ * green/exp/annotating/bench/Makefile.am: New Makefile.
+ * green/exp/annotating/bench/bench.cc: New source.
+
+2010-06-21 Yann Jacquelet <jacquelet(a)lrde.epita.fr>
+
Test on image database the achromatism descriptor.
* green/exp/annotating/achromatism/Makefile.am: New Makefile.
diff --git a/milena/sandbox/green/exp/annotating/achromastism/Makefile.am b/milena/sandbox/green/exp/annotating/bench/Makefile.am
similarity index 100%
copy from milena/sandbox/green/exp/annotating/achromastism/Makefile.am
copy to milena/sandbox/green/exp/annotating/bench/Makefile.am
diff --git a/milena/sandbox/green/exp/annotating/bench/bench.cc b/milena/sandbox/green/exp/annotating/bench/bench.cc
new file mode 100644
index 0000000..8e4525f
--- /dev/null
+++ b/milena/sandbox/green/exp/annotating/bench/bench.cc
@@ -0,0 +1,1213 @@
+// BENCH TEST CF MILLET 2008
+
+#include <iostream>
+#include <sstream>
+#include <boost/filesystem.hpp>
+
+#include <mln/algebra/vec.hh>
+
+#include <mln/img_path.hh>
+
+#include <mln/accu/stat/mean.hh>
+#include <mln/accu/stat/histo1d.hh>
+
+#include <mln/arith/minus.hh>
+#include <mln/arith/times.hh>
+#include <mln/arith/diff_abs.hh>
+#include <mln/arith/div.hh>
+
+#include <mln/core/image/image1d.hh>
+#include <mln/core/image/image2d.hh>
+#include <mln/core/image/dmorph/image_if.hh>
+#include <mln/core/alias/point1d.hh>
+#include <mln/core/alias/box1d.hh>
+
+#include <mln/data/transform.hh>
+#include <mln/data/compute.hh>
+#include <mln/data/convert.hh>
+#include <mln/data/stretch.hh>
+#include <mln/data/fill.hh>
+
+#include <mln/fun/v2v/component.hh>
+#include <mln/fun/v2v/rgb_to_hue_map.hh>
+#include <mln/fun/v2v/rgb_to_saturation_map.hh>
+#include <mln/fun/v2v/rgb_to_value_map.hh>
+
+#include <mln/io/ppm/load.hh>
+#include <mln/io/pgm/save.hh>
+#include <mln/io/plot/save_image_sh.hh>
+
+#include <mln/literal/zero.hh>
+
+#include <mln/math/ceil.hh>
+#include <mln/math/floor.hh>
+
+#include <mln/opt/at.hh>
+
+#include <mln/trait/value_.hh>
+
+#include <mln/value/rgb8.hh>
+
+
+#include <mln/value/int_u8.hh>
+
+template <typename I>
+mln_value(I) count_histo(const mln::Image<I>& histo_)
+{
+ const I& histo = exact(histo_);
+
+ mln_precondition(histo.is_valid());
+
+ mln_value(I) result = mln::literal::zero;
+ mln_piter(I) p(histo.domain());
+
+ for_all(p)
+ result += histo(p);
+
+ return result;
+}
+
+
+template <typename I>
+mln_value(I) sum_frequency_histo(const mln::Image<I>& histo_)
+{
+ const I& histo = exact(histo_);
+
+ mln_precondition(histo.is_valid());
+
+ mln_value(I) sum = mln::literal::zero;
+ mln_piter(I) p(histo.domain());
+
+ for_all(p)
+ sum += histo(p);
+
+ return sum;
+}
+
+
+template <typename I>
+mln_coord(mln_site_(I)) peak_histo(const mln::Image<I>& histo_)
+{
+ const I& histo = exact(histo_);
+
+ mln_precondition(histo.is_valid());
+
+ // Find the peak of the histogram
+ mln_value(I) v_max = mln::opt::at(histo, mln::literal::zero);
+ mln_coord(mln_site_(I)) p_max = mln::literal::zero;
+ mln_piter(I) p(histo.domain());
+
+ for_all(p)
+ {
+ if (v_max < histo(p))
+ {
+ v_max = histo(p);
+ p_max = p.ind();
+ }
+ }
+
+ return p_max;
+}
+
+
+//============================================================================//
+// MILLET HUE DESCRIPTOR
+//
+// This test is used for discrimination between black and white pictures and
+// color ones. Some colored Black and white pictures have their energy near
+// the peak.
+//============================================================================//
+
+float hue1_descriptor(mln::image1d<unsigned> histo, const short threshold)
+{
+ float cnt1;
+ float cnt2;
+ float prop;
+ short peak;
+ mln::point1d inf;
+ mln::point1d sup;
+
+ peak = peak_histo(histo);
+ inf = mln::point1d(mln::math::max(0, peak-threshold));
+ sup = mln::point1d(mln::math::min(255, peak+threshold));
+ cnt1 = count_histo(histo|mln::box1d(inf,sup));
+ cnt2 = count_histo(histo);
+ prop = ((255.0 * cnt1) / cnt2);
+
+ return prop;
+}
+
+
+//============================================================================//
+// MILLET SATURATION DESCRIPTOR
+//
+// This test is used for discrimination between black and white pictures and
+// color ones. Black and white pictures have their energy in the low saturation
+// band.
+//============================================================================//
+
+float sat1_descriptor(mln::image1d<unsigned> histo, const short threshold)
+{
+ float cnt1;
+ float cnt2;
+ float result;
+
+ cnt1 = count_histo(histo | mln::box1d(mln::point1d(0),
+ mln::point1d(threshold)));
+ cnt2 = count_histo(histo);
+ result = ((255.0 * cnt1) / cnt2);
+
+ return result;
+ color = label_hue(peak);}
+
+
+//============================================================================//
+// MILLET DESCRIPTOR
+//
+// This test aims at compute the number of grey levels. Photographies tends to
+// use all the levels or many of them.
+//============================================================================//
+
+template <typename I>
+mln_value(I) count_null_frequency_histo(const mln::Image<I>& histo_)
+{
+ const I& histo = exact(histo_);
+
+ mln_precondition(histo.is_valid());
+
+ mln_value(I) count = mln::literal::zero;
+ mln_piter(I) p(histo.domain());
+
+ for_all(p)
+ if (0 == histo(p))
+ count++;
+
+ return count;
+}
+
+
+float lvl0_descriptor(mln::image1d<unsigned> histo)
+{
+ float result;
+
+ // FIXME 255
+ result = 255-count_null_frequency_histo(histo);
+
+ return result;
+}
+
+//============================================================================//
+// DENSITY DESCRIPTOR
+//
+//
+//============================================================================//
+
+template <typename I>
+float cmp_equi_frequency_histo(const mln::Image<I>& histo_)
+{
+ const I& histo = exact(histo_);
+
+ mln_precondition(histo.is_valid());
+
+ float sum = 0;
+ float var = 0;
+
+ mln_piter(I) p(histo.domain());
+
+ for_all(p)
+ {
+ sum ++;
+ var += mln::math::sqr(histo(p) - (1/256.0));
+ }
+
+ var = var / sum;
+
+ return var;
+}
+
+float hue0_descriptor(mln::image1d<unsigned> histo)
+{
+ mln::image1d<float> histo_float;
+ float sum;
+ float result;
+
+ sum = sum_frequency_histo(histo);
+ histo_float = mln::data::convert(float(), histo) / sum;
+ result = cmp_equi_frequency_histo(histo_float);
+
+ return result*255;
+}
+
+
+float sat0_descriptor(mln::image1d<unsigned> histo)
+{
+ mln::image1d<float> histo_float;
+ float sum;
+ float result;
+
+ sum = sum_frequency_histo(histo);
+ histo_float = mln::data::convert(float(), histo) / sum;
+ result = cmp_equi_frequency_histo(histo_float);
+
+ return result*255;
+}
+
+float val0_descriptor(mln::image1d<unsigned> histo)
+{
+ mln::image1d<float> histo_float;
+ float sum;
+ float result;
+
+ sum = sum_frequency_histo(histo);
+ histo_float = mln::data::convert(float(), histo) / sum;
+ result = cmp_equi_frequency_histo(histo_float);
+
+ return result*255;
+}
+
+//============================================================================//
+// MILLET DESCRIPTOR
+//
+// This test aims at compute some deviation on the peak of the histogram of
+// the image. Large deviations mean lots of graduation in colors (such as
+// photos) and small ones mean something like cartoon.
+//============================================================================//
+
+
+// calcul de contribution
+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;
+}
+
+template <typename I>
+float stddev3(const mln::Image<I>& histo_, unsigned peak)
+{
+ const I& histo = exact(histo_);
+
+ mln_precondition(histo.is_valid());
+
+ // Compute stddev
+
+ float stddev = 0.0;
+
+ mln_piter(I) p(histo.domain());
+
+ for_all(p)
+ {
+ stddev += r((short)peak, mln::opt::at(histo,peak), p.ind(), histo(p));
+ }
+
+ return stddev;
+}
+
+template <typename I>
+float stddev2(const mln::Image<I>& histo_, unsigned peak, unsigned limit)
+{
+ const I& histo = exact(histo_);
+
+ mln_precondition(histo.is_valid());
+
+ float stddev_low = 0.0;
+ float stddev_up = 0.0;
+ float ret = 0.0;
+
+ // A transformer avec des iterators
+
+ if (250 > peak)
+ stddev_up = stddev3(histo |mln::box1d(mln::point1d(peak+1),
+ mln::point1d(peak+limit)), peak);
+
+ if (5 < peak)
+ stddev_low = stddev3(histo |mln::box1d(mln::point1d(peak-limit),
+ mln::point1d(peak-1)), peak);
+
+ ret = (250 < peak)? stddev_low : (5 > peak)? stddev_up :
+ (stddev_low + stddev_up)/2;
+
+ return ret;
+}
+
+float var0_descriptor(mln::image1d<unsigned> histo, const short threshold)
+{
+ typedef mln::fun::v2v::rgb_to_value_map<8> t_rgb_to_value_map;
+
+ float result;
+ short peak;
+
+ peak = peak_histo(histo);
+ result = stddev2(histo, peak, threshold);
+
+ return result;
+}
+
+
+//============================================================================//
+// ERROR DESCRIPTOR
+//============================================================================//
+
+
+float err_descriptor(mln::image2d<mln::value::int_u8> r_img_map,
+ mln::image2d<mln::value::int_u8> g_img_map,
+ mln::image2d<mln::value::int_u8> b_img_map,
+ mln::image2d<mln::value::int_u8> r_rdc_map,
+ mln::image2d<mln::value::int_u8> g_rdc_map,
+ mln::image2d<mln::value::int_u8> b_rdc_map)
+
+
+{
+ typedef mln::accu::meta::stat::mean t_mean;
+ typedef mln::image2d<mln::value::int_u8> t_map;
+ typedef mln_trait_op_minus_(t_map,t_map) t_minus;
+ typedef mln_trait_op_times_(t_minus,t_minus) t_times;
+
+
+ t_minus minus_red;
+ t_minus minus_green;
+ t_minus minus_blue;
+
+ t_times times_red;
+ t_times times_green;
+ t_times times_blue;
+
+ float error_red;
+ float error_green;
+ float error_blue;
+
+ float error;
+
+ minus_red = (r_img_map - r_rdc_map);
+ times_red = minus_red * minus_red;
+
+ minus_green = (g_img_map - g_rdc_map);
+ times_green = minus_green * minus_green;
+
+ minus_blue = (b_img_map - b_rdc_map);
+ times_blue = minus_blue * minus_blue;
+
+ error_red = mln::data::compute(t_mean(), times_red);
+ error_green = mln::data::compute(t_mean(), times_green);
+ error_blue = mln::data::compute(t_mean(), times_blue);
+
+ error = (error_red + error_green + error_blue)/3.0;
+ error = mln::math::sqrt(error);
+ error = 20 * log(255/error);
+
+// Le PNSNR semble offrir plus d'espace pour la discrimination
+// Si les images sont identiques ==> PNSNR = +inf
+// Si les images sont très différentes ==> PNSNR = 0
+ // FIXME METTRE UN MAX A 255
+
+ return error;
+}
+
+
+
+//============================================================================//
+// CLASSIFICATION DE FISHER EN 2 CLASSES SUR UN HISTO 1D
+//============================================================================//
+
+template <typename I>
+mln_value(I) cnt_histo(const mln::Image<I>& histo_)
+{
+ const I& histo = exact(histo_);
+
+ mln_precondition(histo.is_valid());
+
+ mln_value(I) sum = mln::literal::zero;
+ mln_piter(I) p(histo.domain());
+
+ for_all(p)
+ {
+ sum += histo(p);
+ }
+
+ return sum;
+}
+
+template <typename I>
+mln_value(I) sum_histo(const mln::Image<I>& histo_)
+{
+ const I& histo = exact(histo_);
+
+ mln_precondition(histo.is_valid());
+
+ mln_value(I) pos = mln::literal::zero;
+ mln_value(I) sum = mln::literal::zero;
+ mln_piter(I) p(histo.domain());
+
+ for_all(p)
+ {
+ pos = p.ind();
+ sum += pos*histo(p);
+ }
+
+ return sum;
+}
+
+template <typename I>
+mln_value(I) avg_histo(const mln::Image<I>& histo_)
+{
+ const I& histo = exact(histo_);
+
+ mln_precondition(histo.is_valid());
+
+ mln_value(I) pos = mln::literal::zero;
+ mln_value(I) sum = mln::literal::zero;
+ mln_value(I) cnt = mln::literal::zero;
+ mln_piter(I) p(histo.domain());
+
+ for_all(p)
+ {
+ pos = p.ind();
+ cnt += histo(p);
+ sum += pos*histo(p);
+ }
+
+ return (0 == cnt)? 0 : sum/cnt;
+}
+
+template <typename I>
+mln_value(I) var3_histo(const mln::Image<I>& histo_, float mean)
+{
+ const I& histo = exact(histo_);
+
+ mln_precondition(histo.is_valid());
+
+ mln_value(I) pos = mln::literal::zero;
+ mln_value(I) sum = mln::literal::zero;
+ mln_value(I) cnt = mln::literal::zero;
+ mln_piter(I) p(histo.domain());
+
+ for_all(p)
+ {
+ cnt += histo(p);
+ sum += (mln::math::sqr(p.ind()-mean)*histo(p));
+ }
+
+ return (0 == cnt)? 0 : sum/cnt;
+}
+
+template <typename I>
+mln_value(I) var2_histo(const mln::Image<I>& histo_, float mean)
+{
+ const I& histo = exact(histo_);
+
+ mln_precondition(histo.is_valid());
+
+ mln_value(I) pos = mln::literal::zero;
+ mln_value(I) sum = mln::literal::zero;
+ mln_value(I) sqr = mln::literal::zero;
+ mln_value(I) cnt = mln::literal::zero;
+ mln_value(I) dlt = mln::literal::zero;
+ mln_value(I) mxt = mln::literal::zero;
+ mln_piter(I) p(histo.domain());
+
+ for_all(p)
+ {
+ pos = p.ind();
+ cnt += (histo(p));
+ sum += (histo(p)*pos);
+ mxt += (histo(p)*pos*mean);
+ sqr += (histo(p)*mln::math::sqr(pos));
+ dlt += (histo(p)*mln::math::sqr(pos - mean));
+
+ std::cout << "p = " << pos << std::endl;
+ std::cout << "p² = " << mln::math::sqr(pos) << std::endl;
+ std::cout << "p*mean = " << (pos*mean) << std::endl;
+ std::cout << "p-mean = " << (pos-mean) << std::endl;
+ std::cout << "(p-mean)² = " << mln::math::sqr(pos-mean) << std::endl;
+ std::cout << "histo(p) = " << histo(p) << std::endl;
+ std::cout << "histo(p)*p = " << (pos*histo(p)) << std::endl;
+ std::cout << "histo(p)*p²= " << (mln::math::sqr(pos)*histo(p))
+ << std::endl;
+ std::cout << "cnt = " << cnt << std::endl;
+ std::cout << "sum = " << sum << std::endl;
+ std::cout << "sqr = " << sqr << std::endl;
+ std::cout << "dlt = " << dlt << std::endl;
+ std::cout << "mxt = " << mxt << std::endl;
+ std::cout << std::endl;
+ }
+
+ std::cout << "sqr/cnt = " << (sqr/cnt) << std::endl;
+ std::cout << "sum/cnt = " << (sum/cnt) << std::endl;
+ std::cout << "(sum/cnt)² = " << mln::math::sqr(sum/cnt) << std::endl;
+ std::cout << "dlt/cnt = " << dlt/cnt << std::endl;
+ std::cout << "mxt/cnt = " << mxt/cnt << std::endl;
+ std::cout << std::endl;
+
+ std::cout << "sqr = "
+ << (sqr) << std::endl;
+ std::cout << "dlt = "
+ << (dlt) << std::endl;
+ std::cout << "cnt*avg² = "
+ << (mln::math::sqr(sum/cnt)*cnt) << std::endl;
+ std::cout << "2*mxt = "
+ << (2*mxt) << std::endl;
+ std::cout << "sqr - cnt*avg² = "
+ << (sqr/cnt - mln::math::sqr(sum/cnt)) << std::endl;
+ std::cout << "(sqr -2*mxt + cnt*avg²) = "
+ << ((sqr - 2*mxt + mln::math::sqr(sum/cnt))/cnt) << std::endl;
+ std::cout << std::endl;
+ return (0 == cnt)? 0 : sqr/cnt - mln::math::sqr(sum/cnt);
+}
+
+template <typename I>
+mln_value(I) var_histo(const mln::Image<I>& histo_)
+{
+ const I& histo = exact(histo_);
+
+ mln_precondition(histo.is_valid());
+
+ mln_value(I) pos = mln::literal::zero;
+ mln_value(I) sum = mln::literal::zero;
+ mln_value(I) sqr = mln::literal::zero;
+ mln_value(I) cnt = mln::literal::zero;
+ mln_piter(I) p(histo.domain());
+
+ for_all(p)
+ {
+ pos = p.ind();
+ cnt += (histo(p));
+ sum += (histo(p)*pos);
+ sqr += (histo(p)*mln::math::sqr(pos));
+ }
+
+ return (0 == cnt)? 0 : sqr/cnt - mln::math::sqr(sum/cnt);
+}
+
+//============================================================================//
+// CLASSIFIEUR
+//============================================================================//
+
+
+// Linear discriminant analysis in 1d
+// With same variance, threshold = (m1+m2)/2
+// With different variance, (m1*sqrt(v1)+m2*sqrt(v2))/(sqrt(v1)+sqrt(v2))
+float threshold_histo(float avg1, float var1, float avg2, float var2)
+{
+ float sigma1 = mln::math::sqrt(var1);
+ float sigma2 = mln::math::sqrt(var2);
+ float threshold = (avg1*sigma1+avg2*sigma2)/(sigma1+sigma2);
+
+ return threshold;
+}
+
+float threshold3_histo(float avg1, float var1, float avg2, float var2)
+{
+ float threshold = (avg1*var1+avg2*var2)/(var1+var2);
+
+ return threshold;
+}
+
+
+// if gaussian without the same variance
+float threshold2_histo(float avg1, float var1, float avg2, float var2)
+{
+ float a = var2 - var1;
+ float b = -2 * (avg1 * var2 - avg2 * var1);
+ float c = var2 * mln::math::sqr(avg1) - var1 * mln::math::sqr(avg2);
+ float d = mln::math::sqr(b) - 4 * a * c;
+
+ if (d < 0)
+ std::cout << "delta negatif" << std::endl;
+
+ float x1 = (-b+mln::math::sqrt(d))/(2*a);
+ float x2 = (-b-mln::math::sqrt(d))/(2*a);
+
+ std::cout << "a = " << a << std::endl;
+ std::cout << "b = " << b << std::endl;
+ std::cout << "c = " << c << std::endl;
+ std::cout << "d = " << d << std::endl;
+ std::cout << "x1 = " << x1 << std::endl;
+ std::cout << "x2 = " << x2 << std::endl;
+
+ return x2;
+}
+
+template <typename I>
+mln_value(I) sqr_histo(const mln::Image<I>& histo_)
+{
+ const I& histo = exact(histo_);
+
+ mln_precondition(histo.is_valid());
+
+ mln_value(I) sum = mln::literal::zero;
+ mln_piter(I) p(histo.domain());
+
+ for_all(p)
+ sum += (mln::math::sqr(p.ind())*histo(p));
+
+ return sum;
+}
+
+
+short min_error(const mln::image1d<float> histo_grp1,
+ const mln::image1d<float> histo_grp2,
+ float *_c00, float *_c10, float *_c01, float *_c11)
+{
+ float c00[256];
+ float c10[256];
+ float c01[256];
+ float c11[256];
+ float err[256];
+
+ for (short p = 0; p < 256; p++)
+ {
+ c00[p] = cnt_histo(histo_grp1|mln::box1d(mln::point1d(0),
+ mln::point1d(p)));
+
+ c10[p] = cnt_histo(histo_grp1|mln::box1d(mln::point1d(p+1),
+ mln::point1d(255)));
+
+ c01[p] = cnt_histo(histo_grp2|mln::box1d(mln::point1d(0),
+ mln::point1d(p)));
+
+ c11[p] = cnt_histo(histo_grp2|mln::box1d(mln::point1d(p+1),
+ mln::point1d(255)));
+ }
+
+ short threshold = 0;
+ float error = c01[0] + c01[0] + c00[0] + c11[0];
+
+ for(short p = 0; p < 256; p++)
+ {
+ err[p] = c10[p] + c01[p];
+
+// std::cout << " p = " << p
+// << ";c00 = " << c00[p]
+// << ";c10 = " << c10[p]
+// << ";c01 = " << c01[p]
+// << ";c11 = " << c11[p]
+// << std::endl;
+// std::cout << "err[" << p << "] = " << err[p] << std::endl;
+
+ if (error > err[p])
+ {
+ error = err[p];
+ threshold = p;
+ }
+ }
+
+ *_c00 = c00[threshold];
+ *_c10 = c10[threshold];
+ *_c01 = c01[threshold];
+ *_c11 = c11[threshold];
+
+ return threshold;
+}
+
+// return the threshold
+short fisher_analysis(const mln::image1d<float> histo)
+{
+ typedef mln::value::int_u8 t_int_u8;
+
+ // FIXE ME SIZE const short a = mln_min(t_int_u8);
+ // float cnt1[a];
+
+ float cnt1[256];
+ float sum1[256];
+ float sqr1[256];
+ float avg1[256];
+ float var1[256];
+
+ float cnt2[256];
+ float sum2[256];
+ float sqr2[256];
+ float avg2[256];
+ float var2[256];
+
+ float cnt0[256]; // count of points
+ float sum0[256]; // sum of population
+ float sqr0[256]; // sqr of population
+ float avg0[256]; // average of the population
+ float v_in[256]; // variance with-in class
+ float v_bw[256]; // variance between class
+ float var0[256]; // variance of the population
+ short threshold;
+ float pos;
+ float min_var;
+
+ // Assign the first elements
+ cnt1[0] = 0;
+ sum1[0] = 0;
+ sqr1[0] = 0;
+ avg1[0] = 0;
+ var1[0] = 0;
+
+ // Compute the stats of the wall histogram
+ cnt2[0] = 0;
+ sum2[0] = 0;
+ sqr2[0] = 0;
+
+ for(short p = 0; p < 256; p++)
+ {
+ pos = p;
+ cnt2[0] += mln::opt::at(histo,p);
+ sum2[0] += (pos * mln::opt::at(histo,p));
+ sqr2[0] += (mln::math::sqr(pos) * mln::opt::at(histo,p));
+ }
+
+ avg2[0] = (0 == cnt2[0])? 0 : sum2[0] / cnt2[0];
+ var2[0] = (0 == cnt2[0])? 0 : sqr2[0] / cnt2[0] - mln::math::sqr(avg2[0]);
+
+ // watch the array limits
+ for (short p = 1; p < 256; p++)
+ {
+ pos = p;
+
+ // Assign the statistics to the primary class
+ cnt1[p] = cnt1[p-1] + mln::opt::at(histo, p);
+ sum1[p] = sum1[p-1] + pos * mln::opt::at(histo, p);
+ sqr1[p] = sqr1[p-1] + mln::math::sqr(pos) * mln::opt::at(histo, p);
+ avg1[p] = (0 == cnt1[p])? 0 : (sum1[p] / cnt1[p]);
+ var1[p] = (0 == cnt1[p])? 0 : ((sqr1[p] / cnt1[p])-mln::math::sqr(avg1[p]));
+
+ // Assign the statistics to the second class
+ cnt2[p] = cnt2[p-1] - mln::opt::at(histo, p);;
+ sum2[p] = sum2[p-1] - p * mln::opt::at(histo, p);;
+ sqr2[p] = sqr2[p-1] - mln::math::sqr(p) * mln::opt::at(histo, p);;
+ avg2[p] = (0 == cnt2[p])? 0 : (sum2[p] / cnt2[p]);
+ var2[p] = (0 == cnt2[p])? 0 : ((sqr2[p] / cnt2[p])-mln::math::sqr(avg2[p]));
+
+ // Lets compute the invariants
+ cnt0[p] = cnt1[p] + cnt2[p];
+ sum0[p] = sum1[p] + sum2[p];
+ sqr0[p] = sqr1[p] + sqr2[p];
+ avg0[p] = (cnt1[p] * avg1[p] + cnt2[p] * avg2[p])/cnt0[p];
+ v_in[p] = (cnt1[p] * var1[p] + cnt2[p] * var2[p])/cnt0[p];
+ v_bw[p] = (cnt1[p] * mln::math::sqr(avg1[p]-avg0[p]) +
+ cnt2[p] * mln::math::sqr(avg2[p]-avg0[p]))/cnt0[p];
+ var0[p] = v_in[p] + v_bw[p];
+ }
+
+ // Find the threshold that minimizes the intra-class variance
+ min_var = cnt2[0]*var2[0];
+ threshold = 0;
+
+ for(short p = 0; p < 256; p++)
+ {
+ // Compute the intra-class variance
+ v_in[p] = cnt1[p]*var1[p] + cnt2[p]*var2[p];
+// std::cout << "var intra[" << p << "]= " << v_in[p] << std::endl;
+
+ if (min_var > v_in[p])
+ {
+ min_var = v_in[p];
+ threshold = p;
+ }
+ }
+
+ return threshold;
+}
+
+
+
+
+//============================================================================//
+// MAIN
+//============================================================================//
+
+
+
+
+
+#define LVL0_DESCR 0
+#define HUE0_DESCR 1
+#define HUE1_DESCR 2
+#define SAT0_DESCR 3
+#define SAT1_DESCR 4
+#define VAL0_DESCR 5
+#define VAL1_DESCR 6
+#define GMP0_DESCR 7
+#define GMP1_DESCR 8
+#define GMP2_DESCR 9
+#define MGK0_DESCR 9
+#define MGK1_DESCR 10
+#define MGK2_DESCR 11
+
+#define MGK_DESCR(version) (MGK0_DESCR + version)
+#define GMP_DESCR(version) (GMP0_DESCR + version)
+
+#define NB_DESCR 12
+#define NB_DATABASE 2
+#define NB_IMAGE 110
+#define NB_VERSION 3
+
+
+void init_descriptors(std::string file_name[],
+ float result[][NB_DESCR],
+ int size[])
+{
+ for (int i = 0; i < NB_IMAGE; i++)
+ {
+ file_name[i] = std::string("PGM");
+
+ for (int d = 0; d < NB_DESCR; d++)
+ result[i][d] = (i*d) % 256;
+ }
+
+ size[0] = 62;
+ size[1] = 48;
+}
+
+
+void dump_descriptors(const std::string file_name[],
+ const float result[][NB_DESCR],
+ const int size[])
+{
+ std::cout << "#!/usr/bin/gnuplot" << std::endl;
+ std::cout << "set terminal x11 persist 1" << std::endl;
+ std::cout << "plot '-' using 2 with point title 'ICDAR',\\" << std::endl;
+ std::cout << " '-' using 2 with point title 'AFP'" << std::endl;
+
+ int num = 0;
+
+ for (int db = 0; db < NB_DATABASE; db++)
+ {
+ for (int i = 0; i < size[db]; i++)
+ {
+ std::cout << result[num][LVL0_DESCR] << " ";
+ std::cout << result[num][HUE0_DESCR] << " ";
+ std::cout << result[num][HUE1_DESCR] << " ";
+ std::cout << result[num][SAT0_DESCR] << " ";
+ std::cout << result[num][SAT1_DESCR] << " ";
+ std::cout << result[num][VAL0_DESCR] << " ";
+ std::cout << result[num][VAL1_DESCR] << " ";
+ std::cout << result[num][GMP0_DESCR] << " ";
+ std::cout << result[num][GMP1_DESCR] << " ";
+ std::cout << result[num][GMP2_DESCR] << " ";
+ std::cout << result[num][MGK0_DESCR] << " ";
+ std::cout << result[num][MGK1_DESCR] << " ";
+ std::cout << result[num][MGK2_DESCR] << " ";
+ std::cout << " # " << file_name[num] << std::endl;
+ num++;
+ }
+
+ std::cout << "e" << std::endl;
+ }
+}
+
+void compute_histo(const float result[][NB_DESCR],
+ const int size[],
+ mln::image1d<float> histo[][NB_DATABASE])
+{
+ for (int i = 0; i < NB_DESCR; i++)
+ for (int db = 0; db < NB_DATABASE; db++)
+ {
+ histo[i][db].init_(mln::box1d(mln::point1d(0),mln::point1d(255)));
+
+ mln::data::fill(histo[i][db], mln::literal::zero);
+ }
+
+ short v;
+ int num = 0;
+
+ for (int db = 0; db < NB_DATABASE; db++)
+ {
+ for (int i = 0; i < size[db]; i++)
+ {
+ v = (short)mln::math::floor(result[num][VAR0_DESCR]+0.4999);
+ mln::opt::at(histo[VAR0_DESCR][db],v)++;
+
+ v = (short)mln::math::floor(result[num][LVL0_DESCR]+0.4999);
+ mln::opt::at(histo[LVL0_DESCR][db],v)++;
+
+ v = (short)mln::math::floor(result[num][HUE0_DESCR]+0.4999);
+ mln::opt::at(histo[HUE0_DESCR][db],v)++;
+
+ v = (short)mln::math::floor(result[num][HUE1_DESCR]+0.4999);
+ mln::opt::at(histo[HUE1_DESCR][db],v)++;
+
+ v = (short)mln::math::floor(result[num][SAT0_DESCR]+0.4999);
+ mln::opt::at(histo[SAT0_DESCR][db],v)++;
+
+ v = (short)mln::math::floor(result[num][SAT1_DESCR]+0.4999);
+ mln::opt::at(histo[SAT1_DESCR][db],v)++;
+
+ v = (short)mln::math::floor(result[num][VAL0_DESCR]+0.4999);
+ mln::opt::at(histo[VAL0_DESCR][db],v)++;
+
+ v = (short)mln::math::floor(result[num][GMP0_DESCR]+0.4999);
+ mln::opt::at(histo[GMP0_DESCR][db],v)++;
+
+ v = (short)mln::math::floor(result[num][GMP1_DESCR]+0.4999);
+ mln::opt::at(histo[GMP1_DESCR][db],v)++;
+
+ v = (short)mln::math::floor(result[num][GMP2_DESCR]+0.4999);
+ mln::opt::at(histo[GMP2_DESCR][db],v)++;
+
+ v = (short)mln::math::floor(result[num][MGK0_DESCR]+0.4999);
+ mln::opt::at(histo[MGK0_DESCR][db],v)++;
+
+ v = (short)mln::math::floor(result[num][MGK1_DESCR]+0.4999);
+ mln::opt::at(histo[MGK1_DESCR][db],v)++;
+
+ v = (short)mln::math::floor(result[num][MGK2_DESCR]+0.4999);
+ mln::opt::at(histo[MGK2_DESCR][db],v)++;
+
+ num++;
+ }
+ }
+}
+
+void compute_thresholds(const mln::image1d<float> histo[][NB_DATABASE],
+ short threshold[],
+ float c00[],
+ float c10[],
+ float c01[],
+ float c11[])
+{
+ for (int i = 0; i < NB_DESCR; i++)
+ {
+ float avg0 = avg_histo(histo[i][0]);
+ float avg1 = avg_histo(histo[i][1]);
+
+ if (avg0 < avg1)
+ {
+ threshold[i] = min_error(histo[i][0], histo[i][1],
+ &c00[i], &c10[i], &c01[i], &c11[i]);
+ }
+ else
+ {
+ threshold[i] = min_error(histo[i][1], histo[i][0],
+ &c00[i], &c10[i], &c01[i], &c11[i]);
+ }
+
+ std::cerr << " i = " << i
+ << "; c00 = " << c00[i]
+ << "; c10 = " << c10[i]
+ << "; c01 = " << c01[i]
+ << "; c11 = " << c11[i]
+ << "; threshold " << threshold[i]
+ << std::endl;
+
+ }
+}
+
+
+void compute_descriptors(std::string file_name[],
+ float result[][NB_DESCR],
+ int size[])
+{
+ typedef boost::filesystem::path t_path;
+ typedef boost::filesystem::directory_iterator t_iter_path;
+ typedef mln::image1d<unsigned> t_histo;
+ typedef mln::value::rgb8 t_rgb8;
+ typedef mln::value::int_u8 t_int_u8;
+ typedef mln::image2d<t_int_u8> t_map;
+ typedef mln::image2d<t_rgb8> t_input;
+ typedef mln::fun::v2v::rgb_to_hue_map<8> t_rgb_2_hue;
+ typedef mln::fun::v2v::rgb_to_saturation_map<8> t_rgb_2_sat;
+ typedef mln::fun::v2v::rgb_to_value_map<8> t_rgb_2_val;
+ typedef mln::fun::v2v::component<t_rgb8,0> t_rgb_2_red;
+ typedef mln::fun::v2v::component<t_rgb8,1> t_rgb_2_green;
+ typedef mln::fun::v2v::component<t_rgb8,2> t_rgb_2_blue;
+ typedef mln::accu::meta::stat::histo1d t_accu_histo;
+
+
+ t_path img_path[2] = { ICDAR_20P_INPUT_IMG_PATH, AFP_PPM_IMG_PATH};
+ t_path mgk_path[3][2] = {{ICDAR_20P_MGK30_IMG_PATH, AFP_MGK30_IMG_PATH},
+ {ICDAR_20P_MGK20_IMG_PATH, AFP_MGK20_IMG_PATH},
+ {ICDAR_20P_MGK10_IMG_PATH, AFP_MGK10_IMG_PATH}};
+ t_path gmp_path[3][2] = {{ICDAR_20P_GMP30_IMG_PATH, AFP_GMP30_IMG_PATH},
+ {ICDAR_20P_GMP20_IMG_PATH, AFP_GMP20_IMG_PATH},
+ {ICDAR_20P_GMP10_IMG_PATH, AFP_GMP10_IMG_PATH}};
+
+ int num = 0;
+ int cnt = 0;
+
+ for (int db = 0; db < NB_DATABASE; db++)
+ {
+ if (boost::filesystem::exists(img_path[db]) &&
+ boost::filesystem::is_directory(img_path[db]))
+ {
+ boost::filesystem::system_complete(img_path[db]);
+
+ const t_iter_path end_iter;
+
+ cnt = 0;
+
+ for (t_iter_path dir_iter(img_path[db]); end_iter != dir_iter; ++dir_iter)
+ {
+ t_path img_file = dir_iter->path().leaf();
+ t_path dir_file = dir_iter->path();
+ t_input img_input;
+
+ mln::io::ppm::load(img_input, dir_file.string().c_str());
+
+ t_map h_img_map = mln::data::transform(img_input, t_rgb_2_hue());
+ t_map s_img_map = mln::data::transform(img_input, t_rgb_2_sat());
+ t_map v_img_map = mln::data::transform(img_input, t_rgb_2_val());
+ t_map r_img_map = mln::data::transform(img_input, t_rgb_2_red());
+ t_map g_img_map = mln::data::transform(img_input, t_rgb_2_green());
+ t_map b_img_map = mln::data::transform(img_input, t_rgb_2_blue());
+ t_histo h_img_hst = mln::data::compute(t_accu_histo(), h_img_map);
+ t_histo s_img_hst = mln::data::compute(t_accu_histo(), s_img_map);
+ t_histo v_img_hst = mln::data::compute(t_accu_histo(), v_img_map);
+ t_histo r_img_hst = mln::data::compute(t_accu_histo(), r_img_map);
+ t_histo g_img_hst = mln::data::compute(t_accu_histo(), g_img_map);
+ t_histo b_img_hst = mln::data::compute(t_accu_histo(), b_img_map);
+
+ std::cerr << dir_iter->path() << std::endl;
+
+ file_name[num] = img_file.string();
+
+ // descriptors
+ result[num][LVL0_DESCR] = lvl0_descriptor(v_img_hst);
+ result[num][HUE0_DESCR] = hue0_descriptor(h_img_hst);
+ result[num][HUE1_DESCR] = hue1_descriptor(h_img_hst,20);
+ result[num][SAT0_DESCR] = sat0_descriptor(s_img_hst);
+ result[num][SAT1_DESCR] = sat1_descriptor(s_img_hst,50);
+ result[num][VAL0_DESCR] = val0_descriptor(v_img_hst);
+ //result[num][VAL1_DESCR] = var0_descriptor(v_img_hst, 15);
+ result[num][VAL1_DESCR] = 0;
+
+ // for gimp and magick
+ for (int v = 0; v < NB_VERSION; v++)
+ {
+ if (boost::filesystem::exists(mgk_path[v][db]) &&
+ boost::filesystem::exists(gmp_path[v][db]) &&
+ boost::filesystem::is_directory(mgk_path[v][db]) &&
+ boost::filesystem::is_directory(gmp_path[v][db]))
+ {
+ t_path mgk_file = mgk_path[v][db] / img_file;
+ t_path gmp_file = gmp_path[v][db] / img_file;
+ t_input gmp_input;
+
+ mln::io::ppm::load(gmp_input, gmp_file.string().c_str());
+
+ t_map r_gmp_map = mln::data::transform(gmp_input,t_rgb_2_red());
+ t_map g_gmp_map = mln::data::transform(gmp_input,t_rgb_2_green());
+ t_map b_gmp_map = mln::data::transform(gmp_input,t_rgb_2_blue());
+
+ result[num][GMP_DESCR(v)]= err_descriptor(r_img_map,
+ g_img_map,
+ b_img_map,
+ r_gmp_map,
+ g_gmp_map,
+ b_gmp_map);
+
+ t_input mgk_input;
+
+ mln::io::ppm::load(mgk_input, mgk_file.string().c_str());
+
+ t_map r_mgk_map = mln::data::transform(mgk_input,t_rgb_2_red());
+ t_map g_mgk_map = mln::data::transform(mgk_input,t_rgb_2_green());
+ t_map b_mgk_map = mln::data::transform(mgk_input,t_rgb_2_blue());
+
+ result[num][MGK_DESCR(v)]= err_descriptor(r_img_map,
+ g_img_map,
+ b_img_map,
+ r_mgk_map,
+ g_mgk_map,
+ b_mgk_map);
+ }
+ }
+
+ num++;
+ cnt++;
+ }
+ }
+
+ size[db] = cnt;
+ }
+}
+
+
+int main2()
+{
+ typedef mln::image1d<unsigned> t_histo;
+ typedef mln::value::rgb8 t_rgb8;
+ typedef mln::value::int_u8 t_int_u8;
+ typedef mln::image2d<t_int_u8> t_map;
+ typedef mln::image2d<t_rgb8> t_input;
+ typedef mln::fun::v2v::rgb_to_hue_map<8> t_rgb_2_hue;
+ typedef mln::fun::v2v::rgb_to_saturation_map<8> t_rgb_2_sat;
+ typedef mln::fun::v2v::rgb_to_value_map<8> t_rgb_2_val;
+ typedef mln::fun::v2v::component<t_rgb8,0> t_rgb_2_red;
+ typedef mln::fun::v2v::component<t_rgb8,1> t_rgb_2_green;
+ typedef mln::fun::v2v::component<t_rgb8,2> t_rgb_2_blue;
+ typedef mln::accu::meta::stat::histo1d t_accu_histo;
+
+ t_input img_input;
+
+ mln::io::ppm::load(img_input, ICDAR_20P_INPUT_IMG_PATH"/mp00032c_20p.ppm");
+ //mln::io::ppm::load(img_input, AFP_PPM_IMG_PATH"/000_Del218430.ppm");
+
+
+
+ t_map h_img_map = mln::data::transform(img_input, t_rgb_2_hue());
+ t_map s_img_map = mln::data::transform(img_input, t_rgb_2_sat());
+ t_map v_img_map = mln::data::transform(img_input, t_rgb_2_val());
+ t_map r_img_map = mln::data::transform(img_input, t_rgb_2_red());
+ t_map g_img_map = mln::data::transform(img_input, t_rgb_2_green());
+ t_map b_img_map = mln::data::transform(img_input, t_rgb_2_blue());
+ t_histo h_img_hst = mln::data::compute(t_accu_histo(), h_img_map);
+ t_histo s_img_hst = mln::data::compute(t_accu_histo(), s_img_map);
+ t_histo v_img_hst = mln::data::compute(t_accu_histo(), v_img_map);
+ t_histo r_img_hst = mln::data::compute(t_accu_histo(), r_img_map);
+ t_histo g_img_hst = mln::data::compute(t_accu_histo(), g_img_map);
+ t_histo b_img_hst = mln::data::compute(t_accu_histo(), b_img_map);
+
+
+ std::cout << "sat2 : " << sat0_descriptor(s_img_hst) << std::endl;
+
+ return 0;
+}
+
+int main()
+{
+ std::string file_name[NB_IMAGE];
+ float result[NB_IMAGE][NB_DESCR];
+ int size[NB_DATABASE];
+ mln::image1d<float> histo[NB_DESCR][NB_DATABASE];
+ short threshold[NB_DESCR];
+ float c00[NB_DESCR];
+ float c10[NB_DESCR];
+ float c01[NB_DESCR];
+ float c11[NB_DESCR];
+
+ std::cerr << "DESCRIPTORS" << std::endl;
+ compute_descriptors(file_name,result,size);
+// std::cout << "DUMPING" << std::endl;
+// init_descriptors(file_name,result,size);
+ dump_descriptors(file_name,result,size);
+ std::cerr << "HISTO" << std::endl;
+ compute_histo(result,size,histo);
+ std::cerr << "THRESHOLD" << std::endl;
+ compute_thresholds(histo,threshold,c00,c10,c01,c11);
+
+ mln::io::plot::save_image_sh(histo[LVL0_DESCR][0], "lvl0_histo1.sh");
+ mln::io::plot::save_image_sh(histo[HUE0_DESCR][0], "hue0_histo1.sh");
+ mln::io::plot::save_image_sh(histo[HUE1_DESCR][0], "hue1_histo1.sh");
+ mln::io::plot::save_image_sh(histo[SAT0_DESCR][0], "sat0_histo1.sh");
+ mln::io::plot::save_image_sh(histo[SAT1_DESCR][0], "sat1_histo1.sh");
+ mln::io::plot::save_image_sh(histo[VAL0_DESCR][0], "val0_histo1.sh");
+ mln::io::plot::save_image_sh(histo[VAL1_DESCR][0], "val1_histo1.sh");
+ mln::io::plot::save_image_sh(histo[GMP0_DESCR][0], "gmp0_histo1.sh");
+ mln::io::plot::save_image_sh(histo[GMP1_DESCR][0], "gmp1_histo1.sh");
+ mln::io::plot::save_image_sh(histo[GMP2_DESCR][0], "gmp2_histo1.sh");
+ mln::io::plot::save_image_sh(histo[MGK0_DESCR][0], "mgk0_histo1.sh");
+ mln::io::plot::save_image_sh(histo[MGK1_DESCR][0], "mgk1_histo1.sh");
+ mln::io::plot::save_image_sh(histo[MGK2_DESCR][0], "mgk2_histo1.sh");
+
+ mln::io::plot::save_image_sh(histo[LVL0_DESCR][1], "lvl0_histo2.sh");
+ mln::io::plot::save_image_sh(histo[HUE0_DESCR][1], "hue0_histo2.sh");
+ mln::io::plot::save_image_sh(histo[HUE1_DESCR][1], "hue1_histo2.sh");
+ mln::io::plot::save_image_sh(histo[SAT0_DESCR][1], "sat0_histo2.sh");
+ mln::io::plot::save_image_sh(histo[SAT1_DESCR][1], "sat1_histo2.sh");
+ mln::io::plot::save_image_sh(histo[VAL0_DESCR][1], "val0_histo2.sh");
+ mln::io::plot::save_image_sh(histo[VAL1_DESCR][1], "val1_histo2.sh");
+ mln::io::plot::save_image_sh(histo[GMP0_DESCR][1], "gmp0_histo2.sh");
+ mln::io::plot::save_image_sh(histo[GMP1_DESCR][1], "gmp1_histo2.sh");
+ mln::io::plot::save_image_sh(histo[GMP2_DESCR][1], "gmp2_histo2.sh");
+ mln::io::plot::save_image_sh(histo[MGK0_DESCR][1], "mgk0_histo2.sh");
+ mln::io::plot::save_image_sh(histo[MGK1_DESCR][1], "mgk1_histo2.sh");
+ mln::io::plot::save_image_sh(histo[MGK2_DESCR][1], "mgk2_histo2.sh");
+
+ return 0;
+}
+
--
1.5.6.5
1
0
last-svn-commit-31-g2f05ef3 Test error quantification as a color descriptor in our database.
by Yann Jacquelet 15 Nov '10
by Yann Jacquelet 15 Nov '10
15 Nov '10
* green/exp/annotating/error: New directory.
* green/exp/annotating/error/Makefile.am: New Makefile.
* green/exp/annotating/error/error.cc: New source.
---
.../annotating/{achromastism => error}/Makefile.am | 0
milena/sandbox/green/exp/annotating/error/error.cc | 700 ++++++++++++++++++++
2 files changed, 700 insertions(+), 0 deletions(-)
copy milena/sandbox/green/exp/annotating/{achromastism => error}/Makefile.am (100%)
create mode 100644 milena/sandbox/green/exp/annotating/error/error.cc
diff --git a/milena/sandbox/green/exp/annotating/achromastism/Makefile.am b/milena/sandbox/green/exp/annotating/error/Makefile.am
similarity index 100%
copy from milena/sandbox/green/exp/annotating/achromastism/Makefile.am
copy to milena/sandbox/green/exp/annotating/error/Makefile.am
diff --git a/milena/sandbox/green/exp/annotating/error/error.cc b/milena/sandbox/green/exp/annotating/error/error.cc
new file mode 100644
index 0000000..5bc67ba
--- /dev/null
+++ b/milena/sandbox/green/exp/annotating/error/error.cc
@@ -0,0 +1,700 @@
+// HSV TEST CF MILLET 2008
+
+#include <iostream>
+#include <sstream>
+#include <boost/filesystem.hpp>
+
+#include <mln/algebra/vec.hh>
+
+#include <mln/img_path.hh>
+
+#include <mln/accu/stat/mean.hh>
+#include <mln/accu/stat/histo1d.hh>
+
+#include <mln/arith/minus.hh>
+#include <mln/arith/times.hh>
+#include <mln/arith/diff_abs.hh>
+
+#include <mln/core/image/image1d.hh>
+#include <mln/core/image/image2d.hh>
+#include <mln/core/image/dmorph/image_if.hh>
+#include <mln/core/alias/point1d.hh>
+#include <mln/core/alias/box1d.hh>
+
+#include <mln/data/transform.hh>
+#include <mln/data/compute.hh>
+#include <mln/data/stretch.hh>
+#include <mln/data/fill.hh>
+
+#include <mln/fun/v2v/component.hh>
+
+#include <mln/io/ppm/load.hh>
+#include <mln/io/pgm/save.hh>
+#include <mln/io/plot/save_image_sh.hh>
+
+#include <mln/literal/zero.hh>
+
+#include <mln/math/ceil.hh>
+#include <mln/math/floor.hh>
+
+#include <mln/opt/at.hh>
+
+#include <mln/trait/value_.hh>
+
+#include <mln/value/rgb8.hh>
+#include <mln/value/int_u8.hh>
+
+//============================================================================//
+// CLASSIFICATION DE FISHER EN 2 CLASSES SUR UN HISTO 1D
+//============================================================================//
+
+template <typename I>
+mln_value(I) cnt_histo(const mln::Image<I>& histo_)
+{
+ const I& histo = exact(histo_);
+
+ mln_precondition(histo.is_valid());
+
+ mln_value(I) sum = mln::literal::zero;
+ mln_piter(I) p(histo.domain());
+
+ for_all(p)
+ {
+ sum += histo(p);
+ }
+
+ return sum;
+}
+
+template <typename I>
+mln_value(I) sum_histo(const mln::Image<I>& histo_)
+{
+ const I& histo = exact(histo_);
+
+ mln_precondition(histo.is_valid());
+
+ mln_value(I) pos = mln::literal::zero;
+ mln_value(I) sum = mln::literal::zero;
+ mln_piter(I) p(histo.domain());
+
+ for_all(p)
+ {
+ pos = p.ind();
+ sum += pos*histo(p);
+ }
+
+ return sum;
+}
+
+template <typename I>
+mln_value(I) avg_histo(const mln::Image<I>& histo_)
+{
+ const I& histo = exact(histo_);
+
+ mln_precondition(histo.is_valid());
+
+ mln_value(I) pos = mln::literal::zero;
+ mln_value(I) sum = mln::literal::zero;
+ mln_value(I) cnt = mln::literal::zero;
+ mln_piter(I) p(histo.domain());
+
+ for_all(p)
+ {
+ pos = p.ind();
+ cnt += histo(p);
+ sum += pos*histo(p);
+ }
+
+ return (0 == cnt)? 0 : sum/cnt;
+}
+
+template <typename I>
+mln_value(I) var3_histo(const mln::Image<I>& histo_, float mean)
+{
+ const I& histo = exact(histo_);
+
+ mln_precondition(histo.is_valid());
+
+ mln_value(I) pos = mln::literal::zero;
+ mln_value(I) sum = mln::literal::zero;
+ mln_value(I) cnt = mln::literal::zero;
+ mln_piter(I) p(histo.domain());
+
+ for_all(p)
+ {
+ cnt += histo(p);
+ sum += (mln::math::sqr(p.ind()-mean)*histo(p));
+ }
+
+ return (0 == cnt)? 0 : sum/cnt;
+}
+
+template <typename I>
+mln_value(I) var2_histo(const mln::Image<I>& histo_, float mean)
+{
+ const I& histo = exact(histo_);
+
+ mln_precondition(histo.is_valid());
+
+ mln_value(I) pos = mln::literal::zero;
+ mln_value(I) sum = mln::literal::zero;
+ mln_value(I) sqr = mln::literal::zero;
+ mln_value(I) cnt = mln::literal::zero;
+ mln_value(I) dlt = mln::literal::zero;
+ mln_value(I) mxt = mln::literal::zero;
+ mln_piter(I) p(histo.domain());
+
+ for_all(p)
+ {
+ pos = p.ind();
+ cnt += (histo(p));
+ sum += (histo(p)*pos);
+ mxt += (histo(p)*pos*mean);
+ sqr += (histo(p)*mln::math::sqr(pos));
+ dlt += (histo(p)*mln::math::sqr(pos - mean));
+
+ std::cout << "p = " << pos << std::endl;
+ std::cout << "p² = " << mln::math::sqr(pos) << std::endl;
+ std::cout << "p*mean = " << (pos*mean) << std::endl;
+ std::cout << "p-mean = " << (pos-mean) << std::endl;
+ std::cout << "(p-mean)² = " << mln::math::sqr(pos-mean) << std::endl;
+ std::cout << "histo(p) = " << histo(p) << std::endl;
+ std::cout << "histo(p)*p = " << (pos*histo(p)) << std::endl;
+ std::cout << "histo(p)*p²= " << (mln::math::sqr(pos)*histo(p))
+ << std::endl;
+ std::cout << "cnt = " << cnt << std::endl;
+ std::cout << "sum = " << sum << std::endl;
+ std::cout << "sqr = " << sqr << std::endl;
+ std::cout << "dlt = " << dlt << std::endl;
+ std::cout << "mxt = " << mxt << std::endl;
+ std::cout << std::endl;
+ }
+
+ std::cout << "sqr/cnt = " << (sqr/cnt) << std::endl;
+ std::cout << "sum/cnt = " << (sum/cnt) << std::endl;
+ std::cout << "(sum/cnt)² = " << mln::math::sqr(sum/cnt) << std::endl;
+ std::cout << "dlt/cnt = " << dlt/cnt << std::endl;
+ std::cout << "mxt/cnt = " << mxt/cnt << std::endl;
+ std::cout << std::endl;
+
+ std::cout << "sqr = "
+ << (sqr) << std::endl;
+ std::cout << "dlt = "
+ << (dlt) << std::endl;
+ std::cout << "cnt*avg² = "
+ << (mln::math::sqr(sum/cnt)*cnt) << std::endl;
+ std::cout << "2*mxt = "
+ << (2*mxt) << std::endl;
+ std::cout << "sqr - cnt*avg² = "
+ << (sqr/cnt - mln::math::sqr(sum/cnt)) << std::endl;
+ std::cout << "(sqr -2*mxt + cnt*avg²) = "
+ << ((sqr - 2*mxt + mln::math::sqr(sum/cnt))/cnt) << std::endl;
+ std::cout << std::endl;
+ return (0 == cnt)? 0 : sqr/cnt - mln::math::sqr(sum/cnt);
+}
+
+template <typename I>
+mln_value(I) var_histo(const mln::Image<I>& histo_)
+{
+ const I& histo = exact(histo_);
+
+ mln_precondition(histo.is_valid());
+
+ mln_value(I) pos = mln::literal::zero;
+ mln_value(I) sum = mln::literal::zero;
+ mln_value(I) sqr = mln::literal::zero;
+ mln_value(I) cnt = mln::literal::zero;
+ mln_piter(I) p(histo.domain());
+
+ for_all(p)
+ {
+ pos = p.ind();
+ cnt += (histo(p));
+ sum += (histo(p)*pos);
+ sqr += (histo(p)*mln::math::sqr(pos));
+ }
+
+ return (0 == cnt)? 0 : sqr/cnt - mln::math::sqr(sum/cnt);
+}
+
+//============================================================================//
+// CLASSIFIEUR
+//============================================================================//
+
+
+// Linear discriminant analysis in 1d
+// With same variance, threshold = (m1+m2)/2
+// With different variance, (m1*sqrt(v1)+m2*sqrt(v2))/(sqrt(v1)+sqrt(v2))
+float threshold_histo(float avg1, float var1, float avg2, float var2)
+{
+ float sigma1 = mln::math::sqrt(var1);
+ float sigma2 = mln::math::sqrt(var2);
+ float threshold = (avg1*sigma1+avg2*sigma2)/(sigma1+sigma2);
+
+ return threshold;
+}
+
+float threshold3_histo(float avg1, float var1, float avg2, float var2)
+{
+ float threshold = (avg1*var1+avg2*var2)/(var1+var2);
+
+ return threshold;
+}
+
+
+// if gaussian without the same variance
+float threshold2_histo(float avg1, float var1, float avg2, float var2)
+{
+ float a = var2 - var1;
+ float b = -2 * (avg1 * var2 - avg2 * var1);
+ float c = var2 * mln::math::sqr(avg1) - var1 * mln::math::sqr(avg2);
+ float d = mln::math::sqr(b) - 4 * a * c;
+
+ if (d < 0)
+ std::cout << "delta negatif" << std::endl;
+
+ float x1 = (-b+mln::math::sqrt(d))/(2*a);
+ float x2 = (-b-mln::math::sqrt(d))/(2*a);
+
+ std::cout << "a = " << a << std::endl;
+ std::cout << "b = " << b << std::endl;
+ std::cout << "c = " << c << std::endl;
+ std::cout << "d = " << d << std::endl;
+ std::cout << "x1 = " << x1 << std::endl;
+ std::cout << "x2 = " << x2 << std::endl;
+
+ return x2;
+}
+
+template <typename I>
+mln_value(I) sqr_histo(const mln::Image<I>& histo_)
+{
+ const I& histo = exact(histo_);
+
+ mln_precondition(histo.is_valid());
+
+ mln_value(I) sum = mln::literal::zero;
+ mln_piter(I) p(histo.domain());
+
+ for_all(p)
+ sum += (mln::math::sqr(p.ind())*histo(p));
+
+ return sum;
+}
+
+
+short min_error(const mln::image1d<float> histo_grp1,
+ const mln::image1d<float> histo_grp2)
+{
+ float c00[256];
+ float c10[256];
+ float c01[256];
+ float c11[256];
+ float err[256];
+
+ for (short p = 0; p < 256; p++)
+ {
+ c00[p] = cnt_histo(histo_grp1|mln::box1d(mln::point1d(0),
+ mln::point1d(p)));
+
+ c10[p] = cnt_histo(histo_grp1|mln::box1d(mln::point1d(p+1),
+ mln::point1d(255)));
+
+ c01[p] = cnt_histo(histo_grp2|mln::box1d(mln::point1d(0),
+ mln::point1d(p)));
+
+ c11[p] = cnt_histo(histo_grp2|mln::box1d(mln::point1d(p+1),
+ mln::point1d(255)));
+ }
+
+ short threshold = 0;
+ float error = c01[0] + c01[0] + c00[0] + c11[0];
+
+ for(short p = 0; p < 256; p++)
+ {
+ err[p] = c10[p] + c01[p];
+
+ std::cout << " p = " << p
+ << ";c00 = " << c00[p]
+ << ";c10 = " << c10[p]
+ << ";c01 = " << c01[p]
+ << ";c11 = " << c11[p]
+ << std::endl;
+// std::cout << "err[" << p << "] = " << err[p] << std::endl;
+
+ if (error > err[p])
+ {
+ error = err[p];
+ threshold = p;
+ }
+ }
+
+ return threshold;
+}
+
+// return the threshold
+short fisher_analysis(const mln::image1d<float> histo)
+{
+ typedef mln::value::int_u8 t_int_u8;
+
+ // FIXE ME SIZE const short a = mln_min(t_int_u8);
+ // float cnt1[a];
+
+ float cnt1[256];
+ float sum1[256];
+ float sqr1[256];
+ float avg1[256];
+ float var1[256];
+
+ float cnt2[256];
+ float sum2[256];
+ float sqr2[256];
+ float avg2[256];
+ float var2[256];
+
+ float cnt0[256]; // count of points
+ float sum0[256]; // sum of population
+ float sqr0[256]; // sqr of population
+ float avg0[256]; // average of the population
+ float v_in[256]; // variance with-in class
+ float v_bw[256]; // variance between class
+ float var0[256]; // variance of the population
+ short threshold;
+ float pos;
+ float min_var;
+
+ // Assign the first elements
+ cnt1[0] = 0;
+ sum1[0] = 0;
+ sqr1[0] = 0;
+ avg1[0] = 0;
+ var1[0] = 0;
+
+ // Compute the stats of the wall histogram
+ cnt2[0] = 0;
+ sum2[0] = 0;
+ sqr2[0] = 0;
+
+ for(short p = 0; p < 256; p++)
+ {
+ pos = p;
+ cnt2[0] += mln::opt::at(histo,p);
+ sum2[0] += (pos * mln::opt::at(histo,p));
+ sqr2[0] += (mln::math::sqr(pos) * mln::opt::at(histo,p));
+ }
+
+ avg2[0] = (0 == cnt2[0])? 0 : sum2[0] / cnt2[0];
+ var2[0] = (0 == cnt2[0])? 0 : sqr2[0] / cnt2[0] - mln::math::sqr(avg2[0]);
+
+ // watch the array limits
+ for (short p = 1; p < 256; p++)
+ {
+ pos = p;
+
+ // Assign the statistics to the primary class
+ cnt1[p] = cnt1[p-1] + mln::opt::at(histo, p);
+ sum1[p] = sum1[p-1] + pos * mln::opt::at(histo, p);
+ sqr1[p] = sqr1[p-1] + mln::math::sqr(pos) * mln::opt::at(histo, p);
+ avg1[p] = (0 == cnt1[p])? 0 : (sum1[p] / cnt1[p]);
+ var1[p] = (0 == cnt1[p])? 0 : ((sqr1[p] / cnt1[p])-mln::math::sqr(avg1[p]));
+
+ // Assign the statistics to the second class
+ cnt2[p] = cnt2[p-1] - mln::opt::at(histo, p);;
+ sum2[p] = sum2[p-1] - p * mln::opt::at(histo, p);;
+ sqr2[p] = sqr2[p-1] - mln::math::sqr(p) * mln::opt::at(histo, p);;
+ avg2[p] = (0 == cnt2[p])? 0 : (sum2[p] / cnt2[p]);
+ var2[p] = (0 == cnt2[p])? 0 : ((sqr2[p] / cnt2[p])-mln::math::sqr(avg2[p]));
+
+ // Lets compute the invariants
+ cnt0[p] = cnt1[p] + cnt2[p];
+ sum0[p] = sum1[p] + sum2[p];
+ sqr0[p] = sqr1[p] + sqr2[p];
+ avg0[p] = (cnt1[p] * avg1[p] + cnt2[p] * avg2[p])/cnt0[p];
+ v_in[p] = (cnt1[p] * var1[p] + cnt2[p] * var2[p])/cnt0[p];
+ v_bw[p] = (cnt1[p] * mln::math::sqr(avg1[p]-avg0[p]) +
+ cnt2[p] * mln::math::sqr(avg2[p]-avg0[p]))/cnt0[p];
+ var0[p] = v_in[p] + v_bw[p];
+ }
+
+ // Find the threshold that minimizes the intra-class variance
+ min_var = cnt2[0]*var2[0];
+ threshold = 0;
+
+ for(short p = 0; p < 256; p++)
+ {
+ // Compute the intra-class variance
+ v_in[p] = cnt1[p]*var1[p] + cnt2[p]*var2[p];
+// std::cout << "var intra[" << p << "]= " << v_in[p] << std::endl;
+
+ if (min_var > v_in[p])
+ {
+ min_var = v_in[p];
+ threshold = p;
+ }
+ }
+
+ return threshold;
+}
+
+
+//============================================================================//
+// ERROR (MSE, PNSNR) compression p278 Handbook Color
+//============================================================================//
+
+float error_test(const std::string original,
+ const std::string reduced)
+
+{
+
+ typedef mln::value::rgb8 t_rgb8;
+ typedef mln::value::int_u8 t_int_u8;
+ typedef mln::fun::v2v::component<t_rgb8,0> t_component_red;
+ typedef mln::fun::v2v::component<t_rgb8,1> t_component_green;
+ typedef mln::fun::v2v::component<t_rgb8,2> t_component_blue;
+ typedef mln::accu::meta::stat::mean t_mean;
+ typedef mln::accu::meta::stat::histo1d t_histo;
+ typedef mln::image2d<t_int_u8> t_img;
+ typedef mln_trait_op_minus_(t_img,t_img) t_minus;
+ typedef mln_trait_op_times_(t_minus,t_minus) t_times;
+
+ mln::image2d<mln::value::rgb8> original_rgb8;
+ mln::image2d<mln::value::rgb8> reduced_rgb8;
+
+ mln::image2d<mln::value::int_u8> original_red;
+ mln::image2d<mln::value::int_u8> original_green;
+ mln::image2d<mln::value::int_u8> original_blue;
+
+ mln::image2d<mln::value::int_u8> reduced_red;
+ mln::image2d<mln::value::int_u8> reduced_green;
+ mln::image2d<mln::value::int_u8> reduced_blue;
+
+// mln::image2d<mln::value::int_u8> map_red;
+// mln::image2d<mln::value::int_u8> map_green;
+// mln::image2d<mln::value::int_u8> map_blue;
+
+// mln::image1d<unsigned> histo_red;
+// mln::image1d<unsigned> histo_green;
+// mln::image1d<unsigned> histo_blue;
+
+ t_minus minus_red;
+ t_minus minus_green;
+ t_minus minus_blue;
+
+ t_times times_red;
+ t_times times_green;
+ t_times times_blue;
+
+ float error_red;
+ float error_green;
+ float error_blue;
+
+ float error;
+
+
+ mln::io::ppm::load(original_rgb8, original.c_str());
+ mln::io::ppm::load(reduced_rgb8, reduced.c_str());
+
+ original_red = mln::data::transform(original_rgb8, t_component_red());
+ original_green = mln::data::transform(original_rgb8, t_component_green());
+ original_blue = mln::data::transform(original_rgb8, t_component_blue());
+
+ reduced_red = mln::data::transform(reduced_rgb8, t_component_red());
+ reduced_green = mln::data::transform(reduced_rgb8, t_component_green());
+ reduced_blue = mln::data::transform(reduced_rgb8, t_component_blue());
+
+ minus_red = (original_red - reduced_red);
+ times_red = minus_red * minus_red;
+
+ minus_green = (original_green - reduced_green);
+ times_green = minus_green * minus_green;
+
+ minus_blue = (original_blue - reduced_blue);
+ times_blue = minus_blue * minus_blue;
+
+ error_red = mln::data::compute(t_mean(), times_red);
+ error_green = mln::data::compute(t_mean(), times_green);
+ error_blue = mln::data::compute(t_mean(), times_blue);
+
+// map_red = mln::data::stretch(t_int_u8(), times_red);
+// map_green = mln::data::stretch(t_int_u8(), times_blue);
+// map_blue = mln::data::stretch(t_int_u8(), times_green);
+
+// histo_red = mln::data::compute(t_histo(), map_red);
+// histo_green = mln::data::compute(t_histo(), map_green);
+// histo_blue = mln::data::compute(t_histo(), map_blue);
+
+// mln::io::plot::save_image_sh(histo_red, "histo_red.sh");
+// mln::io::plot::save_image_sh(histo_green,"histo_green.sh");
+// mln::io::plot::save_image_sh(histo_blue, "histo_blue.sh");
+
+// mln::io::pgm::save(map_red, "red.pgm");
+// mln::io::pgm::save(map_green,"green.pgm");
+// mln::io::pgm::save(map_blue, "blue.pgm");
+
+ error = (error_red + error_green + error_blue)/3.0;
+ error = mln::math::sqrt(error);
+ error = 20 * log(255/error);
+
+// Le PNSNR semble offrir plus d'espace pour la discrimination
+// Si les images sont identiques ==> PNSNR = +inf
+// Si les images sont très différentes ==> PNSNR = 0
+
+ return error;
+}
+
+
+//============================================================================//
+// MAIN
+//============================================================================//
+
+
+int main2()
+{
+ float val = error_test(AFP_PPM_IMG_PATH"/000_APP2003011515775.ppm",
+ AFP_GMP10_IMG_PATH"/000_APP2003011515775.ppm");
+
+ std::cout << val << std::endl;
+
+ return 0;
+}
+
+int main()
+{
+ typedef boost::filesystem::path t_path;
+ typedef boost::filesystem::directory_iterator t_iter_path;
+
+ mln::image1d<float> histo(256);
+ mln::image1d<float> histo_grp[2]; // histo by group
+
+ histo_grp[0].init_(mln::box1d(mln::point1d(0),mln::point1d(255)));
+ histo_grp[1].init_(mln::box1d(mln::point1d(0),mln::point1d(255)));
+
+ mln::data::fill(histo, mln::literal::zero);
+ mln::data::fill(histo_grp[0], mln::literal::zero);
+ mln::data::fill(histo_grp[1], mln::literal::zero);
+
+ t_path original_path[] = {ICDAR_20P_INPUT_IMG_PATH,
+ AFP_PPM_IMG_PATH};
+
+// t_path reduced1_path[] = {ICDAR_20P_MGK30_IMG_PATH,
+// AFP_MGK30_IMG_PATH};
+
+// t_path reduced1_path[] = {ICDAR_20P_MGK20_IMG_PATH,
+// AFP_MGK20_IMG_PATH};
+
+ t_path reduced1_path[] = {ICDAR_20P_MGK10_IMG_PATH,
+ AFP_MGK10_IMG_PATH};
+
+// t_path reduced2_path[] = {ICDAR_20P_GMP30_IMG_PATH,
+// AFP_GMP30_IMG_PATH};
+
+// t_path reduced2_path[] = {ICDAR_20P_GMP20_IMG_PATH,
+// AFP_GMP20_IMG_PATH};
+
+ t_path reduced2_path[] = {ICDAR_20P_GMP10_IMG_PATH,
+ AFP_GMP10_IMG_PATH};
+
+
+ std::cout << "#!/usr/bin/gnuplot" << std::endl;
+ std::cout << "set terminal x11 persist 1" << std::endl;
+ std::cout << "ERROR" << std::endl;
+ std::cout << "plot '-' using 1 with point notitle,\\" << std::endl;
+ std::cout << " '-' using 1 with point notitle" << std::endl;
+
+ for (int i = 0; i < 2; i++)
+ {
+ if (boost::filesystem::exists(original_path[i]) &&
+ boost::filesystem::exists(reduced1_path[i]) &&
+ boost::filesystem::exists(reduced2_path[i]) &&
+ boost::filesystem::is_directory(original_path[i]) &&
+ boost::filesystem::is_directory(reduced1_path[i]) &&
+ boost::filesystem::is_directory(reduced2_path[i]))
+ {
+ boost::filesystem::system_complete(original_path[i]);
+ const t_iter_path end_iter;
+ float error1 = 0.0;
+ float error2 = 0.0;
+ t_path leaf;
+ t_path reduced1_file;
+ t_path reduced2_file;
+
+ for (t_iter_path dir_iter(original_path[i]);end_iter!=dir_iter;++dir_iter)
+ {
+ leaf = dir_iter->path().leaf();
+ reduced1_file = reduced1_path[i] / leaf;
+ reduced2_file = reduced2_path[i] / leaf;
+
+ error1 = error_test(dir_iter->path().string(), reduced1_file.string());
+ error2 = error_test(dir_iter->path().string(), reduced2_file.string());
+
+ float a1 = 1;
+ short v1 = (short)mln::math::floor(error2+0.4999);
+ mln::opt::at(histo,v1) += a1;
+ mln::opt::at(histo_grp[i],v1) += a1;
+
+// float a1 = error2 - mln::math::floor(error2);
+// float a2 = mln::math::ceil(error2) - error2;
+// short v1 = (short)mln::math::floor(error2);
+// short v2 = (short)mln::math::ceil(error2);
+// mln::opt::at(histo,v1) += a1;
+// mln::opt::at(histo,v2) += a2;
+// mln::opt::at(histo_grp[i],v1) += a1;
+// mln::opt::at(histo_grp[i],v2) += a2;
+
+ std::cout << error1 << " ";
+ std::cout << error2 << " ";
+ std::cout << "# " << dir_iter->path().leaf() << std::endl;
+ }
+ std::cout << "e" << std::endl;
+ }
+ }
+
+ mln::io::plot::save_image_sh(histo, "histo.sh");
+ mln::io::plot::save_image_sh(histo_grp[1], "histo_grp1.sh");
+ mln::io::plot::save_image_sh(histo_grp[0], "histo_grp2.sh");
+
+ float threshold = fisher_analysis(histo);
+ float threshold2 = threshold_histo(avg_histo(histo_grp[1]),
+ var_histo(histo_grp[1]),
+ avg_histo(histo_grp[0]),
+ var_histo(histo_grp[0]));
+ float threshold3 = threshold2_histo(avg_histo(histo_grp[1]),
+ var_histo(histo_grp[1]),
+ avg_histo(histo_grp[0]),
+ var_histo(histo_grp[0]));
+ float threshold4 = min_error(histo_grp[1],histo_grp[0]);
+
+ std::cout << "threshold = " << threshold << std::endl;
+ std::cout << "threshold2 = " << threshold2 << std::endl;
+ std::cout << "threshold3 = " << threshold3 << std::endl;
+ std::cout << "threshold4 = " << threshold4 << std::endl;
+ std::cout << "avg_grp1 = " << avg_histo(histo_grp[1]) << std::endl;
+ std::cout << "avg_grp2 = " << avg_histo(histo_grp[0]) << std::endl;
+
+ // compute the classification matrix
+ // for each sub population
+
+ float c00 = cnt_histo(histo_grp[1] | mln::box1d(mln::point1d(0),
+ mln::point1d(threshold)));
+
+ float c10 = cnt_histo(histo_grp[1] | mln::box1d(mln::point1d(threshold+1),
+ mln::point1d(255)));
+
+ float c01 = cnt_histo(histo_grp[0] | mln::box1d(mln::point1d(0),
+ mln::point1d(threshold)));
+
+ float c11 = cnt_histo(histo_grp[0] | mln::box1d(mln::point1d(threshold+1),
+ mln::point1d(255)));
+
+
+ std::cout << "pop0 = " << cnt_histo(histo_grp[1]) << std::endl;
+ std::cout << "pop1 = " << cnt_histo(histo_grp[0]) << std::endl;
+ std::cout << std::endl;
+
+ std::cout << "c00 = " << c00 << std::endl;
+ std::cout << "c10 = " << c10 << std::endl;
+ std::cout << "c01 = " << c01 << std::endl;
+ std::cout << "c11 = " << c11 << std::endl;
+
+ return 0;
+}
--
1.5.6.5
1
0
15 Nov '10
* green/exp/annotating/histo: New directory.
* green/exp/annotating/histo/histo.cc: New Makefile.am.
* green/exp/annotating/histo/histo.cc: New source.
---
.../annotating/{achromastism => histo}/Makefile.am | 0
milena/sandbox/green/exp/annotating/histo/histo.cc | 306 ++++++++++++++++++++
2 files changed, 306 insertions(+), 0 deletions(-)
copy milena/sandbox/green/exp/annotating/{achromastism => histo}/Makefile.am (100%)
create mode 100644 milena/sandbox/green/exp/annotating/histo/histo.cc
diff --git a/milena/sandbox/green/exp/annotating/achromastism/Makefile.am b/milena/sandbox/green/exp/annotating/histo/Makefile.am
similarity index 100%
copy from milena/sandbox/green/exp/annotating/achromastism/Makefile.am
copy to milena/sandbox/green/exp/annotating/histo/Makefile.am
diff --git a/milena/sandbox/green/exp/annotating/histo/histo.cc b/milena/sandbox/green/exp/annotating/histo/histo.cc
new file mode 100644
index 0000000..2fb0131
--- /dev/null
+++ b/milena/sandbox/green/exp/annotating/histo/histo.cc
@@ -0,0 +1,306 @@
+// Build normalized histogram as density
+
+#include <iostream>
+#include <sstream>
+#include <boost/filesystem.hpp>
+
+#include <mln/img_path.hh>
+
+#include <mln/accu/stat/histo1d.hh>
+
+#include <mln/arith/minus.hh>
+#include <mln/arith/div.hh>
+
+#include <mln/core/image/image1d.hh>
+#include <mln/core/image/image2d.hh>
+#include <mln/core/image/dmorph/image_if.hh>
+
+#include <mln/data/convert.hh>
+#include <mln/data/compute.hh>
+#include <mln/data/stretch.hh>
+#include <mln/data/transform.hh>
+
+#include <mln/literal/zero.hh>
+#include <mln/literal/colors.hh>
+#include <mln/literal/grays.hh>
+
+#include <mln/math/max.hh>
+#include <mln/math/min.hh>
+#include <mln/math/sqr.hh>
+#include <mln/math/sqrt.hh>
+
+#include <mln/opt/at.hh>
+
+#include <mln/geom/nsites.hh>
+
+#include <mln/fun/v2v/rgb_to_hue_map.hh>
+#include <mln/fun/v2v/rgb_to_saturation_map.hh>
+#include <mln/fun/v2v/rgb_to_value_map.hh>
+#include <mln/fun/v2v/component.hh>
+
+#include <mln/io/ppm/load.hh>
+#include <mln/io/pgm/save.hh>
+#include <mln/io/plot/save_image_sh.hh>
+
+#include <mln/value/rgb8.hh>
+
+//============================================================================//
+// HISTOGRAM
+//============================================================================//
+
+template <typename I>
+mln_value(I) cnt_histo(const mln::Image<I>& histo_)
+{
+ const I& histo = exact(histo_);
+
+ mln_precondition(histo.is_valid());
+
+ mln_value(I) cnt = mln::literal::zero;
+ mln_piter(I) p(histo.domain());
+
+ for_all(p)
+ {
+ cnt += histo(p);
+ }
+
+ return cnt;
+}
+
+void histo(const std::string input,
+ const std::string output_map,
+ const std::string output_histo,
+ const char space)
+
+{
+ typedef mln::value::rgb8 t_rgb8;
+ typedef mln::fun::v2v::rgb_to_hue_map<8> t_rgb_to_hue_map;
+ typedef mln::fun::v2v::rgb_to_saturation_map<8> t_rgb_to_sat_map;
+ typedef mln::fun::v2v::rgb_to_value_map<8> t_rgb_to_val_map;
+ typedef mln::fun::v2v::component<t_rgb8,0> t_component_r;
+ typedef mln::fun::v2v::component<t_rgb8,1> t_component_g;
+ typedef mln::fun::v2v::component<t_rgb8,2> t_component_b;
+
+ mln::image2d<mln::value::rgb8> input_rgb8;
+ mln::image2d<mln::value::int_u8> map;
+ mln::image1d<unsigned> histo;
+ mln::image1d<float> histo_float;
+ float sum;
+
+ mln::io::ppm::load(input_rgb8, input.c_str());
+
+ switch(space)
+ {
+ case 'h': map = mln::data::transform(input_rgb8, t_rgb_to_hue_map()); break;
+ case 's': map = mln::data::transform(input_rgb8, t_rgb_to_sat_map()); break;
+ case 'v': map = mln::data::transform(input_rgb8, t_rgb_to_val_map()); break;
+ case 'r': map = mln::data::transform(input_rgb8, t_component_r()); break;
+ case 'g': map = mln::data::transform(input_rgb8, t_component_g()); break;
+ case 'b': map = mln::data::transform(input_rgb8, t_component_b()); break;
+ default: break;// crash
+ }
+
+ histo = mln::data::compute(mln::accu::meta::stat::histo1d(), map);
+ sum = cnt_histo(histo);
+ histo_float = mln::data::convert(float(), histo) / sum;
+
+ mln::io::pgm::save(map, output_map.c_str());
+ mln::io::plot::save_image_sh(histo_float, output_histo.c_str());
+}
+
+//============================================================================//
+// MAIN
+//============================================================================//
+
+
+// in the directory of the images
+// out the density directory
+// 2 use-cases afp and icdar
+
+int main()
+{
+ typedef boost::filesystem::path t_path;
+ typedef boost::filesystem::directory_iterator t_iter_path;
+
+// t_path full_path[] = {t_path(ICDAR_20P_TEXT_ONLY_IMG_PATH),
+// t_path(ICDAR_20P_TEXT_COLOR_IMG_PATH),
+// t_path(ICDAR_20P_TEXT_PHOTO_IMG_PATH)};
+
+// t_path full_path[] = {t_path(AFP_INPUT_IMG_PATH)};
+// t_path full_path[] = {t_path(AFP_GMP30_IMG_PATH)};
+// t_path full_path[] = {t_path(AFP_GMP20_IMG_PATH)};
+// t_path full_path[] = {t_path(AFP_GMP10_IMG_PATH)};
+// t_path full_path[] = {t_path(AFP_MGK30_IMG_PATH)};
+// t_path full_path[] = {t_path(AFP_MGK20_IMG_PATH)};
+// t_path full_path[] = {t_path(AFP_MGK10_IMG_PATH)};
+
+// t_path full_path[] = {t_path(ICDAR_20P_INPUT_IMG_PATH)};
+// t_path full_path[] = {t_path(ICDAR_20P_GMP30_IMG_PATH)};
+ t_path full_path[] = {t_path(ICDAR_20P_GMP20_IMG_PATH)};
+// t_path full_path[] = {t_path(ICDAR_20P_GMP10_IMG_PATH)};
+// t_path full_path[] = {t_path(ICDAR_20P_MGK30_IMG_PATH)};
+// t_path full_path[] = {t_path(ICDAR_20P_MGK20_IMG_PATH)};
+// t_path full_path[] = {t_path(ICDAR_20P_MGK10_IMG_PATH)};
+
+ for (int i = 0; i < 1; ++i)
+ {
+ if (boost::filesystem::exists(full_path[i]) &&
+ boost::filesystem::is_directory(full_path[i]))
+ {
+ boost::filesystem::system_complete(full_path[i]);
+ const t_iter_path end_iter;
+ t_path directory;
+ t_path leaf;
+ t_path output_map;
+ t_path output_histo;
+
+ std::cerr << "entering " << full_path[i] << std::endl;
+
+ for (t_iter_path dir_iter(full_path[i]); end_iter != dir_iter; ++dir_iter)
+ {
+ std::cerr << dir_iter->path() << std::endl;
+
+ leaf = dir_iter->path().leaf();
+
+// directory = ANNOTATING_AFP_R_INPUT_RET_PATH;
+// directory = ANNOTATING_AFP_R_GMP30_RET_PATH;
+// directory = ANNOTATING_AFP_R_GMP20_RET_PATH;
+// directory = ANNOTATING_AFP_R_GMP10_RET_PATH;
+// directory = ANNOTATING_AFP_R_MGK30_RET_PATH;
+// directory = ANNOTATING_AFP_R_MGK20_RET_PATH;
+// directory = ANNOTATING_AFP_R_MGK10_RET_PATH;
+
+// directory = ANNOTATING_ICDAR_R_INPUT_RET_PATH;
+// directory = ANNOTATING_ICDAR_R_GMP30_RET_PATH;
+ directory = ANNOTATING_ICDAR_R_GMP20_RET_PATH;
+// directory = ANNOTATING_ICDAR_R_GMP10_RET_PATH;
+// directory = ANNOTATING_ICDAR_R_MGK30_RET_PATH;
+// directory = ANNOTATING_ICDAR_R_MGK20_RET_PATH;
+// directory = ANNOTATING_ICDAR_R_MGK10_RET_PATH;
+ output_histo = change_extension(directory / leaf, ".sh");
+ output_map = change_extension(directory / leaf, ".pgm");
+
+ histo(dir_iter->path().string(),
+ output_map.string(),
+ output_histo.string(),
+ 'r');
+
+// directory = ANNOTATING_AFP_G_INPUT_RET_PATH;
+// directory = ANNOTATING_AFP_G_GMP30_RET_PATH;
+// directory = ANNOTATING_AFP_G_GMP20_RET_PATH;
+// directory = ANNOTATING_AFP_G_GMP10_RET_PATH;
+// directory = ANNOTATING_AFP_G_MGK30_RET_PATH;
+// directory = ANNOTATING_AFP_G_MGK20_RET_PATH;
+// directory = ANNOTATING_AFP_G_MGK10_RET_PATH;
+
+// directory = ANNOTATING_ICDAR_G_INPUT_RET_PATH;
+// directory = ANNOTATING_ICDAR_G_GMP30_RET_PATH;
+ directory = ANNOTATING_ICDAR_G_GMP20_RET_PATH;
+// directory = ANNOTATING_ICDAR_G_GMP10_RET_PATH;
+// directory = ANNOTATING_ICDAR_G_MGK30_RET_PATH;
+// directory = ANNOTATING_ICDAR_G_MGK20_RET_PATH;
+// directory = ANNOTATING_ICDAR_G_MGK10_RET_PATH;
+ output_histo = change_extension(directory / leaf, ".sh");
+ output_map = change_extension(directory / leaf, ".pgm");
+
+ histo(dir_iter->path().string(),
+ output_map.string(),
+ output_histo.string(),
+ 'g');
+
+// directory = ANNOTATING_AFP_B_INPUT_RET_PATH;
+// directory = ANNOTATING_AFP_B_GMP30_RET_PATH;
+// directory = ANNOTATING_AFP_B_GMP20_RET_PATH;
+// directory = ANNOTATING_AFP_B_GMP10_RET_PATH;
+// directory = ANNOTATING_AFP_B_MGK30_RET_PATH;
+// directory = ANNOTATING_AFP_B_MGK20_RET_PATH;
+// directory = ANNOTATING_AFP_B_MGK10_RET_PATH;
+
+// directory = ANNOTATING_ICDAR_B_INPUT_RET_PATH;
+// directory = ANNOTATING_ICDAR_B_GMP30_RET_PATH;
+ directory = ANNOTATING_ICDAR_B_GMP20_RET_PATH;
+// directory = ANNOTATING_ICDAR_B_GMP10_RET_PATH;
+// directory = ANNOTATING_ICDAR_B_MGK30_RET_PATH;
+// directory = ANNOTATING_ICDAR_B_MGK20_RET_PATH;
+// directory = ANNOTATING_ICDAR_B_MGK10_RET_PATH;
+ output_histo = change_extension(directory / leaf, ".sh");
+ output_map = change_extension(directory / leaf, ".pgm");
+
+ histo(dir_iter->path().string(),
+ output_map.string(),
+ output_histo.string(),
+ 'b');
+
+// directory = ANNOTATING_AFP_H_INPUT_RET_PATH;
+// directory = ANNOTATING_AFP_H_GMP30_RET_PATH;
+// directory = ANNOTATING_AFP_H_GMP20_RET_PATH;
+// directory = ANNOTATING_AFP_H_GMP10_RET_PATH;
+// directory = ANNOTATING_AFP_H_MGK30_RET_PATH;
+// directory = ANNOTATING_AFP_H_MGK20_RET_PATH;
+// directory = ANNOTATING_AFP_H_MGK10_RET_PATH;
+
+// directory = ANNOTATING_ICDAR_H_INPUT_RET_PATH;
+// directory = ANNOTATING_ICDAR_H_GMP30_RET_PATH;
+ directory = ANNOTATING_ICDAR_H_GMP20_RET_PATH;
+// directory = ANNOTATING_ICDAR_H_GMP10_RET_PATH;
+// directory = ANNOTATING_ICDAR_H_MGK30_RET_PATH;
+// directory = ANNOTATING_ICDAR_H_MGK20_RET_PATH;
+// directory = ANNOTATING_ICDAR_H_MGK10_RET_PATH;
+ output_histo = change_extension(directory / leaf, ".sh");
+ output_map = change_extension(directory / leaf, ".pgm");
+
+ histo(dir_iter->path().string(),
+ output_map.string(),
+ output_histo.string(),
+ 'h');
+
+// directory = ANNOTATING_AFP_S_INPUT_RET_PATH;
+// directory = ANNOTATING_AFP_S_GMP30_RET_PATH;
+// directory = ANNOTATING_AFP_S_GMP20_RET_PATH;
+// directory = ANNOTATING_AFP_S_GMP10_RET_PATH;
+// directory = ANNOTATING_AFP_S_MGK30_RET_PATH;
+// directory = ANNOTATING_AFP_S_MGK20_RET_PATH;
+// directory = ANNOTATING_AFP_S_MGK10_RET_PATH;
+
+// directory = ANNOTATING_ICDAR_S_INPUT_RET_PATH;
+// directory = ANNOTATING_ICDAR_S_GMP30_RET_PATH;
+ directory = ANNOTATING_ICDAR_S_GMP20_RET_PATH;
+// directory = ANNOTATING_ICDAR_S_GMP10_RET_PATH;
+// directory = ANNOTATING_ICDAR_S_MGK30_RET_PATH;
+// directory = ANNOTATING_ICDAR_S_MGK20_RET_PATH;
+// directory = ANNOTATING_ICDAR_S_MGK10_RET_PATH;
+ output_histo = change_extension(directory / leaf, ".sh");
+ output_map = change_extension(directory / leaf, ".pgm");
+
+ histo(dir_iter->path().string(),
+ output_map.string(),
+ output_histo.string(),
+ 's');
+
+// directory = ANNOTATING_AFP_V_INPUT_RET_PATH;
+// directory = ANNOTATING_AFP_V_GMP30_RET_PATH;
+// directory = ANNOTATING_AFP_V_GMP20_RET_PATH;
+// directory = ANNOTATING_AFP_V_GMP10_RET_PATH;
+// directory = ANNOTATING_AFP_V_MGK30_RET_PATH;
+// directory = ANNOTATING_AFP_V_MGK20_RET_PATH;
+// directory = ANNOTATING_AFP_V_MGK10_RET_PATH;
+
+// directory = ANNOTATING_ICDAR_V_INPUT_RET_PATH;
+// directory = ANNOTATING_ICDAR_V_GMP30_RET_PATH;
+ directory = ANNOTATING_ICDAR_V_GMP20_RET_PATH;
+// directory = ANNOTATING_ICDAR_V_GMP10_RET_PATH;
+// directory = ANNOTATING_ICDAR_V_MGK30_RET_PATH;
+// directory = ANNOTATING_ICDAR_V_MGK20_RET_PATH;
+// directory = ANNOTATING_ICDAR_V_MGK10_RET_PATH;
+ output_histo = change_extension(directory / leaf, ".sh");
+ output_map = change_extension(directory / leaf, ".pgm");
+
+ histo(dir_iter->path().string(),
+ output_map.string(),
+ output_histo.string(),
+ 'v');
+ }
+ }
+ }
+
+ return 0;
+}
--
1.5.6.5
1
0
* green/exp/annotating/hsv: New directory.
* green/Exp/annotating/hsv/hsv.cc: New source file.
---
milena/sandbox/ChangeLog | 24 +
.../annotating/{achromastism => hsv}/Makefile.am | 0
milena/sandbox/green/exp/annotating/hsv/hsv.cc | 652 ++++++++++++++++++++
3 files changed, 676 insertions(+), 0 deletions(-)
copy milena/sandbox/green/exp/annotating/{achromastism => hsv}/Makefile.am (100%)
create mode 100644 milena/sandbox/green/exp/annotating/hsv/hsv.cc
diff --git a/milena/sandbox/ChangeLog b/milena/sandbox/ChangeLog
index 7489f70..0e7ac9c 100644
--- a/milena/sandbox/ChangeLog
+++ b/milena/sandbox/ChangeLog
@@ -1,5 +1,28 @@
2010-06-21 Yann Jacquelet <jacquelet(a)lrde.epita.fr>
+ Work on Millet hsv descriptors.
+
+ * green/exp/annotating/hsv: New directory.
+ * green/Exp/annotating/hsv/hsv.cc: New source file.
+
+2010-06-21 Yann Jacquelet <jacquelet(a)lrde.epita.fr>
+
+ Work on histograms view as density.
+
+ * green/exp/annotating/histo: New directory.
+ * green/exp/annotating/histo/histo.cc: New Makefile.am.
+ * green/exp/annotating/histo/histo.cc: New source.
+
+2010-06-21 Yann Jacquelet <jacquelet(a)lrde.epita.fr>
+
+ Test error quantification as a color descriptor in our database.
+
+ * green/exp/annotating/error: New directory.
+ * green/exp/annotating/error/Makefile.am: New Makefile.
+ * green/exp/annotating/error/error.cc: New source.
+
+2010-06-21 Yann Jacquelet <jacquelet(a)lrde.epita.fr>
+
Benchmark few descriptors.
* green/exp/annotating/bench: New directory.
@@ -10,6 +33,7 @@
Test on image database the achromatism descriptor.
+ * green/exp/annotating/achromatism: New directory.
* green/exp/annotating/achromatism/Makefile.am: New Makefile.
* green/exp/annotating/achromatism/achromatism.am: New source.
* green/exp/annotating/achromatism/text-color.txt: New image class.
diff --git a/milena/sandbox/green/exp/annotating/achromastism/Makefile.am b/milena/sandbox/green/exp/annotating/hsv/Makefile.am
similarity index 100%
copy from milena/sandbox/green/exp/annotating/achromastism/Makefile.am
copy to milena/sandbox/green/exp/annotating/hsv/Makefile.am
diff --git a/milena/sandbox/green/exp/annotating/hsv/hsv.cc b/milena/sandbox/green/exp/annotating/hsv/hsv.cc
new file mode 100644
index 0000000..2aa9113
--- /dev/null
+++ b/milena/sandbox/green/exp/annotating/hsv/hsv.cc
@@ -0,0 +1,652 @@
+// HSV TEST CF MILLET 2008
+
+#include <iostream>
+#include <sstream>
+#include <boost/filesystem.hpp>
+
+#include <mln/img_path.hh>
+
+#include <mln/accu/stat/histo1d.hh>
+
+#include <mln/arith/minus.hh>
+#include <mln/arith/div.hh>
+
+#include <mln/core/image/image1d.hh>
+#include <mln/core/image/image2d.hh>
+#include <mln/core/image/dmorph/image_if.hh>
+
+#include <mln/data/convert.hh>
+#include <mln/data/compute.hh>
+#include <mln/data/stretch.hh>
+#include <mln/data/transform.hh>
+
+#include <mln/literal/zero.hh>
+#include <mln/literal/colors.hh>
+#include <mln/literal/grays.hh>
+
+#include <mln/math/max.hh>
+#include <mln/math/min.hh>
+#include <mln/math/sqr.hh>
+#include <mln/math/sqrt.hh>
+
+#include <mln/opt/at.hh>
+
+#include <mln/geom/nsites.hh>
+
+#include <mln/fun/v2v/rgb_to_hue_map.hh>
+#include <mln/fun/v2v/rgb_to_saturation_map.hh>
+#include <mln/fun/v2v/rgb_to_value_map.hh>
+
+#include <mln/io/ppm/load.hh>
+#include <mln/io/pgm/save.hh>
+#include <mln/io/plot/save_image_sh.hh>
+
+#include <mln/value/rgb8.hh>
+
+//============================================================================//
+// HISTOGRAM
+//============================================================================//
+
+template <typename I>
+mln_value(I) count_histo(const mln::Image<I>& histo_)
+{
+ const I& histo = exact(histo_);
+
+ mln_precondition(histo.is_valid());
+
+ mln_value(I) result = mln::literal::zero;
+ mln_piter(I) p(histo.domain());
+
+ for_all(p)
+ result += histo(p);
+
+ return result;
+}
+
+template <typename I>
+mln_value(I) sum_frequency_histo(const mln::Image<I>& histo_)
+{
+ const I& histo = exact(histo_);
+
+ mln_precondition(histo.is_valid());
+
+ mln_value(I) sum = mln::literal::zero;
+ mln_piter(I) p(histo.domain());
+
+ for_all(p)
+ sum += histo(p);
+
+ return sum;
+}
+
+template <typename I>
+mln_value(I) count_null_frequency_histo(const mln::Image<I>& histo_)
+{
+ const I& histo = exact(histo_);
+
+ mln_precondition(histo.is_valid());
+
+ mln_value(I) count = mln::literal::zero;
+ mln_piter(I) p(histo.domain());
+
+ for_all(p)
+ if (0 == histo(p))
+ count++;
+
+ return count;
+}
+
+template <typename I>
+mln_coord(mln_site_(I)) peak_histo(const mln::Image<I>& histo_)
+{
+ const I& histo = exact(histo_);
+
+ mln_precondition(histo.is_valid());
+
+ // Find the peak of the histogram
+ mln_value(I) v_max = mln::opt::at(histo, mln::literal::zero);
+ mln_coord(mln_site_(I)) p_max = mln::literal::zero;
+ mln_piter(I) p(histo.domain());
+
+ for_all(p)
+ {
+ if (v_max < histo(p))
+ {
+ v_max = histo(p);
+ p_max = p.ind();
+ }
+ }
+
+ return p_max;
+}
+
+template <typename I>
+mln_value(I) max_frequency_histo(const mln::Image<I>& histo_)
+{
+ const I& histo = exact(histo_);
+
+ mln_precondition(histo.is_valid());
+
+ // Find the value of the peak from the histogram
+ mln_value(I) max = mln::opt::at(histo, mln::literal::zero);
+ mln_piter(I) p(histo.domain());
+
+ for_all(p)
+ {
+ max = mln::math::max(histo(p),max);
+ }
+
+ return max;
+}
+
+template <typename I>
+float mean_histo(const mln::Image<I>& histo_)
+{
+ const I& histo = exact(histo_);
+
+ mln_precondition(histo.is_valid());
+
+ // Find the mean of the histogram
+ float sum = 0;
+ float mean = 0;
+
+ mln_piter(I) p(histo.domain());
+
+ for_all(p)
+ {
+ sum += histo(p);
+ mean += p.ind()*histo(p);
+ }
+
+ mean = mean / sum;
+
+ return mean;
+}
+
+template <typename I>
+float cmp_equi_frequency_histo(const mln::Image<I>& histo_)
+{
+ const I& histo = exact(histo_);
+
+ mln_precondition(histo.is_valid());
+
+ // Find the mean of the histogram
+ float sum = 0;
+ float var = 0;
+
+ mln_piter(I) p(histo.domain());
+
+ for_all(p)
+ {
+ sum += histo(p);
+ var += mln::math::sqr(histo(p) - (1/256.0));
+ }
+
+ var = var / sum;
+
+ return var;
+}
+
+template <typename I>
+float var_histo(const mln::Image<I>& histo_, float mean)
+{
+ const I& histo = exact(histo_);
+
+ mln_precondition(histo.is_valid());
+
+ // Find the mean of the histogram
+ float sum = 0;
+ float var = 0;
+
+ mln_piter(I) p(histo.domain());
+
+ for_all(p)
+ {
+ sum += histo(p);
+ var += mln::math::sqr(p.ind() - mean) * histo(p);
+ }
+
+ var = var / sum;
+
+ return var;
+}
+
+template <typename I>
+float mean_frequency_histo(const mln::Image<I>& histo_)
+{
+ const I& histo = exact(histo_);
+
+ mln_precondition(histo.is_valid());
+
+ // Find the mean of the histogram
+ float sum = 0;
+ float mean = 0;
+
+ mln_piter(I) p(histo.domain());
+
+ for_all(p)
+ {
+ sum++;
+ mean += histo(p);
+ }
+
+ mean = mean / sum;
+
+ return mean;
+}
+
+template <typename I>
+float stddev_frequency_histo(const mln::Image<I>& histo_, float mean)
+{
+ const I& histo = exact(histo_);
+
+ mln_precondition(histo.is_valid());
+
+ // Find the var of the histogram
+ float sum = 0;
+ float var = 0;
+
+ mln_piter(I) p(histo.domain());
+
+ for_all(p)
+ {
+ sum++;
+ var += mln::math::sqr(histo(p)-mean);
+ }
+
+ var = mln::math::sqrt(var / sum);
+
+ return var;
+}
+
+
+//============================================================================//
+// HUE TEST
+//============================================================================//
+
+mln::value::rgb8 label_val(const mln::value::int_u8 val)
+{
+ mln::value::rgb8 result;
+
+ if (82 > val)
+ result = mln::literal::black;
+ else if (179 > val)
+ result= mln::literal::medium_gray;
+ else
+ result = mln::literal::white;
+
+ return result;
+}
+
+
+mln::value::rgb8 label_orange_or_brown(const mln::value::rgb8 color,
+ const mln::value::int_u8 sat,
+ const mln::value::int_u8 val)
+{
+ mln::value::rgb8 result;
+
+ if (mln::literal::orange == color)
+ {
+ unsigned dist_orange = mln::math::abs(sat - 184)
+ + mln::math::abs(val - 65);
+
+ unsigned dist_brown = mln::math::abs(sat - 255)
+ + mln::math::abs(val - 125);
+
+ if (dist_orange < dist_brown)
+ result = mln::literal::orange;
+ else
+ result = mln::literal::brown;
+ }
+ else
+ result = color;
+
+ return result;
+}
+
+mln::value::rgb8 label_yellow_or_green(const mln::value::rgb8 color,
+ const mln::value::int_u8 val)
+{
+ mln::value::rgb8 result;
+
+ if (mln::literal::yellow == color)
+ {
+ // Is it green or yellow ?
+ if (80 > val)
+ result = mln::literal::green;
+ else
+ result = mln::literal::yellow;
+ }
+ else
+ return color;
+
+ return result;
+}
+
+mln::value::rgb8 label_hue(const mln::value::int_u8 hue)
+{
+ mln::value::rgb8 result;
+
+
+ if (10 > hue)
+ result = mln::literal::red;
+ else if (32 > hue)
+ result = mln::literal::orange;
+ else if (53 > hue)
+ result = mln::literal::yellow;
+ else if (74 > hue)
+ result = mln::literal::green; // chartreuse
+ else if (96 > hue)
+ result = mln::literal::green;
+ else if (116 > hue)
+ result = mln::literal::green;// turquoise, aigue-marine
+ else if (138 > hue)
+ result = mln::literal::green; // cyan
+ else if (159 > hue)
+ result = mln::literal::blue; // azur
+ else if (181 > hue)
+ result = mln::literal::blue;
+ else if (202 > hue)
+ result = mln::literal::violet;
+ else if (223 > hue)
+ result = mln::literal::pink;
+ else // if (244 > hue)
+ result = mln::literal::red;
+
+ return result;
+}
+
+float hue_test(const std::string input,
+ const std::string output,
+ const std::string tmp,
+ const short threshold)
+
+{
+ typedef mln::fun::v2v::rgb_to_hue_map<8> t_rgb_to_hue_map;
+
+ mln::image2d<mln::value::rgb8> input_rgb8;
+ mln::image2d<mln::value::int_u8> map;
+ mln::image1d<unsigned> histo;
+ mln::image1d<float> histo_float;
+ float cnt1;
+ float cnt2;
+ float prop;
+ short peak;
+ mln::value::rgb8 color;
+ float sum;
+ mln::point1d inf;
+ mln::point1d sup;
+
+ mln::io::ppm::load(input_rgb8, input.c_str());
+
+ map = mln::data::transform(input_rgb8, t_rgb_to_hue_map());
+ histo = mln::data::compute(mln::accu::meta::stat::histo1d(), map);
+ sum = sum_frequency_histo(histo);
+ histo_float = mln::data::convert(float(), histo) / sum;
+ peak = mean_histo(histo); //peak_histo(histo);
+ color = label_hue(peak);
+ inf = mln::point1d(mln::math::max(0, peak-threshold));
+ sup = mln::point1d(mln::math::min(255, peak+threshold));
+ cnt1 = count_histo(histo_float|mln::box1d(inf,sup));
+ cnt2 = count_histo(histo_float);
+ prop = ((100.0 * cnt1) / cnt2);
+
+ mln::io::plot::save_image_sh(histo_float, output.c_str());
+ mln::io::pgm::save(map, tmp.c_str());
+// std::cout << "peak = " << peak << std::endl;
+// std::cout << "color = " << color << std::endl;
+
+ return prop;
+}
+
+//============================================================================//
+// SATURATION TEST
+//============================================================================//
+
+float saturation_test(const std::string input,
+ const std::string output,
+ const std::string tmp,
+ const short threshold)
+
+{
+ typedef mln::fun::v2v::rgb_to_saturation_map<8> t_rgb_to_saturation_map;
+
+ mln::image2d<mln::value::rgb8> input_rgb8;
+ mln::image2d<mln::value::int_u8> map;
+ mln::image1d<unsigned> histo;
+ mln::image1d<float> histo_float;
+ float cnt1;
+ float cnt2;
+ float sum;
+ float prop;
+
+ mln::io::ppm::load(input_rgb8, input.c_str());
+
+ map = mln::data::transform(input_rgb8, t_rgb_to_saturation_map());
+ histo = mln::data::compute(mln::accu::meta::stat::histo1d(), map);
+ sum = sum_frequency_histo(histo);
+ histo_float = mln::data::convert(float(), histo) / sum;
+ cnt1 = count_histo(histo_float | mln::box1d(mln::point1d(0),
+ mln::point1d(threshold)));
+ cnt2 = count_histo(histo_float);
+ prop = ((100.0 * cnt1) / cnt2);
+
+ mln::io::plot::save_image_sh(histo_float, output.c_str());
+ mln::io::pgm::save(map, tmp.c_str());
+
+ return prop;
+}
+
+//============================================================================//
+// VALUE TEST
+//============================================================================//
+
+// calcul de contribution
+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;
+}
+
+template <typename I>
+float stddev3(const mln::Image<I>& histo_, unsigned peak)
+{
+ const I& histo = exact(histo_);
+
+ mln_precondition(histo.is_valid());
+
+ // Compute stddev
+
+ float stddev = 0.0;
+
+ mln_piter(I) p(histo.domain());
+
+ for_all(p)
+ {
+ stddev += r((short)peak, mln::opt::at(histo,peak), p.ind(), histo(p));
+ }
+
+ return stddev;
+}
+
+template <typename I>
+float stddev2(const mln::Image<I>& histo_, unsigned peak, unsigned limit)
+{
+ const I& histo = exact(histo_);
+
+ mln_precondition(histo.is_valid());
+
+ float stddev_low = 0.0;
+ float stddev_up = 0.0;
+ float ret = 0.0;
+
+ // A transformer avec des iterators
+
+ if (250 > peak)
+ stddev_up = stddev3(histo |mln::box1d(mln::point1d(peak+1),
+ mln::point1d(peak+limit)), peak);
+
+ if (5 < peak)
+ stddev_low = stddev3(histo |mln::box1d(mln::point1d(peak-limit),
+ mln::point1d(peak-1)), peak);
+
+ ret = (250 < peak)? stddev_low : (5 > peak)? stddev_up :
+ (stddev_low + stddev_up)/2;
+
+ return ret;
+}
+
+// DOC:
+// la discrimination entre la base AFP et la base ICDAR peut se faire en
+// étudiant la forme des densités des niveaux de gris.
+// Les images naturelles semblent avoir un spectre recouvrant
+// en général les 256 niveaux de gris alors que les images de documents ont
+// une présence importante du fond. Dans le cadre d'une densité, ce qui est
+// alloué sur le fond ne peut se retrouver ailleurs. Une comparaison avec la
+// densité équiprobable nous renseigne donc sur la nature des images.
+// Il semble néanmoins qu'un certain nombre d'images défient ce dispositif.
+// Par exemple des gros plans sur des zones mono-teintée (ski, voile,site web).
+
+
+
+
+float value_test(const std::string input,
+ const std::string output,
+ const std::string tmp,
+ const short threshold)
+
+{
+ typedef mln::fun::v2v::rgb_to_value_map<8> t_rgb_to_value_map;
+
+ mln::image2d<mln::value::rgb8> input_rgb8;
+ mln::image2d<mln::value::int_u8> map;
+ mln::image1d<unsigned> histo;
+ mln::image1d<float> histo_float;
+ float cnt1;
+ float cnt2;
+ float prop;
+ float sum;
+ float prop4;
+ short peak;
+ mln::point1d inf;
+ mln::point1d sup;
+
+
+ mln::io::ppm::load(input_rgb8, input.c_str());
+
+ map = mln::data::transform(input_rgb8, t_rgb_to_value_map());
+ histo = mln::data::compute(mln::accu::meta::stat::histo1d(), map);
+ sum = sum_frequency_histo(histo);
+ histo_float = mln::data::convert(float(), histo) / sum;
+ prop4 = cmp_equi_frequency_histo(histo_float);
+ peak = peak_histo(histo); // mean_histo(histo);
+ //prop = stddev2(histo, peak, threshold);
+ inf = mln::point1d(mln::math::max(0, peak-threshold));
+ sup = mln::point1d(mln::math::min(255, peak+threshold));
+ cnt1 = count_histo(histo_float|mln::box1d(inf,sup));
+ cnt2 = count_histo(histo_float);
+ prop = ((100.0 * cnt1) / cnt2);
+
+ std::cerr << "peak = " << peak << std::endl;
+ std::cerr << "inf = " << inf << std::endl;
+ std::cerr << "sup = " << sup << std::endl;
+ std::cerr << "cnt1 = " << cnt1 << std::endl;
+ std::cerr << "cnt2 = " << cnt2 << std::endl;
+ std::cerr << "prop = " << prop << std::endl;
+ std::cerr << "prop4= " << prop4 << std::endl;
+
+ mln::io::plot::save_image_sh(histo_float, output.c_str());
+ mln::io::pgm::save(map, tmp.c_str());
+
+ return prop;
+}
+
+//============================================================================//
+// MAIN
+//============================================================================//
+
+
+int main()
+{
+ typedef boost::filesystem::path t_path;
+ typedef boost::filesystem::directory_iterator t_iter_path;
+
+// t_path full_path[] = {t_path(ICDAR_20P_TEXT_ONLY_IMG_PATH),
+// t_path(ICDAR_20P_TEXT_COLOR_IMG_PATH),
+// t_path(ICDAR_20P_TEXT_PHOTO_IMG_PATH)};
+
+ t_path full_path[] = {t_path(AFP_PPM_IMG_PATH)};
+
+ std::cout << "#!/usr/bin/gnuplot" << std::endl;
+ std::cout << "set terminal x11 persist 1" << std::endl;
+ std::cout << "#HUE - SATURATION - VALUE" << std::endl;
+ std::cout << "plot '-' using 1:2 with point notitle,\\" << std::endl;
+ std::cout << " '-' using 1:2 with point notitle,\\" << std::endl;
+ std::cout << " '-' using 1:2 with point notitle" << std::endl;
+
+ for (int i = 0; i < 1; ++i)
+ {
+ if (boost::filesystem::exists(full_path[i]) &&
+ boost::filesystem::is_directory(full_path[i]))
+ {
+ boost::filesystem::system_complete(full_path[i]);
+ const t_iter_path end_iter;
+ float prop = 0.0;
+ t_path directory;
+ t_path leaf;
+ t_path output;
+ t_path tmp;
+
+ std::cerr << "entering " << full_path[i] << std::endl;
+
+ for (t_iter_path dir_iter(full_path[i]); end_iter != dir_iter; ++dir_iter)
+ {
+ std::cerr << dir_iter->path() << std::endl;
+ // concatenation de chaine
+// directory = (ANNOTATING_ICDAR_HUE_RET_PATH);
+ directory = (ANNOTATING_AFP_HUE_RET_PATH);
+ leaf = dir_iter->path().leaf();
+ output = change_extension(directory / leaf, ".sh");
+ tmp = change_extension(directory / leaf, ".pgm");
+
+ prop = hue_test(dir_iter->path().string(),
+ output.string(),
+ tmp.string(),
+ 20);
+
+ std::cout << prop << " ";
+
+// directory = (ANNOTATING_ICDAR_SAT_RET_PATH);
+ directory = (ANNOTATING_AFP_SAT_RET_PATH);
+ leaf = dir_iter->path().leaf();
+ output = change_extension(directory / leaf, ".sh");
+ tmp = change_extension(directory / leaf, ".pgm");
+
+ prop = saturation_test(dir_iter->path().string(),
+ output.string(),
+ tmp.string(),
+ 25);
+
+ std::cout << prop << " ";
+
+// directory = (ANNOTATING_ICDAR_VAL_RET_PATH);
+ directory = (ANNOTATING_AFP_VAL_RET_PATH);
+ leaf = dir_iter->path().leaf();
+ output = change_extension(directory / leaf, ".sh");
+ tmp = change_extension(directory / leaf, ".pgm");
+
+ prop = value_test(dir_iter->path().string(),
+ output.string(),
+ tmp.string(),
+ 15);
+
+ std::cout << prop << " ";
+ std::cout << "# " << dir_iter->path().leaf() << std::endl;
+ }
+ std::cout << "e" << std::endl;
+ }
+ }
+
+ return 0;
+}
--
1.5.6.5
1
0
15 Nov '10
* green/exp/annotating/saturation: New directory.
* green/exp/annotating/saturation/Makefile.am: New Makefile.
* green/exp/annotating/saturation/saturation.cc: New source file.
---
milena/sandbox/ChangeLog | 14 ++++++++-
.../{achromastism => saturation}/Makefile.am | 0
.../achromastism.cc => saturation/saturation.cc} | 30 ++++++++++++--------
.../{achromastism => saturation}/text-color.txt | 0
.../{achromastism => saturation}/text-img.txt | 0
.../{achromastism => saturation}/text-only.txt | 0
6 files changed, 31 insertions(+), 13 deletions(-)
copy milena/sandbox/green/exp/annotating/{achromastism => saturation}/Makefile.am (100%)
copy milena/sandbox/green/exp/annotating/{achromastism/achromastism.cc => saturation/saturation.cc} (75%)
copy milena/sandbox/green/exp/annotating/{achromastism => saturation}/text-color.txt (100%)
copy milena/sandbox/green/exp/annotating/{achromastism => saturation}/text-img.txt (100%)
copy milena/sandbox/green/exp/annotating/{achromastism => saturation}/text-only.txt (100%)
diff --git a/milena/sandbox/ChangeLog b/milena/sandbox/ChangeLog
index 0e7ac9c..15c6c4b 100644
--- a/milena/sandbox/ChangeLog
+++ b/milena/sandbox/ChangeLog
@@ -1,9 +1,21 @@
2010-06-21 Yann Jacquelet <jacquelet(a)lrde.epita.fr>
+ Work on Millet saturation descriptor.
+
+ * green/exp/annotating/saturation: New directory.
+ * green/exp/annotating/saturation/Makefile.am: New Makefile.
+ * green/exp/annotating/saturation/saturation.cc: New source file.
+ * green/exp/annotating/saturation/text-color.txt: New image class.
+ * green/exp/annotating/saturation/text-img.txt: New image class.
+ * green/exp/annotating/saturation/text-only.txt: New image class.
+
+
+2010-06-21 Yann Jacquelet <jacquelet(a)lrde.epita.fr>
+
Work on Millet hsv descriptors.
* green/exp/annotating/hsv: New directory.
- * green/Exp/annotating/hsv/hsv.cc: New source file.
+ * green/exp/annotating/hsv/hsv.cc: New source file.
2010-06-21 Yann Jacquelet <jacquelet(a)lrde.epita.fr>
diff --git a/milena/sandbox/green/exp/annotating/achromastism/Makefile.am b/milena/sandbox/green/exp/annotating/saturation/Makefile.am
similarity index 100%
copy from milena/sandbox/green/exp/annotating/achromastism/Makefile.am
copy to milena/sandbox/green/exp/annotating/saturation/Makefile.am
diff --git a/milena/sandbox/green/exp/annotating/achromastism/achromastism.cc b/milena/sandbox/green/exp/annotating/saturation/saturation.cc
similarity index 75%
copy from milena/sandbox/green/exp/annotating/achromastism/achromastism.cc
copy to milena/sandbox/green/exp/annotating/saturation/saturation.cc
index fdb8e6d..3eb27a4 100644
--- a/milena/sandbox/green/exp/annotating/achromastism/achromastism.cc
+++ b/milena/sandbox/green/exp/annotating/saturation/saturation.cc
@@ -1,4 +1,4 @@
-// ACHROMATISM TEST CF MILLET 2008
+// SATURATION TEST CF MILLET 2008
#include <iostream>
#include <sstream>
@@ -21,9 +21,10 @@
#include <mln/geom/nsites.hh>
-#include <mln/fun/v2v/rgb_to_achromatism_map.hh>
+#include <mln/fun/v2v/rgb_to_saturation_map.hh>
#include <mln/io/ppm/load.hh>
+//#include <mln/io/pgm/save.hh>
#include <mln/io/plot/save_image_sh.hh>
#include <mln/value/rgb8.hh>
@@ -45,12 +46,14 @@ unsigned count_histo(const mln::Image<I>& img_)
return result;
}
-float achromatism_test(const std::string input,
- const std::string output,
- const unsigned threshold)
+
+float saturation_test(const std::string input,
+ const std::string output,
+// const std::string tmp,
+ const unsigned threshold)
{
- typedef mln::fun::v2v::rgb_to_achromatism_map<8> t_rgb_to_achromatism_map;
+ typedef mln::fun::v2v::rgb_to_saturation_map<8> t_rgb_to_saturation_map;
mln::image2d<mln::value::rgb8> input_rgb8;
mln::image2d<mln::value::int_u8> map;
@@ -61,7 +64,7 @@ float achromatism_test(const std::string input,
mln::io::ppm::load(input_rgb8, input.c_str());
- map = mln::data::transform(input_rgb8, t_rgb_to_achromatism_map());
+ map = mln::data::transform(input_rgb8, t_rgb_to_saturation_map());
histo = mln::data::compute(mln::accu::meta::stat::histo1d(), map);
cnt1 = count_histo(histo | mln::box1d(mln::point1d(0),
mln::point1d(threshold)));
@@ -69,6 +72,7 @@ float achromatism_test(const std::string input,
prop = ((100.0 * cnt1) / cnt2);
mln::io::plot::save_image_sh(histo, output.c_str());
+// mln::io::pgm::save(map, tmp.c_str());
return prop;
}
@@ -95,13 +99,15 @@ int main()
for (t_iter_path dir_iter(full_path[i]); end_iter != dir_iter; ++dir_iter)
{
// concatenation de chaine
- t_path directory(ANNOTATING_ACHROMATISM_RET_PATH);
- t_path leaf = dir_iter->path().leaf();
+ t_path directory(ANNOTATING_SATURATION_RET_PATH);
+ t_path leaf = dir_iter->path().leaf();
t_path output = change_extension(directory / leaf, ".sh");
+ t_path tmp = change_extension(directory / leaf, ".pgm");
- prop = achromatism_test(dir_iter->path().string(),
- output.string(),
- 11);
+ prop = saturation_test(dir_iter->path().string(),
+ output.string(),
+// tmp.string(),
+ 25);
std::cout << output << " : " << prop << std::endl;
std::cerr << output << " : " << prop << std::endl;
diff --git a/milena/sandbox/green/exp/annotating/achromastism/text-color.txt b/milena/sandbox/green/exp/annotating/saturation/text-color.txt
similarity index 100%
copy from milena/sandbox/green/exp/annotating/achromastism/text-color.txt
copy to milena/sandbox/green/exp/annotating/saturation/text-color.txt
diff --git a/milena/sandbox/green/exp/annotating/achromastism/text-img.txt b/milena/sandbox/green/exp/annotating/saturation/text-img.txt
similarity index 100%
copy from milena/sandbox/green/exp/annotating/achromastism/text-img.txt
copy to milena/sandbox/green/exp/annotating/saturation/text-img.txt
diff --git a/milena/sandbox/green/exp/annotating/achromastism/text-only.txt b/milena/sandbox/green/exp/annotating/saturation/text-only.txt
similarity index 100%
copy from milena/sandbox/green/exp/annotating/achromastism/text-only.txt
copy to milena/sandbox/green/exp/annotating/saturation/text-only.txt
--
1.5.6.5
1
0
15 Nov '10
* green/exp/annotating/hue: New directory.
* green/exp/annotating/hue/Makefile.am: New Makefile.
* green/exp/annotating/hue/hue.cc: New source file.
* green/exp/annotating/hue/text-color.txt: New image class.
* green/exp/annotating/hue/text-img.txt: New image class.
* green/exp/annotating/hue/text-only.txt: New image class.
---
milena/sandbox/ChangeLog | 11 +
.../annotating/{achromastism => hue}/Makefile.am | 0
milena/sandbox/green/exp/annotating/hue/hue.cc | 291 ++++++++++++++++++++
.../{achromastism => hue}/text-color.txt | 0
.../annotating/{achromastism => hue}/text-img.txt | 0
.../annotating/{achromastism => hue}/text-only.txt | 0
6 files changed, 302 insertions(+), 0 deletions(-)
copy milena/sandbox/green/exp/annotating/{achromastism => hue}/Makefile.am (100%)
create mode 100644 milena/sandbox/green/exp/annotating/hue/hue.cc
copy milena/sandbox/green/exp/annotating/{achromastism => hue}/text-color.txt (100%)
copy milena/sandbox/green/exp/annotating/{achromastism => hue}/text-img.txt (100%)
copy milena/sandbox/green/exp/annotating/{achromastism => hue}/text-only.txt (100%)
diff --git a/milena/sandbox/ChangeLog b/milena/sandbox/ChangeLog
index 15c6c4b..c41ef7c 100644
--- a/milena/sandbox/ChangeLog
+++ b/milena/sandbox/ChangeLog
@@ -2,6 +2,17 @@
Work on Millet saturation descriptor.
+ * green/exp/annotating/hue: New directory.
+ * green/exp/annotating/hue/Makefile.am: New Makefile.
+ * green/exp/annotating/hue/hue.cc: New source file.
+ * green/exp/annotating/hue/text-color.txt: New image class.
+ * green/exp/annotating/hue/text-img.txt: New image class.
+ * green/exp/annotating/hue/text-only.txt: New image class.
+
+2010-06-21 Yann Jacquelet <jacquelet(a)lrde.epita.fr>
+
+ Work on Millet saturation descriptor.
+
* green/exp/annotating/saturation: New directory.
* green/exp/annotating/saturation/Makefile.am: New Makefile.
* green/exp/annotating/saturation/saturation.cc: New source file.
diff --git a/milena/sandbox/green/exp/annotating/achromastism/Makefile.am b/milena/sandbox/green/exp/annotating/hue/Makefile.am
similarity index 100%
copy from milena/sandbox/green/exp/annotating/achromastism/Makefile.am
copy to milena/sandbox/green/exp/annotating/hue/Makefile.am
diff --git a/milena/sandbox/green/exp/annotating/hue/hue.cc b/milena/sandbox/green/exp/annotating/hue/hue.cc
new file mode 100644
index 0000000..883e1c6
--- /dev/null
+++ b/milena/sandbox/green/exp/annotating/hue/hue.cc
@@ -0,0 +1,291 @@
+// SATURATION TEST CF MILLET 2008
+
+#include <iostream>
+#include <sstream>
+#include <boost/filesystem.hpp>
+
+#include <mln/img_path.hh>
+
+#include <mln/accu/stat/histo1d.hh>
+
+#include <mln/core/image/image1d.hh>
+#include <mln/core/image/image2d.hh>
+#include <mln/core/image/dmorph/image_if.hh>
+
+#include <mln/data/compute.hh>
+#include <mln/data/stretch.hh>
+#include <mln/data/transform.hh>
+
+#include <mln/literal/colors.hh>
+#include <mln/literal/grays.hh>
+
+#include <mln/math/max.hh>
+#include <mln/math/min.hh>
+
+#include <mln/opt/at.hh>
+
+#include <mln/geom/nsites.hh>
+
+#include <mln/fun/v2v/rgb_to_hue_map.hh>
+
+#include <mln/io/ppm/load.hh>
+#include <mln/io/pgm/save.hh>
+#include <mln/io/plot/save_image_sh.hh>
+
+#include <mln/value/rgb8.hh>
+
+mln::value::rgb8 label_val(const mln::value::int_u8 val)
+{
+ mln::value::rgb8 result;
+
+ if (82 > val)
+ result = mln::literal::black;
+ else if (179 > val)
+ result= mln::literal::medium_gray;
+ else
+ result = mln::literal::white;
+
+ return result;
+}
+
+
+mln::value::rgb8 label_orange_or_brown(const mln::value::rgb8 color,
+ const mln::value::int_u8 sat,
+ const mln::value::int_u8 val)
+{
+ mln::value::rgb8 result;
+
+ if (mln::literal::orange == color)
+ {
+ unsigned dist_orange = mln::math::abs(sat - 184)
+ + mln::math::abs(val - 65);
+
+ unsigned dist_brown = mln::math::abs(sat - 255)
+ + mln::math::abs(val - 125);
+
+ if (dist_orange < dist_brown)
+ result = mln::literal::orange;
+ else
+ result = mln::literal::brown;
+ }
+ else
+ result = color;
+
+ return result;
+}
+
+mln::value::rgb8 label_yellow_or_green(const mln::value::rgb8 color,
+ const mln::value::int_u8 val)
+{
+ mln::value::rgb8 result;
+
+ if (mln::literal::yellow == color)
+ {
+ // Is it green or yellow ?
+ if (80 > val)
+ result = mln::literal::green;
+ else
+ result = mln::literal::yellow;
+ }
+ else
+ return color;
+
+ return result;
+}
+
+mln::value::rgb8 label_hue(const mln::value::int_u8 hue)
+{
+ mln::value::rgb8 result;
+
+
+ if (10 > hue)
+ result = mln::literal::red;
+ else if (32 > hue)
+ result = mln::literal::orange;
+ else if (53 > hue)
+ result = mln::literal::yellow;
+ else if (74 > hue)
+ result = mln::literal::green; // chartreuse
+ else if (96 > hue)
+ result = mln::literal::green;
+ else if (116 > hue)
+ result = mln::literal::green;// turquoise, aigue-marine
+ else if (138 > hue)
+ result = mln::literal::green; // cyan
+ else if (159 > hue)
+ result = mln::literal::blue; // azur
+ else if (181 > hue)
+ result = mln::literal::blue;
+ else if (202 > hue)
+ result = mln::literal::violet;
+ else if (223 > hue)
+ result = mln::literal::pink;
+ else // if (244 > hue)
+ result = mln::literal::red;
+
+
+// if (14 > hue)
+// result = mln::literal::red;
+// else if (29 > hue)
+// result = mln::literal::orange;
+// else if (45 > hue)
+// result = mln::literal::yellow;
+// else if (113 > hue)
+// result = mln::literal::green;
+// else if (149 > hue)
+// result = mln::literal::cyan;
+// else if (205 > hue)
+// result = mln::literal::blue;
+// else if (235 > hue)
+// result = mln::literal::violet;
+// else if (242 > hue)
+// result = mln::literal::pink;
+// else
+// result = mln::literal::red;
+
+ return result;
+}
+
+template <typename I>
+unsigned count_histo(const mln::Image<I>& img_)
+{
+ const I& img = exact(img_);
+
+ mln_precondition(img.is_valid());
+
+ unsigned result = 0;
+
+ mln_piter(I) p(img.domain());
+
+ for_all(p)
+ result += img(p);
+
+ return result;
+}
+
+template <typename I>
+unsigned peak_histo(const mln::Image<I>& histo_)
+{
+ const I& histo = exact(histo_);
+
+ mln_precondition(histo.is_valid());
+
+ // Find the peak of the histogram
+ unsigned v_max = mln::opt::at(histo, 0);
+ short p_max = 0;
+
+ mln_piter(I) p(histo.domain());
+
+ for_all(p)
+ {
+ if (v_max < histo(p))
+ {
+ v_max = histo(p);
+ p_max = p.ind();
+ }
+ }
+
+ return p_max;
+}
+
+template <typename I>
+unsigned mean_histo(const mln::Image<I>& histo_)
+{
+ const I& histo = exact(histo_);
+
+ mln_precondition(histo.is_valid());
+
+ // Find the mean of the histogram
+ float sum = 0;
+ float mean = 0;
+
+ mln_piter(I) p(histo.domain());
+
+ for_all(p)
+ {
+ sum += histo(p);
+ mean += p.ind()*histo(p);
+ }
+
+ mean = mean / sum;
+
+ return mean;
+}
+
+
+float hue_test(const std::string input,
+ const std::string output,
+ const std::string tmp,
+ const unsigned threshold)
+
+{
+ typedef mln::fun::v2v::rgb_to_hue_map<8> t_rgb_to_hue_map;
+
+ mln::image2d<mln::value::rgb8> input_rgb8;
+ mln::image2d<mln::value::int_u8> map;
+ mln::image1d<unsigned> histo;
+ unsigned cnt1;
+ unsigned cnt2;
+ float prop;
+ unsigned peak;
+ mln::value::rgb8 color;
+
+ mln::io::ppm::load(input_rgb8, input.c_str());
+
+ map = mln::data::transform(input_rgb8, t_rgb_to_hue_map());
+ histo = mln::data::compute(mln::accu::meta::stat::histo1d(), map);
+ peak = mean_histo(histo); //peak_histo(histo);
+ color = label_hue(peak);
+ cnt1 = count_histo(histo | mln::box1d(mln::point1d(peak-threshold),
+ mln::point1d(peak+threshold)));
+ cnt2 = mln::geom::nsites(input_rgb8);
+ prop = ((100.0 * cnt1) / cnt2);
+
+ mln::io::plot::save_image_sh(histo, output.c_str());
+ mln::io::pgm::save(map, tmp.c_str());
+ std::cout << "peak = " << peak << std::endl;
+ std::cout << "color = " << color << std::endl;
+
+ return prop;
+}
+
+
+int main()
+{
+ typedef boost::filesystem::path t_path;
+ typedef boost::filesystem::directory_iterator t_iter_path;
+
+ t_path full_path[] = {t_path(ICDAR_20P_PPM_IMG_PATH)};
+
+ for (int i = 0; i < 1; ++i)
+ {
+ std::cout << "entering " << full_path[i] << std::endl;
+
+ if (boost::filesystem::exists(full_path[i]) &&
+ boost::filesystem::is_directory(full_path[i]))
+ {
+ boost::filesystem::system_complete(full_path[i]);
+ const t_iter_path end_iter;
+ float prop = 0.0;
+
+ for (t_iter_path dir_iter(full_path[i]); end_iter != dir_iter; ++dir_iter)
+ {
+ // concatenation de chaine
+ t_path directory(ANNOTATING_HUE_RET_PATH);
+ t_path leaf = dir_iter->path().leaf();
+ t_path output = change_extension(directory / leaf, ".sh");
+ t_path tmp = change_extension(directory / leaf, ".pgm");
+
+ prop = hue_test(dir_iter->path().string(),
+ output.string(),
+ tmp.string(),
+ 20);
+
+ std::cout << output << " : " << prop << std::endl;
+ std::cerr << output << " : " << prop << std::endl;
+ }
+ }
+ }
+
+ return 0;
+}
diff --git a/milena/sandbox/green/exp/annotating/achromastism/text-color.txt b/milena/sandbox/green/exp/annotating/hue/text-color.txt
similarity index 100%
copy from milena/sandbox/green/exp/annotating/achromastism/text-color.txt
copy to milena/sandbox/green/exp/annotating/hue/text-color.txt
diff --git a/milena/sandbox/green/exp/annotating/achromastism/text-img.txt b/milena/sandbox/green/exp/annotating/hue/text-img.txt
similarity index 100%
copy from milena/sandbox/green/exp/annotating/achromastism/text-img.txt
copy to milena/sandbox/green/exp/annotating/hue/text-img.txt
diff --git a/milena/sandbox/green/exp/annotating/achromastism/text-only.txt b/milena/sandbox/green/exp/annotating/hue/text-only.txt
similarity index 100%
copy from milena/sandbox/green/exp/annotating/achromastism/text-only.txt
copy to milena/sandbox/green/exp/annotating/hue/text-only.txt
--
1.5.6.5
1
0
15 Nov '10
* green/exp/annotating/value: New directory.
* green/exp/annotating/value/Makefile.am: New Makefile.
* green/exp/annotating/value/value.cc: New source file.
* green/exp/annotating/value/text-color.txt: New image class.
* green/exp/annotating/value/text-img.txt: New image class.
* green/exp/annotating/value/text-only.txt: New image class.
---
.../annotating/{achromastism => value}/Makefile.am | 0
.../{achromastism => value}/text-color.txt | 0
.../{achromastism => value}/text-img.txt | 0
.../{achromastism => value}/text-only.txt | 0
.../exp/annotating/{hue/hue.cc => value/value.cc} | 143 ++++++++++++--------
5 files changed, 84 insertions(+), 59 deletions(-)
copy milena/sandbox/green/exp/annotating/{achromastism => value}/Makefile.am (100%)
copy milena/sandbox/green/exp/annotating/{achromastism => value}/text-color.txt (100%)
copy milena/sandbox/green/exp/annotating/{achromastism => value}/text-img.txt (100%)
copy milena/sandbox/green/exp/annotating/{achromastism => value}/text-only.txt (100%)
copy milena/sandbox/green/exp/annotating/{hue/hue.cc => value/value.cc} (68%)
diff --git a/milena/sandbox/green/exp/annotating/achromastism/Makefile.am b/milena/sandbox/green/exp/annotating/value/Makefile.am
similarity index 100%
copy from milena/sandbox/green/exp/annotating/achromastism/Makefile.am
copy to milena/sandbox/green/exp/annotating/value/Makefile.am
diff --git a/milena/sandbox/green/exp/annotating/achromastism/text-color.txt b/milena/sandbox/green/exp/annotating/value/text-color.txt
similarity index 100%
copy from milena/sandbox/green/exp/annotating/achromastism/text-color.txt
copy to milena/sandbox/green/exp/annotating/value/text-color.txt
diff --git a/milena/sandbox/green/exp/annotating/achromastism/text-img.txt b/milena/sandbox/green/exp/annotating/value/text-img.txt
similarity index 100%
copy from milena/sandbox/green/exp/annotating/achromastism/text-img.txt
copy to milena/sandbox/green/exp/annotating/value/text-img.txt
diff --git a/milena/sandbox/green/exp/annotating/achromastism/text-only.txt b/milena/sandbox/green/exp/annotating/value/text-only.txt
similarity index 100%
copy from milena/sandbox/green/exp/annotating/achromastism/text-only.txt
copy to milena/sandbox/green/exp/annotating/value/text-only.txt
diff --git a/milena/sandbox/green/exp/annotating/hue/hue.cc b/milena/sandbox/green/exp/annotating/value/value.cc
similarity index 68%
copy from milena/sandbox/green/exp/annotating/hue/hue.cc
copy to milena/sandbox/green/exp/annotating/value/value.cc
index 883e1c6..9209d47 100644
--- a/milena/sandbox/green/exp/annotating/hue/hue.cc
+++ b/milena/sandbox/green/exp/annotating/value/value.cc
@@ -1,4 +1,4 @@
-// SATURATION TEST CF MILLET 2008
+// VALUE TEST CF MILLET 2008
#include <iostream>
#include <sstream>
@@ -26,7 +26,7 @@
#include <mln/geom/nsites.hh>
-#include <mln/fun/v2v/rgb_to_hue_map.hh>
+#include <mln/fun/v2v/rgb_to_value_map.hh>
#include <mln/io/ppm/load.hh>
#include <mln/io/pgm/save.hh>
@@ -97,52 +97,25 @@ mln::value::rgb8 label_hue(const mln::value::int_u8 hue)
{
mln::value::rgb8 result;
-
- if (10 > hue)
+ if (14 > hue)
result = mln::literal::red;
- else if (32 > hue)
+ else if (29 > hue)
result = mln::literal::orange;
- else if (53 > hue)
+ else if (45 > hue)
result = mln::literal::yellow;
- else if (74 > hue)
- result = mln::literal::green; // chartreuse
- else if (96 > hue)
+ else if (113 > hue)
result = mln::literal::green;
- else if (116 > hue)
- result = mln::literal::green;// turquoise, aigue-marine
- else if (138 > hue)
- result = mln::literal::green; // cyan
- else if (159 > hue)
- result = mln::literal::blue; // azur
- else if (181 > hue)
+ else if (149 > hue)
+ result = mln::literal::cyan;
+ else if (205 > hue)
result = mln::literal::blue;
- else if (202 > hue)
+ else if (235 > hue)
result = mln::literal::violet;
- else if (223 > hue)
+ else if (242 > hue)
result = mln::literal::pink;
- else // if (244 > hue)
+ else
result = mln::literal::red;
-
-// if (14 > hue)
-// result = mln::literal::red;
-// else if (29 > hue)
-// result = mln::literal::orange;
-// else if (45 > hue)
-// result = mln::literal::yellow;
-// else if (113 > hue)
-// result = mln::literal::green;
-// else if (149 > hue)
-// result = mln::literal::cyan;
-// else if (205 > hue)
-// result = mln::literal::blue;
-// else if (235 > hue)
-// result = mln::literal::violet;
-// else if (242 > hue)
-// result = mln::literal::pink;
-// else
-// result = mln::literal::red;
-
return result;
}
@@ -212,14 +185,69 @@ unsigned mean_histo(const mln::Image<I>& histo_)
return mean;
}
+// calcul de contribution
+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;
+}
+
+template <typename I>
+float stddev3(const mln::Image<I>& histo_, unsigned peak)
+{
+ const I& histo = exact(histo_);
+
+ mln_precondition(histo.is_valid());
+
+ // Compute stddev
+
+ float stddev = 0.0;
+
+ mln_piter(I) p(histo.domain());
+
+ for_all(p)
+ {
+ stddev += r((short)peak, mln::opt::at(histo,peak), p.ind(), histo(p));
+ }
+
+ return stddev;
+}
+
+template <typename I>
+float stddev2(const mln::Image<I>& histo_, unsigned peak, unsigned limit)
+{
+ const I& histo = exact(histo_);
+
+ mln_precondition(histo.is_valid());
+
+ float stddev_low = 0.0;
+ float stddev_up = 0.0;
+ float ret = 0.0;
+
+ // A transformer avec des iterators
+
+ if (250 > peak)
+ stddev_up = stddev3(histo |mln::box1d(mln::point1d(peak+1),
+ mln::point1d(peak+limit)), peak);
+
+ if (5 < peak)
+ stddev_low = stddev3(histo |mln::box1d(mln::point1d(peak-limit),
+ mln::point1d(peak-1)), peak);
+
+ ret = (250 < peak)? stddev_low : (5 > peak)? stddev_up :
+ (stddev_low + stddev_up)/2;
+
+ return ret;
+}
-float hue_test(const std::string input,
- const std::string output,
- const std::string tmp,
- const unsigned threshold)
+float value_test(const std::string input,
+ const std::string output,
+ const std::string tmp,
+ const unsigned threshold)
{
- typedef mln::fun::v2v::rgb_to_hue_map<8> t_rgb_to_hue_map;
+ typedef mln::fun::v2v::rgb_to_value_map<8> t_rgb_to_value_map;
mln::image2d<mln::value::rgb8> input_rgb8;
mln::image2d<mln::value::int_u8> map;
@@ -228,23 +256,20 @@ float hue_test(const std::string input,
unsigned cnt2;
float prop;
unsigned peak;
- mln::value::rgb8 color;
mln::io::ppm::load(input_rgb8, input.c_str());
- map = mln::data::transform(input_rgb8, t_rgb_to_hue_map());
+ map = mln::data::transform(input_rgb8, t_rgb_to_value_map());
histo = mln::data::compute(mln::accu::meta::stat::histo1d(), map);
- peak = mean_histo(histo); //peak_histo(histo);
- color = label_hue(peak);
- cnt1 = count_histo(histo | mln::box1d(mln::point1d(peak-threshold),
- mln::point1d(peak+threshold)));
- cnt2 = mln::geom::nsites(input_rgb8);
- prop = ((100.0 * cnt1) / cnt2);
+ peak = peak_histo(histo); // mean_histo(histo);
+ prop = stddev2(histo, peak, limit);
+// cnt1 = count_histo(histo | mln::box1d(mln::point1d(peak-threshold),
+// mln::point1d(peak+threshold)));
+// cnt2 = mln::geom::nsites(input_rgb8);
+// prop = ((100.0 * cnt1) / cnt2);
mln::io::plot::save_image_sh(histo, output.c_str());
mln::io::pgm::save(map, tmp.c_str());
- std::cout << "peak = " << peak << std::endl;
- std::cout << "color = " << color << std::endl;
return prop;
}
@@ -271,15 +296,15 @@ int main()
for (t_iter_path dir_iter(full_path[i]); end_iter != dir_iter; ++dir_iter)
{
// concatenation de chaine
- t_path directory(ANNOTATING_HUE_RET_PATH);
+ t_path directory(ANNOTATING_VALUE_RET_PATH);
t_path leaf = dir_iter->path().leaf();
t_path output = change_extension(directory / leaf, ".sh");
t_path tmp = change_extension(directory / leaf, ".pgm");
- prop = hue_test(dir_iter->path().string(),
- output.string(),
- tmp.string(),
- 20);
+ prop = value_test(dir_iter->path().string(),
+ output.string(),
+ tmp.string(),
+ 15);
std::cout << output << " : " << prop << std::endl;
std::cerr << output << " : " << prop << std::endl;
--
1.5.6.5
1
0
* green/mln/accu/stat/histo1d.hh: New header component.
* green/mln/fun/p2b/achromatic.hh: New header component.
* green/mln/fun/p2b/component_equals.hh: New header component.
* green/mln/fun/v2v/achromatism.hh: New header component.
* green/mln/fun/v2v/hue_concentration.hh: New header component.
* green/mln/fun/v2v/rgb_to_achromatism_map.hh: New header component.
* green/mln/fun/v2v/rgb_to_hsv.hh: New header component.
* green/mln/fun/v2v/rgb_to_hue_map.hh: New header component.
* green/mln/fun/v2v/rgb_to_saturation_map.hh: New header component.
* green/mln/fun/v2v/rgb_to_value_map.hh: New header component.
* green/mln/img_path.hh: New header component.
* green/mln/math/ceil.hh: New header component.
* green/mln/math/floor.hh: New header component.
* green/mln/math/hsv.hh: New header component.
---
milena/sandbox/ChangeLog | 32 ++-
milena/sandbox/green/mln/accu/stat/histo1d.hh | 66 ++--
milena/sandbox/green/mln/fun/p2b/achromatic.hh | 112 +++++
.../sandbox/green/mln/fun/p2b/component_equals.hh | 99 +++++
milena/sandbox/green/mln/fun/v2v/achromatism.hh | 64 +++
.../sandbox/green/mln/fun/v2v/hue_concentration.hh | 100 +++++
.../green/mln/fun/v2v/rgb_to_achromatism_map.hh | 77 ++++
milena/sandbox/green/mln/fun/v2v/rgb_to_hsv.hh | 149 +++++++
milena/sandbox/green/mln/fun/v2v/rgb_to_hue_map.hh | 96 +++++
.../green/mln/fun/v2v/rgb_to_saturation_map.hh | 83 ++++
.../sandbox/green/mln/fun/v2v/rgb_to_value_map.hh | 75 ++++
milena/sandbox/green/mln/img_path.hh | 227 +++++++++--
milena/sandbox/green/mln/math/ceil.hh | 64 +++
milena/sandbox/green/mln/math/floor.hh | 64 +++
milena/sandbox/green/mln/value/hsv.hh | 424 ++++++++++++++++++++
15 files changed, 1670 insertions(+), 62 deletions(-)
create mode 100644 milena/sandbox/green/mln/fun/p2b/achromatic.hh
create mode 100644 milena/sandbox/green/mln/fun/p2b/component_equals.hh
create mode 100644 milena/sandbox/green/mln/fun/v2v/achromatism.hh
create mode 100644 milena/sandbox/green/mln/fun/v2v/hue_concentration.hh
create mode 100644 milena/sandbox/green/mln/fun/v2v/rgb_to_achromatism_map.hh
create mode 100644 milena/sandbox/green/mln/fun/v2v/rgb_to_hsv.hh
create mode 100644 milena/sandbox/green/mln/fun/v2v/rgb_to_hue_map.hh
create mode 100644 milena/sandbox/green/mln/fun/v2v/rgb_to_saturation_map.hh
create mode 100644 milena/sandbox/green/mln/fun/v2v/rgb_to_value_map.hh
create mode 100644 milena/sandbox/green/mln/math/ceil.hh
create mode 100644 milena/sandbox/green/mln/math/floor.hh
create mode 100644 milena/sandbox/green/mln/value/hsv.hh
diff --git a/milena/sandbox/ChangeLog b/milena/sandbox/ChangeLog
index c41ef7c..62c6e21 100644
--- a/milena/sandbox/ChangeLog
+++ b/milena/sandbox/ChangeLog
@@ -1,6 +1,36 @@
2010-06-21 Yann Jacquelet <jacquelet(a)lrde.epita.fr>
- Work on Millet saturation descriptor.
+ Add milena library components.
+
+ * green/mln/accu/stat/histo1d.hh: New header component.
+ * green/mln/fun/p2b/achromatic.hh: New header component.
+ * green/mln/fun/p2b/component_equals.hh: New header component.
+ * green/mln/fun/v2v/achromatism.hh: New header component.
+ * green/mln/fun/v2v/hue_concentration.hh: New header component.
+ * green/mln/fun/v2v/rgb_to_achromatism_map.hh: New header component.
+ * green/mln/fun/v2v/rgb_to_hsv.hh: New header component.
+ * green/mln/fun/v2v/rgb_to_hue_map.hh: New header component.
+ * green/mln/fun/v2v/rgb_to_saturation_map.hh: New header component.
+ * green/mln/fun/v2v/rgb_to_value_map.hh: New header component.
+ * green/mln/img_path.hh: New header component.
+ * green/mln/math/ceil.hh: New header component.
+ * green/mln/math/floor.hh: New header component.
+ * green/mln/math/hsv.hh: New header component.
+
+2010-06-21 Yann Jacquelet <jacquelet(a)lrde.epita.fr>
+
+ Work on Millet value descriptor.
+
+ * green/exp/annotating/value: New directory.
+ * green/exp/annotating/value/Makefile.am: New Makefile.
+ * green/exp/annotating/value/value.cc: New source file.
+ * green/exp/annotating/value/text-color.txt: New image class.
+ * green/exp/annotating/value/text-img.txt: New image class.
+ * green/exp/annotating/value/text-only.txt: New image class.
+
+2010-06-21 Yann Jacquelet <jacquelet(a)lrde.epita.fr>
+
+ Work on Millet hue descriptor.
* green/exp/annotating/hue: New directory.
* green/exp/annotating/hue/Makefile.am: New Makefile.
diff --git a/milena/sandbox/green/mln/accu/stat/histo1d.hh b/milena/sandbox/green/mln/accu/stat/histo1d.hh
index 807f3bd..57d6103 100644
--- a/milena/sandbox/green/mln/accu/stat/histo1d.hh
+++ b/milena/sandbox/green/mln/accu/stat/histo1d.hh
@@ -76,26 +76,26 @@
namespace mln
{
-
+
namespace accu
{
-
+
namespace stat
{
-
+
// Forward declaration
template <typename V>
struct histo1d;
} // end of namespace mln::accu::stat
-
+
namespace meta
{
-
+
namespace stat
{
-
+
struct histo1d : public Meta_Accumulator<histo1d>
{
template <typename V>
@@ -104,16 +104,16 @@ namespace mln
typedef accu::stat::histo1d<V> ret;
};
};
-
+
} // end of namespace mln::accu::meta::stat
-
+
} // end of namespace mln::accu::meta
-
+
} // end of namespace mln::accu
namespace trait
{
-
+
template <typename V>
struct accumulator_< mln::accu::stat::histo1d<V> >
{
@@ -124,34 +124,34 @@ namespace mln
};
template <typename V>
- struct set_precise_binary_<op::eq,
+ struct set_precise_binary_<op::eq,
accu::stat::histo1d<V>,
accu::stat::histo1d<V> >
{
typedef bool ret;
};
-
+
} // end of namespace mln::trait
namespace accu
{
-
+
namespace stat
- {
+ {
- /// \brief Define an histogram which returns an image1d .
+ /// \brief Define an histogram which returns an image1d .
///
/// Param V defines the space in which we count the values.
/// For instance, this histogram works with image2d<int_u8> or with
/// image1d<int_u<14> >. The histogram count the occurrence of each value.
/// The number of bins depends of the graylevel values, for 8 bits there
- /// is 256 bins, for 14 bits there is 16384 bins. Note that over
+ /// is 256 bins, for 14 bits there is 16384 bins. Note that over
/// quantification works too (up to 14 bits).
///
/// \ingroup modaccuvalues
template <typename V>
- struct histo1d :
+ struct histo1d :
public mln::accu::internal::base<image1d<unsigned>, histo1d<V> >
{
typedef V argument;
@@ -162,22 +162,22 @@ namespace mln
/// \{
/// \brief Initialize the size of the resulting image1d.
///
- /// Initialize the size the resulting image from the theorical dynamic
+ /// Initialize the size the resulting image from the theorical dynamic
/// of the graylevel values (Use V to manage it).
histo1d();
/// \}
-
+
/// Manipulators.
/// \{
/// \brief Initialize the histogram with zero value.
///
- /// This method must be called just before starting the use of the
- /// histogram. If it's not, resulting values won't converge to the
+ /// This method must be called just before starting the use of the
+ /// histogram. If it's not, resulting values won't converge to the
/// density.
void init();
-
+
/// \brief Update the histogram with the graylevel of the pixel t.
/// \param[in] t a graylevel pixel of type V.
///
@@ -189,7 +189,7 @@ namespace mln
/// \brief Update the histogram with an other histogram.
/// \param[in] other the other histogram.
///
- /// The end user shouldn't call this method. This is part of
+ /// The end user shouldn't call this method. This is part of
/// data compute interface mechanism.
void take(const histo1d<V>& other);
@@ -234,7 +234,7 @@ namespace mln
typedef mln_trait_value_comp(V,0) comp;
typedef point<grid::tick, V> v_point1d;
typedef box<v_point1d> v_box1d;
-
+
// comp keep a trace of the dimension of the theorical image.
// mln_min(comp) --> 0
// mln_max(comp) --> 2^(n-1) [127 for n=7][255 for n=8] ...
@@ -242,8 +242,8 @@ namespace mln
count_.init_(box1d(point1d(mln_min(comp)),
point1d(mln_max(comp))));
- // std::cout << "min : " << mln_min(comp) << std::endl;
- // std::cout << "max : " << mln_max(comp) << std::endl;
+// std::cout << "min : " << mln_min(comp) << std::endl;
+// std::cout << "max : " << mln_max(comp) << std::endl;
trace::exiting("mln::accu::stat::histo1d<V>::histo1d");
}
@@ -264,14 +264,14 @@ namespace mln
{
trace::entering("mln::accu::stat::histo1d<V>::take");
- // Just convert a graylevel value (int_u8 like) to a position for an
+ // Just convert a graylevel value (int_u8 like) to a position for an
// iterator on the resulting image.
++count_(point1d(t));
trace::exiting("mln::accu::stat::histo1d<V>::take");
}
-
+
template <typename V>
inline
void histo1d<V>::take(const histo1d<V>& other)
@@ -282,7 +282,7 @@ namespace mln
trace::exiting("mln::accu::stat::histo1d<V>::take");
}
-
+
template <typename V>
inline
typename histo1d<V>::result histo1d<V>::to_result() const
@@ -292,7 +292,7 @@ namespace mln
trace::exiting("mln::accu::stat::histo1d<V>::to_result");
return count_;
}
-
+
template <typename V>
inline
histo1d<V>::operator result() const
@@ -301,7 +301,7 @@ namespace mln
trace::exiting("mln::accu::stat::histo1d<V>::operator result");
return count_;
- }
+ }
template <typename V>
inline
@@ -309,7 +309,7 @@ namespace mln
{
trace::entering("mln::accu::stat::histo1d<V>::is_valid");
bool result = count_.is_valid();
-
+
trace::exiting("mln::accu::stat::histo1d<V>::is_valid");
return result;
}
@@ -322,7 +322,7 @@ namespace mln
bool result = true;
const image1d<unsigned>& res1 = histo1.to_result();
const image1d<unsigned>& res2 = histo2.to_result();
-
+
mln_precondition(res1.is_valid());
mln_precondition(res2.is_valid());
diff --git a/milena/sandbox/green/mln/fun/p2b/achromatic.hh b/milena/sandbox/green/mln/fun/p2b/achromatic.hh
new file mode 100644
index 0000000..1f45b2d
--- /dev/null
+++ b/milena/sandbox/green/mln/fun/p2b/achromatic.hh
@@ -0,0 +1,112 @@
+// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef MLN_FUN_P2B_ACHROMATIC_HH
+# define MLN_FUN_P2B_ACHROMATIC_HH
+
+/// \file
+///
+/// In the vectorial image context (as RGB, HSL, HSV), compare one component
+/// to a specific value.
+
+# include <mln/core/alias/point2d.hh>
+# include <mln/core/concept/function.hh>
+# include <mln/trait/value/comp.hh>
+
+
+namespace mln
+{
+
+ namespace fun
+ {
+
+ namespace p2b
+ {
+ /// \brief Functor that compare the i-th component of a value.
+ // V is for the type of the value received
+ // i is the ith component to select
+ template <typename T_rgb>
+ struct achromatic : public Function_v2b< achromatic<T_rgb> >
+ {
+ typedef bool result;
+ bool operator()(const point2d& p) const;
+
+ achromatic(const image2d<T_rgb>& img, const float threshold);
+
+ const float threshold_;
+ const image2d<T_rgb>& img_;
+ };
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename T_rgb>
+ achromatic<T_rgb>::achromatic(const image2d<T_rgb>& img,
+ const float threshold)
+ : threshold_(threshold), img_(img)
+ {
+ }
+
+ template <typename T_rgb>
+ bool achromatic<T_rgb>::operator()(const point2d& p) const
+ {
+ typedef typename T_rgb::red_t t_red;
+ typedef typename T_rgb::green_t t_green;
+ typedef typename T_rgb::blue_t t_blue;
+
+ const T_rgb rgb = img_(p);
+
+ // To obtain red between 0 and 1
+ const float max_red = mln_max(t_red);
+ const float min_red = mln_min(t_red);
+ const float red = (rgb.red() - min_red)/(max_red - min_red);
+
+ // To obtain green between 0 and 1
+ const float max_green = mln_max(t_green);
+ const float min_green = mln_min(t_green);
+ const float green = (rgb.green()-min_green)/(max_green-min_green);
+
+ // To obtain blue between 0 and 1
+ const float max_blue = mln_max(t_blue);
+ const float min_blue = mln_min(t_blue);
+ const float blue = (rgb.blue()-min_blue)/(max_blue-min_blue);
+
+ bool result = (threshold_ > math::abs(red - green) &&
+ threshold_ > math::abs(red - blue) &&
+ threshold_ > math::abs(green - blue));
+
+ return result;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::fun::p2b
+
+ } // end of namespace mln::fun
+
+} // end of namespace mln
+
+
+#endif // ! MLN_FUN_P2B_ACHROMATIC_HH
diff --git a/milena/sandbox/green/mln/fun/p2b/component_equals.hh b/milena/sandbox/green/mln/fun/p2b/component_equals.hh
new file mode 100644
index 0000000..2a4c62c
--- /dev/null
+++ b/milena/sandbox/green/mln/fun/p2b/component_equals.hh
@@ -0,0 +1,99 @@
+// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef MLN_FUN_P2B_COMPONENT_EQUALS_HH
+# define MLN_FUN_P2B_COMPONENT_EQUALS_HH
+
+/// \file
+///
+/// In the vectorial image context (as RGB, HSL, HSV), compare one component
+/// to a specific value.
+
+# include <mln/core/alias/point2d.hh>
+# include <mln/core/concept/function.hh>
+# include <mln/trait/value/comp.hh>
+
+
+namespace mln
+{
+
+ namespace fun
+ {
+
+ namespace p2b
+ {
+
+ /// \brief Functor that compare the i-th component of a value.
+ // V is for the type of the value received
+ // i is the ith component to select
+ template <typename I, unsigned i>
+ struct component_equals : public Function_v2b< component_equals<I,i> >
+ {
+ typedef bool result;
+ bool operator()(const point2d& p) const;
+
+ component_equals(const I& img,
+ const mln_trait_value_comp(mln_value(I),i)& ref);
+
+ const mln_trait_value_comp(mln_value(I),i) _ref;
+ const I& _img;
+ };
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename I, unsigned i>
+ inline
+ component_equals<I,i>::
+ component_equals(const I& img,
+ const mln_trait_value_comp(mln_value(I),i)& ref)
+ : _ref(ref), _img(img)
+ {
+ }
+
+ template <typename I, unsigned i>
+ inline
+ bool
+ component_equals<I,i>::operator()(const point2d& p) const
+ {
+ typedef mln_value(I) t_value;
+ typedef mln_trait_value_comp(t_value,i) mln_value_comp;
+
+ t_value v = _img(p);
+ mln_value_comp c = trait::value::internal::comp<t_value,i>::on(v);
+
+ return (c == _ref);
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::fun::p2b
+
+ } // end of namespace mln::fun
+
+} // end of namespace mln
+
+
+#endif // ! MLN_FUN_P2B_COMPONENT_EQUALS_HH
diff --git a/milena/sandbox/green/mln/fun/v2v/achromatism.hh b/milena/sandbox/green/mln/fun/v2v/achromatism.hh
new file mode 100644
index 0000000..72b545c
--- /dev/null
+++ b/milena/sandbox/green/mln/fun/v2v/achromatism.hh
@@ -0,0 +1,64 @@
+// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef MLN_FUN_V2V_ACHROMATISM_HH
+# define MLN_FUN_V2V_ACHROMATISM_HH
+
+# include <mln/value/rgb8.hh>
+
+namespace mln
+{
+
+ namespace fun
+ {
+
+ namespace v2v
+ {
+
+ struct achromatism : public Function_v2v< achromatism >
+ {
+ typedef float result;
+
+ float operator()(const value::rgb8 rgb) const;
+ };
+
+# ifndef MLN_INCLUDE_ONLY
+
+ float achromatism::operator()(const value::rgb8 rgb) const
+ {
+ return (math::abs(rgb.red() - rgb.green())
+ + math::abs(rgb.red() - rgb.blue())
+ + math::abs(rgb.green() - rgb.blue()))/3.0;
+ }
+
+# endif // !MLN_INCLUDE_ONLY
+
+ } // end of namespace fun::v2v
+
+ } // end of namespace fun
+
+} // end of namespace mln
+
+#endif // ! MLN_FUN_V2V_ACHROMATISM_HH
diff --git a/milena/sandbox/green/mln/fun/v2v/hue_concentration.hh b/milena/sandbox/green/mln/fun/v2v/hue_concentration.hh
new file mode 100644
index 0000000..84d26c8
--- /dev/null
+++ b/milena/sandbox/green/mln/fun/v2v/hue_concentration.hh
@@ -0,0 +1,100 @@
+// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef MLN_FUN_V2V_HUE_CONCENTRATION_HH
+# define MLN_FUN_V2V_HUE_CONCENTRATION_HH
+
+# include <mln/core/image/image1d.hh>
+# include <mln/math/abs.hh>
+# include <mln/opt/at.hh>
+# include <mln/value/hsv.hh>
+# include <mln/value/rgb8.hh>
+
+namespace mln
+{
+
+ namespace fun
+ {
+
+ namespace v2v
+ {
+
+ unsigned peak_histo(const mln::image1d<unsigned>& hue_histo);
+
+ struct hue_concentration : public Function_v2v< hue_concentration >
+ {
+ typedef float result;
+
+ float operator()(const float hue) const;
+
+ hue_concentration(const mln::image1d<unsigned>& hue_histo)
+ {
+ peak = peak_histo(hue_histo);
+ }
+
+ unsigned peak;
+ };
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ unsigned peak_histo(const mln::image1d<unsigned>& hue_histo)
+ {
+ mln_precondition(hue_histo.is_valid());
+
+ // Find the peak of the histogram
+ unsigned v_max = mln::opt::at(hue_histo, 0);
+ short p_max = 0;
+
+ mln_piter_(mln::image1d<unsigned>) p(hue_histo.domain());
+
+ for_all(p)
+ {
+ if (v_max < hue_histo(p))
+ {
+ v_max = hue_histo(p);
+ p_max = p.ind();
+ }
+ }
+
+ return p_max;
+ }
+
+
+ float hue_concentration::operator()(float hue) const
+ {
+ return mln::math::abs(peak - hue);
+ }
+
+# endif // !MLN_INCLUDE_ONLY
+
+ } // end of namespace fun::v2v
+
+ } // end of namespace fun
+
+} // end of namespace mln
+
+#endif // ! MLN_FUN_V2V_HUE_CONCENTRATION_HH
diff --git a/milena/sandbox/green/mln/fun/v2v/rgb_to_achromatism_map.hh b/milena/sandbox/green/mln/fun/v2v/rgb_to_achromatism_map.hh
new file mode 100644
index 0000000..6de63ec
--- /dev/null
+++ b/milena/sandbox/green/mln/fun/v2v/rgb_to_achromatism_map.hh
@@ -0,0 +1,77 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef MLN_FUN_V2V_RGB_TO_ACHROMATISM_MAP_HH
+# define MLN_FUN_V2V_RGB_TO_ACHROMATISM_MAP_HH
+
+# include <mln/math/abs.hh>
+# include <mln/math/max.hh>
+
+# include <mln/value/rgb.hh>
+
+
+/// \file
+///
+/// \brief Convert rgb value to achromatism map.
+
+namespace mln
+{
+
+ namespace fun
+ {
+
+ namespace v2v
+ {
+
+ /// \brief Convert rgb value to achromatism map.
+ ///
+ /// \ingroup modfunv2v
+
+ template <unsigned n>
+ struct rgb_to_achromatism_map :
+ Function_v2v< rgb_to_achromatism_map<n> >
+ {
+ typedef value::rgb<n> argument;
+ typedef value::int_u<n> result;
+
+ result operator()(const argument& v) const
+ {
+ result max = math::max(math::max(v.red(),v.green()),v.blue());
+ result min = math::min(math::min(v.red(),v.green()),v.blue());
+ result ret = max - min;
+
+ return ret;
+ }
+ };
+
+ } // end of namespace mln::fun::v2v
+
+ } // end of namespace mln::fun
+
+} // end of namespace mln
+
+#endif // ! MLN_FUN_V2V_RGB_TO_ACHROMATISM_MAP_HH
diff --git a/milena/sandbox/green/mln/fun/v2v/rgb_to_hsv.hh b/milena/sandbox/green/mln/fun/v2v/rgb_to_hsv.hh
new file mode 100644
index 0000000..3dd8eb0
--- /dev/null
+++ b/milena/sandbox/green/mln/fun/v2v/rgb_to_hsv.hh
@@ -0,0 +1,149 @@
+// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef MLN_FUN_V2V_RGB_TO_HSV_HH
+# define MLN_FUN_V2V_RGB_TO_HSV_HH
+
+#include <mln/math/max.hh>
+#include <mln/math/min.hh>
+
+#include <mln/trait/promote.hh>
+
+#include <mln/value/hsv.hh>
+#include <mln/value/rgb.hh>
+
+namespace mln
+{
+
+ namespace value
+ {
+ template <typename H, typename S, typename V> class hsv_;
+ typedef hsv_<float, float, float> hsv_f;
+ typedef hsv_<double, double, double> hsv_d;
+ template <unsigned n> struct rgb;
+ }
+
+ namespace fun
+ {
+
+ namespace v2v
+ {
+
+ template <typename T_hsv>
+ struct f_rgb_to_hsv_ : public Function_v2v< f_rgb_to_hsv_<T_hsv> >
+ {
+ typedef T_hsv result;
+
+
+ /// HSV implementation from millet.2008.phd.pdf p67
+ template <typename T_rgb>
+ T_hsv operator()(const T_rgb& rgb) const;
+
+ };
+
+ typedef f_rgb_to_hsv_<value::hsv_f> f_rgb_to_hsv_f_t;
+
+ extern f_rgb_to_hsv_f_t f_rgb_to_hsv_f;
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ /// Global variables.
+ /// \{
+ f_rgb_to_hsv_f_t f_rgb_to_hsv_f;
+ /// \}
+
+
+ template <typename T_hsv>
+ template <typename T_rgb>
+ inline
+ T_hsv
+ f_rgb_to_hsv_<T_hsv>::operator()(const T_rgb& rgb) const
+ {
+ typedef typename T_rgb::red_t t_red;
+ typedef typename T_rgb::green_t t_green;
+ typedef typename T_rgb::blue_t t_blue;
+ typedef typename T_hsv::h_type t_hue;
+ typedef typename T_hsv::s_type t_sat;
+ typedef typename T_hsv::v_type t_val;
+ typedef mln_trait_promote(t_hue, t_sat) t_max_hue_sat;
+ typedef mln_trait_promote(t_max_hue_sat, t_val) t_max_hsv;
+
+ // To obtain red between 0 and 1
+ const t_max_hsv max_red = mln_max(t_red);
+ const t_max_hsv min_red = mln_min(t_red);
+ const t_max_hsv red = (rgb.red() - min_red)/(max_red - min_red);
+
+ // To obtain green between 0 and 1
+ const t_max_hsv max_green = mln_max(t_green);
+ const t_max_hsv min_green = mln_min(t_green);
+ const t_max_hsv green =(rgb.green()-min_green)/(max_green-min_green);
+
+ // To obtain blue between 0 and 1
+ const t_max_hsv max_blue = mln_max(t_blue);
+ const t_max_hsv min_blue = mln_min(t_blue);
+ const t_max_hsv blue = (rgb.blue()-min_blue)/(max_blue-min_blue);
+
+ const t_max_hsv max = math::max(red, math::max(green, blue));
+ const t_max_hsv min = math::min(red, math::min(green, blue));
+ const t_max_hsv max_minus_min = max-min;
+ const t_max_hsv s = 0.03;
+
+ // Locals.
+ T_hsv hsv;
+
+ // SPECIFIC CASE WHEN PIXEL IS ACHROMATIC
+ if (s > math::abs(red - blue) &&
+ s > math::abs(blue - red) &&
+ s > math::abs(red - green))
+ {
+ hsv.val() = (red + green + blue)/3.0;
+ hsv.sat() = 0.0;
+ hsv.hue() = -1.0;
+ }
+ else
+ {
+ hsv.val() = max;
+ hsv.sat() = max_minus_min / max;
+ if (max == red)
+ hsv.hue() = 60 * ((green - blue) / max_minus_min);
+ else if (max == green)
+ hsv.hue() = 60 * (2 + (blue - red) / max_minus_min);
+ else // (max == blue)
+ hsv.hue() = 60 * (4 + (red - green) / max_minus_min);
+ }
+ return hsv;
+ }
+
+
+# endif // !MLN_INCLUDE_ONLY
+
+ } // end of namespace fun::v2v
+
+ } // end of namespace fun
+
+} // end of namespace mln
+
+#endif // ! MLN_FUN_V2V_RGB_TO_HSV_HH
diff --git a/milena/sandbox/green/mln/fun/v2v/rgb_to_hue_map.hh b/milena/sandbox/green/mln/fun/v2v/rgb_to_hue_map.hh
new file mode 100644
index 0000000..8b228e0
--- /dev/null
+++ b/milena/sandbox/green/mln/fun/v2v/rgb_to_hue_map.hh
@@ -0,0 +1,96 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef MLN_FUN_V2V_RGB_TO_HUE_MAP_HH
+# define MLN_FUN_V2V_RGB_TO_HUE_MAP_HH
+
+# include <mln/math/abs.hh>
+# include <mln/math/max.hh>
+
+# include <mln/value/rgb.hh>
+
+
+/// \file
+///
+/// \brief Convert rgb value to hue map.
+
+namespace mln
+{
+
+ namespace fun
+ {
+
+ namespace v2v
+ {
+
+ /// \brief Convert rgb value to hue map.
+ ///
+ /// \ingroup modfunv2v
+
+ template <unsigned n>
+ struct rgb_to_hue_map :
+ Function_v2v< rgb_to_hue_map<n> >
+ {
+ typedef value::rgb<n> argument;
+ typedef value::int_u<n> result;
+
+ result operator()(const argument& v) const
+ {
+ const float max = math::max(math::max(v.red(), v.green()), v.blue());
+ const float min = math::min(math::min(v.red(), v.green()), v.blue());
+ const float diff = max - min;
+ float hue = 0;
+
+ if (0 != diff)
+ {
+ if (v.red() == max)
+ {
+ hue = 60 * ((v.green() - v.blue()) / diff);
+
+ if (0 < hue)
+ hue = 360.0 + hue;
+ }
+ else if (v.green() == max)
+ hue = 60 * (2 + (v.blue() - v.red()) / diff);
+ else // (v.blue() == max)
+ hue = 60 * (4 + (v.red() - v.green()) / diff);
+ }
+
+ const result ret = (hue/360.0) * (mln_max(result) - mln_min(result))
+ + mln_min(result);
+
+ return ret;
+ }
+ };
+
+ } // end of namespace mln::fun::v2v
+
+ } // end of namespace mln::fun
+
+} // end of namespace mln
+
+#endif // ! MLN_FUN_V2V_RGB_TO_HUE_MAP_HH
diff --git a/milena/sandbox/green/mln/fun/v2v/rgb_to_saturation_map.hh b/milena/sandbox/green/mln/fun/v2v/rgb_to_saturation_map.hh
new file mode 100644
index 0000000..a8847a0
--- /dev/null
+++ b/milena/sandbox/green/mln/fun/v2v/rgb_to_saturation_map.hh
@@ -0,0 +1,83 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef MLN_FUN_V2V_RGB_TO_SATURATION_MAP_HH
+# define MLN_FUN_V2V_RGB_TO_SATURATION_MAP_HH
+
+# include <mln/math/abs.hh>
+# include <mln/math/max.hh>
+
+# include <mln/value/rgb.hh>
+
+
+/// \file
+///
+/// \brief Convert rgb value to saturation map.
+
+namespace mln
+{
+
+ namespace fun
+ {
+
+ namespace v2v
+ {
+
+ /// \brief Convert rgb value to saturation map.
+ ///
+ /// \ingroup modfunv2v
+
+ template <unsigned n>
+ struct rgb_to_saturation_map :
+ Function_v2v< rgb_to_saturation_map<n> >
+ {
+ typedef value::rgb<n> argument;
+ typedef value::int_u<n> result;
+
+ result operator()(const argument& v) const
+ {
+ const float max = math::max(math::max(v.red(), v.green()), v.blue());
+ const float min = math::min(math::min(v.red(), v.green()), v.blue());
+ float sat = 0.0;
+
+ if (0 != max)
+ sat = (1 - (float)min/max);
+
+ const result ret = sat * (mln_max(result) - mln_min(result))
+ + mln_min(result);
+
+ return ret;
+ }
+ };
+
+ } // end of namespace mln::fun::v2v
+
+ } // end of namespace mln::fun
+
+} // end of namespace mln
+
+#endif // ! MLN_FUN_V2V_RGB_TO_SATURATION_MAP_HH
diff --git a/milena/sandbox/green/mln/fun/v2v/rgb_to_value_map.hh b/milena/sandbox/green/mln/fun/v2v/rgb_to_value_map.hh
new file mode 100644
index 0000000..12ac1db
--- /dev/null
+++ b/milena/sandbox/green/mln/fun/v2v/rgb_to_value_map.hh
@@ -0,0 +1,75 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef MLN_FUN_V2V_RGB_TO_VALUE_MAP_HH
+# define MLN_FUN_V2V_RGB_TO_VALUE_MAP_HH
+
+# include <mln/math/abs.hh>
+# include <mln/math/max.hh>
+
+# include <mln/value/rgb.hh>
+
+
+/// \file
+///
+/// \brief Convert rgb value to value map.
+
+namespace mln
+{
+
+ namespace fun
+ {
+
+ namespace v2v
+ {
+
+ /// \brief Convert rgb value to value map.
+ ///
+ /// \ingroup modfunv2v
+
+ template <unsigned n>
+ struct rgb_to_value_map :
+ Function_v2v< rgb_to_value_map<n> >
+ {
+ typedef value::rgb<n> argument;
+ typedef value::int_u<n> result;
+
+ result operator()(const argument& v) const
+ {
+ const result ret = math::max(math::max(v.red(), v.green()), v.blue());
+
+ return ret;
+ }
+ };
+
+ } // end of namespace mln::fun::v2v
+
+ } // end of namespace mln::fun
+
+} // end of namespace mln
+
+#endif // ! MLN_FUN_V2V_RGB_TO_VALUE_MAP_HH
diff --git a/milena/sandbox/green/mln/img_path.hh b/milena/sandbox/green/mln/img_path.hh
index 7368c22..d205e1f 100644
--- a/milena/sandbox/green/mln/img_path.hh
+++ b/milena/sandbox/green/mln/img_path.hh
@@ -28,41 +28,212 @@
#ifndef MLN_IMG_PATH_HH
# define MLN_IMG_PATH_HH
-# define IMG_PATH "/home/green/svn/oln/trunk/milena/sandbox/green/img"
-# define RESULT_PATH "/home/green/svn/oln/trunk/milena/sandbox/green/result"
+# define IMG_PATH "/home/green/git/img"
+# define RET_PATH "/home/green/git/result"
# define INIM_IMG_PATH IMG_PATH"/inim"
-# define INIM_FG_BG_IMG_PATH INIM_IMG_PATH"/fg_bg"
+# define INIM_BG_IMG_PATH INIM_IMG_PATH"/bg"
+# define INIM_FG_IMG_PATH INIM_IMG_PATH"/fg"
# define INIM_IN_IMG_PATH INIM_IMG_PATH"/in"
# define OLENA_IMG_PATH IMG_PATH"/olena"
-# define SCRIBO_IMG_PATH IMG_PATH"/scribo"
-# define SCRIBO_JPG_IMG_PATH SCRIBO_IMG_PATH"/jpg_50p"
-# define SCRIBO_PGM_IMG_PATH SCRIBO_IMG_PATH"/pgm_50p"
-# define SCRIBO_PPM_IMG_PATH SCRIBO_IMG_PATH"/ppm_50p"
-
-# define ANNOTATING_IMG_PATH IMG_PATH"/annotating"
-# define ANNOTATING_BILL_IMG_PATH ANNOTATING_IMG_PATH"/bill"
-# define ANNOTATING_FAX_IMG_PATH ANNOTATING_IMG_PATH"/fax"
-# define ANNOTATING_HANDWRITTEN_IMG_PATH ANNOTATING_IMG_PATH"/handwritten"
-# define ANNOTATING_LOGO_IMG_PATH ANNOTATING_IMG_PATH"/logo"
-# define ANNOTATING_MAP_IMG_PATH ANNOTATING_IMG_PATH"/map"
-# define ANNOTATING_SCREENSHOT_IMG_PATH ANNOTATING_IMG_PATH"/screenshot"
-# define ANNOTATING_SLIDE_IMG_PATH ANNOTATING_IMG_PATH"/slide"
-# define ANNOTATING_TYPED_IMG_PATH ANNOTATING_IMG_PATH"/typed"
-# define ANNOTATING_PHOTO_IMG_PATH ANNOTATING_IMG_PATH"/photo"
+# define ICDAR_IMG_PATH IMG_PATH"/icdar"
+# define ICDAR_100P_IMG_PATH ICDAR_IMG_PATH"/100p"
+# define ICDAR_100P_PPM_IMG_PATH ICDAR_100P_IMG_PATH"/ppm"
+# define ICDAR_100P_PGM_IMG_PATH ICDAR_100P_IMG_PATH"/pgm"
+# define ICDAR_100P_PBM_IMG_PATH ICDAR_100P_IMG_PATH"/pbm"
+# define ICDAR_100P_THICK_IMG_PATH ICDAR_100P_IMG_PATH"/gradient_thick"
+# define ICDAR_100P_THIN_IMG_PATH ICDAR_100P_IMG_PATH"/gradient_thin"
+
+# define ICDAR_50P_IMG_PATH ICDAR_IMG_PATH"/50p"
+# define ICDAR_50P_PPM_IMG_PATH ICDAR_50P_IMG_PATH"/ppm"
+# define ICDAR_50P_PGM_IMG_PATH ICDAR_50P_IMG_PATH"/pgm"
+# define ICDAR_50P_PBM_IMG_PATH ICDAR_50P_IMG_PATH"/pbm"
+
+# define ICDAR_20P_IMG_PATH ICDAR_IMG_PATH"/20p"
+# define ICDAR_20P_TEXT_ONLY_IMG_PATH ICDAR_20P_IMG_PATH"/text-only"
+# define ICDAR_20P_TEXT_COLOR_IMG_PATH ICDAR_20P_IMG_PATH"/text-color"
+# define ICDAR_20P_TEXT_PHOTO_IMG_PATH ICDAR_20P_IMG_PATH"/text-photo"
+# define ICDAR_20P_GMP30_IMG_PATH ICDAR_20P_IMG_PATH"/gimp-pal-30"
+# define ICDAR_20P_MGK30_IMG_PATH ICDAR_20P_IMG_PATH"/magick-pal-30"
+# define ICDAR_20P_GMP20_IMG_PATH ICDAR_20P_IMG_PATH"/gimp-pal-20"
+# define ICDAR_20P_MGK20_IMG_PATH ICDAR_20P_IMG_PATH"/magick-pal-20"
+# define ICDAR_20P_GMP10_IMG_PATH ICDAR_20P_IMG_PATH"/gimp-pal-10"
+# define ICDAR_20P_MGK10_IMG_PATH ICDAR_20P_IMG_PATH"/magick-pal-10"
+# define ICDAR_20P_INPUT_IMG_PATH ICDAR_20P_IMG_PATH"/ppm"
+# define ICDAR_20P_CROP_IMG_PATH ICDAR_20P_IMG_PATH"/crop"
+# define ICDAR_20P_PGM_IMG_PATH ICDAR_20P_IMG_PATH"/pgm"
+# define ICDAR_20P_PPM_IMG_PATH ICDAR_20P_IMG_PATH"/ppm"
+# define ICDAR_20P_PBM_IMG_PATH ICDAR_20P_IMG_PATH"/pbm"
+
+# define AFP_IMG_PATH IMG_PATH"/afp"
+# define AFP_GMP30_IMG_PATH AFP_IMG_PATH"/gimp-pal-30"
+# define AFP_GMP20_IMG_PATH AFP_IMG_PATH"/gimp-pal-20"
+# define AFP_GMP10_IMG_PATH AFP_IMG_PATH"/gimp-pal-10"
+# define AFP_MGK30_IMG_PATH AFP_IMG_PATH"/magick-pal-30"
+# define AFP_MGK20_IMG_PATH AFP_IMG_PATH"/magick-pal-20"
+# define AFP_MGK10_IMG_PATH AFP_IMG_PATH"/magick-pal-10"
+# define AFP_INPUT_IMG_PATH AFP_IMG_PATH"/ppm"
+# define AFP_PPM_IMG_PATH AFP_IMG_PATH"/ppm"
+# define AFP_JPG_IMG_PATH AFP_IMG_PATH"/jpg"
+
+# define ANNOTATING_1_IMG_PATH IMG_PATH"/annotating-1"
+# define ANNOTATING_1_BILL_IMG_PATH ANNOTATING_1_IMG_PATH"/bill"
+# define ANNOTATING_1_FAX_IMG_PATH ANNOTATING_1_IMG_PATH"/fax"
+# define ANNOTATING_1_HANDWRITTEN_IMG_PATH ANNOTATING_1_IMG_PATH"/handwritten"
+# define ANNOTATING_1_LOGO_IMG_PATH ANNOTATING_1_IMG_PATH"/logo"
+# define ANNOTATING_1_MAP_IMG_PATH ANNOTATING_1_IMG_PATH"/map"
+# define ANNOTATING_1_SCREENSHOT_IMG_PATH ANNOTATING_1_IMG_PATH"/screenshot"
+# define ANNOTATING_1_SLIDE_IMG_PATH ANNOTATING_1_IMG_PATH"/slide"
+# define ANNOTATING_1_TYPED_IMG_PATH ANNOTATING_1_IMG_PATH"/typed"
+# define ANNOTATING_1_PHOTO_IMG_PATH ANNOTATING_1_IMG_PATH"/photo"
+
+# define ANNOTATING_2_IMG_PATH IMG_PATH"/annotating-2"
+# define ANNOTATING_2_BILL_IMG_PATH ANNOTATING_2_IMG_PATH"/bill"
+# define ANNOTATING_2_FAX_IMG_PATH ANNOTATING_2_IMG_PATH"/fax"
+# define ANNOTATING_2_HANDWRITTEN_IMG_PATH ANNOTATING_2_IMG_PATH"/handwritten"
+# define ANNOTATING_2_LOGO_IMG_PATH ANNOTATING_2_IMG_PATH"/logo"
+# define ANNOTATING_2_MAP_IMG_PATH ANNOTATING_2_IMG_PATH"/map"
+# define ANNOTATING_2_SCREENSHOT_IMG_PATH ANNOTATING_2_IMG_PATH"/screenshot"
+# define ANNOTATING_2_SLIDE_IMG_PATH ANNOTATING_2_IMG_PATH"/slide"
+# define ANNOTATING_2_TYPED_IMG_PATH ANNOTATING_2_IMG_PATH"/typed"
+# define ANNOTATING_2_PHOTO_IMG_PATH ANNOTATING_2_IMG_PATH"/photo"
// result directories
-# define RESULT_ANNOTATING_PATH RESULT_PATH"/annotating"
-# define RESULT_ANNOTATING_BILL_PATH RESULT_ANNOTATING_PATH"/bill"
-# define RESULT_ANNOTATING_FAX_PATH RESULT_ANNOTATING_PATH"/fax"
-# define RESULT_ANNOTATING_HANDWRITTEN_PATH RESULT_ANNOTATING_PATH"/handwritten"
-# define RESULT_ANNOTATING_LOGO_PATH RESULT_ANNOTATING_PATH"/logo"
-# define RESULT_ANNOTATING_MAP_PATH RESULT_ANNOTATING_PATH"/map"
-# define RESULT_ANNOTATING_SCREENSHOT_PATH RESULT_ANNOTATING_PATH"/screenshot"
-# define RESULT_ANNOTATING_SLIDE_PATH RESULT_ANNOTATING_PATH"/slide"
-# define RESULT_ANNOTATING_TYPED_PATH RESULT_ANNOTATING_PATH"/typed"
-# define RESULT_ANNOTATING_PHOTO_PATH RESULT_ANNOTATING_PATH"/photo"
+# define ANNOTATING_RET_PATH RET_PATH"/annotating"
+
+# define ANNOTATING_ICDAR_RET_PATH ANNOTATING_RET_PATH"/icdar"
+
+# define ANNOTATING_ICDAR_INPUT_RET_PATH ANNOTATING_ICDAR_RET_PATH"/input"
+# define ANNOTATING_ICDAR_H_INPUT_RET_PATH ANNOTATING_ICDAR_INPUT_RET_PATH"/h"
+# define ANNOTATING_ICDAR_S_INPUT_RET_PATH ANNOTATING_ICDAR_INPUT_RET_PATH"/s"
+# define ANNOTATING_ICDAR_V_INPUT_RET_PATH ANNOTATING_ICDAR_INPUT_RET_PATH"/v"
+# define ANNOTATING_ICDAR_R_INPUT_RET_PATH ANNOTATING_ICDAR_INPUT_RET_PATH"/r"
+# define ANNOTATING_ICDAR_G_INPUT_RET_PATH ANNOTATING_ICDAR_INPUT_RET_PATH"/g"
+# define ANNOTATING_ICDAR_B_INPUT_RET_PATH ANNOTATING_ICDAR_INPUT_RET_PATH"/b"
+
+# define ANNOTATING_ICDAR_GMP30_RET_PATH ANNOTATING_ICDAR_RET_PATH"/gimp-pal-30"
+# define ANNOTATING_ICDAR_H_GMP30_RET_PATH ANNOTATING_ICDAR_GMP30_RET_PATH"/h"
+# define ANNOTATING_ICDAR_S_GMP30_RET_PATH ANNOTATING_ICDAR_GMP30_RET_PATH"/s"
+# define ANNOTATING_ICDAR_V_GMP30_RET_PATH ANNOTATING_ICDAR_GMP30_RET_PATH"/v"
+# define ANNOTATING_ICDAR_R_GMP30_RET_PATH ANNOTATING_ICDAR_GMP30_RET_PATH"/r"
+# define ANNOTATING_ICDAR_G_GMP30_RET_PATH ANNOTATING_ICDAR_GMP30_RET_PATH"/g"
+# define ANNOTATING_ICDAR_B_GMP30_RET_PATH ANNOTATING_ICDAR_GMP30_RET_PATH"/b"
+
+# define ANNOTATING_ICDAR_GMP20_RET_PATH ANNOTATING_ICDAR_RET_PATH"/gimp-pal-20"
+# define ANNOTATING_ICDAR_H_GMP20_RET_PATH ANNOTATING_ICDAR_GMP20_RET_PATH"/h"
+# define ANNOTATING_ICDAR_S_GMP20_RET_PATH ANNOTATING_ICDAR_GMP20_RET_PATH"/s"
+# define ANNOTATING_ICDAR_V_GMP20_RET_PATH ANNOTATING_ICDAR_GMP20_RET_PATH"/v"
+# define ANNOTATING_ICDAR_R_GMP20_RET_PATH ANNOTATING_ICDAR_GMP20_RET_PATH"/r"
+# define ANNOTATING_ICDAR_G_GMP20_RET_PATH ANNOTATING_ICDAR_GMP20_RET_PATH"/g"
+# define ANNOTATING_ICDAR_B_GMP20_RET_PATH ANNOTATING_ICDAR_GMP20_RET_PATH"/b"
+
+# define ANNOTATING_ICDAR_GMP10_RET_PATH ANNOTATING_ICDAR_RET_PATH"/gimp-pal-10"
+# define ANNOTATING_ICDAR_H_GMP10_RET_PATH ANNOTATING_ICDAR_GMP10_RET_PATH"/h"
+# define ANNOTATING_ICDAR_S_GMP10_RET_PATH ANNOTATING_ICDAR_GMP10_RET_PATH"/s"
+# define ANNOTATING_ICDAR_V_GMP10_RET_PATH ANNOTATING_ICDAR_GMP10_RET_PATH"/v"
+# define ANNOTATING_ICDAR_R_GMP10_RET_PATH ANNOTATING_ICDAR_GMP10_RET_PATH"/r"
+# define ANNOTATING_ICDAR_G_GMP10_RET_PATH ANNOTATING_ICDAR_GMP10_RET_PATH"/g"
+# define ANNOTATING_ICDAR_B_GMP10_RET_PATH ANNOTATING_ICDAR_GMP10_RET_PATH"/b"
+
+# define ANNOTATING_ICDAR_MGK30_RET_PATH ANNOTATING_ICDAR_RET_PATH"/magick-pal-30"
+# define ANNOTATING_ICDAR_H_MGK30_RET_PATH ANNOTATING_ICDAR_MGK30_RET_PATH"/h"
+# define ANNOTATING_ICDAR_S_MGK30_RET_PATH ANNOTATING_ICDAR_MGK30_RET_PATH"/s"
+# define ANNOTATING_ICDAR_V_MGK30_RET_PATH ANNOTATING_ICDAR_MGK30_RET_PATH"/v"
+# define ANNOTATING_ICDAR_R_MGK30_RET_PATH ANNOTATING_ICDAR_MGK30_RET_PATH"/r"
+# define ANNOTATING_ICDAR_G_MGK30_RET_PATH ANNOTATING_ICDAR_MGK30_RET_PATH"/g"
+# define ANNOTATING_ICDAR_B_MGK30_RET_PATH ANNOTATING_ICDAR_MGK30_RET_PATH"/b"
+
+# define ANNOTATING_ICDAR_MGK20_RET_PATH ANNOTATING_ICDAR_RET_PATH"/magick-pal-20"
+# define ANNOTATING_ICDAR_H_MGK20_RET_PATH ANNOTATING_ICDAR_MGK20_RET_PATH"/h"
+# define ANNOTATING_ICDAR_S_MGK20_RET_PATH ANNOTATING_ICDAR_MGK20_RET_PATH"/s"
+# define ANNOTATING_ICDAR_V_MGK20_RET_PATH ANNOTATING_ICDAR_MGK20_RET_PATH"/v"
+# define ANNOTATING_ICDAR_R_MGK20_RET_PATH ANNOTATING_ICDAR_MGK20_RET_PATH"/r"
+# define ANNOTATING_ICDAR_G_MGK20_RET_PATH ANNOTATING_ICDAR_MGK20_RET_PATH"/g"
+# define ANNOTATING_ICDAR_B_MGK20_RET_PATH ANNOTATING_ICDAR_MGK20_RET_PATH"/b"
+
+# define ANNOTATING_ICDAR_MGK10_RET_PATH ANNOTATING_ICDAR_RET_PATH"/magick-pal-10"
+# define ANNOTATING_ICDAR_H_MGK10_RET_PATH ANNOTATING_ICDAR_MGK10_RET_PATH"/h"
+# define ANNOTATING_ICDAR_S_MGK10_RET_PATH ANNOTATING_ICDAR_MGK10_RET_PATH"/s"
+# define ANNOTATING_ICDAR_V_MGK10_RET_PATH ANNOTATING_ICDAR_MGK10_RET_PATH"/v"
+# define ANNOTATING_ICDAR_R_MGK10_RET_PATH ANNOTATING_ICDAR_MGK10_RET_PATH"/r"
+# define ANNOTATING_ICDAR_G_MGK10_RET_PATH ANNOTATING_ICDAR_MGK10_RET_PATH"/g"
+# define ANNOTATING_ICDAR_B_MGK10_RET_PATH ANNOTATING_ICDAR_MGK10_RET_PATH"/b"
+
+
+
+
+# define ANNOTATING_AFP_RET_PATH ANNOTATING_RET_PATH"/afp"
+
+# define ANNOTATING_AFP_INPUT_RET_PATH ANNOTATING_AFP_RET_PATH"/input"
+# define ANNOTATING_AFP_H_INPUT_RET_PATH ANNOTATING_AFP_INPUT_RET_PATH"/h"
+# define ANNOTATING_AFP_S_INPUT_RET_PATH ANNOTATING_AFP_INPUT_RET_PATH"/s"
+# define ANNOTATING_AFP_V_INPUT_RET_PATH ANNOTATING_AFP_INPUT_RET_PATH"/v"
+# define ANNOTATING_AFP_R_INPUT_RET_PATH ANNOTATING_AFP_INPUT_RET_PATH"/r"
+# define ANNOTATING_AFP_G_INPUT_RET_PATH ANNOTATING_AFP_INPUT_RET_PATH"/g"
+# define ANNOTATING_AFP_B_INPUT_RET_PATH ANNOTATING_AFP_INPUT_RET_PATH"/b"
+
+# define ANNOTATING_AFP_GMP30_RET_PATH ANNOTATING_AFP_RET_PATH"/gimp-pal-30"
+# define ANNOTATING_AFP_H_GMP30_RET_PATH ANNOTATING_AFP_GMP30_RET_PATH"/h"
+# define ANNOTATING_AFP_S_GMP30_RET_PATH ANNOTATING_AFP_GMP30_RET_PATH"/s"
+# define ANNOTATING_AFP_V_GMP30_RET_PATH ANNOTATING_AFP_GMP30_RET_PATH"/v"
+# define ANNOTATING_AFP_R_GMP30_RET_PATH ANNOTATING_AFP_GMP30_RET_PATH"/r"
+# define ANNOTATING_AFP_G_GMP30_RET_PATH ANNOTATING_AFP_GMP30_RET_PATH"/g"
+# define ANNOTATING_AFP_B_GMP30_RET_PATH ANNOTATING_AFP_GMP30_RET_PATH"/b"
+
+# define ANNOTATING_AFP_GMP20_RET_PATH ANNOTATING_AFP_RET_PATH"/gimp-pal-20"
+# define ANNOTATING_AFP_H_GMP20_RET_PATH ANNOTATING_AFP_GMP20_RET_PATH"/h"
+# define ANNOTATING_AFP_S_GMP20_RET_PATH ANNOTATING_AFP_GMP20_RET_PATH"/s"
+# define ANNOTATING_AFP_V_GMP20_RET_PATH ANNOTATING_AFP_GMP20_RET_PATH"/v"
+# define ANNOTATING_AFP_R_GMP20_RET_PATH ANNOTATING_AFP_GMP20_RET_PATH"/r"
+# define ANNOTATING_AFP_G_GMP20_RET_PATH ANNOTATING_AFP_GMP20_RET_PATH"/g"
+# define ANNOTATING_AFP_B_GMP20_RET_PATH ANNOTATING_AFP_GMP20_RET_PATH"/b"
+
+# define ANNOTATING_AFP_GMP10_RET_PATH ANNOTATING_AFP_RET_PATH"/gimp-pal-10"
+# define ANNOTATING_AFP_H_GMP10_RET_PATH ANNOTATING_AFP_GMP10_RET_PATH"/h"
+# define ANNOTATING_AFP_S_GMP10_RET_PATH ANNOTATING_AFP_GMP10_RET_PATH"/s"
+# define ANNOTATING_AFP_V_GMP10_RET_PATH ANNOTATING_AFP_GMP10_RET_PATH"/v"
+# define ANNOTATING_AFP_R_GMP10_RET_PATH ANNOTATING_AFP_GMP10_RET_PATH"/r"
+# define ANNOTATING_AFP_G_GMP10_RET_PATH ANNOTATING_AFP_GMP10_RET_PATH"/g"
+# define ANNOTATING_AFP_B_GMP10_RET_PATH ANNOTATING_AFP_GMP10_RET_PATH"/b"
+
+# define ANNOTATING_AFP_MGK30_RET_PATH ANNOTATING_AFP_RET_PATH"/magick-pal-30"
+# define ANNOTATING_AFP_H_MGK30_RET_PATH ANNOTATING_AFP_MGK30_RET_PATH"/h"
+# define ANNOTATING_AFP_S_MGK30_RET_PATH ANNOTATING_AFP_MGK30_RET_PATH"/s"
+# define ANNOTATING_AFP_V_MGK30_RET_PATH ANNOTATING_AFP_MGK30_RET_PATH"/v"
+# define ANNOTATING_AFP_R_MGK30_RET_PATH ANNOTATING_AFP_MGK30_RET_PATH"/r"
+# define ANNOTATING_AFP_G_MGK30_RET_PATH ANNOTATING_AFP_MGK30_RET_PATH"/g"
+# define ANNOTATING_AFP_B_MGK30_RET_PATH ANNOTATING_AFP_MGK30_RET_PATH"/b"
+
+# define ANNOTATING_AFP_MGK20_RET_PATH ANNOTATING_AFP_RET_PATH"/magick-pal-20"
+# define ANNOTATING_AFP_H_MGK20_RET_PATH ANNOTATING_AFP_MGK20_RET_PATH"/h"
+# define ANNOTATING_AFP_S_MGK20_RET_PATH ANNOTATING_AFP_MGK20_RET_PATH"/s"
+# define ANNOTATING_AFP_V_MGK20_RET_PATH ANNOTATING_AFP_MGK20_RET_PATH"/v"
+# define ANNOTATING_AFP_R_MGK20_RET_PATH ANNOTATING_AFP_MGK20_RET_PATH"/r"
+# define ANNOTATING_AFP_G_MGK20_RET_PATH ANNOTATING_AFP_MGK20_RET_PATH"/g"
+# define ANNOTATING_AFP_B_MGK20_RET_PATH ANNOTATING_AFP_MGK20_RET_PATH"/b"
+
+# define ANNOTATING_AFP_MGK10_RET_PATH ANNOTATING_AFP_RET_PATH"/magick-pal-10"
+# define ANNOTATING_AFP_H_MGK10_RET_PATH ANNOTATING_AFP_MGK10_RET_PATH"/h"
+# define ANNOTATING_AFP_S_MGK10_RET_PATH ANNOTATING_AFP_MGK10_RET_PATH"/s"
+# define ANNOTATING_AFP_V_MGK10_RET_PATH ANNOTATING_AFP_MGK10_RET_PATH"/v"
+# define ANNOTATING_AFP_R_MGK10_RET_PATH ANNOTATING_AFP_MGK10_RET_PATH"/r"
+# define ANNOTATING_AFP_G_MGK10_RET_PATH ANNOTATING_AFP_MGK10_RET_PATH"/g"
+# define ANNOTATING_AFP_B_MGK10_RET_PATH ANNOTATING_AFP_MGK10_RET_PATH"/b"
+
+
+# define ANNOTATING_BILL_RET_PATH ANNOTATING_RET_PATH"/bill"
+# define ANNOTATING_FAX_RET_PATH ANNOTATING_RET_PATH"/fax"
+# define ANNOTATING_HANDWRITTEN_RET_PATH ANNOTATING_RET_PATH"/handwritten"
+# define ANNOTATING_LOGO_RET_PATH ANNOTATING_RET_PATH"/logo"
+# define ANNOTATING_MAP_RET_PATH ANNOTATING_RET_PATH"/map"
+# define ANNOTATING_SCREENSHOT_RET_PATH ANNOTATING_RET_PATH"/screenshot"
+# define ANNOTATING_SLIDE_RET_PATH ANNOTATING_RET_PATH"/slide"
+# define ANNOTATING_TYPED_RET_PATH ANNOTATING_RET_PATH"/typed"
+# define ANNOTATING_PHOTO_RET_PATH ANNOTATING_RET_PATH"/photo"
+
+# define ANNOTATING_ICDAR_ACHROMATISM_RET_PATH ANNOTATING_ICDAR_RET_PATH"/achromatism"
+
#endif // ! MLN_IMG_PATH_HH
diff --git a/milena/sandbox/green/mln/math/ceil.hh b/milena/sandbox/green/mln/math/ceil.hh
new file mode 100644
index 0000000..6fc08c8
--- /dev/null
+++ b/milena/sandbox/green/mln/math/ceil.hh
@@ -0,0 +1,64 @@
+// Copyright (C) 2007, 2008, 2009, 2010
+// EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef MLN_MATH_CEIL_HH
+# define MLN_MATH_CEIL_HH
+
+/*! \file
+ *
+ * \brief Define the ceil (ceil) routine.
+ */
+
+# include <cmath>
+
+
+namespace mln
+{
+
+ namespace math
+ {
+
+ template <typename T>
+ T ceil(const T& v);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename T>
+ inline
+ T ceil(const T& v)
+ {
+ return std::ceil(v);
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::math
+
+} // end of namespace mln
+
+
+#endif // ! MLN_MATH_FLOOR_HH
diff --git a/milena/sandbox/green/mln/math/floor.hh b/milena/sandbox/green/mln/math/floor.hh
new file mode 100644
index 0000000..97e63bd
--- /dev/null
+++ b/milena/sandbox/green/mln/math/floor.hh
@@ -0,0 +1,64 @@
+// Copyright (C) 2007, 2008, 2009, 2010
+// EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef MLN_MATH_FLOOR_HH
+# define MLN_MATH_FLOOR_HH
+
+/*! \file
+ *
+ * \brief Define the floor (floor) routine.
+ */
+
+# include <cmath>
+
+
+namespace mln
+{
+
+ namespace math
+ {
+
+ template <typename T>
+ T floor(const T& v);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename T>
+ inline
+ T floor(const T& v)
+ {
+ return std::floor(v);
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::math
+
+} // end of namespace mln
+
+
+#endif // ! MLN_MATH_FLOOR_HH
diff --git a/milena/sandbox/green/mln/value/hsv.hh b/milena/sandbox/green/mln/value/hsv.hh
new file mode 100644
index 0000000..69948d9
--- /dev/null
+++ b/milena/sandbox/green/mln/value/hsv.hh
@@ -0,0 +1,424 @@
+// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef MLN_VALUE_HSV_HH
+# define MLN_VALUE_HSV_HH
+
+#include <mln/value/ops.hh>
+
+#include <mln/value/concept/vectorial.hh>
+#include <mln/value/int_u.hh>
+// #include <mln/algebra/vec.hh>
+
+// Used in from_to
+// #include <mln/fun/v2v/rgb_to_hsv.hh>
+
+
+namespace mln
+{
+
+ // Forward declarations.
+ namespace value
+ {
+
+ template <typename H, typename S, typename V>
+ class hsv_;
+
+ }
+
+
+/*
+ namespace convert
+ {
+
+ namespace over_load
+ {
+
+ // rgb to hsv_
+ void
+ from_to_(const value::rgb<16>& from, value::hsv_<float,float,float>& to);
+
+ // rgb to hsv_
+ void
+ from_to_(const value::rgb<8>& from, value::hsv_<float,float,float>& to);
+
+ } // end of namespace mln::convert::over_load
+
+ } // end of namespace mln::convert
+*/
+
+
+ namespace trait
+ {
+
+ template <typename H, typename S, typename V>
+ struct set_precise_binary_< op::plus, mln::value::hsv_<H,S,V>,
+ mln::value::hsv_<H,S,V> >
+ {
+ typedef mln::value::hsv_<H,S,V> ret;
+ };
+
+ template <typename H, typename S, typename V>
+ struct set_precise_binary_< op::minus, mln::value::hsv_<H,S,V>,
+ mln::value::hsv_<H,S,V> >
+ {
+ typedef mln::value::hsv_<H,S,V> ret;
+ };
+
+ template <typename H, typename S, typename V, typename S2>
+ struct set_precise_binary_< op::times, mln::value::hsv_<H,S,V>,
+ mln::value::scalar_<S2> >
+ {
+ typedef mln::value::hsv_<H,S,V> ret;
+ };
+
+ template <typename H, typename S, typename V, typename S2>
+ struct set_precise_binary_< op::div, mln::value::hsv_<H,S,V>,
+ mln::value::scalar_<S2> >
+ {
+ typedef mln::value::hsv_<H,S,V> ret;
+ };
+
+
+ // FIXME : Is there any way more generic? a way to factor
+ // set_precise_binary_< op::div, mln::value::hsv_<H,S,V>, mln::value::scalar_<S> >
+ // and
+ // set_precise_binary_< op::div, mln::value::hsv_<H,S,V>, mln::value::int_u<m> >
+ // as for op::times.
+
+ template <typename H, typename S, typename V, unsigned m>
+ struct set_precise_binary_< op::times, mln::value::hsv_<H,S,V>,
+ mln::value::int_u<m> >
+ {
+ typedef mln::value::hsv_<H,S,V> ret;
+ };
+
+ template <typename H, typename S, typename V, unsigned m>
+ struct set_precise_binary_< op::div, mln::value::hsv_<H,S,V>,
+ mln::value::int_u<m> >
+ {
+ typedef mln::value::hsv_<H,S,V> ret;
+ };
+
+ template <typename H, typename S, typename V>
+ struct value_< mln::value::hsv_<H,S,V> >
+ {
+ enum {
+ dim = 3,
+ nbits = (sizeof (H) + sizeof (S) + sizeof (V)) * 8,
+ card = mln_value_card_from_(nbits)
+ };
+
+ typedef trait::value::nature::vectorial nature;
+ typedef trait::value::kind::color kind;
+ typedef mln_value_quant_from_(card) quant;
+
+ typedef void comp;
+ typedef H comp_0;
+ typedef S comp_1;
+ typedef V comp_2;
+
+ template <typename VAL>
+ static comp_0 get_comp_0(const VAL& v) { return v.hue(); }
+
+ template <typename VAL>
+ static comp_1 get_comp_1(const VAL& v) { return v.sat(); }
+
+ template <typename VAL>
+ static comp_2 get_comp_2(const VAL& v) { return v.val(); }
+
+ typedef mln::value::hsv_<H,S,V> sum;
+ };
+
+ } // end of namespace trait
+
+
+ namespace value
+ {
+
+ template <typename E>
+ struct HSV : Object<E>
+ {
+ };
+
+ template <typename H, typename S, typename V>
+ class hsv_ : public HSV< hsv_<H,S,V> >
+ {
+ public:
+
+ typedef H h_type;
+ typedef S s_type;
+ typedef V v_type;
+
+ /// Constructor without argument.
+ hsv_()
+ {
+ }
+
+ hsv_(const literal::zero_t&)
+ : hue_(0),
+ sat_(0),
+ val_(0)
+ {
+ }
+
+ /// Constructor from component values.
+ hsv_(const H& hue, const S& sat, const V& val)
+ : hue_(hue),
+ sat_(sat),
+ val_(val)
+ {
+ }
+
+ /// Read-only access to the hue component.
+ const H& hue() const;
+ const S& sat() const;
+ const V& val() const;
+
+ /// Read-write access to the hue component.
+ H& hue();
+ S& sat();
+ V& val();
+
+ private:
+ //FIXME: Don't we want to store these values in a vector?
+ H hue_;
+ S sat_;
+ V val_;
+ };
+
+
+ typedef hsv_<float, float, float> hsv_f;
+ typedef hsv_<double, double, double> hsv_d;
+
+
+ /// Print an hsv \p c into the output stream \p ostr.
+ ///
+ /// \param[in,out] ostr An output stream.
+ /// \param[in] c An rgb.
+ ///
+ /// \return The modified output stream \p ostr.
+ template <typename H, typename S, typename V>
+ std::ostream& operator<<(std::ostream& ostr, const hsv_<H,S,V>& c);
+
+
+ /// Addition.
+ /// {
+ template <typename H, typename S, typename V>
+ hsv_<H,S,V>
+ operator+(const hsv_<H,S,V>& lhs, const hsv_<H,S,V>& rhs);
+ /// \}
+
+ /// Subtraction.
+ /// \{
+ template <typename H, typename S, typename V>
+ hsv_<H,S,V>
+ operator-(const hsv_<H,S,V>& lhs, const hsv_<H,S,V>& rhs);
+ /// \}
+
+ /// Product.
+ /// \{
+ template <typename H, typename S, typename V, typename S2>
+ hsv_<H,S,V>
+ operator*(const hsv_<H,S,V>& lhs, const mln::value::scalar_<S2>& s);
+ /// \}
+
+ /// Division.
+ /// \{
+ template <typename H, typename S, typename V, typename S2>
+ hsv_<H,S,V>
+ operator/(const hsv_<H,S,V>& lhs, const mln::value::scalar_<S2>& s);
+ /// \}
+
+ /// Comparison.
+ /// \{
+ template <typename H, typename S, typename V>
+ bool
+ operator==(const hsv_<H,S,V>& lhs, const hsv_<H,S,V>& rhs);
+ /// \}
+
+ } // end of namespace mln::value
+
+
+
+ // More forward declarations
+ namespace fun
+ {
+ namespace v2v
+ {
+
+ template <typename T_hsv>
+ struct f_rgb_to_hsv_;
+
+ typedef f_rgb_to_hsv_<value::hsv_f> f_rgb_to_hsv_f_t;
+
+ extern f_rgb_to_hsv_f_t f_rgb_to_hsv_f;
+
+ }
+
+ }
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ namespace value
+ {
+
+ template <typename H, typename S, typename V>
+ const H&
+ hsv_<H,S,V>::hue() const
+ {
+ return this->hue_;
+ }
+
+ template <typename H, typename S, typename V>
+ const S&
+ hsv_<H,S,V>::sat() const
+ {
+ return this->sat_;
+ }
+
+ template <typename H, typename S, typename V>
+ const V&
+ hsv_<H,S,V>::val() const
+ {
+ return this->val_;
+ }
+
+ template <typename H, typename S, typename V>
+ H&
+ hsv_<H,S,V>::hue()
+ {
+ return this->hue_;
+ }
+
+ template <typename H, typename S, typename V>
+ S&
+ hsv_<H,S,V>::sat()
+ {
+ return this->sat_;
+ }
+
+ template <typename H, typename S, typename V>
+ V&
+ hsv_<H,S,V>::val()
+ {
+ return this->val_;
+ }
+
+
+ template <typename H, typename S, typename V>
+ inline
+ std::ostream& operator<<(std::ostream& ostr, const hsv_<H,S,V>& v)
+ {
+ return ostr << '(' << debug::format(v.hue())
+ << ',' << debug::format(v.sat())
+ << ',' << debug::format(v.val())
+ << ')';
+ }
+
+
+ template <typename H, typename S, typename V>
+ hsv_<H,S,V>
+ operator+(const hsv_<H,S,V>& lhs, const hsv_<H,S,V>& rhs)
+ {
+ return hsv_<H,S,V>(lhs.hue() + rhs.hue(),
+ lhs.sat() + rhs.sat(),
+ lhs.val() + rhs.val());
+ }
+
+
+ template <typename H, typename S, typename V>
+ hsv_<H,S,V>
+ operator-(const hsv_<H,S,V>& lhs, const hsv_<H,S,V>& rhs)
+ {
+ return hsv_<H,S,V>(lhs.hue() - rhs.hue(),
+ lhs.sat() - rhs.sat(),
+ lhs.val() - rhs.val());
+ }
+
+
+ template <typename H, typename S, typename V, typename S2>
+ hsv_<H,S,V>
+ operator*(const hsv_<H,S,V>& lhs, const mln::value::scalar_<S2>& s)
+ {
+ return hsv_<H,S,V>(lhs.hue() * s,
+ lhs.sat() * s,
+ lhs.val() * s);
+ }
+
+
+ template <typename H, typename S, typename V, typename S2>
+ hsv_<H,S,V>
+ operator/(const hsv_<H,S,V>& lhs, const mln::value::scalar_<S2>& s)
+ {
+ return hsv_<H,S,V>(lhs.hue() / s,
+ lhs.sat() / s,
+ lhs.val() / s);
+ }
+
+ template <typename H, typename S, typename V>
+ bool
+ operator==(const hsv_<H,S,V>& lhs, const hsv_<H,S,V>& rhs)
+ {
+ return lhs.hue() == rhs.hue()
+ && lhs.sat() == rhs.sat()
+ && lhs.val() == rhs.val();
+ }
+
+ } // end of namespace mln::value
+
+/*
+ namespace convert
+ {
+
+ namespace over_load
+ {
+
+ inline
+ void
+ from_to_(const value::rgb<16>& from, value::hsv_<float,float,float>& to)
+ {
+ to = fun::v2v::f_rgb_to_hsv_f(from);
+ }
+
+ inline
+ void
+ from_to_(const value::rgb<8>& from, value::hsv_<float,float,float>& to)
+ {
+ to = fun::v2v::f_rgb_to_hsv_f(from);
+ }
+
+ } // end of namespace mln::convert::over_load
+
+ } // end of namespace mln::convert
+*/
+
+# endif // ! MLN_INCLUDE_ONLY
+
+
+} // end of namespace mln
+
+#endif // ! MLN_VALUE_HSV_HH
--
1.5.6.5
1
0
15 Nov '10
* mln/convert/from_to.hxx: New conversion utilities.
* mln/convert/impl/from_unsigned_to_value.hh: New conversion utilities.
---
milena/ChangeLog | 7 +++++++
milena/mln/convert/from_to.hxx | 4 ++++
milena/mln/convert/impl/from_unsigned_to_value.hh | 10 ++++++++++
3 files changed, 21 insertions(+), 0 deletions(-)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 10c5def..3804c90 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,3 +1,10 @@
+2010-06-21 Yann Jacquelet <jacquelet(a)lrde.epita.fr>
+
+ Fix the way to convert unsigned to float.
+
+ * mln/convert/from_to.hxx: New conversion utilities.
+ * mln/convert/impl/from_unsigned_to_value.hh: New conversion utilities.
+
2009-12-02 Yann Jacquelet <jacquelet(a)lrde.epita.fr>
Fix the outside template use case for the convolve macros.
diff --git a/milena/mln/convert/from_to.hxx b/milena/mln/convert/from_to.hxx
index ebc30cd..8334b14 100644
--- a/milena/mln/convert/from_to.hxx
+++ b/milena/mln/convert/from_to.hxx
@@ -261,6 +261,10 @@ namespace mln
void
from_to_(const Value<F>& from, Value<T>& to);
+ // unsigned -> float
+ void
+ from_to_(const unsigned& from, float& to);
+
// double-> Value
template <typename V>
void
diff --git a/milena/mln/convert/impl/from_unsigned_to_value.hh b/milena/mln/convert/impl/from_unsigned_to_value.hh
index ad54cff..fe09a3e 100644
--- a/milena/mln/convert/impl/from_unsigned_to_value.hh
+++ b/milena/mln/convert/impl/from_unsigned_to_value.hh
@@ -118,6 +118,16 @@ namespace mln
internal::from_unsigned_to_value_dispatch(from, to);
}
+
+ // Facades.
+ // unsigned-> float
+ void
+ from_to_(const unsigned& from, float& to)
+ {
+ to = from;
+ }
+
+
} // end of namespace mln::convert::over_load
--
1.5.6.5
1
0