LRE
Sign In
Sign Up
Sign In
Sign Up
Manage this list
×
Keyboard Shortcuts
Thread View
j
: Next unread message
k
: Previous unread message
j a
: Jump to all threads
j l
: Jump to MailingList overview
2025
January
2024
December
November
October
September
August
July
June
May
April
March
February
January
2023
December
November
October
September
August
July
June
May
April
March
February
January
2022
December
November
October
September
August
July
June
May
April
March
February
January
2021
December
November
October
September
August
July
June
May
April
March
February
January
2020
December
November
October
September
August
July
June
May
April
March
February
January
2019
December
November
October
September
August
July
June
May
April
March
February
January
2018
December
November
October
September
August
July
June
May
April
March
February
January
2017
December
November
October
September
August
July
June
May
April
March
February
January
2016
December
November
October
September
August
July
June
May
April
March
February
January
2015
December
November
October
September
August
July
June
May
April
March
February
January
2014
December
November
October
September
August
July
June
May
April
March
February
January
2013
December
November
October
September
August
July
June
May
April
March
February
January
2012
December
November
October
September
August
July
June
May
April
March
February
January
2011
December
November
October
September
August
July
June
May
April
March
February
January
2010
December
November
October
September
August
July
June
May
April
March
February
January
2009
December
November
October
September
August
July
June
May
April
March
February
January
2008
December
November
October
September
August
July
June
May
April
March
February
January
2007
December
November
October
September
August
July
June
May
April
March
February
January
2006
December
November
October
September
August
July
June
May
April
March
February
January
2005
December
November
October
September
August
July
June
May
April
March
February
January
2004
December
November
October
September
August
July
June
May
April
March
List overview
Download
Olena-patches
----- 2025 -----
January 2025
----- 2024 -----
December 2024
November 2024
October 2024
September 2024
August 2024
July 2024
June 2024
May 2024
April 2024
March 2024
February 2024
January 2024
----- 2023 -----
December 2023
November 2023
October 2023
September 2023
August 2023
July 2023
June 2023
May 2023
April 2023
March 2023
February 2023
January 2023
----- 2022 -----
December 2022
November 2022
October 2022
September 2022
August 2022
July 2022
June 2022
May 2022
April 2022
March 2022
February 2022
January 2022
----- 2021 -----
December 2021
November 2021
October 2021
September 2021
August 2021
July 2021
June 2021
May 2021
April 2021
March 2021
February 2021
January 2021
----- 2020 -----
December 2020
November 2020
October 2020
September 2020
August 2020
July 2020
June 2020
May 2020
April 2020
March 2020
February 2020
January 2020
----- 2019 -----
December 2019
November 2019
October 2019
September 2019
August 2019
July 2019
June 2019
May 2019
April 2019
March 2019
February 2019
January 2019
----- 2018 -----
December 2018
November 2018
October 2018
September 2018
August 2018
July 2018
June 2018
May 2018
April 2018
March 2018
February 2018
January 2018
----- 2017 -----
December 2017
November 2017
October 2017
September 2017
August 2017
July 2017
June 2017
May 2017
April 2017
March 2017
February 2017
January 2017
----- 2016 -----
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
June 2016
May 2016
April 2016
March 2016
February 2016
January 2016
----- 2015 -----
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
----- 2014 -----
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
----- 2013 -----
December 2013
November 2013
October 2013
September 2013
August 2013
July 2013
June 2013
May 2013
April 2013
March 2013
February 2013
January 2013
----- 2012 -----
December 2012
November 2012
October 2012
September 2012
August 2012
July 2012
June 2012
May 2012
April 2012
March 2012
February 2012
January 2012
----- 2011 -----
December 2011
November 2011
October 2011
September 2011
August 2011
July 2011
June 2011
May 2011
April 2011
March 2011
February 2011
January 2011
----- 2010 -----
December 2010
November 2010
October 2010
September 2010
August 2010
July 2010
June 2010
May 2010
April 2010
March 2010
February 2010
January 2010
----- 2009 -----
December 2009
November 2009
October 2009
September 2009
August 2009
July 2009
June 2009
May 2009
April 2009
March 2009
February 2009
January 2009
----- 2008 -----
December 2008
November 2008
October 2008
September 2008
August 2008
July 2008
June 2008
May 2008
April 2008
March 2008
February 2008
January 2008
----- 2007 -----
December 2007
November 2007
October 2007
September 2007
August 2007
July 2007
June 2007
May 2007
April 2007
March 2007
February 2007
January 2007
----- 2006 -----
December 2006
November 2006
October 2006
September 2006
August 2006
July 2006
June 2006
May 2006
April 2006
March 2006
February 2006
January 2006
----- 2005 -----
December 2005
November 2005
October 2005
September 2005
August 2005
July 2005
June 2005
May 2005
April 2005
March 2005
February 2005
January 2005
----- 2004 -----
December 2004
November 2004
October 2004
September 2004
August 2004
July 2004
June 2004
May 2004
April 2004
March 2004
olena-patches@lrde.epita.fr
9625 discussions
Start a n
N
ew thread
last-svn-commit-40-g2cfa144 Fix the way to convert unsigned to float.
by Yann Jacquelet
* 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
14Â years, 2Â months
1
0
0
0
last-svn-commit-37-gd4f2e49 Work on Millet saturation descriptor.
by Yann Jacquelet
* 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 eb301e5..2c3ec85 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
14Â years, 2Â months
1
0
0
0
last-svn-commit-34-g1d23bfa Work on histograms view as density.
by Yann Jacquelet
* 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
14Â years, 2Â months
1
0
0
0
last-svn-commit-35-g485f8de Work on Millet hsv descriptors.
by Yann Jacquelet
* 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 cc4634d..15be8a1 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
14Â years, 2Â months
1
0
0
0
last-svn-commit-36-ge9328a0 Work on Millet saturation descriptor.
by Yann Jacquelet
* 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 15be8a1..eb301e5 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
14Â years, 2Â months
1
0
0
0
last-svn-commit-32-g174b917 Benchmark few descriptors.
by Yann Jacquelet
* 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 d86642a..cc4634d 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
14Â years, 2Â months
1
0
0
0
last-svn-commit-33-g2c26e60 Test error quantification as a color descriptor in our database.
by Yann Jacquelet
* 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
14Â years, 2Â months
1
0
0
0
last-svn-commit-31-gba99cc2 Test on image database the achromatism descriptor.
by Yann Jacquelet
* 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. * green/exp/annotating/achromatism/text-img.txt: New image class. * green/exp/annotating/achromatism/text-only.txt: New image class. --- milena/sandbox/ChangeLog | 18 +++ .../{nb_color => achromastism}/Makefile.am | 4 +- .../exp/annotating/achromastism/achromastism.cc | 113 ++++++++++++++++++++ .../exp/annotating/achromastism/text-color.txt | 15 +++ .../green/exp/annotating/achromastism/text-img.txt | 40 +++++++ .../exp/annotating/achromastism/text-only.txt | 8 ++ 6 files changed, 197 insertions(+), 1 deletions(-) copy milena/sandbox/green/exp/annotating/{nb_color => achromastism}/Makefile.am (96%) create mode 100644 milena/sandbox/green/exp/annotating/achromastism/achromastism.cc create mode 100644 milena/sandbox/green/exp/annotating/achromastism/text-color.txt create mode 100644 milena/sandbox/green/exp/annotating/achromastism/text-img.txt create mode 100644 milena/sandbox/green/exp/annotating/achromastism/text-only.txt diff --git a/milena/sandbox/ChangeLog b/milena/sandbox/ChangeLog index 27c37db..d86642a 100644 --- a/milena/sandbox/ChangeLog +++ b/milena/sandbox/ChangeLog @@ -1,3 +1,21 @@ +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. + * green/exp/annotating/achromatism/achromatism.am: New source. + * green/exp/annotating/achromatism/text-color.txt: New image class. + * green/exp/annotating/achromatism/text-img.txt: New image class. + * green/exp/annotating/achromatism/text-only.txt: New image class. + +2010-06-21 Yann Jacquelet <jacquelet(a)lrde.epita.fr> + + Turn around Millet 2008 hsv descriptors. + + * green/demo/annotating/hsv: New directory. + * green/demo/annotating/hsv/Makefile.am: New Makefile. + + 2010-02-10 Yann Jacquelet <jacquelet(a)lrde.epita.fr> Save Theo's exhaustive demonstration results. diff --git a/milena/sandbox/green/exp/annotating/nb_color/Makefile.am b/milena/sandbox/green/exp/annotating/achromastism/Makefile.am similarity index 96% copy from milena/sandbox/green/exp/annotating/nb_color/Makefile.am copy to milena/sandbox/green/exp/annotating/achromastism/Makefile.am index 8e204c6..d33b94d 100644 --- a/milena/sandbox/green/exp/annotating/nb_color/Makefile.am +++ b/milena/sandbox/green/exp/annotating/achromastism/Makefile.am @@ -7,7 +7,9 @@ ######### LOADLIBES= -lboost_filesystem -INCLUDES= -I$(HOME)/svn/oln/trunk/milena/sandbox/green +INCLUDES1= -I$(HOME)/git/olena/milena/sandbox/green +INCLUDES2= -I$(HOME)/git/olena/milena +INCLUDES= $(INCLUDES1) $(INCLUDES2) #CXXFLAGS= -ggdb -O0 -Wall -W -pedantic -ansi -pipe $(INCLUDES) #CXXFLAGS= -DNDEBUG -O1 -Wall -W -pedantic -ansi -pipe $(INCLUDES) CXXFLAGS= -DNDEBUG -O3 -Wall -W -pedantic -ansi -pipe $(INCLUDES) diff --git a/milena/sandbox/green/exp/annotating/achromastism/achromastism.cc b/milena/sandbox/green/exp/annotating/achromastism/achromastism.cc new file mode 100644 index 0000000..fdb8e6d --- /dev/null +++ b/milena/sandbox/green/exp/annotating/achromastism/achromastism.cc @@ -0,0 +1,113 @@ +// ACHROMATISM 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/math/max.hh> +#include <mln/math/min.hh> + +#include <mln/geom/nsites.hh> + +#include <mln/fun/v2v/rgb_to_achromatism_map.hh> + +#include <mln/io/ppm/load.hh> +#include <mln/io/plot/save_image_sh.hh> + +#include <mln/value/rgb8.hh> + +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; +} + +float achromatism_test(const std::string input, + const std::string output, + const unsigned threshold) + +{ + typedef mln::fun::v2v::rgb_to_achromatism_map<8> t_rgb_to_achromatism_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; + + mln::io::ppm::load(input_rgb8, input.c_str()); + + map = mln::data::transform(input_rgb8, t_rgb_to_achromatism_map()); + histo = mln::data::compute(mln::accu::meta::stat::histo1d(), map); + cnt1 = count_histo(histo | mln::box1d(mln::point1d(0), + mln::point1d(threshold))); + cnt2 = mln::geom::nsites(input_rgb8); + prop = ((100.0 * cnt1) / cnt2); + + mln::io::plot::save_image_sh(histo, output.c_str()); + + 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_ACHROMATISM_RET_PATH); + t_path leaf = dir_iter->path().leaf(); + t_path output = change_extension(directory / leaf, ".sh"); + + prop = achromatism_test(dir_iter->path().string(), + output.string(), + 11); + + 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/achromastism/text-color.txt new file mode 100644 index 0000000..4dfcbd3 --- /dev/null +++ b/milena/sandbox/green/exp/annotating/achromastism/text-color.txt @@ -0,0 +1,15 @@ +mp00262c_20p.ppm +mp00263c_20p.ppm +mp00319c_20p.ppm +mp00440c_20p.ppm +mp00608c_20p.ppm +mp00630c_20p.ppm +mp00631c_20p.ppm +ta00028c_20p.ppm +ta00037c_20p.ppm +ta00043c_20p.ppm +ta00046c_20p.ppm +ta00073c_20p.ppm +ta00081c_20p.ppm +ta00089c_20p.ppm +ta00090c_20p.ppm diff --git a/milena/sandbox/green/exp/annotating/achromastism/text-img.txt b/milena/sandbox/green/exp/annotating/achromastism/text-img.txt new file mode 100644 index 0000000..4ecb7ca --- /dev/null +++ b/milena/sandbox/green/exp/annotating/achromastism/text-img.txt @@ -0,0 +1,40 @@ +mp00032c_20p.ppm +mp00042c_20p.ppm +mp00076c_20p.ppm +mp00082c_20p.ppm +mp00142c_20p.ppm +mp00215c_20p.ppm +mp00228c_20p.ppm +mp00234c_20p.ppm +mp00248c_20p.ppm +mp00252c_20p.ppm +mp00253c_20p.ppm +mp00255c_20p.ppm +mp00259c_20p.ppm +mp00271c_20p.ppm +mp00290c_20p.ppm +mp00293c_20p.ppm +mp00304c_20p.ppm +mp00307c_20p.ppm +mp00311c_20p.ppm +mp00376c_20p.ppm +mp00411c_20p.ppm +mp00419c_20p.ppm +mp00447c_20p.ppm +mp00498c_20p.ppm +mp00510c_20p.ppm +mp00550c_20p.ppm +mp00573c_20p.ppm +mp00589c_20p.ppm +mp00592c_20p.ppm +mp00597c_20p.ppm +mp00599c_20p.ppm +mp00600c_20p.ppm +ta00031c_20p.ppm +ta00034c_20p.ppm +ta00063c_20p.ppm +ta00065c_20p.ppm +ta00072c_20p.ppm +ta00081c_20p.ppm +ta00083c_20p.ppm + diff --git a/milena/sandbox/green/exp/annotating/achromastism/text-only.txt b/milena/sandbox/green/exp/annotating/achromastism/text-only.txt new file mode 100644 index 0000000..0218a2a --- /dev/null +++ b/milena/sandbox/green/exp/annotating/achromastism/text-only.txt @@ -0,0 +1,8 @@ +mp00329c_20p.ppm +ta00036c_20p.ppm +ta00039c_20p.ppm +ta00040c_20p.ppm +ta00049c_20p.ppm +ta00055c_20p.ppm +ta00057c_20p.ppm +ta00068c_20p.ppm -- 1.5.6.5
14Â years, 2Â months
1
0
0
0
last-svn-commit-25-g1dff8cf Extend the histogram visualization tools for new projection concept.
by Yann Jacquelet
* green/mln/display/project_histo.hh (project2_histo): New functions that keep the max of the histogram or the class associate to it while projecting along a direction. * green/mln/display/project_histo.hh (project3_histo): New functions that keep the color of the class associate to the histogram maximum while projecting along a direction. * green/mln/display/display_histo.hh: New interface functions for project2_histo and project3_histo. --- milena/sandbox/ChangeLog | 13 + milena/sandbox/green/mln/display/display_histo.hh | 50 +++ milena/sandbox/green/mln/display/project_histo.hh | 344 +++++++++++++++++++++ 3 files changed, 407 insertions(+), 0 deletions(-) diff --git a/milena/sandbox/ChangeLog b/milena/sandbox/ChangeLog index f34508b..b9d40cb 100644 --- a/milena/sandbox/ChangeLog +++ b/milena/sandbox/ChangeLog @@ -1,5 +1,18 @@ 2010-01-05 Yann Jacquelet <jacquelet(a)lrde.epita.fr> + Extend the histogram visualization tools for new projection concept. + + * green/mln/display/project_histo.hh (project2_histo): New functions + that keep the max of the histogram or the class associate to it while + projecting along a direction. + * green/mln/display/project_histo.hh (project3_histo): New functions + that keep the color of the class associate to the histogram maximum + while projecting along a direction. + * green/mln/display/display_histo.hh: New interface functions for + project2_histo and project3_histo. + +2010-01-05 Yann Jacquelet <jacquelet(a)lrde.epita.fr> + Build translation table between number of pixels and percentage of pixels in image for the scribo database. diff --git a/milena/sandbox/green/mln/display/display_histo.hh b/milena/sandbox/green/mln/display/display_histo.hh index 1fd5da4..2ba0b61 100644 --- a/milena/sandbox/green/mln/display/display_histo.hh +++ b/milena/sandbox/green/mln/display/display_histo.hh @@ -33,6 +33,8 @@ # include <mln/display/project_histo.hh> # include <mln/fun/v2v/log.hh> # include <mln/value/int_u8.hh> +# include <mln/value/rgb8.hh> +# include <mln/value/label_8.hh> /// \file @@ -55,6 +57,20 @@ namespace mln image2d<value::int_u8> display_histo3d_unsigned(const image3d<unsigned>& histo); + image2d<value::int_u8> + display2_histo3d_unsigned(const image3d<unsigned>& histo); + + image2d<value::label_8> + display2_histo3d_unsigned(const image3d<unsigned>& histo, + const image3d<value::label_8>& label); + + image2d<value::rgb8> + display3_histo3d_unsigned(const image3d<unsigned>& histo); + + image2d<value::rgb8> + display3_histo3d_unsigned(const image3d<unsigned>& histo, + const image3d<value::label_8>& label); + #ifndef MLN_INCLUDE_ONLY /// \brief Allow the visualization of a 3d histogram by projection. @@ -86,6 +102,40 @@ namespace mln return proj_int; } + image2d<value::int_u8> + display2_histo3d_unsigned(const image3d<unsigned>& histo) + { + image2d<value::int_u8> proj = project2_histo<0>(histo); + + return proj; + } + + image2d<value::label_8> + display2_histo3d_unsigned(const image3d<unsigned>& histo, + const image3d<value::label_8>& label) + { + image2d<value::label_8> proj = project2_histo<0>(histo, label); + + return proj; + } + + image2d<value::rgb8> + display3_histo3d_unsigned(const image3d<unsigned>& histo) + { + image2d<value::rgb8> proj = project3_histo<0>(histo); + + return proj; + } + + image2d<value::rgb8> + display3_histo3d_unsigned(const image3d<unsigned>& histo, + const image3d<value::label_8>& label) + { + image2d<value::rgb8> proj = project3_histo<0>(histo, label); + + return proj; + } + #endif // ! MLN_INCLUDE_ONLY diff --git a/milena/sandbox/green/mln/display/project_histo.hh b/milena/sandbox/green/mln/display/project_histo.hh index f0e6858..d842c70 100644 --- a/milena/sandbox/green/mln/display/project_histo.hh +++ b/milena/sandbox/green/mln/display/project_histo.hh @@ -37,6 +37,12 @@ # include <mln/accu/image/take.hh> # include <mln/accu/image/to_result.hh> +# include <mln/opt/at.hh> + +# include <mln/value/int_u8.hh> +# include <mln/value/rgb8.hh> +# include <mln/value/label_8.hh> + /// \file /// /// \brief Allow the visualization of 3d histogram. @@ -54,6 +60,10 @@ namespace mln image2d<mln_result(A)> project_histo(const image3d<V>& histo); + template <typename A, unsigned direction, typename V> + image2d<mln_result(A)> + project2_histo(const image3d<V>& histo); + # ifndef MLN_INCLUDE_ONLY /// \brief Allow the visualization of 3d histogram. @@ -86,6 +96,340 @@ namespace mln return accu::image::to_result(histo_accu); } + template <unsigned direction> + image2d<value::int_u8> + project2_histo(const image3d<unsigned>& histo) + { + image2d<value::int_u8> result; + + if (0 == direction) // blue + { + image2d<value::int_u8> arg_max(histo.ncols(), histo.nslices()); + + for (unsigned j = 0; j < histo.ncols(); ++j) + for (unsigned i = 0; i < histo.nslices(); ++i) + { + unsigned max = 0; // minimum as possible + signed pos = -1; + + for (unsigned k = 0; k < histo.nrows(); ++k) + { + if (max <= opt::at(histo,i,j,k)) + { + max = opt::at(histo,i,j,k); + pos = k; + } + } + + opt::at(arg_max,i,j) = pos; + } + + result = arg_max; + } + else if (1 == direction) // red + { + image2d<value::int_u8> arg_max(histo.nrows(), histo.nslices()); + + for (unsigned j = 0; j < histo.nslices(); ++j) + for (unsigned i = 0; i < histo.nrows(); ++i) + { + unsigned max = 0; // minimum as possible + signed pos = -1; + + for (unsigned k = 0; k < histo.ncols(); ++k) + { + if (max <= opt::at(histo,i,j,k)) + { + max = opt::at(histo,i,j,k); + pos = k; + } + } + + opt::at(arg_max,i,j) = pos; + } + + result = arg_max; + } + else // 2 == direction // green + { + image2d<value::int_u8> arg_max(histo.nrows(), histo.ncols()); + + for (unsigned j = 0; j < histo.ncols(); ++j) + for (unsigned i = 0; i < histo.nrows(); ++i) + { + unsigned max = 0; // minimum as possible + signed pos = -1; + + for (unsigned k = 0; k < histo.nslices(); ++k) + { + if (max <= opt::at(histo,i,j,k)) + { + max = opt::at(histo,i,j,k); + pos = k; + } + } + + opt::at(arg_max,i,j) = pos; + } + + result = arg_max; + } + + return result; + } + + template <unsigned direction> + image2d<value::label_8> + project2_histo(const image3d<unsigned>& histo, + const image3d<value::label_8>& label) + { + image2d<value::label_8> result; + + if (0 == direction) // blue + { + image2d<value::label_8> arg_max(histo.ncols(), histo.nslices()); + + for (unsigned j = 0; j < histo.ncols(); ++j) + for (unsigned i = 0; i < histo.nslices(); ++i) + { + unsigned max = 0; // minimum as possible + signed pos = -1; + + for (unsigned k = 0; k < histo.nrows(); ++k) + { + if (max <= opt::at(histo,i,j,k)) + { + max = opt::at(histo,i,j,k); + pos = k; + } + } + + opt::at(arg_max,i,j) = opt::at(label,i,j,pos); + } + + result = arg_max; + } + else if (1 == direction) // red + { + image2d<value::label_8> arg_max(histo.nrows(), histo.nslices()); + + for (unsigned j = 0; j < histo.nslices(); ++j) + for (unsigned i = 0; i < histo.nrows(); ++i) + { + unsigned max = 0; // minimum as possible + signed pos = -1; + + for (unsigned k = 0; k < histo.ncols(); ++k) + { + if (max <= opt::at(histo,i,j,k)) + { + max = opt::at(histo,i,j,k); + pos = k; + } + } + + opt::at(arg_max,i,j) = opt::at(label,pos,i,j); + } + + result = arg_max; + } + else // 2 == direction // green + { + image2d<value::label_8> arg_max(histo.nrows(), histo.ncols()); + + for (unsigned j = 0; j < histo.ncols(); ++j) + for (unsigned i = 0; i < histo.nrows(); ++i) + { + unsigned max = 0; // minimum as possible + signed pos = -1; + + for (unsigned k = 0; k < histo.nslices(); ++k) + { + if (max <= opt::at(histo,i,j,k)) + { + max = opt::at(histo,i,j,k); + pos = k; + } + } + + opt::at(arg_max,i,j) = opt::at(label,i,pos,j); + } + + result = arg_max; + } + + return result; + } + + + // FIXME ... determine the color of each class. + template <unsigned direction> + image2d<value::rgb8> + project3_histo(const image3d<unsigned>& histo, + const image3d<value::label_8>& label) + { + image2d<value::rgb8> result; + + if (0 == direction) // blue + { + image2d<value::rgb8> arg_max(histo.ncols(), histo.nslices()); + + for (unsigned j = 0; j < histo.ncols(); ++j) + for (unsigned i = 0; i < histo.nslices(); ++i) + { + unsigned max = 0; // minimum as possible + signed pos = -1; + + for (unsigned k = 0; k < histo.nrows(); ++k) + { + if (max <= opt::at(histo,i,j,k)) + { + max = opt::at(histo,i,j,k); + pos = k; + } + } + + opt::at(arg_max,i,j) = value::rgb8(i,j,pos); + } + + result = arg_max; + } + else if (1 == direction) // red + { + image2d<value::rgb8> arg_max(histo.nrows(), histo.nslices()); + + for (unsigned j = 0; j < histo.nslices(); ++j) + for (unsigned i = 0; i < histo.nrows(); ++i) + { + unsigned max = 0; // minimum as possible + signed pos = -1; + + for (unsigned k = 0; k < histo.ncols(); ++k) + { + if (max <= opt::at(histo,i,j,k)) + { + max = opt::at(histo,i,j,k); + pos = k; + } + } + + opt::at(arg_max,i,j) = value::rgb8(pos,i,j); + } + + result = arg_max; + } + else // 2 == direction // green + { + image2d<value::rgb8> arg_max(histo.nrows(), histo.ncols()); + + for (unsigned j = 0; j < histo.ncols(); ++j) + for (unsigned i = 0; i < histo.nrows(); ++i) + { + unsigned max = 0; // minimum as possible + signed pos = -1; + + for (unsigned k = 0; k < histo.nslices(); ++k) + { + if (max <= opt::at(histo,i,j,k)) + { + max = opt::at(histo,i,j,k); + pos = k; + } + } + + // FIXME ... how to fix the n of rgb + opt::at(arg_max,i,j) = value::rgb8(i,pos,j); + } + + result = arg_max; + } + + return result; + } + + template <unsigned direction> + image2d<value::rgb8> + project3_histo(const image3d<unsigned>& histo) + { + image2d<value::rgb8> result; + + if (0 == direction) // blue + { + image2d<value::rgb8> arg_max(histo.ncols(), histo.nslices()); + + for (unsigned j = 0; j < histo.ncols(); ++j) + for (unsigned i = 0; i < histo.nslices(); ++i) + { + unsigned max = 0; // minimum as possible + signed pos = -1; + + for (unsigned k = 0; k < histo.nrows(); ++k) + { + if (max <= opt::at(histo,i,j,k)) + { + max = opt::at(histo,i,j,k); + pos = k; + } + } + + opt::at(arg_max,i,j) = value::rgb8(i,j,pos); + } + + result = arg_max; + } + else if (1 == direction) // red + { + image2d<value::rgb8> arg_max(histo.nrows(), histo.nslices()); + + for (unsigned j = 0; j < histo.nslices(); ++j) + for (unsigned i = 0; i < histo.nrows(); ++i) + { + unsigned max = 0; // minimum as possible + signed pos = -1; + + for (unsigned k = 0; k < histo.ncols(); ++k) + { + if (max <= opt::at(histo,i,j,k)) + { + max = opt::at(histo,i,j,k); + pos = k; + } + } + + opt::at(arg_max,i,j) = value::rgb8(pos,i,j); + } + + result = arg_max; + } + else // 2 == direction // green + { + image2d<value::rgb8> arg_max(histo.nrows(), histo.ncols()); + + for (unsigned j = 0; j < histo.ncols(); ++j) + for (unsigned i = 0; i < histo.nrows(); ++i) + { + unsigned max = 0; // minimum as possible + signed pos = -1; + + for (unsigned k = 0; k < histo.nslices(); ++k) + { + if (max <= opt::at(histo,i,j,k)) + { + max = opt::at(histo,i,j,k); + pos = k; + } + } + + // FIXME ... how to fix the n of rgb + opt::at(arg_max,i,j) = value::rgb8(i,pos,j); + } + + result = arg_max; + } + + return result; + } + # endif // ! MLN_INCLUDE_ONLY -- 1.5.6.5
14Â years, 2Â months
1
0
0
0
last-svn-commit-26-g3849ff5 Fix last details in the image processing chain.
by Yann Jacquelet
* green/tools/annotating/histo/histo.cc: Manage new inputs/outputs. * green/tools/annotating/opening/opening.cc: Manage new inputs/outputs. * green/tools/annotating/iz/Makefile.am: New Makefile. * green/tools/annotating/iz/iz.cc: New file. * green/tools/annotating/regmax/regmax.cc: Manage new inputs/outputs. --- milena/sandbox/ChangeLog | 10 + .../sandbox/green/tools/annotating/histo/histo.cc | 84 +++-- .../tools/annotating/{histo => iz}/Makefile.am | 0 milena/sandbox/green/tools/annotating/iz/iz.cc | 373 ++++++++++++++++++++ .../green/tools/annotating/opening/opening.cc | 76 +++-- .../green/tools/annotating/regmax/regmax.cc | 253 ++++++++++++-- 6 files changed, 714 insertions(+), 82 deletions(-) copy milena/sandbox/green/tools/annotating/{histo => iz}/Makefile.am (100%) create mode 100644 milena/sandbox/green/tools/annotating/iz/iz.cc diff --git a/milena/sandbox/ChangeLog b/milena/sandbox/ChangeLog index b9d40cb..097ea5c 100644 --- a/milena/sandbox/ChangeLog +++ b/milena/sandbox/ChangeLog @@ -1,3 +1,13 @@ +2010-02-10 Yann Jacquelet <jacquelet(a)lrde.epita.fr> + + Fix last details in the image processing chain. + + * green/tools/annotating/histo/histo.cc: Manage new inputs/outputs. + * green/tools/annotating/opening/opening.cc: Manage new inputs/outputs. + * green/tools/annotating/iz/Makefile.am: New Makefile. + * green/tools/annotating/iz/iz.cc: New file. + * green/tools/annotating/regmax/regmax.cc: Manage new inputs/outputs. + 2010-01-05 Yann Jacquelet <jacquelet(a)lrde.epita.fr> Extend the histogram visualization tools for new projection concept. diff --git a/milena/sandbox/green/tools/annotating/histo/histo.cc b/milena/sandbox/green/tools/annotating/histo/histo.cc index ab0b8af..8037e1a 100644 --- a/milena/sandbox/green/tools/annotating/histo/histo.cc +++ b/milena/sandbox/green/tools/annotating/histo/histo.cc @@ -16,14 +16,14 @@ #include <mln/fun/v2v/rgb8_to_rgbn.hh> -#include <mln/io/dump/save.hh> #include <mln/io/pbm/load.hh> -#include <mln/io/pbm/save.hh> -#include <mln/io/pgm/load.hh> -#include <mln/io/pgm/save.hh> #include <mln/io/ppm/load.hh> +#include <mln/io/dump/save.hh> +#include <mln/io/pgm/save.hh> #include <mln/io/ppm/save.hh> +#include <mln/literal/colors.hh> + #include <mln/opt/at.hh> #include <mln/pw/value.hh> @@ -33,15 +33,19 @@ template <unsigned n> -void mk_histo(const std::string& input, - const std::string& output, - const std::string& histo, - const std::string& mask) +void mk_histo(const std::string& input, // in + const std::string& quant, // in + const std::string& histo, // out + const std::string& proj1, // out + const std::string& proj2, // out + const std::string& mask) // [in] { typedef mln::value::int_u8 t_int_u8; + typedef mln::value::int_u<n> t_int_un; typedef mln::value::rgb8 t_rgb8; typedef mln::value::rgb<n> t_rgbn; typedef mln::image2d<t_int_u8> t_image2d_int_u8; + typedef mln::image2d<t_int_un> t_image2d_int_un; typedef mln::image2d<t_rgb8> t_image2d_rgb8; typedef mln::image2d<t_rgbn> t_image2d_rgbn; typedef mln::image2d<bool> t_image2d_bool; @@ -54,7 +58,9 @@ void mk_histo(const std::string& input, t_image2d_rgbn i1_input; // input rgbn t_image2d_bool m0_input; // mask input t_histo3d h1_input; // histo input - t_image2d_int_u8 p1_histo; // histo proj + t_image2d_int_u8 p1_histo1;// histo proj1 + t_image2d_rgbn p1_histo2;// histo proj2 + t_rgbn red(mln::literal::red); mln::io::ppm::load(i0_input, input.c_str()); i1_input = mln::data::transform(i0_input, t_rgb8_to_rgbn()); @@ -72,9 +78,13 @@ void mk_histo(const std::string& input, // END OF IMAGE PROCESSING CHAIN // BEGIN DUMPING - p1_histo = mln::display::display_histo3d_unsigned(h1_input); + p1_histo1 = mln::display::display_histo3d_unsigned(h1_input); + p1_histo2 = mln::display::display3_histo3d_unsigned(h1_input, red); + + mln::io::ppm::save(i1_input, quant.c_str()); mln::io::dump::save(h1_input, histo.c_str()); - mln::io::pgm::save(p1_histo, output.c_str()); + mln::io::pgm::save(p1_histo1, proj1.c_str()); + mln::io::ppm::save(p1_histo2, proj2.c_str()); // END DUMPING } @@ -82,35 +92,47 @@ void mk_histo(const std::string& input, void usage() { std::cout << std::endl; - std::cout << "histo input.ppm q out.ppm histo.dump [msk.pbm]" << std::endl; - std::cout << "where" << std::endl; - std::cout << "input.ppm is the 8 bits color ppm image" << std::endl; - std::cout << "q is the degree of quanification {2,3,4,5,6,7,8}" << std::endl; - std::cout << "out.pgm is the r/g projection of the histogram" << std::endl; - std::cout << "out.dump is the quantified color histogram" << std::endl; - std::cout << "msk.pbm is the mask which select the pixels" << std::endl; + std::cout << "histo input.ppm q quant.ppm histo.dump proj.pgm" + << " proj.ppm [msk.pbm]" << std::endl; + std::cout << std::endl; + std::cout << "where :" << std::endl; + std::cout << "* [ in] input.ppm is the 8 bits color ppm image" << std::endl; + std::cout << "* [ in] q is the degree of quantification" + << " {2,3,4,5,6,7,8}" << std::endl; + std::cout << "* [out] quant.ppm is the q bits quantified input" + << " image" << std::endl; + std::cout << "* [out] histo.dump is the quantified color" + << " histogram" << std::endl; + std::cout << "* [out] proj.pgm is the r/g projection of the" + << " histogram (summing along the blue axe)" << std::endl; + std::cout << "* [out] proj.ppm is the r/g projection of the" + << " histogram with maxima plot on" << std::endl; + std::cout << "* [ in] msk.pbm is the mask which selects the" + << " pixels" << std::endl; std::cout << std::endl; } int main(int argc, char* args[]) { - if (5 == argc || 6 == argc) + if (7 == argc || 8 == argc) { - const std::string input(args[1]); - const char q = args[2][0]; - const std::string output(args[3]); - const std::string histo(args[4]); - const std::string mask(6 == argc? args[5] : ""); + const std::string input(args[1]); // in + const char q = args[2][0]; // in + const std::string quant(args[3]); // out + const std::string histo(args[4]); // out + const std::string proj1(args[5]); // out + const std::string proj2(args[6]); // out + const std::string mask(8 == argc? args[7] : ""); // [in] switch(q) { - case '2': mk_histo<2>(input, output, histo, mask); break; - case '3': mk_histo<3>(input, output, histo, mask); break; - case '4': mk_histo<4>(input, output, histo, mask); break; - case '5': mk_histo<5>(input, output, histo, mask); break; - case '6': mk_histo<6>(input, output, histo, mask); break; - case '7': mk_histo<7>(input, output, histo, mask); break; - case '8': mk_histo<8>(input, output, histo, mask); break; + case '2': mk_histo<2>(input, quant, histo, proj1, proj2, mask); break; + case '3': mk_histo<3>(input, quant, histo, proj1, proj2, mask); break; + case '4': mk_histo<4>(input, quant, histo, proj1, proj2, mask); break; + case '5': mk_histo<5>(input, quant, histo, proj1, proj2, mask); break; + case '6': mk_histo<6>(input, quant, histo, proj1, proj2, mask); break; + case '7': mk_histo<7>(input, quant, histo, proj1, proj2, mask); break; + case '8': mk_histo<8>(input, quant, histo, proj1, proj2, mask); break; default: usage(); break; } } diff --git a/milena/sandbox/green/tools/annotating/histo/Makefile.am b/milena/sandbox/green/tools/annotating/iz/Makefile.am similarity index 100% copy from milena/sandbox/green/tools/annotating/histo/Makefile.am copy to milena/sandbox/green/tools/annotating/iz/Makefile.am diff --git a/milena/sandbox/green/tools/annotating/iz/iz.cc b/milena/sandbox/green/tools/annotating/iz/iz.cc new file mode 100644 index 0000000..07e5dd9 --- /dev/null +++ b/milena/sandbox/green/tools/annotating/iz/iz.cc @@ -0,0 +1,373 @@ +// TOOLS ==> influence zone transformation + +#include <iostream> +#include <fstream> +#include <boost/format.hpp> + +#include <mln/accu/stat/histo3d_rgb.hh> + +#include <mln/core/macros.hh> +#include <mln/core/alias/neighb3d.hh> +#include <mln/core/image/image2d.hh> +#include <mln/core/image/image3d.hh> + +#include <mln/data/compute.hh> + +#include <mln/display/display_histo.hh> + +#include <mln/io/dump/load.hh> +#include <mln/io/dump/save.hh> +#include <mln/io/ppm/load.hh> +#include <mln/io/ppm/save.hh> +#include <mln/io/pgm/load.hh> +#include <mln/io/pgm/save.hh> + +#include <mln/literal/colors.hh> + +#include <mln/labeling/compute.hh> +#include <mln/labeling/mean_values.hh> + +#include <mln/transform/influence_zone_geodesic.hh> + +#include <mln/value/int_u8.hh> + +template <unsigned n> +struct t_labeling_rgbn : mln::Function_v2v< t_labeling_rgbn<n> > +{ + typedef mln::value::rgb<n> t_rgbn; + typedef mln::value::label_8 t_lbl8; + typedef t_rgbn argument; + typedef t_lbl8 result; + typedef mln::image3d<t_lbl8> t_label; + + const t_label& _label; + + t_labeling_rgbn(const t_label& label) : _label(label) {} + + result operator()(const argument& c) const + { + t_lbl8 tmp = mln::opt::at(_label, c.blue(), c.red(), c.green()); + + return tmp; + } +}; + +void compute_stats(const mln::image2d<mln::value::rgb8>& i_input_rgb8, + const mln::image2d<mln::value::label_8>& l_input_lbl8, + const mln::image3d<unsigned>& h_histo_rgbn, + const mln::image3d<mln::value::label_8>& l_histo_lbl8, + const mln::value::label_8& n_labels, + const std::string& log) +{ + typedef mln::algebra::vec<3,float> t_vec3f; + typedef mln::accu::math::sum<unsigned,unsigned> t_sum; + typedef mln::accu::stat::mean<t_vec3f,t_vec3f,t_vec3f> t_mean; + typedef mln::util::array<unsigned> t_count_array; + typedef mln::util::array<t_vec3f> t_mean_array; + + mln::util::array<float> abs((unsigned)(n_labels)+1); + mln::util::array<float> rel((unsigned)(n_labels)+1); + unsigned nb = 0; + + for (unsigned i = 0; i <= n_labels; ++i) + { + abs[i] = 0.0; + rel[i] = 0.0; + } + + // COMPUTE THE SUM + t_count_array count = mln::labeling::compute(t_sum(), + h_histo_rgbn, + l_histo_lbl8, + n_labels); + + // COMPUTE THE TOTAL + for (unsigned i = 0; i <= n_labels; ++i) + { + unsigned c = count[i]; + nb += c; + } + + // COMPUTE THE PERCENTAGES + for (unsigned i = 0; i <= n_labels; ++i) + if (0 < count[i]) + { + abs[i] = ((float)count[i] / nb)*100.0; + rel[i] = ((float)count[i] / (nb - count[0]))*100.0; + } + + // COMPUTE THE MEAN + + t_mean_array mean = mln::labeling::compute(t_mean(), + i_input_rgb8, + l_input_lbl8, + n_labels); + + // CORRECT 0 LABEL STATS + rel[0] = 0; + mean[0][0] = 255.0; + mean[0][1] = 255.0; + mean[0][2] = 0.0; + + // PRINT STATS + std::ofstream log_stream(log.c_str()); + + for (unsigned i = 0; i <= n_labels; ++i) + { + const t_vec3f& mean_v = mean[i]; + + log_stream << boost::format("%2i|" + "r = %6.2f, g = %6.2f, b = %6.2f |" + "c = %7i, %%i = %5.2f, %%c = %5.2f") + % i + % mean_v[0] + % mean_v[1] + % mean_v[2] + % count[i] + % abs[i] + % rel[i] + << std::endl; + } + + log_stream << std::endl << std::endl; + log_stream.flush(); + log_stream.close(); +} + +bool expect(std::istream& stream, const std::string expected) +{ + bool result; + std::string got; + + stream >> got; + + result = (got == expected); + + return result; +} + +std::istream& operator>>(std::istream& stream, + mln::algebra::vec<3,float>& color) +{ + unsigned lbl; + + stream >> lbl; + if (expect(stream, std::string("|")) && + expect(stream, std::string("r")) && + expect(stream, std::string("="))) + { + stream >> color[0]; + + if (expect(stream, std::string(",")) && + expect(stream, std::string("g")) && + expect(stream, std::string("="))) + { + stream >> color[1]; + + if (expect(stream, std::string(",")) && + expect(stream, std::string("b")) && + expect(stream, std::string("="))) + { + stream >> color[2]; + } + } + } + + return stream; +} + +void load(mln::util::array< mln::algebra::vec<3,float> >& m2_label, + const char *colormap) +{ + typedef mln::algebra::vec<3,float> t_vec3f; + typedef mln::util::array<t_vec3f> t_mean_array; + + std::ifstream stream(colormap); + std::string buffer; + + getline(stream, buffer); + + while (0 < buffer.size()) + { + std::stringstream line(buffer); + t_vec3f mean_v; + + line >> mean_v; + + m2_label.append(mean_v); + + getline(stream, buffer); + } + + stream.close(); +} + +template<unsigned n> +void mk_iz(const std::string& labeled, // in + const unsigned d, // in + const mln::neighb3d& nbh, // in + const std::string& input, // in + const std::string& quant, // in + const std::string& histo, // in + const std::string& colormap,// in + const std::string& iz, // out + const std::string& proj, // out + const std::string& mean, // out + const std::string& stats) // [out] +{ + typedef mln::value::int_u8 t_int_u8; + typedef mln::value::label_8 t_lbl8; + typedef mln::value::rgb8 t_rgb8; + typedef mln::value::rgb<n> t_rgbn; + typedef mln::algebra::vec<3,float> t_v3f; + typedef mln::image2d<t_int_u8> t_image2d_int_u8; + typedef mln::image2d<t_rgb8> t_image2d_rgb8; + typedef mln::image2d<t_rgbn> t_image2d_rgbn; + typedef mln::image2d<t_lbl8> t_image2d_lbl8; + typedef mln::image3d<unsigned> t_histo3d; + typedef mln::image3d<t_lbl8> t_image3d_lbl8; + typedef mln::accu::meta::stat::histo3d_rgb t_histo3d_fun; + typedef mln::accu::stat::mean<t_v3f,t_v3f,t_v3f> t_mean; + typedef mln::util::array<t_v3f> t_mean_array; + + // START OF IMAGE PROCESSING CHAIN + t_image2d_rgb8 i0_input; // input img + t_image2d_rgbn i1_input; // quant img + t_histo3d h1_input; // histo input + t_histo3d h2_input; // histo input + t_image2d_int_u8 p1_histo; // histo proj + t_image2d_rgb8 p3_histo; // histo proj + t_image3d_lbl8 l2_histo; // label histo + t_image3d_lbl8 l3_histo; // iz label hist + t_mean_array m2_label; // colormap + t_mean_array m3_label; // colormap + t_image2d_lbl8 l3_input; // label input + t_image2d_rgb8 i3_mean; // reconstructed + + t_lbl8 n_lbl; // nb labels + t_rgb8 red(mln::literal::red); + + mln::io::dump::load(l2_histo, labeled.c_str()); + mln::io::ppm::load(i0_input, input.c_str()); + mln::io::ppm::load(i1_input, quant.c_str()); + mln::io::dump::load(h1_input, histo.c_str()); + load(m2_label, colormap.c_str()); + + if (0 == d) + { + l3_histo = mln::transform::influence_zone_geodesic(l2_histo, nbh); + } + else + { + l3_histo = mln::transform::influence_zone_geodesic(l2_histo, nbh, d); + } + // END OF IMAGE PROCESSING CHAIN + + // BEGIN DUMPING + + n_lbl = (t_lbl8)(m2_label.size()-1); + + l3_input = mln::data::transform(i1_input, t_labeling_rgbn<n>(l3_histo)); + i3_mean = mln::labeling::mean_values(i0_input, l3_input, n_lbl); + m3_label = mln::labeling::compute(t_mean(), i0_input, l3_input, n_lbl); + + // CORRECT 0 LABEL STATS + m3_label[0][0] = 255.0; + m3_label[0][1] = 255.0; + m3_label[0][2] = 0.0; + + p3_histo = mln::display::display3_histo3d_unsigned<n>(h1_input, + l3_histo, + m3_label, + red); + mln::io::dump::save(l3_input, iz.c_str()); + mln::io::ppm::save(p3_histo, proj.c_str()); + mln::io::ppm::save(i3_mean, mean.c_str()); + + if (0 < stats.size()) + compute_stats(i0_input, l3_input, h1_input, l3_histo, n_lbl, stats); + + // END DUMPING +} + + +void usage() +{ + std::cout << std::endl; + std::cout << "iz labeled.dump d nbh input.ppm q quant.ppm" + << " histo.dump colormap.txt iz.dump proj.ppm" + << " mean.ppm [stats.txt]" << std::endl; + std::cout << std::endl; + std::cout << "where :" << std::endl; + std::cout << "* [ in] labeled.dump is the labeled 3d histogram" << std::endl; + std::cout << "* [ in] d is the depth for the zone influence" + << " transformation (0 means infinite)" << std::endl; + std::cout << "* [ in] nbh is the 3d neighbourhood {6,18,26}" << std::endl; + std::cout << "* [ in] input.ppm is the 8 bits color ppm image" << std::endl; + std::cout << "* [ in] q is the degree of quantification" + << " {2,3,4,5,6,7,8}" << std::endl; + std::cout << "* [ in] quant.ppm is the q bits quantified input" + << " image" << std::endl; + std::cout << "* [ in] histo.dump is the quantified color" + << " histogram" << std::endl; + std::cout << "* [ in] colormap.txt is the colormap for labels" << std::endl; + std::cout << "* [out] iz.dump is the iz labeled 3d histogram" << std::endl; + std::cout << "* [out] proj.ppm is the r/g projection of the" + << " histogram with maxima label plot on" << std::endl; + std::cout << "* [out] mean.ppm is the mean reconstructed image" << std::endl; + std::cout << "* [out] stats.txt is the statistical label report"<< std::endl; + std::cout << std::endl; +} + +int main(int argc, char* args[]) +{ + if (12 == argc || 13 == argc) + { + const std::string labeled(args[1]); // in + const unsigned d = atoi(args[2]); // in + const char nbh = args[3][0]; // in + const std::string input(args[4]); // in + const char q = args[5][0]; // in + const std::string quant(args[6]); // in + const std::string histo(args[7]); // in + const std::string colormap(args[8]); // in + const std::string iz(args[9]); // out + const std::string proj(args[10]); // out + const std::string mean(args[11]); // out + const std::string stats(13 == argc? args[12] : ""); // [out] + + + mln::neighb3d neighbourhood; + + switch (nbh) + { + case '6': neighbourhood = mln::c6(); break; + case '1': neighbourhood = mln::c18(); break; + case '2': neighbourhood = mln::c26(); break; + default: usage(); return 0; // force usage and quit + } + + switch (q) + { + case '2' : mk_iz<2>(labeled,d,neighbourhood,input,quant, + histo,colormap,iz,proj,mean,stats);break; + case '3' : mk_iz<3>(labeled,d,neighbourhood,input,quant, + histo,colormap,iz,proj,mean,stats);break; + case '4' : mk_iz<4>(labeled,d,neighbourhood,input,quant, + histo,colormap,iz,proj,mean,stats);break; + case '5' : mk_iz<5>(labeled,d,neighbourhood,input,quant, + histo,colormap,iz,proj,mean,stats);break; + case '6' : mk_iz<6>(labeled,d,neighbourhood,input,quant, + histo,colormap,iz,proj,mean,stats);break; + case '7' : mk_iz<7>(labeled,d,neighbourhood,input,quant, + histo,colormap,iz,proj,mean,stats);break; + case '8' : mk_iz<8>(labeled,d,neighbourhood,input,quant, + histo,colormap,iz,proj,mean,stats);break; + default: usage(); break; + } + } + else + usage(); + + return 0; +} diff --git a/milena/sandbox/green/tools/annotating/opening/opening.cc b/milena/sandbox/green/tools/annotating/opening/opening.cc index 3e1dbf2..cdd37fb 100644 --- a/milena/sandbox/green/tools/annotating/opening/opening.cc +++ b/milena/sandbox/green/tools/annotating/opening/opening.cc @@ -15,36 +15,47 @@ #include <mln/io/dump/load.hh> #include <mln/io/dump/save.hh> -#include <mln/io/pgm/load.hh> +#include <mln/io/ppm/save.hh> #include <mln/io/pgm/save.hh> +#include <mln/literal/colors.hh> + #include <mln/morpho/opening/volume.hh> +#include <mln/value/rgb.hh> #include <mln/value/int_u8.hh> -void mk_opening(const std::string& input, - const unsigned min_vol, - const std::string& output, - const std::string& opened) +template <unsigned n> +void mk_opening(const std::string& histo, // in + const unsigned min_vol, // in + const std::string& opened, // out + const std::string& proj1, // out + const std::string& proj2) // out { typedef mln::value::int_u8 t_int_u8; + typedef mln::value::rgb<n> t_rgbn; typedef mln::image2d<t_int_u8> t_image2d_int_u8; + typedef mln::image2d<t_rgbn> t_image2d_rgbn; typedef mln::image3d<unsigned> t_histo3d; typedef mln::accu::meta::stat::histo3d_rgb t_histo3d_fun; // START OF IMAGE PROCESSING CHAIN t_histo3d h1_input; // histo input t_histo3d h2_input; // histo input - t_image2d_int_u8 p1_histo; // histo proj + t_image2d_int_u8 p1_histo1;// histo proj1 + t_image2d_rgbn p1_histo2;// histo proj2 + t_rgbn red(mln::literal::red); - mln::io::dump::load(h1_input, input.c_str()); + mln::io::dump::load(h1_input, histo.c_str()); h2_input = mln::morpho::opening::volume(h1_input, mln::c6(), min_vol); // END OF IMAGE PROCESSING CHAIN // BEGIN DUMPING - p1_histo = mln::display::display_histo3d_unsigned(h2_input); + p1_histo1 = mln::display::display_histo3d_unsigned(h2_input); + p1_histo2 = mln::display::display3_histo3d_unsigned(h2_input, red); mln::io::dump::save(h2_input, opened.c_str()); - mln::io::pgm::save(p1_histo, output.c_str()); + mln::io::pgm::save(p1_histo1, proj1.c_str()); + mln::io::ppm::save(p1_histo2, proj2.c_str()); // END DUMPING } @@ -52,25 +63,46 @@ void mk_opening(const std::string& input, void usage() { std::cout << std::endl; - std::cout << "opening input.dump v out.dump out.ppm" << std::endl; - std::cout << "where" << std::endl; - std::cout << "input.dump is the 3d color input histo" << std::endl; - std::cout << "v is the minimum size of each composant" << std::endl; - std::cout << "out.pgm is the r/g proj of the opened histogram" << std::endl; - std::cout << "out.dump is the opened histogram" << std::endl; + std::cout << "opening q histo.dump v opened.dump proj.pgm" + << " proj.ppm" << std::endl; + std::cout << std::endl; + std::cout << "where :" << std::endl; + std::cout << "* [ in] q is the degree of quantification" + << " {2,3,4,5,6,7,8}" << std::endl; + std::cout << "* [ in] histo.dump is the quantified color" + << " histogram" << std::endl; + std::cout << "* [ in] v is the minimum size (in pixels) of" + << " each composant" << std::endl; + std::cout << "* [out] opened.dump is the filtered histogram" << std::endl; + std::cout << "* [out] proj.pgm is the r/g projection of the" + << " histogram (summing along the blue axe)" << std::endl; + std::cout << "* [out] proj.ppm is the r/g projection of the" + << " histogram with maxima plot on" << std::endl; std::cout << std::endl; } int main(int argc, char* args[]) { - if (5 == argc) + if (7 == argc) { - const std::string input(args[1]); - const unsigned min_vol = atoi(args[2]); - const std::string output(args[3]); - const std::string opened(args[4]); - - mk_opening(input, min_vol, output, opened); + const char q = args[1][0]; // in + const std::string histo(args[2]); // in + const unsigned min_vol = atoi(args[3]); // in + const std::string opened(args[4]); // out + const std::string proj1(args[5]); // out + const std::string proj2(args[6]); // out + + switch(q) + { + case '2': mk_opening<2>(histo, min_vol, opened, proj1, proj2); break; + case '3': mk_opening<3>(histo, min_vol, opened, proj1, proj2); break; + case '4': mk_opening<4>(histo, min_vol, opened, proj1, proj2); break; + case '5': mk_opening<5>(histo, min_vol, opened, proj1, proj2); break; + case '6': mk_opening<6>(histo, min_vol, opened, proj1, proj2); break; + case '7': mk_opening<7>(histo, min_vol, opened, proj1, proj2); break; + case '8': mk_opening<8>(histo, min_vol, opened, proj1, proj2); break; + default: usage(); break; + } } else usage(); diff --git a/milena/sandbox/green/tools/annotating/regmax/regmax.cc b/milena/sandbox/green/tools/annotating/regmax/regmax.cc index 2079bc4..0ff4d2e 100644 --- a/milena/sandbox/green/tools/annotating/regmax/regmax.cc +++ b/milena/sandbox/green/tools/annotating/regmax/regmax.cc @@ -1,8 +1,13 @@ // TOOLS ==> regmax on histo #include <iostream> +#include <fstream> +#include <boost/format.hpp> #include <mln/accu/stat/histo3d_rgb.hh> +#include <mln/accu/stat/mean.hh> + +#include <mln/algebra/vec.hh> #include <mln/core/macros.hh> #include <mln/core/alias/neighb3d.hh> @@ -18,9 +23,14 @@ #include <mln/io/dump/save.hh> #include <mln/io/pgm/load.hh> #include <mln/io/pgm/save.hh> +#include <mln/io/ppm/load.hh> #include <mln/io/ppm/save.hh> #include <mln/labeling/regional_maxima.hh> +#include <mln/labeling/compute.hh> +#include <mln/labeling/mean_values.hh> + +#include <mln/literal/colors.hh> #include <mln/morpho/opening/volume.hh> @@ -28,6 +38,8 @@ #include <mln/value/int_u8.hh> #include <mln/value/rgb8.hh> +#include <mln/util/array.hh> + template <unsigned n> struct t_labeling_rgbn : mln::Function_v2v< t_labeling_rgbn<n> > { @@ -49,19 +61,134 @@ struct t_labeling_rgbn : mln::Function_v2v< t_labeling_rgbn<n> > } }; -void mk_regmax(const std::string& input, - const std::string& quant, - const std::string& histo, - const std::string& label, - const std::string& output) +void compute_stats(const mln::image2d<mln::value::rgb8>& i_input_rgb8, + const mln::image2d<mln::value::label_8>& l_input_lbl8, + const mln::image3d<unsigned>& h_histo_rgbn, + const mln::image3d<mln::value::label_8>& l_histo_lbl8, + const mln::value::label_8& n_labels, + const std::string& log) +{ + typedef mln::algebra::vec<3,float> t_vec3f; + typedef mln::accu::math::sum<unsigned,unsigned> t_sum; + typedef mln::accu::stat::mean<t_vec3f,t_vec3f,t_vec3f> t_mean; + typedef mln::util::array<unsigned> t_count_array; + typedef mln::util::array<t_vec3f> t_mean_array; + + mln::util::array<float> abs((unsigned)(n_labels)+1); + mln::util::array<float> rel((unsigned)(n_labels)+1); + unsigned nb = 0; + + for (unsigned i = 0; i <= n_labels; ++i) + { + abs[i] = 0.0; + rel[i] = 0.0; + } + + // COMPUTE THE SUM + t_count_array count = mln::labeling::compute(t_sum(), + h_histo_rgbn, + l_histo_lbl8, + n_labels); + + // COMPUTE THE TOTAL + for (unsigned i = 0; i <= n_labels; ++i) + { + unsigned c = count[i]; + nb += c; + } + + // COMPUTE THE PERCENTAGES + for (unsigned i = 0; i <= n_labels; ++i) + if (0 < count[i]) + { + abs[i] = ((float)count[i] / nb)*100.0; + rel[i] = ((float)count[i] / (nb - count[0]))*100.0; + } + + // COMPUTE THE MEAN + + t_mean_array mean = mln::labeling::compute(t_mean(), + i_input_rgb8, + l_input_lbl8, + n_labels); + + // CORRECT 0 LABEL STATS + rel[0] = 0; + mean[0][0] = 255.0; + mean[0][1] = 255.0; + mean[0][2] = 0.0; + + // PRINT STATS + std::ofstream log_stream(log.c_str()); + + for (unsigned i = 0; i <= n_labels; ++i) + { + const t_vec3f& mean_v = mean[i]; + + log_stream << boost::format("%2i|" + "r = %6.2f, g = %6.2f, b = %6.2f |" + "c = %7i, %%i = %5.2f, %%c = %5.2f") + % i + % mean_v[0] + % mean_v[1] + % mean_v[2] + % count[i] + % abs[i] + % rel[i] + << std::endl; + } + + log_stream << std::endl << std::endl; + log_stream.flush(); + log_stream.close(); +} + +void save(mln::util::array< mln::algebra::vec<3,float> >& m2_label, + const char *colormap) +{ + typedef mln::algebra::vec<3,float> t_vec3f; + typedef mln::util::array<t_vec3f> t_mean_array; + + std::ofstream stream(colormap); + + for (unsigned i = 0; i < m2_label.size(); ++i) + { + const t_vec3f& mean_v = m2_label[i]; + + stream << boost::format("%2i | r = %6.2f, g = %6.2f, b = %6.2f") + % i + % mean_v[0] + % mean_v[1] + % mean_v[2] + << std::endl; + } + + stream.flush(); + stream.close(); +} + +template <unsigned n> +void mk_regmax(const std::string& input, // in + const std::string& quant, // in + const std::string& histo, // in + const std::string& opened, // in + const mln::neighb3d& nbh, // in + const std::string& labeled, // out + const std::string& proj, // out + const std::string& colormap,// out + const std::string& mean, // out + const std::string& stats) // [out] { typedef mln::value::label_8 t_lbl8; typedef mln::value::rgb8 t_rgb8; - typedef mln::value::rgbn t_rgbn; + typedef mln::value::rgb<n> t_rgbn; typedef mln::value::int_u8 t_int_u8; + typedef mln::value::int_u<n> t_int_un; typedef mln::algebra::vec<3,float> t_v3f; typedef mln::image2d<t_int_u8> t_image2d_int_u8; + typedef mln::image2d<t_int_un> t_image2d_int_un; typedef mln::image2d<t_rgb8> t_image2d_rgb8; + typedef mln::image2d<t_rgbn> t_image2d_rgbn; typedef mln::image3d<t_lbl8> t_image3d_lbl8; typedef mln::image2d<t_lbl8> t_image2d_lbl8; typedef mln::image3d<unsigned> t_histo3d; @@ -71,60 +198,128 @@ void mk_regmax(const std::string& input, t_image2d_rgb8 i0_input; // input img t_image2d_rgbn i1_input; // quant img + t_histo3d h1_input; // input histo t_histo3d h2_input; // opened histo -// t_image2d_int_u8 p2_label; // histo proj - t_image2d_lbl8 p2_label; // histo proj -// t_image2d_rgb8 p2_label; // histo proj + t_image2d_rgb8 p2_label; // histo proj t_image3d_lbl8 l2_histo; // label histo - t_mean_array m2_label; // palette + t_image2d_lbl8 l2_input; // label input + t_mean_array m2_label; // colormap + t_image2d_rgb8 i2_mean; // reconstructed t_lbl8 n_lbl; // nb class + t_rgb8 red(mln::literal::red); + // BEGIN LOADING mln::io::ppm::load(i0_input, input.c_str()); mln::io::ppm::load(i1_input, quant.c_str()); - mln::io::dump::load(h2_input, histo.c_str()); + mln::io::dump::load(h1_input, histo.c_str()); + mln::io::dump::load(h2_input, opened.c_str()); // END LOADING // BEGIN IMAGE PROCESSING - l2_histo = mln::labeling::regional_maxima(h2_input, mln::c6(), n_lbl); + l2_histo = mln::labeling::regional_maxima(h2_input, nbh, n_lbl); // END IMAGE PROCESSING // BEGIN SAVING - mln::debug::println(h2_input); mln::io::dump::save(l2_histo, labeled.c_str()); l2_input = mln::data::transform(i1_input, t_labeling_rgbn<n>(l2_histo)); - m2_label = mln::labeling::compute(t_mean(), i0_input, l2_input, n_labels); - p2_label =mln::display::display3_histo3d_unsigned(h2_input,l2_histo,m2_label); + i2_mean = mln::labeling::mean_values(i0_input, l2_input, n_lbl); + m2_label = mln::labeling::compute(t_mean(), i0_input, l2_input, n_lbl); + + // CORRECT 0 LABEL STATS + m2_label[0][0] = 255.0; + m2_label[0][1] = 255.0; + m2_label[0][2] = 0.0; + + p2_label =mln::display::display3_histo3d_unsigned<n>(h1_input, + l2_histo, + m2_label, + red); + + mln::io::ppm::save(p2_label, proj.c_str()); + save(m2_label, colormap.c_str()); + mln::io::ppm::save(i2_mean, mean.c_str()); + + if (0 < stats.size()) + compute_stats(i0_input, l2_input, h1_input, l2_histo, n_lbl, stats); -// mln::io::pgm::save(p2_label, output.c_str()); - mln::io::ppm::save(p2_label, output.c_str()); - std::cout << "Nb classes : " << n_lbl << std::endl; // END SAVING } - void usage() { std::cout << std::endl; - std::cout << "regmax input.dump out.dump out.ppm" << std::endl; - std::cout << "where" << std::endl; - std::cout << "input.dump is opened histo" << std::endl; - std::cout << "out.pgm is the r/g proj of the opened histogram" << std::endl; - std::cout << "out.dump is the labeled histogram" << std::endl; + std::cout << "regmax input.ppm q quant.ppm histo.dump" + << " opened.dump nbh labeled.dump proj.ppm" + << " colormap.txt mean.ppm [stats.txt]" << std::endl; + std::cout << std::endl; + std::cout << "where :" << std::endl; + std::cout << "* [ in] input.ppm is the 8 bits color ppm image" << std::endl; + std::cout << "* [ in] q is the degree of quantification" + << " {2,3,4,5,6,7,8}" << std::endl; + std::cout << "* [ in] quant.ppm is the q bits quantified input" + << " image" << std::endl; + std::cout << "* [ in] histo.dump is the quantified color" + << " histogram" << std::endl; + std::cout << "* [ in] opened.dump is the filtered histogram" << std::endl; + std::cout << "* [ in] nbh is the 3d neighbourhood {6,18,26}" << std::endl; + std::cout << "* [out] labeled.dump is the labeled 3d histogram" << std::endl; + std::cout << "* [out] proj.ppm is the r/g projection of the" + << " histogram with maxima label plot on" << std::endl; + std::cout << "* [out] colormap.txt is the colormap for labels" << std::endl; + std::cout << "* [out] mean.ppm is the mean reconstructed image" << std::endl; + std::cout << "* [out] stats.txt is the statistical label report"<< std::endl; std::cout << std::endl; } int main(int argc, char* args[]) { - if (4 == argc) + if (11 == argc || 12 == argc) { - const std::string input(args[1]); - const std::string output(args[2]); - const std::string labeled(args[3]); + const std::string input(args[1]); // in + const char q = args[2][0]; // in + const std::string quant(args[3]); // in + const std::string histo(args[4]); // in + const std::string opened(args[5]); // in + const char nbh = args[6][0]; // in + const std::string labeled(args[7]); // out + const std::string proj(args[8]); // out + const std::string colormap(args[9]);// out + const std::string mean(args[10]); // out + const std::string stats(12 == argc? args[11] : ""); // [out] + + + mln::neighb3d neighbourhood; + + switch (nbh) + { + case '6': neighbourhood = mln::c6(); break; + case '1': neighbourhood = mln::c18(); break; + case '2': neighbourhood = mln::c26(); break; + default: usage(); return 0; // force usage and quit + } + + switch (q) + { - mk_regmax(input, output, labeled); + case '2': mk_regmax<2>(input,quant,histo,opened,neighbourhood, + labeled,proj,colormap,mean,stats); break; + case '3': mk_regmax<3>(input,quant,histo,opened,neighbourhood, + labeled,proj,colormap,mean,stats); break; + case '4': mk_regmax<4>(input,quant,histo,opened,neighbourhood, + labeled,proj,colormap,mean,stats); break; + case '5': mk_regmax<5>(input,quant,histo,opened,neighbourhood, + labeled,proj,colormap,mean,stats); break; + case '6': mk_regmax<6>(input,quant,histo,opened,neighbourhood, + labeled,proj,colormap,mean,stats); break; + case '7': mk_regmax<7>(input,quant,histo,opened,neighbourhood, + labeled,proj,colormap,mean,stats); break; + case '8': mk_regmax<8>(input,quant,histo,opened,neighbourhood, + labeled,proj,colormap,mean,stats); break; + default: usage(); break; + } } else usage(); -- 1.5.6.5
14Â years, 2Â months
1
0
0
0
← Newer
1
...
328
329
330
331
332
333
334
...
963
Older →
Jump to page:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
Results per page:
10
25
50
100
200