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
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
April 2011
----- 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
4 participants
107 discussions
Start a n
N
ew thread
last-svn-commit-835-g78843e4 Compute font and boldness data.
by Guillaume Lazzara
* scribo/core/component_features_data.hh, * scribo/core/component_info.hh, * scribo/core/line_info.hh, * scribo/core/paragraph_info.hh, * scribo/core/paragraph_set.hh: Add support for text features in core structures. * scribo/debug/text_color_image.hh: New debug routine. * scribo/estim/components_features.hh: * scribo/estim/font_boldness.hh, * scribo/estim/font_color.hh, * scribo/estim/internal/compute_skeleton.hh: New. * scribo/io/xml/internal/extended_page_xml_visitor.hh, * scribo/io/xml/internal/full_xml_visitor.hh: Use text features in XML. * scribo/primitive/extract/components.hh, * scribo/text/extract_lines.hh: Add new overloads * scribo/text/extract_lines_with_features.hh: New. * scribo/toolchain/internal/content_in_doc_functor.hh: Update call to extract::components. * src/debug/Makefile.am, * src/debug/show_components_boldness.cc, * src/debug/show_components_color.cc, * src/debug/show_lines_boldness.cc: New debug examples. * tests/Makefile.am, * tests/estim/Makefile.am, * tests/estim/font_boldness.cc, * tests/estim/font_color.cc: New tests. * tests/img/phillip.pbm, * tests/img/phillip.ppm: New test data. --- scribo/ChangeLog | 43 ++++ scribo/scribo/core/component_features_data.hh | 68 ++++++ scribo/scribo/core/component_info.hh | 40 ++++- scribo/scribo/core/line_info.hh | 118 +++++++++++- scribo/scribo/core/paragraph_info.hh | 102 +++++++++- scribo/scribo/core/paragraph_set.hh | 11 + scribo/scribo/debug/text_color_image.hh | 100 +++++++++ scribo/scribo/estim/components_features.hh | 169 +++++++++++++++ scribo/scribo/estim/font_boldness.hh | 215 ++++++++++++++++++++ scribo/scribo/estim/font_color.hh | 206 +++++++++++++++++++ scribo/scribo/estim/internal/compute_skeleton.hh | 112 ++++++++++ .../io/xml/internal/extended_page_xml_visitor.hh | 9 +- scribo/scribo/io/xml/internal/full_xml_visitor.hh | 33 ++-- scribo/scribo/primitive/extract/components.hh | 70 ++++--- scribo/scribo/text/extract_lines.hh | 22 ++ scribo/scribo/text/extract_lines_with_features.hh | 131 ++++++++++++ .../toolchain/internal/content_in_doc_functor.hh | 3 +- scribo/src/debug/Makefile.am | 16 ++ scribo/src/debug/show_components_boldness.cc | 72 +++++++ scribo/src/debug/show_components_color.cc | 73 +++++++ scribo/src/debug/show_lines_boldness.cc | 199 ++++++++++++++++++ scribo/tests/Makefile.am | 5 +- scribo/tests/estim/Makefile.am | 29 +++ scribo/tests/estim/font_boldness.cc | 46 ++++ scribo/tests/estim/font_color.cc | 48 +++++ scribo/tests/img/phillip.pbm | Bin 0 -> 1633 bytes scribo/tests/img/phillip.ppm | 5 + 27 files changed, 1895 insertions(+), 50 deletions(-) create mode 100644 scribo/scribo/core/component_features_data.hh create mode 100644 scribo/scribo/debug/text_color_image.hh create mode 100644 scribo/scribo/estim/components_features.hh create mode 100644 scribo/scribo/estim/font_boldness.hh create mode 100644 scribo/scribo/estim/font_color.hh create mode 100644 scribo/scribo/estim/internal/compute_skeleton.hh create mode 100644 scribo/scribo/text/extract_lines_with_features.hh create mode 100644 scribo/src/debug/show_components_boldness.cc create mode 100644 scribo/src/debug/show_components_color.cc create mode 100644 scribo/src/debug/show_lines_boldness.cc create mode 100644 scribo/tests/estim/Makefile.am create mode 100644 scribo/tests/estim/font_boldness.cc create mode 100644 scribo/tests/estim/font_color.cc create mode 100644 scribo/tests/img/phillip.pbm create mode 100644 scribo/tests/img/phillip.ppm diff --git a/scribo/ChangeLog b/scribo/ChangeLog index 4592e73..2fc8d6d 100644 --- a/scribo/ChangeLog +++ b/scribo/ChangeLog @@ -1,5 +1,48 @@ 2011-04-05 Guillaume Lazzara <z(a)lrde.epita.fr> + Compute font and boldness data. + + * scribo/core/component_features_data.hh, + * scribo/core/component_info.hh, + * scribo/core/line_info.hh, + * scribo/core/paragraph_info.hh, + * scribo/core/paragraph_set.hh: Add support for text features in + core structures. + + * scribo/debug/text_color_image.hh: New debug routine. + + * scribo/estim/components_features.hh: + * scribo/estim/font_boldness.hh, + * scribo/estim/font_color.hh, + * scribo/estim/internal/compute_skeleton.hh: New. + + * scribo/io/xml/internal/extended_page_xml_visitor.hh, + * scribo/io/xml/internal/full_xml_visitor.hh: Use text features in + XML. + + * scribo/primitive/extract/components.hh, + * scribo/text/extract_lines.hh: Add new overloads + + * scribo/text/extract_lines_with_features.hh: New. + + * scribo/toolchain/internal/content_in_doc_functor.hh: Update call + to extract::components. + + * src/debug/Makefile.am, + * src/debug/show_components_boldness.cc, + * src/debug/show_components_color.cc, + * src/debug/show_lines_boldness.cc: New debug examples. + + * tests/Makefile.am, + * tests/estim/Makefile.am, + * tests/estim/font_boldness.cc, + * tests/estim/font_color.cc: New tests. + + * tests/img/phillip.pbm, + * tests/img/phillip.ppm: New test data. + +2011-04-05 Guillaume Lazzara <z(a)lrde.epita.fr> + Add a new alignments extraction routine. * scribo/primitive/extract/alignments.hh, diff --git a/scribo/scribo/core/component_features_data.hh b/scribo/scribo/core/component_features_data.hh new file mode 100644 index 0000000..f5ba60f --- /dev/null +++ b/scribo/scribo/core/component_features_data.hh @@ -0,0 +1,68 @@ +// Copyright (C) 2011 EPITA Research and Development Laboratory (LRDE) +// +// This file is part of Olena. +// +// Olena is free software: you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, version 2 of the License. +// +// Olena is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Olena. If not, see <
http://www.gnu.org/licenses/
>. +// +// As a special exception, you may use this file as part of a free +// software project without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to produce +// an executable, this file does not by itself cause the resulting +// executable to be covered by the GNU General Public License. This +// exception does not however invalidate any other reasons why the +// executable file might be covered by the GNU General Public License. + +#ifndef SCRIBO_CORE_COMPONENT_FEATURES_DATA_HH +# define SCRIBO_CORE_COMPONENT_FEATURES_DATA_HH + +/// \file +/// +/// \brief Component features data structure. + + +# include <scribo/core/def/color_type.hh> + +namespace scribo +{ + + struct component_features_data + { + bool valid; + scribo::def::color_type color; + float boldness; + }; + + + std::ostream& + operator<<(std::ostream& ostr, const component_features_data& data); + + +# ifndef MLN_INCLUDE_ONLY + + inline + std::ostream& + operator<<(std::ostream& ostr, const component_features_data& data) + { + return ostr << "features[" + << "valid=" << data.valid + << ", color=" << data.color + << ", boldness=" << data.boldness + << "]" << std::endl; + } + +# endif // ! MLN_INCLUDE_ONLY + +} // end of namespace scribo + +#endif // ! SCRIBO_CORE_COMPONENT_FEATURES_DATA_HH diff --git a/scribo/scribo/core/component_info.hh b/scribo/scribo/core/component_info.hh index f825aee..164a242 100644 --- a/scribo/scribo/core/component_info.hh +++ b/scribo/scribo/core/component_info.hh @@ -36,6 +36,7 @@ # include <mln/core/alias/point2d.hh> # include <mln/util/object_id.hh> +# include <scribo/core/component_features_data.hh> # include <scribo/core/concept/serializable.hh> # include <scribo/core/tag/component.hh> # include <scribo/core/tag/line.hh> @@ -64,6 +65,13 @@ namespace scribo // The number of pixels in this component. unsigned card() const; + + bool has_features() const; + void update_features(const component_features_data& features); + + const component_features_data& features() const; + + component::Tag tag() const; void update_tag(component::Tag tag); @@ -72,12 +80,14 @@ namespace scribo bool is_valid() const; - private: + protected: component_id_t id_; mln::box2d bbox_; mln::point2d mass_center_; unsigned card_; + component_features_data features_; + component::Tag tag_; component::Type type_; }; @@ -106,9 +116,12 @@ namespace scribo unsigned card, component::Type type) : id_(id), bbox_(bbox), mass_center_(mass_center), card_(card), - tag_(component::None), type_(type) + type_(type) { - + if (!bbox.is_valid()) + tag_ = component::Ignored; + else + tag_ = component::None; } @@ -142,6 +155,26 @@ namespace scribo return card_; } + inline + bool + component_info::has_features() const + { + return features_.valid; + } + + inline + void + component_info::update_features(const component_features_data& features) + { + features_ = features; + } + + inline + const component_features_data& + component_info::features() const + { + return features_; + } inline component::Tag @@ -193,6 +226,7 @@ namespace scribo << ", mass_center=" << info.mass_center() << ", card=" << info.card() << ", tag=" << info.tag() + << ", features=" << info.features() << ")" << std::endl; } diff --git a/scribo/scribo/core/line_info.hh b/scribo/scribo/core/line_info.hh index 749e627..73d7856 100644 --- a/scribo/scribo/core/line_info.hh +++ b/scribo/scribo/core/line_info.hh @@ -43,10 +43,13 @@ # include <mln/core/alias/box2d.hh> # include <mln/core/alias/point2d.hh> # include <mln/accu/stat/median_h.hh> +# include <mln/accu/stat/mean.hh> # include <mln/accu/shape/bbox.hh> # include <mln/math/min.hh> # include <mln/util/object_id.hh> # include <mln/value/int_u.hh> +# include <mln/math/sqr.hh> +# include <mln/value/rgb8.hh> # include <scribo/core/tag/component.hh> # include <scribo/core/tag/line.hh> @@ -69,6 +72,7 @@ namespace scribo namespace internal { + /// Data structure for \c scribo::line_info<I>. template <typename L> struct line_info_data @@ -120,6 +124,14 @@ namespace scribo bool indented_; + float boldness_; + float boldness_reliability_; + + mln::value::rgb8 color_; + + // sqrt(Max(VAR(R), VAR(G), VAR(B))) + float color_reliability_; + std::string text_; std::string html_text_; @@ -128,6 +140,19 @@ namespace scribo }; + + // Functor used to sort components ids. + // Order by location from left to right. + template <typename L> + struct sort_comp_ids + { + sort_comp_ids(const component_set<L>& comp_set); + bool operator()(const component_id_t& l, const component_id_t& r) const; + + component_set<L> comps_; + }; + + } // end of namespace scribo::internal @@ -181,6 +206,12 @@ namespace scribo unsigned pixel_area() const; + float boldness() const; + float boldness_reliability() const; + + const mln::value::rgb8& color() const; + float color_reliability() const; + int baseline() const; int meanline() const; int ascent() const; @@ -530,6 +561,38 @@ namespace scribo template <typename L> + float + line_info<L>::boldness() const + { + return data_->boldness_; + } + + + template <typename L> + float + line_info<L>::boldness_reliability() const + { + return data_->boldness_reliability_; + } + + + template <typename L> + const mln::value::rgb8& + line_info<L>::color() const + { + return data_->color_; + } + + + template <typename L> + float + line_info<L>::color_reliability() const + { + return data_->color_reliability_; + } + + + template <typename L> int line_info<L>::baseline() const { @@ -919,6 +982,20 @@ namespace scribo char_space, char_width; + // FIXME: we should use the median for computing the line + // color. Means should be kept for variance computation. + mln::accu::stat::mean<mln::value::int_u<8> > + color_red, + color_green, + color_blue, + boldness; + + float + sum2_red = 0, + sum2_green = 0, + sum2_blue = 0, + sum2_boldness = 0; + unsigned pixel_area = 0; mln::accu::shape::bbox<P> bbox; @@ -941,8 +1018,8 @@ namespace scribo ref_line = mln::math::min(comp_set(c).bbox().pmin().row(), ref_line); } - // FIXME: compute font color! + unsigned used_comps = 0; for_all_elements(i, data_->components_) { unsigned c = data_->components_(i); @@ -959,6 +1036,22 @@ namespace scribo if (comp_set(c).type() == component::Punctuation) continue; + // This component will be used for stats, the counter is + // incremented. + ++used_comps; + + // Compute boldness + boldness.take(comp_set(c).features().boldness); + sum2_boldness += mln::math::sqr<float>(comp_set(c).features().boldness); + + // Compute color + color_red.take(comp_set(c).features().color.red()); + color_green.take(comp_set(c).features().color.green()); + color_blue.take(comp_set(c).features().color.blue()); + + sum2_red += mln::math::sqr<unsigned>(comp_set(c).features().color.red()); + sum2_green += mln::math::sqr<unsigned>(comp_set(c).features().color.green()); + sum2_blue += mln::math::sqr<unsigned>(comp_set(c).features().color.blue()); // FIXME: we must guaranty here that the relationship is from @@ -1018,6 +1111,25 @@ namespace scribo data_->components_.hook_std_vector_().end(), internal::sort_comp_ids<L>(comp_set)); + // Boldness + data_->boldness_ = boldness.to_result(); + data_->boldness_reliability_ = std::sqrt(sum2_boldness); + + // Color + data_->color_ = mln::value::rgb8(color_red, color_green, color_blue); + + // FIXME: we may prefer using the non-biased variance. + float + var_red = sum2_red / (float)(used_comps) + - mln::math::sqr<float>(color_red.to_result()), + var_green = sum2_green / (float)(used_comps) + - mln::math::sqr<float>(color_green.to_result()), + var_blue = sum2_blue / (float)(used_comps) + - mln::math::sqr<float>(color_blue.to_result()); + + data_->color_reliability_ = std::sqrt(std::max(var_red, + std::max(var_green, var_blue))); + // Char space if (char_space.card() < 2) data_->char_space_ = 0; @@ -1074,6 +1186,10 @@ namespace scribo << ", type=" << info.type() << ", bbox=" << info.bbox() << ", ebbox=" << info.ebbox() + << ", boldness=" << info.boldness() + << ", boldness_reliability=" << info.boldness_reliability() + << ", color=" << info.color() + << ", color_reliability=" << info.color_reliability() << ", components=" << info.component_ids() << ", baseline=" << info.baseline() << ", meanline=" << info.meanline() diff --git a/scribo/scribo/core/paragraph_info.hh b/scribo/scribo/core/paragraph_info.hh index f4b1309..2a9b626 100644 --- a/scribo/scribo/core/paragraph_info.hh +++ b/scribo/scribo/core/paragraph_info.hh @@ -44,6 +44,13 @@ namespace scribo paragraph_info(); paragraph_info(const line_links<L>& llinks); + /*! \brief Add a new line to this paragraph + + This method is provided for an incremental construction. + + Once this method has been called, needs_stats_update() will + return true until force_stats_update() is called. + */ void add_line(const line_info<L>& line); const mln::box2d& bbox() const; @@ -54,12 +61,25 @@ namespace scribo unsigned nlines() const; + // FIXME: add boldness? + + const mln::value::rgb8& color() const; + float color_reliability() const; + bool is_valid() const; + bool needs_stats_update() const; + void force_stats_update(); + private: mln::util::array<line_id_t> line_ids_; mln::accu::shape::bbox<mln_site(L)> bbox_; line_links<L> llinks_; + + mln::value::rgb8 color_; + float color_reliability_; + + bool needs_stats_update_; }; @@ -68,12 +88,13 @@ namespace scribo template <typename L> paragraph_info<L>::paragraph_info() + : needs_stats_update_(false) { } template <typename L> paragraph_info<L>::paragraph_info(const line_links<L>& llinks) - : llinks_(llinks) + : llinks_(llinks), needs_stats_update_(false) { } @@ -83,6 +104,9 @@ namespace scribo { line_ids_.append(line.id()); bbox_.take(line.bbox()); + + // More data may need to be updated! + needs_stats_update_ = true; } template <typename L> @@ -115,12 +139,86 @@ namespace scribo } template <typename L> + const mln::value::rgb8& + paragraph_info<L>::color() const + { + return color_; + } + + + template <typename L> + float + paragraph_info<L>::color_reliability() const + { + return color_reliability_; + } + + template <typename L> bool paragraph_info<L>::is_valid() const { return llinks_.is_valid(); } + template <typename L> + bool + paragraph_info<L>::needs_stats_update() const + { + return needs_stats_update_; + } + + template <typename L> + void + paragraph_info<L>::force_stats_update() + { + if (!needs_stats_update_) + return; + + const line_set<L>& lines = llinks_.lines(); + + mln::accu::stat::mean<mln::value::int_u<8> > + color_red, + color_green, + color_blue; + + float + sum2_red = 0, + sum2_green = 0, + sum2_blue = 0; + + for_all_elements(e, line_ids_) + { + unsigned lid = line_ids_(e); + + color_red.take(lines(lid).color().red()); + color_green.take(lines(lid).color().green()); + color_blue.take(lines(lid).color().blue()); + sum2_red += mln::math::sqr<unsigned>(lines(lid).color().red()); + sum2_green += mln::math::sqr<unsigned>(lines(lid).color().green()); + sum2_blue += mln::math::sqr<unsigned>(lines(lid).color().blue()); + } + + color_ = mln::value::rgb8(color_red.to_result(), + color_green.to_result(), + color_blue.to_result()); + + float + var_red = sum2_red / (float)line_ids_.nelements() + - mln::math::sqr<float>(color_red.to_result()), + var_green = sum2_green / (float)line_ids_.nelements() + - mln::math::sqr<float>(color_green.to_result()), + var_blue = sum2_blue / (float)line_ids_.nelements() + - mln::math::sqr<float>(color_blue.to_result()); + + color_reliability_ = std::sqrt(std::max(var_red, + std::max(var_green, var_blue))); + + // Update color + + // FIXME: Update paragraph stats + + needs_stats_update_ = false; + } template <typename L> std::ostream& @@ -129,6 +227,8 @@ namespace scribo return ostr << "paragraph_info(" << "line_ids=" << info.line_ids() << ", bbox=" << info.bbox() + << ", color=" << info.color() + << ", color_reliability=" << info.color_reliability() << ")" << std::endl; } diff --git a/scribo/scribo/core/paragraph_set.hh b/scribo/scribo/core/paragraph_set.hh index f081472..ec9f51b 100644 --- a/scribo/scribo/core/paragraph_set.hh +++ b/scribo/scribo/core/paragraph_set.hh @@ -95,6 +95,11 @@ namespace scribo scribo::paragraph_set<L> paragraph(const line_links<L>& llinks); + /// \brief Construct a paragraph set from line set information. + template <typename L> + scribo::paragraph_set<L> + paragraph(const scribo::line_set<L>& lines); + } // end of namespace scribo::make @@ -239,6 +244,9 @@ namespace scribo parset(par_id).add_line(lines(l)); } + for_all_paragraphs(p, parset) + parset(p).force_stats_update(); + return parset; } @@ -264,6 +272,9 @@ namespace scribo parset(par_id).add_line(lines(l)); } + for_all_paragraphs(p, parset) + parset(p).force_stats_update(); + return parset; } diff --git a/scribo/scribo/debug/text_color_image.hh b/scribo/scribo/debug/text_color_image.hh new file mode 100644 index 0000000..f8d76c8 --- /dev/null +++ b/scribo/scribo/debug/text_color_image.hh @@ -0,0 +1,100 @@ +// Copyright (C) 2011 EPITA Research and Development Laboratory (LRDE) +// +// This file is part of Olena. +// +// Olena is free software: you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, version 2 of the License. +// +// Olena is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Olena. If not, see <
http://www.gnu.org/licenses/
>. +// +// As a special exception, you may use this file as part of a free +// software project without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to produce +// an executable, this file does not by itself cause the resulting +// executable to be covered by the GNU General Public License. This +// exception does not however invalidate any other reasons why the +// executable file might be covered by the GNU General Public License. + +#ifndef SCRIBO_DEBUG_TEXT_COLOR_IMAGE_HH +# define SCRIBO_DEBUG_TEXT_COLOR_IMAGE_HH + +/// \file +/// +/// Draw text components with their respective colors. + +# include <mln/core/image/image2d.hh> +# include <mln/value/rgb8.hh> +# include <mln/data/fill.hh> +# include <mln/literal/white.hh> +# include <mln/util/array.hh> + +# include <mln/pw/all.hh> +# include <mln/core/image/dmorph/image_if.hh> + +# include <scribo/core/macros.hh> +# include <scribo/core/document.hh> + +namespace scribo +{ + + namespace debug + { + using namespace mln; + + template <typename L> + image2d<value::rgb8> + text_color_image(const document<L>& doc); + + +# ifndef MLN_INCLUDE_ONLY + + template <typename L> + image2d<mln::value::rgb8> + text_color_image(const document<L>& doc) + { + image2d<value::rgb8> debug; + initialize(debug, doc.binary_image()); + data::fill(debug, literal::white); + + const paragraph_set<L>& parset = doc.paragraphs(); + const line_set<L>& lines = doc.lines(); + const component_set<L>& comp_set = lines.components(); + const L& lbl = comp_set.labeled_image(); + + for_all_paragraphs(p, parset) + { + const mln::util::array<line_id_t>& line_ids = parset(p).line_ids(); + + for_all_paragraph_lines(lid, line_ids) + { + line_id_t l = line_ids(lid); + const mln::util::array<component_id_t>& comps = lines(l).component_ids(); + + for_all_elements(e, comps) + { + unsigned comp_id = comps(e); + data::fill(((debug | comp_set(comp_id).bbox()).rw() | (pw::value(lbl) == pw::cst(comp_id))).rw(), + parset(p).color()); + } + + } + } + + return debug; + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace scribo::debug + +} // end of namespace scribo + +#endif // ! SCRIBO_DEBUG_TEXT_COLOR_IMAGE_HH diff --git a/scribo/scribo/estim/components_features.hh b/scribo/scribo/estim/components_features.hh new file mode 100644 index 0000000..ee34123 --- /dev/null +++ b/scribo/scribo/estim/components_features.hh @@ -0,0 +1,169 @@ +// Copyright (C) 2011 EPITA Research and Development Laboratory (LRDE) +// +// This file is part of Olena. +// +// Olena is free software: you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, version 2 of the License. +// +// Olena is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Olena. If not, see <
http://www.gnu.org/licenses/
>. +// +// As a special exception, you may use this file as part of a free +// software project without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to produce +// an executable, this file does not by itself cause the resulting +// executable to be covered by the GNU General Public License. This +// exception does not however invalidate any other reasons why the +// executable file might be covered by the GNU General Public License. + +#ifndef SCRIBO_ESTIM_COMPONENT_FEATURES_HH +# define SCRIBO_ESTIM_COMPONENT_FEATURES_HH + +# include <mln/core/image/image2d.hh> +# include <mln/core/alias/neighb2d.hh> +# include <mln/topo/skeleton/crest.hh> +# include <mln/topo/skeleton/is_simple_point.hh> +# include <mln/transform/distance_front.hh> +# include <mln/logical/not.hh> +# include <mln/make/w_window2d_int.hh> +# include <mln/value/int_u8.hh> +# include <mln/arith/revert.hh> +# include <mln/morpho/skeleton_constrained.hh> +# include <mln/core/routine/extend.hh> +# include <mln/labeling/blobs.hh> +# include <mln/accu/stat/mean.hh> + + +# include <mln/data/compute.hh> +# include <mln/io/pbm/save.hh> +# include <mln/io/pgm/save.hh> +# include <mln/util/timer.hh> + +# include <scribo/core/component_set.hh> +# include <scribo/estim/font_color.hh> +# include <scribo/estim/font_boldness.hh> + +#include <mln/data/convert.hh> + + +namespace scribo +{ + + namespace estim + { + + using namespace mln; + + /// \brief Compute components features. + /// + /// \sa component_features_data + // + template <typename I, typename J, typename L> + component_set<L> + components_features(const Image<I>& input, const Image<J>& bin_input, + const component_set<L>& components); + + +# ifndef MLN_INCLUDE_ONLY + + + template <typename I, typename J, typename L> + component_set<L> + components_features(const Image<I>& input, const Image<J>& bin_input, + const component_set<L>& components) + { + trace::entering("scribo::estim::components_features"); + + component_set<L> output = components.duplicate(); + + component_features_data features; + features.valid = true; + + typedef mln_concrete(J) B; + B skel; + L skel_lbl; + mln_value(L) nlabels; + + util::timer t; + t.start(); + { + int psi = 7; + int vals[] = { 0, 9, 0, 9, 0, + 9, 6, 4, 6, 9, + 0, 4, 0, 4, 0, + 9, 6, 4, 6, 9, + 0, 9, 0, 9, 0 }; + + typedef mln_ch_value(I,value::int_u8) dist_t; + dist_t + dist = transform::distance_front(logical::not_(bin_input), c8(), + mln::make::w_window2d_int(vals), + mln_max(value::int_u8)); + t.stop(); + std::cout << "Distance front " << t << std::endl; + t.restart(); + + dist_t dist_map = arith::revert(dist); + + t.stop(); + std::cout << "Revert " << t << std::endl; + t.restart(); + + B K = topo::skeleton::crest(bin_input, dist, c8(), psi); + + t.stop(); + std::cout << "Crest " << t << std::endl; + t.restart(); + + skel = + morpho::skeleton_constrained(bin_input, c8(), + topo::skeleton::is_simple_point<B,neighb2d>, + extend(K, false), dist_map); + + t.stop(); + std::cout << "Skeleton constrained " << t << std::endl; + } + t.restart(); + + const L& lbl = output.labeled_image(); + + for_all_comps(c, output) + { + // Estimate component color + features.color = data::compute(accu::meta::stat::mean(), + ((input | output(c).bbox()) + | (pw::value(lbl) == pw::cst(c) + && pw::value(skel)))); + + + // Estimate component boldness + features.boldness = internal::boldness_from_lbl( + (lbl | output(c).bbox()) | (pw::value(lbl) == pw::cst(c)), + (skel | output(c).bbox()) | (pw::value(lbl) == pw::cst(c))); + + output(c).update_features(features); + } + + + t.stop(); + std::cout << "compute color and boldness " << t << std::endl; + + trace::exiting("scribo::estim::components_features"); + return output; + } + + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace scribo::estim + +} // end of namespace scribo + +# endif // ! SCRIBO_ESTIM_COMPONENT_FEATURES_HH diff --git a/scribo/scribo/estim/font_boldness.hh b/scribo/scribo/estim/font_boldness.hh new file mode 100644 index 0000000..0b145bf --- /dev/null +++ b/scribo/scribo/estim/font_boldness.hh @@ -0,0 +1,215 @@ +// Copyright (C) 2011 EPITA Research and Development Laboratory (LRDE) +// +// This file is part of Olena. +// +// Olena is free software: you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, version 2 of the License. +// +// Olena is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Olena. If not, see <
http://www.gnu.org/licenses/
>. +// +// As a special exception, you may use this file as part of a free +// software project without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to produce +// an executable, this file does not by itself cause the resulting +// executable to be covered by the GNU General Public License. This +// exception does not however invalidate any other reasons why the +// executable file might be covered by the GNU General Public License. + +#ifndef SCRIBO_ESTIM_FONT_BOLDNESS_HH +# define SCRIBO_ESTIM_FONT_BOLDNESS_HH + +/// \file +/// +/// \brief Estimate the font color. + +# include <mln/core/image/image2d.hh> +# include <mln/core/alias/neighb2d.hh> + +# include <mln/labeling/blobs.hh> +# include <mln/accu/stat/mean.hh> +# include <mln/value/next.hh> + +# include <scribo/core/macros.hh> +# include <scribo/core/def/lbl_type.hh> +# include <scribo/estim/internal/compute_skeleton.hh> + + +namespace scribo +{ + + namespace estim + { + + using namespace mln; + + /// \brief Estimate the font color. + // + template <typename I> + float + font_boldness(const Image<I>& text_ima); + + +# ifndef MLN_INCLUDE_ONLY + + namespace internal + { + + + template <typename I, typename J> + float + boldness_from_lbl(const Image<I>& ima_lbl_, + const Image<J>& skel_) + { + trace::entering("scribo::estim::internal::boldness_from_lbl"); + + const I& ima_lbl = exact(ima_lbl_); + const J& skel = exact(skel_); + mln_precondition(ima_lbl.is_valid()); + mln_precondition(skel.is_valid()); + + mln_piter(I) p(ima_lbl.domain()); + int skel_p = 0, ima_p = 0; + + for_all(p) + { + if (skel(p)) + ++skel_p; + + if (ima_lbl(p)) + ++ima_p; + } + + float res = ima_p / (float) skel_p; + + trace::exiting("scribo::estim::internal::boldness_from_lbl"); + return res; + } + + + // FIXME: this version is invalid!!! It supposes that image and + // skeleton labeling associate the same id to a component and + // its corresponding skeleton. This is wrong! + template <typename I, typename J> + float + boldness_from_lbl(const Image<I>& ima_lbl_, + const mln_value(I)& nlabels, + const Image<J>& skel_lbl_) + { + trace::entering("scribo::estim::internal::boldness_from_lbl"); + + const I& ima_lbl = exact(ima_lbl_); + const J& skel_lbl = exact(skel_lbl_); + mln_precondition(ima_lbl.is_valid()); + mln_precondition(skel_lbl.is_valid()); + + mln_piter(I) p(ima_lbl.domain()); + std::vector<int> skel_p(value::next(nlabels), 0); + std::vector<int> ima_p(value::next(nlabels), 0); + + for_all(p) + { + int val = skel_lbl(p); + + if (val) + ++skel_p[val]; + + val = ima_lbl(p); + + if (val) + ++ima_p[val]; + } + + accu::stat::mean<float> mean; + for_all_ncomponents(i, nlabels) + mean.take(ima_p[i] / skel_p[i]); + + // double variance = 0.; + // for (unsigned int i = 0; i < nlabels; ++i) + // variance += ((ima_p[i] / skel_p[i]) - mean.to_result()) * ((ima_p[i] / skel_p[i]) - mean.to_result()); + + // variance /= nlabels; + + trace::exiting("scribo::estim::internal::boldness_from_lbl"); + return mean.to_result(); + } + + } // end of namespace scribo::estim::internal + + + // IMPLEMENTATIONS + + namespace impl + { + + namespace generic + { + + template <typename I> + float + font_boldness(const Image<I>& ima_) + { + trace::entering("scribo::estim::impl::generic::font_boldness"); + + const I& ima = exact(ima_); + mln_precondition(ima.is_valid()); + mlc_is(mln_value(I), bool)::check(); + + typedef scribo::def::lbl_type V; + typedef mln_ch_value(I,V) L; + + mln_concrete(I) skel = internal::compute_skeleton(ima); + + V nslabels; + L slbl = labeling::blobs(skel, c8(), nslabels); + + V nlabels; + L lbl = labeling::blobs(ima, c8(), nlabels); + + float + output = internal::boldness_from_lbl(lbl, nlabels, slbl); + + trace::exiting("scribo::estim::impl::generic::font_boldness"); + return output; + } + + } // end of namespace scribo::estim::generic::impl + + } // end of namespace scribo::estim::impl + + + + // FACADE + + template <typename I> + float + font_boldness(const Image<I>& ima) + { + trace::entering("scribo::estim::font_boldness"); + + mln_precondition(exact(ima).is_valid()); + mlc_is(mln_value(I), bool)::check(); + + float output = impl::generic::font_boldness(ima); + + trace::exiting("scribo::estim::font_boldness"); + return output; + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace scribo::estim + +} // end of namespace scribo + +# endif // ! SCRIBO_ESTIM_FONT_BOLDNESS_HH + + + diff --git a/scribo/scribo/estim/font_color.hh b/scribo/scribo/estim/font_color.hh new file mode 100644 index 0000000..9a3c429 --- /dev/null +++ b/scribo/scribo/estim/font_color.hh @@ -0,0 +1,206 @@ +// Copyright (C) 2011 EPITA Research and Development Laboratory (LRDE) +// +// This file is part of Olena. +// +// Olena is free software: you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, version 2 of the License. +// +// Olena is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Olena. If not, see <
http://www.gnu.org/licenses/
>. +// +// As a special exception, you may use this file as part of a free +// software project without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to produce +// an executable, this file does not by itself cause the resulting +// executable to be covered by the GNU General Public License. This +// exception does not however invalidate any other reasons why the +// executable file might be covered by the GNU General Public License. + +#ifndef SCRIBO_ESTIM_FONT_COLOR_HH +# define SCRIBO_ESTIM_FONT_COLOR_HH + +/// \file +/// +/// \brief Estimate the font color. + +# include <mln/core/image/image2d.hh> +# include <mln/core/alias/neighb2d.hh> +# include <mln/value/int_u8.hh> +# include <mln/labeling/compute.hh> +# include <mln/accu/stat/mean.hh> +# include <mln/accu/stat/median_h.hh> +# include <mln/value/int_u12.hh> +# include <mln/value/rgb8.hh> + +# include <scribo/estim/internal/compute_skeleton.hh> + + +namespace scribo +{ + + namespace estim + { + + using namespace mln; + + /// \brief Estimate the font color. + // + template <typename I, typename J> + mln_value(I) + font_color(const Image<I>& text_ima, const Image<J>& bin_text_ima); + + +# ifndef MLN_INCLUDE_ONLY + + namespace impl + { + + template <typename I, typename J> + mln_value(I) + font_color_rgb(const Image<I>& text_ima_, + const Image<J>& bin_text_ima_) + { + trace::entering("scribo::estim::impl::font_color_rgb"); + + typedef mln_value(I) V1; + typedef mln_value(J) V2; + //mlc_is(V1, value::rgb)::check(); + mlc_is(V2, bool)::check(); + + const I& text_ima = exact(text_ima_); + const J& bin_text_ima = exact(bin_text_ima_); + + mln_concrete(J) skel = internal::compute_skeleton(bin_text_ima); + + value::int_u8 nlabels = 0; + mln_ch_value(I,value::int_u8) + lbl = labeling::blobs(skel, c8(), nlabels); + + util::array<algebra::vec<3u, float> > res = + labeling::compute(accu::meta::stat::mean(), text_ima, lbl, nlabels); + + accu::stat::median_h<value::int_u12> m_red; + accu::stat::median_h<value::int_u12> m_green; + accu::stat::median_h<value::int_u12> m_blue; + m_red.init(); + m_green.init(); + m_blue.init(); + + mln_value(I) med_rgb; + + for (unsigned int i = 1; i <= nlabels; ++i) + { + m_red.take(res[i][0]); + m_green.take(res[i][1]); + m_blue.take(res[i][2]); + } + + med_rgb.red() = m_red.to_result(); + med_rgb.green() = m_green.to_result(); + med_rgb.blue() = m_blue.to_result(); + + trace::exiting("scribo::estim::impl::font_color_rgb"); + return med_rgb; + } + + + template <typename I, typename J> + mln_value(I) + font_color_grayscale(const Image<I>& text_ima_, + const Image<J>& bin_text_ima_) + { + trace::entering("scribo::estim::impl::font_color_grayscale"); + + typedef mln_value(I) V1; + typedef mln_value(J) V2; + //mlc_is(V1, value::rgb)::check(); + mlc_is(V2, bool)::check(); + + const I& text_ima = exact(text_ima_); + const J& bin_text_ima = exact(bin_text_ima_); + + mln_concrete(J) skel = internal::compute_skeleton(bin_text_ima); + + value::int_u8 nlabels = 0; + mln_ch_value(J,value::int_u8) lbl = labeling::blobs(skel, c8(), nlabels); + + util::array<algebra::vec<3u, float> > res = + labeling::compute(accu::meta::stat::mean(), text_ima, lbl, nlabels); + + accu::stat::median_h<value::int_u12> m_val; + m_val.init(); + + mln_value(I) med_val; + for (unsigned int i = 1; i <= nlabels; ++i) + m_val.take(res[i][0]); + + med_val = m_val.to_result(); + + trace::exiting("scribo::estim::impl::font_color_grayscale"); + return med_val; + } + + } // end of namespace scribo::estim::impl + + + // DISPATCH + + namespace internal + { + + template <typename I, typename J> + mln_value(I) + font_color_dispatch(const value::rgb8&, + const Image<I>& text_ima, const Image<J>& bin_text_ima) + { + return impl::font_color_rgb(exact(text_ima), exact(bin_text_ima)); + } + + + template <typename V, typename I, typename J> + mln_value(I) + font_color_dispatch(const V&, + const Image<I>& text_ima, const Image<J>& bin_text_ima) + { + return impl::font_color_grayscale(exact(text_ima), exact(bin_text_ima)); + } + + + template <typename I, typename J> + mln_value(I) + font_color_dispatch(const Image<I>& text_ima, const Image<J>& bin_text_ima) + { + return font_color_dispatch(mln_value(I)(), text_ima, bin_text_ima); + } + + } // end of namespace scribo::estim::internal + + + // FACADE + + template <typename I, typename J> + mln_value(I) + font_color(const Image<I>& text_ima, const Image<J>& bin_text_ima) + { + trace::entering("scribo::estim::font_color"); + + mln_value(I) output = internal::font_color_dispatch(text_ima, bin_text_ima); + + trace::exiting("scribo::estim::font_color"); + return output; + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace scribo::estim + +} // end of namespace scribo + +# endif // ! SCRIBO_ESTIM_FONT_COLOR_HH diff --git a/scribo/scribo/estim/internal/compute_skeleton.hh b/scribo/scribo/estim/internal/compute_skeleton.hh new file mode 100644 index 0000000..52ecf01 --- /dev/null +++ b/scribo/scribo/estim/internal/compute_skeleton.hh @@ -0,0 +1,112 @@ +// Copyright (C) 2011 EPITA Research and Development Laboratory (LRDE) +// +// This file is part of Olena. +// +// Olena is free software: you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, version 2 of the License. +// +// Olena is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Olena. If not, see <
http://www.gnu.org/licenses/
>. +// +// As a special exception, you may use this file as part of a free +// software project without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to produce +// an executable, this file does not by itself cause the resulting +// executable to be covered by the GNU General Public License. This +// exception does not however invalidate any other reasons why the +// executable file might be covered by the GNU General Public License. + +#ifndef SCRIBO_ESTIM_INTERNAL_COMPUTE_SKELETON_HH +# define SCRIBO_ESTIM_INTERNAL_COMPUTE_SKELETON_HH + +/// \file +/// +/// \brief Compute a skeleton useful for font estimations. + + +# include <mln/core/image/image2d.hh> +# include <mln/core/alias/neighb2d.hh> +# include <mln/topo/skeleton/crest.hh> +# include <mln/topo/skeleton/is_simple_point.hh> +# include <mln/transform/distance_front.hh> +# include <mln/logical/not.hh> +# include <mln/make/w_window2d_int.hh> +# include <mln/value/int_u8.hh> +# include <mln/arith/revert.hh> +# include <mln/morpho/skeleton_constrained.hh> +# include <mln/core/routine/extend.hh> +# include <mln/labeling/blobs.hh> +# include <mln/accu/stat/mean.hh> +# include <mln/value/rgb8.hh> + + +namespace scribo +{ + + namespace estim + { + + namespace internal + { + using namespace mln; + + + /// \brief Compute a skeleton useful for font estimations. + // + template <typename I> + mln_concrete(I) + compute_skeleton(const Image<I>& input); + + +# ifndef MLN_INCLUDE_ONLY + + template <typename I> + mln_concrete(I) + compute_skeleton(const Image<I>& input_) + { + trace::entering("scribo::estim::internal::compute_skeleton"); + + const I& input = exact(input_); + mlc_is(mln_value(I), bool)::check(); + mln_precondition(input.is_valid()); + + int psi = 7; + int vals[] = { 0, 9, 0, 9, 0, + 9, 6, 4, 6, 9, + 0, 4, 0, 4, 0, + 9, 6, 4, 6, 9, + 0, 9, 0, 9, 0 }; + + mln_ch_value(I,value::int_u8) + dist = transform::distance_front(logical::not_(input), c8(), + mln::make::w_window2d_int(vals), + mln_max(value::int_u8)); + + mln_ch_value(I,value::int_u8) dist_map = arith::revert(dist); + mln_concrete(I) K = topo::skeleton::crest(input, dist, c8(), psi); + + mln_concrete(I) skel = + morpho::skeleton_constrained(input, c8(), + topo::skeleton::is_simple_point<I,neighb2d>, + extend(K, false), dist_map); + + trace::exiting("scribo::estim::internal::compute_skeleton"); + return skel; + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace scribo::estim::internal + + } // end of namespace scribo::estim + +} // end of namespace scribo + +#endif // ! SCRIBO_ESTIM_INTERNAL_COMPUTE_SKELETON_HH diff --git a/scribo/scribo/io/xml/internal/extended_page_xml_visitor.hh b/scribo/scribo/io/xml/internal/extended_page_xml_visitor.hh index 44d8342..b906a4a 100644 --- a/scribo/scribo/io/xml/internal/extended_page_xml_visitor.hh +++ b/scribo/scribo/io/xml/internal/extended_page_xml_visitor.hh @@ -234,7 +234,10 @@ namespace scribo << "\" kerning=\"" << lines(fid).char_space(); // EXTENSIONS - Not officially supported - output << "\" baseline=\"" << lines(fid).baseline() + // FIXME: add boldness? + output << "\" color=\"" << parset(p).color() + << "\" color_reliability=\"" << parset(p).color_reliability() + << "\" baseline=\"" << lines(fid).baseline() << "\" meanline=\"" << lines(fid).meanline() << "\" x_height=\"" << lines(fid).x_height() << "\" d_height=\"" << lines(fid).d_height() @@ -271,6 +274,10 @@ namespace scribo output << " <line "; output << "id=\"" << line.id() + << "\" boldness=\"" << line.boldness() + << "\" boldness_reliability=\"" << line.boldness_reliability() + << "\" color=\"" << line.color() + << "\" color_reliability=\"" << line.color_reliability() << "\" txt_orientation=\"" << line.orientation() << "\" txt_reading_orientation=\"" << line.reading_orientation() << "\" txt_reading_direction=\"" << line.reading_direction() diff --git a/scribo/scribo/io/xml/internal/full_xml_visitor.hh b/scribo/scribo/io/xml/internal/full_xml_visitor.hh index 28f43e9..bba7691 100644 --- a/scribo/scribo/io/xml/internal/full_xml_visitor.hh +++ b/scribo/scribo/io/xml/internal/full_xml_visitor.hh @@ -251,20 +251,21 @@ namespace scribo output << " <component_set nelements=\"" << comp_set.nelements() << "\">" << std::endl; for_all_comps(c, comp_set) - { - output << " <component_info" - << " id=\"" << comp_set(c).id() - << "\" mass_center_x=\"" << comp_set(c).mass_center().col() - << "\" mass_center_y=\"" << comp_set(c).mass_center().row() - << "\" card=\"" << comp_set(c).card() - << "\" tag=\"" << comp_set(c).tag() - << "\" type=\"" << comp_set(c).type() - << "\" pmin_x=\"" << comp_set(c).bbox().pmin().col() - << "\" pmin_y=\"" << comp_set(c).bbox().pmin().row() - << "\" pmax_x=\"" << comp_set(c).bbox().pmax().col() - << "\" pmax_y=\"" << comp_set(c).bbox().pmax().row() - << "\"/>" << std::endl; - } + if (comp_set(c).is_valid()) + { + output << " <component_info" + << " id=\"" << comp_set(c).id() + << "\" mass_center_x=\"" << comp_set(c).mass_center().col() + << "\" mass_center_y=\"" << comp_set(c).mass_center().row() + << "\" card=\"" << comp_set(c).card() + << "\" tag=\"" << comp_set(c).tag() + << "\" type=\"" << comp_set(c).type() + << "\" pmin_x=\"" << comp_set(c).bbox().pmin().col() + << "\" pmin_y=\"" << comp_set(c).bbox().pmin().row() + << "\" pmax_x=\"" << comp_set(c).bbox().pmax().col() + << "\" pmax_y=\"" << comp_set(c).bbox().pmax().row() + << "\"/>" << std::endl; + } // Save labeled image @@ -426,6 +427,10 @@ namespace scribo output << " <line " << std::endl; output << "id=\"" << line.id() + << "\" boldness=\"" << line.boldness() + << "\" boldness_reliability=\"" << line.boldness_reliability() + << "\" color=\"" << line.color() + << "\" color_reliability=\"" << line.color_reliability() << "\" txt_orientation=\"" << line.orientation() << "\" txt_reading_orientation=\"" << line.reading_orientation() << "\" txt_reading_direction=\"" << line.reading_direction() diff --git a/scribo/scribo/primitive/extract/components.hh b/scribo/scribo/primitive/extract/components.hh index 849dd7b..fe2b523 100644 --- a/scribo/scribo/primitive/extract/components.hh +++ b/scribo/scribo/primitive/extract/components.hh @@ -48,6 +48,7 @@ # include <mln/extension/fill.hh> # include <scribo/core/component_set.hh> +# include <scribo/estim/components_features.hh> @@ -73,51 +74,64 @@ namespace scribo /// /// \return An image of labeled components. // + template <typename I, typename J, typename N, typename V> + inline + component_set<mln_ch_value(I,V)> + components(const Image<I>& input, const Image<J>& binary_input, + const Neighborhood<N>& nbh, V& ncomponents, + component::Type type = component::Undefined); + + template <typename I, typename N, typename V> inline component_set<mln_ch_value(I,V)> - components(const Image<I>& input, + components(const Image<I>& binary_input, const Neighborhood<N>& nbh, V& ncomponents, component::Type type = component::Undefined); # ifndef MLN_INCLUDE_ONLY - - namespace internal + template <typename I, typename J, typename N, typename V> + inline + component_set<mln_ch_value(I,V)> + components(const Image<I>& input, const Image<J>& binary_input, + const Neighborhood<N>& nbh, V& ncomponents, + component::Type type = component::Undefined) { + trace::entering("scribo::components"); - template <typename I, typename N, typename V> - inline - void - components_tests(const Image<I>& input, - const Neighborhood<N>& nbh, V& ncomponents, - component::Type type) - { - mlc_equal(mln_value(I),bool)::check(); + mlc_equal(mln_value(J),bool)::check(); // mlc_is_a(V, mln::value::Symbolic)::check(); - mln_precondition(exact(input).is_valid()); - mln_precondition(exact(nbh).is_valid()); - (void) input; - (void) nbh; - (void) ncomponents; - (void) type; - } + mln_precondition(exact(input).is_valid()); + mln_precondition(exact(binary_input).is_valid()); + mln_precondition(exact(nbh).is_valid()); + typedef mln_ch_value(I,V) L; + component_set<L> + output = extract::components(binary_input, nbh, ncomponents, type); - } // end of namespace scribo::primitive::extract::internal + output = estim::components_features(input, binary_input, output); + + trace::exiting("scribo::components"); + return output; + } template <typename I, typename N, typename V> inline component_set<mln_ch_value(I,V)> - components(const Image<I>& input, + components(const Image<I>& binary_input, const Neighborhood<N>& nbh, V& ncomponents, component::Type type = component::Undefined) { trace::entering("scribo::components"); - internal::components_tests(input, nbh, ncomponents, type); + mlc_equal(mln_value(I),bool)::check(); +// mlc_is_a(V, mln::value::Symbolic)::check(); + mln_precondition(exact(binary_input).is_valid()); + mln_precondition(exact(nbh).is_valid()); + typedef mln_ch_value(I,V) L; typedef mln::accu::shape::bbox<mln_site(L)> bbox_accu_t; @@ -125,14 +139,15 @@ namespace scribo typedef mln::accu::pair<bbox_accu_t, center_accu_t> pair_accu_t; // Setting extension value. - extension::fill(input, 0); + extension::fill(binary_input, false); mln::util::couple<L, - mln::util::couple<mln::util::array<mln_result(pair_accu_t)>, - mln::util::array<pair_accu_t> > > - - results = labeling::value_and_compute(input, true, nbh, ncomponents, - pair_accu_t()); + mln::util::couple< + mln::util::array<mln_result(pair_accu_t)>, + mln::util::array<pair_accu_t> > > + results = labeling::value_and_compute(binary_input, true, nbh, + ncomponents, + pair_accu_t()); component_set<L> output(results.first(), ncomponents, results.second().second(), type); @@ -141,6 +156,7 @@ namespace scribo return output; } + # endif // ! MLN_INCLUDE_ONLY } // end of namespace scribo::primitive::extract diff --git a/scribo/scribo/text/extract_lines.hh b/scribo/scribo/text/extract_lines.hh index 53fd742..3e9254a 100644 --- a/scribo/scribo/text/extract_lines.hh +++ b/scribo/scribo/text/extract_lines.hh @@ -81,6 +81,12 @@ namespace scribo extract_lines(const Image<I>& input, const Neighborhood<N>& nbh); + /// \overload + template <typename L> + line_set<mln_ch_value(L,scribo::def::lbl_type)> + extract_lines(const component_set<L>& input); + + # ifndef MLN_INCLUDE_ONLY @@ -119,6 +125,22 @@ namespace scribo if (exact(separators).is_valid()) comps.add_separators(separators); + line_set<mln_ch_value(I,scribo::def::lbl_type)> + lines = extract_lines(comps); + + trace::exiting("scribo::text::extract_lines"); + return lines; + } + + + template <typename L> + line_set<mln_ch_value(L,scribo::def::lbl_type)> + extract_lines(const component_set<L>& comps) + { + trace::entering("scribo::text::extract_lines"); + + mln_precondition(comps.is_valid()); + /// Linking potential comps object_links<L> left_link = primitive::link::with_single_left_link_dmax_ratio( diff --git a/scribo/scribo/text/extract_lines_with_features.hh b/scribo/scribo/text/extract_lines_with_features.hh new file mode 100644 index 0000000..fd413eb --- /dev/null +++ b/scribo/scribo/text/extract_lines_with_features.hh @@ -0,0 +1,131 @@ +// Copyright (C) 2011 EPITA Research and Development Laboratory (LRDE) +// +// This file is part of Olena. +// +// Olena is free software: you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, version 2 of the License. +// +// Olena is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Olena. If not, see <
http://www.gnu.org/licenses/
>. +// +// As a special exception, you may use this file as part of a free +// software project without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to produce +// an executable, this file does not by itself cause the resulting +// executable to be covered by the GNU General Public License. This +// exception does not however invalidate any other reasons why the +// executable file might be covered by the GNU General Public License. + +#ifndef SCRIBO_TEXT_EXTRACT_LINES_WITH_FEATURES_HH +# define SCRIBO_TEXT_EXTRACT_LINES_WITH_FEATURES_HH + +/// \file +/// +/// Extract line of text bounding boxes. + + +# include <mln/core/concept/image.hh> + +# include <scribo/text/extract_lines.hh> + + +namespace scribo +{ + + namespace text + { + + using namespace mln; + + /// Extract lines of text in a binary image. + /*! + ** \param[in] input Original color image. + ** \param[in] input_binary A binary image. + ** \param[in] nbh A neighborhood used for labeling. + ** \param[in] separators A binary image with separator information. + ** + ** \return A set of lines. + */ + template <typename I, typename J, typename N> + line_set<mln_ch_value(I,scribo::def::lbl_type)> + extract_lines_with_features(const Image<I>& input, + const Image<J>& input_binary, + const Neighborhood<N>& nbh, + const mln_ch_value(I,bool)& separators); + + + /// \overload + template <typename I, typename J, typename N> + line_set<mln_ch_value(I,scribo::def::lbl_type)> + extract_lines_with_features(const Image<I>& input, + const Image<J>& input_binary, + const Neighborhood<N>& nbh); + + +# ifndef MLN_INCLUDE_ONLY + + + template <typename I, typename J, typename N> + line_set<mln_ch_value(I,scribo::def::lbl_type)> + extract_lines_with_features(const Image<I>& input, + const Image<J>& input_binary, + const Neighborhood<N>& nbh) + { + mln_ch_value(I,bool) seps; + return extract_lines_with_features(input, input_binary, nbh, seps); + } + + + template <typename I, typename J, typename N> + line_set<mln_ch_value(I,scribo::def::lbl_type)> + extract_lines_with_features(const Image<I>& input_, + const Image<J>& input_binary_, + const Neighborhood<N>& nbh_, + const mln_ch_value(I,bool)& separators) + { + trace::entering("scribo::text::extract_lines_with_features"); + + const I& input = exact(input_); + const J& input_binary = exact(input_binary_); + const N& nbh = exact(nbh_); + + mln_precondition(input.is_valid()); + mln_precondition(input_binary.is_valid()); + mln_precondition(nbh.is_valid()); + + /// Finding comps. + typedef mln_ch_value(I,scribo::def::lbl_type) L; + scribo::def::lbl_type ncomps; + component_set<L> + comps = scribo::primitive::extract::components(input, input_binary, + nbh, ncomps); + + /// First filtering. + comps = scribo::filter::components_small(comps, 3); + + /// Use separators. + if (exact(separators).is_valid()) + comps.add_separators(separators); + + line_set<mln_ch_value(I,scribo::def::lbl_type)> + lines = extract_lines(comps); + + trace::exiting("scribo::text::extract_lines_with_features"); + return lines; + } + + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace scribo::text + +} // end of namespace scribo + +#endif // ! SCRIBO_TEXT_EXTRACT_LINES_WITH_FEATURES_HH diff --git a/scribo/scribo/toolchain/internal/content_in_doc_functor.hh b/scribo/scribo/toolchain/internal/content_in_doc_functor.hh index 624a54e..0a920a6 100644 --- a/scribo/scribo/toolchain/internal/content_in_doc_functor.hh +++ b/scribo/scribo/toolchain/internal/content_in_doc_functor.hh @@ -254,7 +254,8 @@ namespace scribo V ncomponents; component_set<L> - components = scribo::primitive::extract::components(input_cleaned, + components = scribo::primitive::extract::components(original_image, + input_cleaned, c8(), ncomponents); diff --git a/scribo/src/debug/Makefile.am b/scribo/src/debug/Makefile.am index 60d7afa..be8bb78 100644 --- a/scribo/src/debug/Makefile.am +++ b/scribo/src/debug/Makefile.am @@ -22,6 +22,7 @@ noinst_PROGRAMS = \ show_groups_bboxes \ show_info_x_height \ show_info_median_inter_characters \ + show_lines_boldness \ show_separators \ show_links_left_right_links_validation \ show_links_bbox_h_ratio \ @@ -54,6 +55,7 @@ show_components_bboxes_SOURCES = show_components_bboxes.cc show_groups_bboxes_SOURCES = show_groups_bboxes.cc show_info_x_height_SOURCES = show_info_x_height.cc show_info_median_inter_characters_SOURCES = show_info_median_inter_characters.cc +show_lines_boldness_SOURCES = show_lines_boldness.cc show_separators_SOURCES = show_separators.cc show_links_left_right_links_validation_SOURCES = show_links_left_right_links_validation.cc show_links_bbox_h_ratio_SOURCES = show_links_bbox_h_ratio.cc @@ -83,6 +85,20 @@ show_objects_thin_SOURCES = show_objects_thin.cc if HAVE_MAGICKXX + noinst_PROGRAMS += show_components_color + show_components_color_SOURCES = show_components_color.cc + show_components_color_CPPFLAGS = $(AM_CPPFLAGS) \ + $(MAGICKXX_CPPFLAGS) + show_components_color_LDFLAGS = $(AM_LDFLAGS) \ + $(MAGICKXX_LDFLAGS) + + noinst_PROGRAMS += show_components_boldness + show_components_boldness_SOURCES = show_components_boldness.cc + show_components_boldness_CPPFLAGS = $(AM_CPPFLAGS) \ + $(MAGICKXX_CPPFLAGS) + show_components_boldness_LDFLAGS = $(AM_LDFLAGS) \ + $(MAGICKXX_LDFLAGS) + if HAVE_QT noinst_PROGRAMS += show_paragraph_blocks diff --git a/scribo/src/debug/show_components_boldness.cc b/scribo/src/debug/show_components_boldness.cc new file mode 100644 index 0000000..f9aca3f --- /dev/null +++ b/scribo/src/debug/show_components_boldness.cc @@ -0,0 +1,72 @@ +// Copyright (C) 2011 EPITA Research and Development Laboratory (LRDE) +// +// This file is part of Olena. +// +// Olena is free software: you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, version 2 of the License. +// +// Olena is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Olena. If not, see <
http://www.gnu.org/licenses/
>. + +#include <mln/core/image/image2d.hh> +#include <mln/core/alias/neighb2d.hh> +#include <mln/core/image/dmorph/image_if.hh> +#include <mln/pw/all.hh> +#include <mln/io/pbm/load.hh> +#include <mln/io/ppm/save.hh> +#include <mln/io/magick/load.hh> +#include <mln/value/int_u.hh> +#include <mln/literal/colors.hh> +#include <mln/draw/box.hh> + +#include <scribo/core/component_set.hh> +#include <scribo/primitive/extract/components.hh> + +int main(int argc, char *argv[]) +{ + using namespace mln; + using namespace scribo; + + if (argc != 4) + { + std::cerr << "Usage : " << argv[0] << " input.* input.pbm out.pgm" << std::endl; + return 1; + } + + Magick::InitializeMagick(0); + + typedef mln::value::int_u<30> V; + typedef image2d<V> L; + + image2d<value::rgb8> input; + io::magick::load(input, argv[1]); + + image2d<bool> input_bin; + io::pbm::load(input_bin, argv[2]); + + V ncomponents; + component_set<L> + components = scribo::primitive::extract::components(input, input_bin, c8(), + ncomponents); + + image2d<value::int_u8> output; + initialize(output, input); + data::fill(output, 0); + + const L& lbl = components.labeled_image(); + for_all_comps(c, components) + if (components(c).is_valid()) + { + data::fill(((output | components(c).bbox()).rw() + | (pw::value(lbl) == pw::cst(c))).rw(), + components(c).features().boldness); + } + + io::pgm::save(output, argv[3]); +} diff --git a/scribo/src/debug/show_components_color.cc b/scribo/src/debug/show_components_color.cc new file mode 100644 index 0000000..a13b85b --- /dev/null +++ b/scribo/src/debug/show_components_color.cc @@ -0,0 +1,73 @@ +// Copyright (C) 2010, 2011 EPITA Research and Development Laboratory +// (LRDE) +// +// This file is part of Olena. +// +// Olena is free software: you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, version 2 of the License. +// +// Olena is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Olena. If not, see <
http://www.gnu.org/licenses/
>. + +#include <mln/core/image/image2d.hh> +#include <mln/core/alias/neighb2d.hh> +#include <mln/core/image/dmorph/image_if.hh> +#include <mln/pw/all.hh> +#include <mln/io/pbm/load.hh> +#include <mln/io/ppm/save.hh> +#include <mln/io/magick/load.hh> +#include <mln/value/int_u.hh> +#include <mln/literal/colors.hh> +#include <mln/draw/box.hh> + +#include <scribo/core/component_set.hh> +#include <scribo/primitive/extract/components.hh> + +int main(int argc, char *argv[]) +{ + using namespace mln; + using namespace scribo; + + if (argc != 4) + { + std::cerr << "Usage : " << argv[0] << " input.* input.pbm out.ppm" << std::endl; + return 1; + } + + Magick::InitializeMagick(0); + + typedef mln::value::int_u<30> V; + typedef image2d<V> L; + + image2d<value::rgb8> input; + io::magick::load(input, argv[1]); + + image2d<bool> input_bin; + io::pbm::load(input_bin, argv[2]); + + V ncomponents; + component_set<L> + components = scribo::primitive::extract::components(input, input_bin, c8(), + ncomponents); + + image2d<value::rgb8> output; + initialize(output, input); + data::fill(output, literal::white); + + const L& lbl = components.labeled_image(); + for_all_comps(c, components) + if (components(c).is_valid()) + { + data::fill(((output | components(c).bbox()).rw() + | (pw::value(lbl) == pw::cst(c))).rw(), + components(c).features().color); + } + + io::ppm::save(output, argv[3]); +} diff --git a/scribo/src/debug/show_lines_boldness.cc b/scribo/src/debug/show_lines_boldness.cc new file mode 100644 index 0000000..a3815c0 --- /dev/null +++ b/scribo/src/debug/show_lines_boldness.cc @@ -0,0 +1,199 @@ +// Copyright (C) 2011 EPITA Research and Development Laboratory (LRDE) +// +// This file is part of Olena. +// +// Olena is free software: you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, version 2 of the License. +// +// Olena is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Olena. If not, see <
http://www.gnu.org/licenses/
>. +// +// As a special exception, you may use this file as part of a free +// software project without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to produce +// an executable, this file does not by itself cause the resulting +// executable to be covered by the GNU General Public License. This +// exception does not however invalidate any other reasons why the +// executable file might be covered by the GNU General Public License. + +#include <iostream> + +#include <mln/core/image/image2d.hh> +#include <mln/io/pbm/load.hh> +#include <mln/value/int_u16.hh> +#include <mln/draw/box_plain.hh> +#include <mln/pw/all.hh> +#include <mln/core/image/dmorph/image_if.hh> +#include <mln/data/convert.hh> +#include <mln/literal/colors.hh> + +#include <scribo/text/recognition.hh> + +#include <scribo/debug/usage.hh> + +#include <scribo/core/document.hh> +#include <scribo/core/component_set.hh> +#include <scribo/core/object_links.hh> +#include <scribo/core/object_groups.hh> + +#include <scribo/text/extract_lines_with_features.hh> +#include <scribo/estim/components_features.hh> + +#include <scribo/io/xml/save.hh> + + +const char *args_desc[][2] = +{ + {0, 0} +}; + + + +int main(int argc, char* argv[]) +{ + using namespace scribo; + using namespace mln; + + if (argc != 3) + return scribo::debug::usage(argv, + "Show text lines", + "input.pbm out_prefix", + args_desc); + + trace::entering("main"); + + image2d<bool> input; + mln::io::pbm::load(input, argv[1]); + + std::string prefix = argv[2]; + + typedef image2d<scribo::def::lbl_type> L; + + // Extract lines + line_set<L> + lines = text::extract_lines_with_features( + data::convert(value::rgb8(), input), input, c8()); + const component_set<L>& comp_set = lines.components(); + + mln::math::round<unsigned> round; + + // Min boldness / line + { + image2d<value::int_u8> min_boldness; + initialize(min_boldness, input); + + data::fill(min_boldness, 0); + for_all_lines(l, lines) + if (lines(l).is_textline()) + { + float min = 65000; + + // Compute min + for_all_line_comps(cid, lines(l).component_ids()) + { + unsigned id = lines(l).component_ids()(cid); + if (comp_set(id).features().boldness < min) + min = comp_set(id).features().boldness; + } + + // Draw + for_all_line_comps(cid, lines(l).component_ids()) + { + unsigned id = lines(l).component_ids()(cid); + data::fill(((min_boldness | comp_set(id).bbox()).rw() + | (pw::value(comp_set.labeled_image()) == pw::cst(id))).rw(), round(min)); + } + + } + + mln::io::pgm::save(min_boldness, prefix + "_min_boldness.pgm"); + } + + // Max boldness / line + { + image2d<value::int_u8> max_boldness; + initialize(max_boldness, input); + + data::fill(max_boldness, 0); + for_all_lines(l, lines) + if (lines(l).is_textline()) + { + float max = 65000; + + // Compute max + for_all_line_comps(cid, lines(l).component_ids()) + { + unsigned id = lines(l).component_ids()(cid); + if (comp_set(id).features().boldness < max) + max = comp_set(id).features().boldness; + } + + // Draw + for_all_line_comps(cid, lines(l).component_ids()) + { + unsigned id = lines(l).component_ids()(cid); + data::fill(((max_boldness | comp_set(id).bbox()).rw() + | (pw::value(comp_set.labeled_image()) == pw::cst(id))).rw(), round(max)); + } + + } + + mln::io::pgm::save(max_boldness, prefix + "_max_boldness.pgm"); + } + + + // Mean boldness / line + { + image2d<value::int_u8> min_boldness; + initialize(min_boldness, input); + + data::fill(min_boldness, 0); + for_all_lines(l, lines) + if (lines(l).is_textline()) + { + // Draw + for_all_line_comps(cid, lines(l).component_ids()) + { + unsigned id = lines(l).component_ids()(cid); + data::fill(((min_boldness | comp_set(id).bbox()).rw() + | (pw::value(comp_set.labeled_image()) == pw::cst(id))).rw(), round(lines(l).boldness())); + } + + } + + mln::io::pgm::save(min_boldness, prefix + "_mean_boldness.pgm"); + } + + // Stddev boldness / line + { + image2d<value::int_u8> min_boldness; + initialize(min_boldness, input); + + data::fill(min_boldness, 0); + for_all_lines(l, lines) + if (lines(l).is_textline()) + { + // Draw + for_all_line_comps(cid, lines(l).component_ids()) + { + unsigned id = lines(l).component_ids()(cid); + data::fill(((min_boldness | comp_set(id).bbox()).rw() + | (pw::value(comp_set.labeled_image()) == pw::cst(id))).rw(), round(lines(l).boldness_reliability())); + } + + } + + mln::io::pgm::save(min_boldness, prefix + "_stddev_boldness.pgm"); + } + + + trace::exiting("main"); +} + diff --git a/scribo/tests/Makefile.am b/scribo/tests/Makefile.am index 09768b1..1f227b7 100644 --- a/scribo/tests/Makefile.am +++ b/scribo/tests/Makefile.am @@ -1,5 +1,5 @@ -# Copyright (C) 2009, 2010 EPITA Research and Development Laboratory -# (LRDE). +# Copyright (C) 2009, 2010, 2011 EPITA Research and Development +# Laboratory (LRDE). # # This file is part of Olena. # @@ -31,6 +31,7 @@ SUBDIRS = \ binarization \ convert \ core \ + estim \ filter \ preprocessing \ primitive \ diff --git a/scribo/tests/estim/Makefile.am b/scribo/tests/estim/Makefile.am new file mode 100644 index 0000000..1c39ab6 --- /dev/null +++ b/scribo/tests/estim/Makefile.am @@ -0,0 +1,29 @@ +# Copyright (C) 2011 EPITA Research and Development Laboratory (LRDE). +# +# This file is part of Olena. +# +# Olena is free software: you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free +# Software Foundation, version 2 of the License. +# +# Olena is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Olena. If not, see <
http://www.gnu.org/licenses/
>. +# + +## Process this file through Automake to create Makefile.in. + +include $(top_srcdir)/scribo/tests/tests.mk + +check_PROGRAMS = \ + font_color \ + font_boldness + +font_color_SOURCES = font_color.cc +font_boldness_SOURCES = font_boldness.cc + +TESTS = $(check_PROGRAMS) diff --git a/scribo/tests/estim/font_boldness.cc b/scribo/tests/estim/font_boldness.cc new file mode 100644 index 0000000..9e85795 --- /dev/null +++ b/scribo/tests/estim/font_boldness.cc @@ -0,0 +1,46 @@ +// Copyright (C) 2011 EPITA Research and Development Laboratory (LRDE). +// +// This file is part of Olena. +// +// Olena is free software: you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, version 2 of the License. +// +// Olena is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Olena. If not, see <
http://www.gnu.org/licenses/
>. + +/// \file + +#include <cstdio> +#include <cstdlib> + +#include <mln/core/image/image2d.hh> +#include <mln/data/compare.hh> + +#include <mln/io/ppm/load.hh> +#include <mln/io/pbm/load.hh> + +#include <mln/value/rgb8.hh> + +#include <scribo/estim/font_boldness.hh> + +#include "tests/data.hh" + +using namespace mln; + +int main() +{ + image2d<bool> input; + io::pbm::load(input, SCRIBO_IMG_DIR "/phillip.pbm"); + + float val = scribo::estim::font_boldness(input); + + mln_assertion(((int)(val * 100) / 100.f) == 18.44f); + + return 0; +} diff --git a/scribo/tests/estim/font_color.cc b/scribo/tests/estim/font_color.cc new file mode 100644 index 0000000..45c453d --- /dev/null +++ b/scribo/tests/estim/font_color.cc @@ -0,0 +1,48 @@ +// Copyright (C) 2011 EPITA Research and Development Laboratory (LRDE). +// +// This file is part of Olena. +// +// Olena is free software: you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, version 2 of the License. +// +// Olena is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Olena. If not, see <
http://www.gnu.org/licenses/
>. + +/// \file + +#include <cstdio> +#include <cstdlib> + +#include <mln/core/image/image2d.hh> +#include <mln/data/compare.hh> + +#include <mln/io/ppm/load.hh> +#include <mln/io/pbm/load.hh> + +#include <mln/value/rgb8.hh> + +#include <scribo/estim/font_color.hh> + +#include "tests/data.hh" + +using namespace mln; + +int main() +{ + image2d<value::rgb8> input_rgb; + io::ppm::load(input_rgb, SCRIBO_IMG_DIR "/phillip.ppm"); + image2d<bool> input_bin; + io::pbm::load(input_bin, SCRIBO_IMG_DIR "/phillip.pbm"); + + value::rgb8 val = scribo::estim::font_color(input_rgb, input_bin); + + mln_assertion(val == value::rgb8(77, 146, 140)); + + return 0; +} diff --git a/scribo/tests/img/phillip.pbm b/scribo/tests/img/phillip.pbm new file mode 100644 index 0000000000000000000000000000000000000000..ed60f945bbe7a0bf176fcb69695be9ed2ab9ac47 GIT binary patch literal 1633 zcmdth&x#W<90%}(912C4M@YbnUb-&G`sZK}b`fEPW$^)=wIjPw+fs|TAZGT>=27As z<d{Qj{Qi=ecE(mudND&v=ab+3GWlh4@pyb+y{hKbs$5r7b#<%W+{~(Zsg5U)l)7H8 zm(P!m79^9|YFbUI<;}XBd|2VBvy0bnU#iRMQ&q0sU#oIHRj1YGYPMK@tmbQVUS2Jb zbg{Zs56&-7&mNACpPZ<ZXXE&vwI6%y@g_zay$L$V-Jpdw#u}?#k=3&zHuzg>xOSsX z`9WnnHM>}5+6>6usbfsnDQ|s18$;^bcW_0WVr?Yt-q*=S-=){7;a#)RN}g`+`l^4U zI>+*1tQJlq2al9LYy^I-wpuiW<xn1&ww|7Zz7RF3h}<*XEE%+cGB#>Bo=p0V8LDgZ zZJ;b`om6aac~q)Z_LY4Zks(KIno&&|p0dC^DLUno4YXz~@BpDss<ZNt<QEmB`NEo! zIb|rq$fF1Jo@$?zMo5u6M#iEqNQN4BTA*q<78OFQ3>05b-BO06PSOZAxYZ4*B&D7; zMyw~goeESLJ3UaDE3{QjSzOk;R<+Yk;^WPVnF8`+>-q}8Dtn5$Q9bvRYPVJ6@L@R# z6TZ`Qe5`QTlfda1Q9QQAU`Em+Fea%oeML2JAhsHD1QDCmw2Gr;jT1g87SU_@o%}sa fwAZ>rG#qepc%Se7g6czg?Y~lUXtwW%@K5#=Ut6W* literal 0 HcmV?d00001 diff --git a/scribo/tests/img/phillip.ppm b/scribo/tests/img/phillip.ppm new file mode 100644 index 0000000..d668fcf --- /dev/null +++ b/scribo/tests/img/phillip.ppm @@ -0,0 +1,5 @@ +P6 +# CREATOR: XV Version 3.10a Rev: 12/29/94 (PNG patch 1.2) +176 69 +255 +ýõóýôóýõñüóñýõòýõôýõóþõóÿøöÿùöÿù÷ÿùöÿ÷ôÿöôÿøôÿ÷ôÿøôÿùõÿùôÿùôÿùöÿù÷ÿøöÿ÷öÿøöÿú÷ÿúøÿúøÿùøÿúøÿúøÿùøÿù÷ÿüùÿüùÿû÷þøõýöôþ÷öÿùøÿù÷ÿúøÿûøÿûøÿûøÿýúÿýûÿþüÿþüÿþýÿþüÿýûÿþüÿþýÿÿþÿÿþÿÿýÿÿýÿþýÿþûÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿþÿÿþÿÿþþþýýüûÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþöóþõóýõñüôñýõòýõôýöôýöóÿøöÿùöÿùöÿøöÿøõÿøôþøôþ÷ôÿùôþøõþøóþ÷óÿùöÿù÷þøöþ÷õÿ÷õÿùõÿùöÿùöÿù÷ÿúøÿúøÿùøÿùøÿüøÿûøÿüøþúöýøöþø÷ÿúùÿúøÿúøÿúøþù÷ýöôÿúøÿûúÿþýÿþüÿýûÿýúÿýûÿþüÿþüÿýûÿÿþÿÿýÿÿýÿþýÿþüÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿþþÿþýÿþýÿþýÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýöóþôóþöóþöóþøõþ÷õýöóýõôÿ÷öÿúöÿù÷ÿøöÿøöÿ÷ôþøõþ÷õÿùöþ÷õþ÷óýöóÿøõÿú÷þùöþøôþ÷ôÿ÷õÿú÷ÿúøÿûùÿûùÿûùÿúùÿúùÿûøÿûøÿüùÿüùÿûøÿúøÿúùÿúùÿûøÿúøþù÷ý÷öÿúùÿüûÿþûÿþüÿýúÿýúÿýúÿýúÿüúÿûúÿþýÿþýÿÿýÿÿýÿÿýÿÿÿÿÿÿÿÿþÿÿþÿÿþÿÿþÿÿÿÿÿþÿþþÿþýÿþýÿþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿþýÿþýÿþýÿýýÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿþþÿþþÿÿÿÿÿÿÿþþÿþþÿÿÿÿÿÿÿÿþÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿþýöôþöôþ÷ôÿ÷óÿù÷ÿù÷þøõþ÷õÿ÷õÿùöÿù÷ÿùöÿøöÿ÷õþøõþ÷ôÿøõÿùöþùõý÷ôÿ÷öÿú÷þù÷þ÷õþ÷õÿùøÿüúÿüúÿüúÿûúÿûúÿúùÿúøÿù÷ÿûùÿüùÿú÷ÿúøÿúøÿûùÿüùÿüùÿûúÿüúÿûùÿüûÿþüÿýûÿýûÿýúÿûùÿûùÿûùÿûùÿúùÿüûÿþýÿþýÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿÿÿÿÿÿþþÿþþÿÿÿÿÿÿÿÿÿÿÿþÿÿýÿÿýÿÿþÿþþÿþþÿþþÿþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþÿýýÿýþÿþþÿþþÿþþþþýþþþÿþþÿþþÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿþþ÷õþöõþøôÿöóÿùöÿù÷ÿùöÿøõÿøõÿùöÿù÷ÿù÷ÿøöÿùõþøôþöóÿùôÿùöÿúöÿùöÿùøÿûøþúøþ÷õþøõÿù÷ÿúùÿûøÿúøÿùøÿùøþøöþøöÿù÷ÿûùÿüùÿú÷ÿúøÿûøÿýúÿýùÿýùÿþüÿþüÿýûÿýüÿþüÿýûÿþûÿýúÿûùÿûùÿûùÿûùÿüúÿüûÿþýÿþýÿÿýÿÿýÿþýÿþýÿÿþÿÿþÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþÿýýÿûýÿþþþþþþýýþýýþûûÿýþÿþþÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿþõóÿ÷ôÿùôÿ÷ôÿùöÿùöÿùöÿùöÿøõÿùõÿù÷ÿøöÿøöÿùõþùôþ÷ôÿúöÿûøÿû÷ÿúöÿøöÿúøÿùøÿøöÿøöþøöþù÷ÿú÷þø÷þø÷ÿùøþùöþù÷ÿûøÿýùÿüùÿûøÿûùÿûùÿýûÿûùÿüúÿþüÿþüÿþüÿýûÿüúÿüùÿýûÿþúþûøý÷öÿøöÿüúÿýûÿýüÿþýÿÿýÿÿýÿþýÿþýÿþýÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþÿþýÿÿýÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿþÿÿÿÿþþÿþþÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿþÿþþÿþþÿþþþþþýûüþûüþýýþüýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýôòþõóÿøóÿ÷ôþùöþøõþøõþøöÿ÷õÿ÷ôÿ÷õÿøöÿøõÿùõÿùõÿùöÿú÷ÿúöÿùõÿøôÿ÷õþù÷þøöÿø÷ÿù÷þù÷þù÷ÿøöþøöþø÷ÿùøÿúøÿúùÿüùÿüùÿüùÿûùÿûúÿüúÿýúÿûùÿûùÿýûÿþüÿþûÿýûÿüúÿüúÿýûÿýúþûøý÷õþøöÿýûÿýûÿþýÿþýÿýûÿýûÿþýÿþýÿÿþÿÿþÿÿýÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿþÿÿþÿÿÿÿþþÿþýÿÿüÿÿüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþþÿÿþÿÿþÿÿþÿþþÿþþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿÿÿþþÿþþÿÿÿÿÿþÿþþÿþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿþþÿþýÿýýþýýüúûûúùþýýýûýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýöòüóòýõòÿöóþùöþøõþùõþøõÿöôþöóþöóÿ÷õÿ÷õÿøôÿùõÿùõÿùõÿùõþ÷óþ÷óþöôý÷ôý÷ôÿøöÿù÷ÿùöþøõþ÷ôýöôÿøöÿøøÿùøÿù÷ÿúøÿûùÿüùÿûùÿûùÿüùÿûúÿúùÿúøÿûùÿýûÿüúÿûúÿýüÿýûÿýúÿýúÿýúþüøþûøÿüùÿüùÿüøÿüöÿûõÿüúÿÿüÿÿþÿÿþÿÿþÿÿýÿþþÿþþÿþþÿþþÿþþÿþþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿþÿÿþÿÿþÿÿþÿÿýÿÿûÿþ÷ÿúôÿøòÿü÷ÿÿüÿÿþÿÿþÿÿþÿÿþÿÿÿÿÿþÿÿþÿÿÿÿþþÿþþÿþþÿþýÿýýÿþüÿüøÿúöÿøöÿýûÿÿþÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿýÿÿýÿÿþÿÿýÿÿüÿÿûÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿÿþÿÿýÿþüÿüùÿûõÿüôÿþøÿÿúÿÿþÿÿÿÿÿþÿþþÿþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþýýþûüýüüûùúûùùÿüüÿýþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿý÷óüõòüôòÿõôÿùõÿøõÿøõÿ÷ôþôòýôòþöóÿ÷õÿ÷õÿøõÿùõÿøõÿùõÿùöþùöýøôýõóûôòýöôÿù÷ÿùöþøõý÷óýöóüõóþøõþø÷ÿù÷ÿùöÿùöÿûùÿûùÿûùÿúùÿûùÿûùÿúùÿûùÿúúÿûúÿûúÿûúÿþýÿýüÿúùÿúùÿüùÿû÷ÿúóþöìýòãúìÙöäÒúïæÿûøÿýúÿþýÿÿþÿþýÿþýÿþþÿþþÿþþÿþþÿþþÿýþÿÿÿÿÿþÿÿþÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿþÿÿþÿÿþÿþûÿüôþøßûðË÷äË÷ÖÅûç×ÿòðÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿÿÿþþÿúúÿø÷ÿòðÿééþáÚýàÎûÞÄúßÖÿùóÿÿþÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿþÿÿýÿþüÿüûÿüøÿúòÿùåÿùßÿøÓÿøêÿÿüÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿÿþÿýûÿöîþëÕýÞÂýèœýîÓÿéÙÿûõÿþüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿþÿþþþüýýùúýüûûøúûøùÿüüÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøõÿøôþ÷óþöóþùôþøõÿøôÿ÷óþôòýõòÿ÷õÿ÷öÿøöÿøõÿøôÿøõÿùöÿú÷ÿú÷ÿùöýöóúñïûñîþòïþõðþõðýõïýôïþóîþôðþòñþõòþõñþöòþ÷öÿøöÿøöÿø÷ÿúùÿùøÿùøÿüúÿûûÿüûÿûúÿûúÿüûÿûúÿúùþùöüôí÷ëÞðâÕäÑÆÕŹş²µ¹ŽÓÚÚüú÷ÿýúÿþýÿÿýÿþüÿþûÿþþÿþþÿÿÿÿÿþÿþþÿýþÿþþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿþþÿýüÿÿþÿýûüôðòáÛÛÕÃŒ¶©§¶±ŠŠÉÅ»íÜÙÿùñÿþúÿÿþÿÿþÿÿþÿÿþÿÿþÿýüÿööýääùÒÍòÀÀêÉœÞÁ³Ì±¿À¯ÁÔÒðôôÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿþýþúöýìéúãäôçÛìÜÑãÚºÓͺÇɯÑËØÿüûÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿÿÿþÿýûþôïöçÔÛÍ®Á¿§³¯·ŽÓŽŽóîèÿ÷òÿÿþÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿþÿÿýÿÿýÿÿÿÿþþÿýýÿûýÿþýÿþþÿþþÿþþÿþýÿþýÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ôÿ÷óþ÷óýõóþøõþøôÿøôÿ÷õÿöõÿøõÿ÷õÿöõÿöôþ÷ôþ÷óÿøôÿøõÿù÷ÿøõþöóûíêöÛØôØÓ÷ÖÑ÷ßÖ÷ç×÷ê×øãÖ÷ØÏøÛÕ÷ÓÑ÷åØøäØøëÜúåâüíçþðîþõóÿøöþù÷þ÷öÿúøÿúúÿûúÿúúÿûúÿûúÿù÷þ÷ö÷ðíÞÔÌÀ³©§±Š€€|¢{¯šÀÕ×üú÷ÿþûÿþýÿþýÿþüÿþüÿÿþÿÿþÿÿÿÿÿÿÿþþÿþýÿþýÿþþÿÿþÿÿþÿÿÿÿÿþÿÿþÿþþÿþýÿþýüùôèàÓ¶°« ²šr€oªp§ªåãÃýøëÿþýÿþýÿþþÿþþÿÿýÿüúúìçäȹČ®«y|ÊÐêòöÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿÿþýûùóåßÖž»¹®¡³¢€x¡}µ¢§ÉÙúúúÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿÿþÿüúüçä뺷¹·Šr¢oi°¡v¥Š¹µæÉÇÿööÿþýÿþýÿþýÿþþÿûûÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿþÿÿþÿÿþÿÿÿÿÿÿÿþþÿþýÿþýÿþþÿÿýÿþýþüüþüüÿþýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþõóÿöóþ÷óýöóÿ÷ôÿøöÿøõÿøõÿøõÿ÷ôÿöôÿöôÿöóþöóþöóÿøôÿøõÿù÷ÿøõýôïñÝØ×µ°Åµ«Ç±ªÈ»²Ì¿±É¿Èµ¯Æ¬§Èž±Ê°ªÌIJϻ®Òįڷ³åοðÖÐ÷çÚûæãþóîýöôþ÷öÿúùÿúùÿúùÿúúþúúý÷÷úñðäÛÛ¡ŽŽsY`Uer²¬ÈÜÜýûøÿþûÿýüÿýýÿþýÿþýÿþþÿþþÿýýÿýýÿþþÿýýÿýýÿþþÿþþÿþýÿÿþÿÿþÿÿþÿÿÿÿÿþþüûôðìŸËÇqQTRYY}¬Å°íìâÿüüÿþþÿþþÿþþÿþýýüúïåâž²wmbeU¡n¢ÄÔïõùÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿþþûôôàÑѬ€dZ¢i aŠag¶ªµÛâýûúÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþýúøïÞÚ·§¥m©¢UL UJ `h¥ª°·òãêýö÷ÿýýÿþýÿüûÿûûÿÿÿÿÿþÿÿþÿÿþÿÿþÿÿþÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþýýþýüþýýÿþýÿýýþûüûùúÿûûÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýôòýôòþõóþõóþöóÿ÷õÿøôÿ÷ôÿøõÿ÷ôÿöôÿ÷õÿöôÿöóÿöóÿøõÿùöÿù÷þøöûóîâÙΡ€|}w|tz{|¡§Ž©¡ËœªâŸ¹öæÙûòðýôóý÷÷ÿ÷÷ÿ÷÷ÿøùþúúýø÷÷ìëÐÅÅx¡UFYTc¹ÙèâþûùÿþüÿýüÿüûÿþýÿþýÿþþÿþþÿýýÿýýÿþþÿýþÿþþÿþþÿþþÿþýÿÿþÿþþÿþþÿÿÿÿþýûõôßÐТ«QMWOZ Xk ªÍÙÖÿúûÿÿþÿþýÿþýÿýüûù÷àÝÛ§€a¡cVaYt¬ÇÕøùúÿýýÿûýÿûýÿþþÿþýÿüüùñòÍÌÉmš] XbZ`zº¡ÎååþûûÿüýÿýþÿþþÿþÿÿýþÿüüúõóÖÕΡTVS]JY ^€ÐÆÏûööÿýýÿþþÿýýÿýýÿþþÿþþÿþþÿþþÿþþÿÿþÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþýýþýüþýüþüüþûüþûýýûûÿüýÿÿþÿÿÿÿÿÿÿÿþÿÿþÿÿÿûòïüóñþõóþõóþöóÿöôÿ÷óÿöóÿöôÿ÷ôÿöôÿ÷õÿöõÿöôÿ÷óÿöôÿ÷õÿ÷öþ÷ô÷òíÓÙÌ}£UUHKGWR QRR P PT[i ÏÇœîØÕûîéýõöÿ÷øÿöøÿùùÿúùþøöóêåÁºµfTSYTY¿¶éñêþüúÿþûÿýûÿüûÿýûÿþýÿþþÿþþÿþýÿþýÿüüÿüþÿþþÿÿþÿÿýÿþýÿþýÿþþÿþþÿþýÿüûøôñËÏÌl¥X£RQRKR\i «ÍÒú÷ùÿþýÿýýÿþýþýüøóòÕÔ×~£§[X_bTk®§œÖÛýùúÿýýÿûúÿûýÿþþÿþýþüûóì윌ŸcVQJ¢IU¥¢°¯Üèêþüûÿüýÿýþÿýþÿýþÿüüþùùñå깎Â`¡ AI§<DBN\r« «ÃÑúõõÿþýÿþþÿþþÿýþÿþþÿþþÿþþÿþþÿþþÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿþþÿýýþýüþûüýüûýúüþýýÿüýÿýýÿþþÿþþÿþþÿþýÿÿþÿÿþúñîýóñþ÷óþ÷óÿ÷óÿ÷ôÿ÷óÿôóÿõóÿ÷óÿöôÿöôÿõôÿöôþ÷óþôóþõôþõôýôòòêèÀÈÃiNLB@DUKGGQ NQKVNZb¢À°°ñßÙýôôÿ÷øÿ÷øÿùúÿùùý÷ôîèÞŽŸ©aV]QOU¥¡ÉÈóöòÿýûÿþüÿýüÿüüÿýüÿþýÿþþÿýýÿýýÿþýÿüüÿüþÿýþÿýýÿüûÿüûÿûüÿÿþÿþþÿýýÿûûøöòÆ×Ïg V£HMYT SRgÆÌöõ÷ÿüüÿýýÿþýýûúòçè÷Án¡c_\R`m·ªÑããþúúÿüüÿùúÿûüÿüûÿûûþûùíðã©Â¬fc¢[BHU¢º±ëîíÿûúÿýþÿýýÿýýÿýþÿúüýøúìêì«ÁÂZ£RLMQ£QV£S]£ºÉöööÿþýÿüüÿûüÿýýÿýýÿþýÿÿýÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿþÿÿþþþþþüüýüûýûüýüüþüüÿüüÿüýÿýýÿþýÿþýÿÿþÿÿþúóðþôòÿ÷óÿ÷óþ÷óþöóþöóþõóÿ÷óÿöóÿöôÿöõÿöõÿøõþ÷ôþõóþõóýôóûòðëÞÞ¯š®YMKJEORSEFRNYRWDQI\ÎŒÂøîêýôõþöøÿøøþ÷÷ûóñäÛÓŽTLWMXZ«š²ÐØûù÷ÿýûÿþüÿýûÿüüÿûüÿþýÿþþÿýýÿüüÿüüÿýýÿýþÿþþÿýýÿüûÿüüÿýüÿÿþÿþþÿýýÿúúùøõÍàÞh¥®Q¢QUYQVJe£¡ÊÐõõ÷ÿüûÿüûÿýúýûøïç泶ºVbVTPh»žàéêþúúÿüüÿùúÿûüÿûûÿúúüõôã×Õ©§gabQ¢¢JS«®€ÏÇõöóÿûúÿýþÿýýÿüýÿýþÿûýýøúðë춿ÃZ£^LRPWZb^©¬€Ïàùùùÿþýÿýüÿûûÿûýÿýýÿþüÿþüÿÿþÿÿþÿÿþÿÿýÿþþÿþþÿÿÿÿÿþÿþýÿþýÿÿþÿþþÿþþÿÿÿÿþþþûûþûüþüüþûûÿûûÿüýÿüýÿþýÿÿþÿÿþÿÿÿþõóþôóþ÷óþöòþöòþõóþóòþõôÿ÷ôÿöóÿöôÿööÿöõÿ÷õÿøöÿ÷õþöôþôôùóïãÙÙŠSKGLKXOSLEKFXOSBL>KW §æàØûññþö÷ýööýõõùðíÛÑÉŠKEOQ[h®±ÂÙåýúùÿüúÿüúÿüûÿüüÿüüÿýýÿýýÿýûÿüüÿûüÿüýÿýýÿýýÿüýÿûüÿþýÿÿýÿÿþÿþþþýýþúúûùøÜéé²»Wb`aSTNh³Ž»Úàû÷ùÿûûÿüúÿûùüùõèæÛ«£OZWYV cžÂîððÿúûÿýüÿúûÿùúÿ÷ùþøø÷îìÑÉÁz¢_W`OKg©°ÂÞÔüù÷ÿùúÿùûÿúüþùûþøûþøûü÷ùòòòÄÜ×c²£^OOY\OM¢g¯®Áßëüúúÿýýÿýýÿüüÿýýÿýýÿýüÿþýÿÿþÿÿþÿÿþÿÿýÿþþÿþþÿÿÿÿÿþÿþýÿþþÿþýÿþýÿþýÿþþþýýýúúýøúþûûþûûþüüþüýÿüýþþüþþüÿÿþÿÿÿÿ÷óþõòþöòþöòþöòþöóþôóÿ÷õÿøõÿ÷õÿööþöõþõôÿöôÿ÷õÿöôÿöôþõô÷òíÛÜÓ£€PJQHNRO¡©O¡ŽQ ºS¢»NšºB€±QTQFNGERuÇÎÀöîëýõõýööüóóõìêÐÆÃn?JNWQ|©¶Ôåìüùøþúúÿûúÿüúÿûûÿüûÿûûÿûûÿúúÿùûÿûûÿúûÿúûÿúûÿûüÿûýÿýýÿþþÿþþÿþþþýýþúúþùúñöõ²ÖÛa°¿Wš«UNNFY§ŽÏÛâîðýùúÿúûÿûûþùùøòíÙÜÉ©KT XMYl¬ÌØöôõÿûûÿúüÿüüþùûûöùû÷÷îìèÀÄ·gTSWNN€u«ÂÓåéýùøÿúúþúûþ÷úþøúû÷úü÷ùú÷ùöö÷ßííÒÖ^·YCQQNW¬ÀÇ×ãîòýúûýûûþûüÿýýÿüýÿýýÿûúÿûúÿûûÿýýÿÿþÿþýÿüüÿýýÿýüÿþýÿýýÿüýÿýüÿýúÿýúþýüýüûýùùúøøúøøýùúþúûþûûÿûýþûüþúùÿÿþÿÿÿÿ÷óþõòþöòþöòþöòþöôÿ÷ôÿ÷ôÿ÷ôÿ÷ôÿõôþöõþõôÿõóþõôþõóþõóýôòõîéÍÓÇrJ@WOTX}¹ÆÊÝËÞÍßÎÛvÃÎiª³[IGMREO c¿²ïëçûóôýööûóôïêé¿ÃÄ^9OFQD¯œâëïýøøþúúÿúúþúùýøùÿüúÿüûþúúþùúþøûþùûþùúý÷ùûõ÷ûõ÷ûöøýøùÿúüÿýüÿûûÿýüÿûûÿúûüüûäóó¢ÚákºÂQ«G¯¬J«šXžŸÍÛÖëòöö÷þùûÿüüÿüûüöôïáßų°l]WYLRd±ž¿ÚäûøøÿûüÿúûÿùúþøùûöøùõõììåµÈ±eR WIRJ«Ææìñûùùÿúúþûûþøúþøúú÷ùúôøüøùûøøôõ÷ÕêíËÕi¬ŽJ§X£[Žµn»¿Òã×íòöøùýùúýúúþûûÿúúþùúþúúýùùúõöþøøÿûýÿþýÿþýÿüüÿýüÿýüÿýûþüúþùùÿûúÿúúÿùúþûúýúúýùúüùùûøùýúúýøùþüýÿýýÿýüÿýûÿÿþÿþþÿöóÿöóþ÷óýõòýôñþöôÿ÷ôÿöôÿöóÿöóþõóþõôþôôÿõóþõôþôóýóóûòñîå⻞žaRD]UVlª€»ÓÕàêíäëïäëïÜéíÉáåŠÏÔr±ŽFDFPFL W²¬êèåùóóûööúòóçà⬶œU?QBWO¢ŸÃìïñûö÷þúúÿúúþúùþùùÿûúþûúþùúþùúýùúüøúþúúýøùùõ÷öóôöóôùôõýøùÿûûÿüûÿüüÿúûÿýüþýýúüûçôóÃâä£ÓÚÕÚ×Ú¶ßæÜíñõö÷üøùþùúÿûûþüûùóòêâÞ³¶®SSGKDZqŽÂÕåïþúûÿûüþùûýøúýöøü÷øöððâÚد£Q MeMZJ¥ÅÓíïôýùúþøúý÷ùý÷ùþùúýøúüøùüùùüøùú÷øôõ÷ÞìïºÞãÑÞÑߢÚæÆæìçõøûûûüùûýùúþûûþûûþùúýøùùöøüøùûøøüøùÿûüÿúûÿúûÿýüÿýüÿýüÿýüþüûÿüûÿýûÿüúÿúùþüùýûúþûúýúûþúûüùúû÷øýùüþüüþûüÿýýÿþþÿþýýôòþõòþ÷óýõòüôòþöôþöóþõóÿöôÿöôþõôþôóýôóþôóþôóþôóýóóùñðèßÛª§©WWNcX\³ª×ßÝóïð÷ñóùóô÷òòðïïÞæåªÌÈ[£E=IFKUª«æçäøóóúôõøððÞ×Ú£±NMP>R^££®ÎÎòòòùôöüøøýø÷ýööýöõþöõü÷õý÷÷ýøøü÷øúöøýùúþùúý÷øúööúööûööýøùÿúúþúúþùúÿùúÿüûÿüýþýýýüúö÷÷éñôãîòåïñïóôù÷øýøùü÷ùþúúÿûûþûúûöõéæ‮¬OL:36Y±Äèíóþùûÿûýþùüýøúùóöüö÷õêíØÇÊJ;PFM`ªÓØòñõþùùýøùýøùýøùþúüþûüýûüüúûüøùûøùù÷øöôöîòôêôôíö÷ñ÷ùøøúýüýþüüýúüþûüþüüþúúþùùúöøùöøýøúþûùþùúþúûýùùûöøÿúûÿýýÿýüÿýüÿüüÿýýÿýûþüùþù÷þûøÿûúþúùûø÷ýùùüøùûøùûøúþùûþùûÿýúÿýýÿýýúòðþôòþ÷óþöóþ÷ôþõóþôóþõóÿ÷õÿ÷õþöôþõóýõôýõóýôóüóòûòò÷ïîáÜÕ§ VROXV Yº·æèæõïïúòôûóôùòò÷ðððìëÑÚÔy¥¡JA>MDSª¯äåäøóóúôõõííÖÌËGO KBIp¢ŠÅÛÚ÷õôúôôùòóúëêùàß÷ÙØùØÔ÷ßÖúêÞýñéüððùôõúõöýöøýö÷þøøýùøýøøýøøýø÷ûö÷ýö÷þö÷ÿ÷öþ÷öýööÿúùþùùû÷øøôö÷ôõøôôûö÷ýùùýùúÿûüþûúúö÷÷òóàåâ·®IBC15X¥ÁÊóòôúõùÿúýþûýýøúùô÷ùõ÷òìíÏÌÌlCJHCKr£ÁÛÝû÷ùþüúþûúþúúþûúþùùþùúþùúýûúýùúýøùü÷øùôõ÷ôôúøøþüùþûüþúûÿûûþùûþùûþûûþûúýúùýø÷ûõöùòöþö÷ÿõõÿñïþåäýöôûöøþúúÿüüÿüúÿüúþüùþùöþùïýöæûð×ùçÜþôæýùóû÷öýùøüùùûøùûøúþûüþýüþûúÿûúÿýûúñïþõóþ÷óþõóþöôþõóþôóÿöôÿ÷öÿ÷õþöôþöôÿ÷öþ÷õýöóûòòúññöîìÙÕÍ¡RHNKT\§ÃÈðìì÷ññüóõûóôúóóúóóöîîßÚÖ¡KM <J@S¶²åæåùóõúõöõîìÎÍÁqJSLQJ¥³ÙäæúõóøèéòÑ×ìÍÉßž³Ó¹³Î¶«ÎŸ²ÛÁµåÈÂóÐÖöïéöòðùóõýõ÷ÿùùþùùýøöûõíúñèõíæôæâ÷ßàøÔÙ÷ØÚ÷ÔÛûëåøòì÷ëè÷áãøééøððûööýøùþúûÿüýþûúùõöóêíÕÊÒz¡ŠSEB /G]¯¢ŽÕ×øô÷úõøþøûÿûüþùûüöøùõöíëêÁËÊfJL?G?~¥ÔàãüùúÿýýÿüüÿôöþãêûèêûòïüôòûóîúìëúßäùåèôÚáøíëûøñÿ÷ðÿóòÿóôÿùúþùúþúûþüýþüüýúùý÷÷üõôöìí÷ßåôÄÓðÎÐ枟öìíùóöýøøþùøûöóùóïüöíöðáîæ»æÏ«ßÆÚ§éɬòÒ×ùòîüù÷üùøýùùýúüþýýþüüþúûÿþþÿÿýüóñþõóþõòýõòþöóþõôþõôÿöôþöôþöõþõõþõõÿ÷öÿøöþ÷õûóòûòòôêéÍÃÁp OHYTWgšª¹ÐØôîïùòóüóöýôõüôõüôõøðïá×ÓGNFN JY·éêèùóõùóõñëçÃŲgQ^S\M ±Ãæêë÷ñèíÜÍбš¬²Š{v šŒ®ªáØÀóäáøòôþöøÿùùþùøùòêêßÆÕȮ˶¬ÄµªÅ©£Ä«€Å± ÉŽªÐ«Ïù̺¯É°¯ÎÁœãâÜùôôþøúÿûûÿüýþüûûøöðéæÅžcVD J|J[o¯£Ìâàüøùü÷ùûöùþúûýøúüöø÷ñóçäߪŸµULUHS?€£Ÿ²ãëëüøøÿùúþû÷øìåçȺÚγÛÏ·Öɵ֞«Õ³¥Óš Øœ¥ÓŒšÚÊ«ÞÌ·ÜÀ©àŽ¶ôÔÓÿùøÿúüÿüýÿýþÿýýþûùýôíùçÚíжÞƵœ®¥¬²€ŠÖÍß÷óõùôõúñïñãÕåÏŒÒÄ°ªš€sm r©€³¬ÔÍ·ñïäùõôüùúüùúýøùþúûÿýüÿÿÿÿÿÿýõñþõóþõòýôñþõóþõôÿöôÿõôþõóþöôþõõþôôÿ÷öþ÷õþöôýóóûòñðå圱Ž[FHW`^wŽ³ÉÙáöïðûóôüôöüôõûóôúóó÷îìÛÖÏ MJHPQ]ÆÁîíëøòó÷ñòèâÞ®Ž©ZS\SRSœÍèâáâÚÎÀÀ¶aZLRZ^hu¡¬¡áËÓúóóýõ÷ýõøþøöòå௚}¥upifro{mrs§žÓÛøõöþøúþùûÿüýÿüüýúøðêåž»¯ZV MSI^¯±áëêþúûýøúýöùþúûþùúý÷ø÷ïïÞÎÊ¢OGXJJPªÌÉñôôûöøûöùü÷ôéçÛ©·¢x|rvhfrltpt²³ÈÕÒþùøÿûüÿûüÿýþÿýüýöííÞÅÏœ°Š¬jav¶ÂÙøóõùïìíÏÎÏ¥ iO71A L_gª¡ÐÞÍñëäúø÷ýùùùöøü÷øÿýýÿÿþÿÿÿþ÷óþõóþõòþôòþõóþõôþöôÿ÷õÿ÷öÿ÷öÿööÿööÿ÷÷þõóüóòüóòúòðêæ⎲Q6BSXXµºÛãéùóóüôõýôöûóôùñò÷îïñæåÊÂÁrSHMKUd€ÊÍñíî÷òóóîïàÚØ¡JLKM Da °ÃÕºÁ¥¯«n MB@NVYS~ZM l³³»ôååùóôûóöüööìå८£]\KE:?G[NU Ll£¯ÐàøôöþùûþùûÿúýÿüüýùõëêÜ€œSNJ?G\ŽœðóòÿûûþúüþøûÿûüÿûüþùùöñìÕÓÁyCCLSSg«¶ØØúùúýøúü÷øøñîÝØdzZU§E>JENAR5NgŽ·ÄÛÝýøøÿûûÿûüÿûûýúøìïá«œ€qY QL¡EW©ÅòêéêÑÀŸ¹s=A <E >LFA?¢^®«ÖÃÀöñîü÷øû÷÷úö÷þüüÿþýÿÿþÿøôþ÷óþõòþõòþöóþöôþöôÿ÷ôÿ÷õÿöõÿööÿööÿööþôóûòñûóòøñîãàÛ³¬R:BDJT¯»ééìûóóûóôýôôûòóùððôêéæÚÓ«©¬VTD N LUr§ŽÃÖÝóîñöðòóîïÚ×ÖBD;L@jš®ŠYJ8==OTZ HVDU €ªâÖÙøñóûóõúõöáäâššZVHB825IFUHt¢®ÄØæúööþùúþøúÿúüÿùúüóðàÕ̬QEH3CMª¥Ì×÷÷÷ÿüüþûýþúüÿýüÿüüýööñíêÊÍŸpCN<TGm°ÊÝæüøúþùûýøøöììÎÃœf XP\:L0C;OAip¶ÆÖæëüøøÿøúÿùûþøùü÷öèîâÇ©B3E L\`«ÃçßÛœŸ²kWPG 9C2<1I >M M¶¯ëæèõòóöñóúõøýúúÿþýÿÿþÿ÷ôþ÷óþöóþöóþöóþöôÿöôÿõóÿõôÿõôÿõöÿõõÿõôþõóýôóüóò÷îëÚÓÌŠ P?L =FV ¹ÁïëìýóòüóóýóóûòñöéèíÒÐÒÀ¬LZCH KSŒÉÛæìöðòõîñòëíÐÌÐsIE>OAdzc@K:EIMPP9L <Fn¢€ÑÌÎúòóüô÷öóõÓãâr®«L]O>>/3M HSL}²°Ôáêü÷÷ý÷øýö÷þùùüöøøïëÒÇŒz¥VCTBBZ¡³¿ÚçýúúÿýýÿüýÿûýÿýýÿûúýöõïêâœÊªjTXG^Lw¯œÜæðýøúýöùúôöíåäµ°^M?_UUJ\BOJ\ªÈåíóþùùÿøúÿøúþøùüõöçèâ¥À«U8~I=EW² r98;LTKCZ;A 9Tx]€ áÝç÷ööøôöú÷ùúøùÿþýÿþþÿöóþöóþöóþöóþ÷ôÿöôþõôþôóþôóþôóþõôþóóþóôÿõôÿõóþôòõéæÎÁºmIHK=I[Š³ÉÈòëëúîìõéçûèæöãÙíÎÄѱ¥ ¡dU`GC C`§ËÓìîñ÷ðòõîïíâ䟲ŸaMMPTDOPJL€EŠ°M²ŽF§®<¢GQ>3D>Ab§¥ÁÌÊúóóüõøõñõÌåèaºÅF§·V©¶NŽEªG1CJ?BS¿ºâèìúôõúôõ÷òôúõöùóõñëêÃÅÁcC:IC>g€»Ðàìû÷úÿûýÿûýÿüþÿýýÿûûüòñæÍЊTDIFGRÂÎêïõûöùúôø÷ôöìîî¥ÎÏ9±Œ;©¹B²P ŽEªBCB:~QQhŒÓõõ÷ÿúúÿùúÿøúþøùüø÷íîé²ÎœR¢@HNSK^_<@5²D»_«œN€·@«±8 CJ GO\9f¯ªÄÐàõóôüøùýûûþüüÿýüÿýýþöóþõòýõòþõóþöóþõóþõóþôóþóóýóòþôóýóóþóóþôôþôóüóññç⟜³bARDEOiœººíÓÑðÒÏìÖÆìÌÁÜÉÄ«iIUVP>Iq²ŽÍÞâóðòôîñòêìæÙÚ®ªQRMRUG>IB¡f·Á ÍÚ¡ØáÑÜw¿ÎXŠS:6AVFd¢¢¹ÐÌøóóüõøøô÷âíñ©ÙæÓâ¢ÖâÐÜŒÅ`8<B;D[Äœêíí÷óóöòóöñóùôööóóçççÅŸO9M>G H~£ŸãéðüøúÿúýÿûþÿýþÿýýþüüûòïÝÏÍH~RGMOk¢ÍÑôóöüöùü÷úúöøóóöÑéî¡Úæ ÙåÐáËÚ ²Y` MGC}B[ª°Òßú÷ùÿùúÿøúÿøúÿøúýùø÷íéñ®_KFC3B{W]XT¬kÀÛ¡ÕçÀâë¿àèË×hM¢ EJ§|<=MnŠ°ÅÑòóòúöøþûûþûûÿúûÿýüþöòþôòýôñýôòþôòþôóþõóþôôþôóýóòþóóüóòýóòþôóýôóúñðëãÞ®œ®`JXCMRd»ª¥À¯ªŒ·£¯€Š~SL@UOS@_§ÊÒæìîôðòôîñòêìâ×ÓHRJRL~J 5MeŽŒÖáØéîçïñåðñÎâ䶶T=ODR=c¥ŒÒÕøóôýöøüöøø÷øîóöìòõèðòßëëÂÒËl;<<>@`¢¡°ÏÊññï÷òôøôõöòóøóõòïðÜÞß¹¶LCT 79K¡ÃËòóõþùûÿùüÿúýÿûþÿýýþûûõðîÏÏÎyDaG¡J<gœÓÛú÷øþùúýøúû÷ùùõøõõùðôøñõøíóõäæé³·¿JCBYE L f©Ëáéüøùûô÷ÿöúÿúúÿøúþøøõì麜·A€CEa|MZIK @®ÅÇØÕèðñóôñîòòñóèìíÅÆKNLS=5;¥€ÊÖòóóûøùþúûþûûÿúúÿüýýõñýôóþôóýôòüóñþôôÿõôÿõôÿõôþôóþóóüóòüóòþôóýôòùîîåÙØ®£VRWJOVQnxzjXMPFC<FHPL¢µÃËÞéóñò÷ñó÷ðòõîíßÛÎKQLQLO?d¯Ž¯ÖÝæîñ÷óô÷óôøóóðîêœÉŸ[>T>FAk©ÆÕÜùóôþøùþùùþúúþùúýùùøõõïêæÅÀ·dEK?@?e©ªÅÛÚõóòúôöúôöøóõúô÷ôîîÖÊÏ¥NIT9FXµÖÑùööýøùýõùÿøúÿûýÿýüþûùôïìÅÔÈlLYQDEv¥£ÑÜÞü÷ùþøúü÷ùû÷ùüöùúöúýøüýúúúøøìéç°±K=@]@@xª Þèêý÷ùýøùÿøúÿûüÿúûþøøôê朚TWAKFD~H [œÙÚèïøõöûö÷öòõöóõôïðÕÎÊp F=y: .AY£ÏÐñóóûøùþúûÿýüÿùúÿûüýóñýóñýôòýôòüôñÿõôþôôþôóÿôóþóóþóóþôôþôôýôóüóñøëëÜÍÏQZVQMTMU] XRAC>IB@:KT§sŒÇžÙßçêïõñòùòôúòô÷ìêÖÆœxN HQIU T`¡Í×ãêîöóôûôöùõõ÷òòòîêÆÒÀ`?B<>Ku³ÑÚåøñôÿøûÿúúÿùùþøøýø÷ûöõîé㶹©[X GDCItž»Óâäöóóúõ÷úõ÷ûöøûöøôïîÎÉÊlFO HJPl€ ÈÜÚúö÷üöøýõøÿøûÿüýÿýüý÷õðáᶮž] X[PCD{»·àèçùôöüøùþ÷úýøùý÷ùûöúþúýþûûüú÷äèáž±>-€ ?B?O®ëîîý÷úþøúÿùûÿúýÿúüýùøíê䊷©B9 B|CB}<FvœÀÍàéøó÷ýùùûöøûôöùôööòòäÞØ:L{K42PÇØïóóýøùÿúûþýûþüûÿûûýôñýôñýôñýóòþôòþõóþôóüóñþóòþôóýòóþõõþôõýóòüòñõëêÑÇÊsMZMTMOKK[QaOT;J:IC\«y¹ÅžÚæéîðôðò÷òóúóõüôõõìèÊŒŽdQ=L>YM±¶Ñâéõñôøóõûõ÷úööøòóíæ乿²ZF:;: Q}³Äßåîùô÷þ÷ùÿøùÿøùþøøûôõøòóæáÝ£€V_ISF^¹Äáéê÷óóý÷øýøúýøùü÷øñîë¿ÇœaMK2C Dz¡šÔÞàü÷øý÷ùýöùþ÷ûÿûýÿýüý÷ôëÝ×€M_BM;M¿ÁèíîûõùýøúÿùûþùúýøùýøúÿùûþøúüôòàÔÊ«L FJ5?E«ÇŸõôóûõøüõøÿùûþøûþöúüòóãÕΚY{~QtR3yI {:]¬Óßòòóùóöþúúýöøüö÷÷óô÷óòäÚÓG K5TF\ÆÔõö÷þúûÿüüþýûþùúÿúýþöóÿ÷ôþöóýóñýóñþôóýóòûòïýóñüóòúñòþóôþóóýóòûñññèæÄÆÅhO]JRCKGO]RaK\IL7Hš`®»ÀÒÀÝæìðñøòó÷ñó÷ðòøòôûóóðè䶎¬VO=M7] Rª«ŠÏÑïðòúôö÷òôùóõúõöøóóçÞÛ¢¡P~S> BEXÅËíîòúô÷ûô÷ÿøùþøùü÷øúôöôóòÝàÛ§BMMQ@_ÂÓêîïøõõýöøþúúüö÷ùõõëëã®È®QNLB XL¢·Áâèìýøùý÷ùüôúü÷ûÿúüþüúûöñãâÒDYAT<Uš£ÌÖìïòüöùþøúþøûþøûýøúýøúÿûüþøù÷íëÒ¶Žk O:7/MSŠ¶³ÕÙúöøû÷ùü÷ùÿûýþûüþ÷ùùïðÔÌÎj©@H>3U}F œÒãîóüøøü÷øüöùýö÷üõööòõù÷öçéàªIY =T>S¡¢ ÆÝõõ÷ýùúÿýýþýüþúùÿúýþ÷óÿ÷ôÿøõþõòýôòþôóüôòüòñýóñüóñüóòþóôþôóýóòüñðìßݱ²µbRXKLAIQU\TVAFM¢PŠ€VŽ±vÀÍŠÔßØèîóóõûôôûóóøñòôïñôïñõîïæâà«PKCF?]o¶ÁÏâæøóöùóô÷òôøòóöòôöòñãàÝ QOCCK^¢ËÐóñóûô÷ûöøýøùþøùüöøûõ÷óíïÖÌÏr€>G?D A_«¡·ÒáõõôùõöúôöýøøùôõöîðãÒÏ¡\KDCVd§É×ðñôýøùü÷ùüôøüöùýöùþøøøõïÙàÊzEX{T}IJn¡¬žÒÞíðó÷ñöþøúþøúþùûþûúþúúÿûûþùøõð뿹®ZFBH4D]§žÄÛâú÷ùýøúþùûÿûüþúûýõøöïðÍÇÅb\E2)<\¢±Öèýúûþüüýùúü÷ùüö÷üô÷øôùúøöèêߪAA=ZvK m®ÄÛïïóúøùþýýýüûü÷ùþùûÿøôÿøõÿøôþõóþóóÿôóþõóþõóþôòýóòÿõôÿõõÿöõþõôûðïäÒÒŠ\UQMGIL¥ X±Ž]±a§°]Ž\¯ŒW±ÇW·ËqÁÍÍÕšÖÝÉãêåîðùöõþø÷þööýõõúóóöòòôðññéìÚÎÔ §¥MIIDM_¢ÂÔíïñûõöùòõúôöúõööóôòðîÛàÕ¢SEMFUkŸÑÖøôõþ÷ùý÷ùýøùþøùý÷ùüö÷òëëÌÄÉg©?@=BUq·§Ðãèüùøüö÷üö÷ýö÷ùôõóìîÚÐÉKV@JVt³×åõóøûõúüöùüõøûõøùôøü÷÷õíêÉÈœZQTX;Lk¶»Ëàèíîóóîôü÷úýøúþùüÿüûÿúûÿúúþúøððé«ŒªZID7AN}¢ÂÛåíú÷ùýöùýöùÿûüþûüýùøòïë·Ç»_@£A ARds¬ÖèîþýýÿýýþûüþüüþúúýúùüøùøõôßáÙu¬C DGXG[·¬¹Úçïñôüùùþüüüúùú÷ùúöùÿøóÿ÷óþöòþôòþóòÿôóÿöõÿøõÿ÷ôÿõôÿõõÿõõÿõõþöõúïìÛÎÉNTKNN|byŒ³ÏÖÌÛÐÛÓÞ€Øâ°ÜéµÝéÄâìÛëîéïïôóôúôôýõôþ÷÷þööþ÷÷ýõõüöõùôôóëìÍÁÈmOBH>Ne¬€žÖàúööþøøüöøýøùýùøû÷öñïìÉÑÇcP:PFaw®§Õáàý÷øÿøúþøúþùúþùúüö÷úôôòì霶œ_G? CC KŽ«ãìíþûùþùøþùùýøøúöõñíîÍÐÊg;[7GBv³Íáìüùùü÷ùýùúýøúü÷øü÷ùýø÷óáß· §NQFR2V»Ãâíðîðôíìõ÷ó÷ý÷úþûüÿüüÿüýÿýýýøøêæá·€WGH7TN«ÁÔçëðøõöýöùþûüÿýýÿüýýööíáÝŠ¶«VLPA€C2š£~Áœóôôÿþþÿýýÿùûÿýýÿûûþûúþüû÷ïïÔŒŸi£G4¥7Q \t»®Ñéïûúûþüýþûûüúùýùúýøûÿ÷óÿöòþôñýôñýôñÿöôÿøõÿ÷õÿ÷õÿöôþõõþôóþóòýóó÷îèÑÐÀnEUOUT~oµÓÍçðïèñòèðòêòòíòòòóôôôô÷ööúööûöôü÷öýöõýõõþööþööÿö÷ÿ÷÷þø÷ýøöõíêÅŸºaWEJ 5PwªÚæèþùøÿùùÿ÷øÿùùþùùü÷õïäà·©ªZ_<KF` Áµéïëÿøúÿùúÿúûÿüüþûûý÷÷ûôóîíã°·°WOF<JOž¹óòñÿüùÿüùÿûúþúùûöôðîíŸÐÈ_;J >[T±Žãìïþüüþûüþüýþúüþúúþúúþùøðëé®8D>]:£eÆÇîòõðò÷íì÷÷óùý÷úÿüýÿýýÿýþÿþýüóðÛ¿ÇwQHC@G_¢¢±×Þóóõü÷øþùüÿûýÿüýÿüüýôóãÌÅ ¢P:§¢MLfW¡¥©ÐÌýúøÿýýÿûýÿúüÿüýÿûûÿûûþúûöðîÊÄÂS XMOII¢r»¶ãòôÿþýÿþýþûûþúúÿúúÿþýÿöóþõóþõóÿõóÿöóÿ÷õÿ÷öÿ÷öÿ÷öÿöôþôôýóòüññüòññéãÂÁ³\T\ YW[ y¡€ÓÞÛüöôýøöý÷öý÷öýø÷ý÷÷þööþùøþøøþ÷õÿøøþø÷þ÷÷þööþöõÿö÷ÿø÷ÿùøþøöóîæ¹À²[UXMAOŽ³åçèÿøøþùùþôøÿùùþùùü÷ôéãÚ€£Z\HNK]££ÊÊööóÿøúÿúûÿüüÿýüÿûúþùøüóòèÜ×®«XKE>RV£Š§ÆÊøôóÿûúÿýúÿýûþüúûöõíÞ⬪·RMM>YdÈÀóöôÿýýÿýýÿýþÿýýÿûüÿûûýúùèé犯2<GC<f ²ÎÓóô÷òóøöñùýùýþüýÿüýÿþþÿýýÿüúûõòÌËË\GWZVW£mŠŠÆàäýùøþùúÿúýÿýþÿüýÿüüý÷óÞÓÁlT@VNOa¡²ÂÛÜþûùÿýýÿýýÿüýÿýýÿýüÿüüþüûõî쌶»TZM7¡Qb»·ôöôÿþýÿþýÿÿýÿþüÿþüÿÿþÿ÷óþõóþõóÿõóÿõóÿöôÿ÷öÿ÷öÿ÷õþõóþôóýõóýôòýòðíãݯ«©L]`aK] ¹ºãéåþøöÿøöÿ÷öÿøöÿøöÿøøÿøøÿúùÿùøÿùöÿùøÿ÷öþøøþ÷÷þ÷öþ÷öþøøÿù÷ýöóíáØŠ³£[QbPOT€¡§ÉÅðïîþööþùùþ÷ùÿùøþ÷÷ùõòãæÖ©YQ[P KXš·ÐÚüù÷ÿùúÿùúÿüûÿûúÿúøþú÷ûòíÝËÁ©Y=W?M`©ŸÕÔüööÿûùÿûùÿýûþüûýøôçÝÙ£©KPL~LMh«ÒÇöôóÿûþÿþþÿþþÿýþÿýýÿüüü÷õÙÔÍ]¢£4D^GOjŽÈÞÚúøøýúúýùúÿþþÿýþÿýüÿýûÿýýþùùùõí¿ÇžgN¢OA€IV©ãêêþúùÿüüÿüýÿýýÿüûÿúúûôìÉÅV7£<3<Yµáéìÿýüÿþþÿþýÿýþÿþþÿþýÿüúþú÷òìãšÁžQYc b]UŽª¥ÒÎýüøÿÿýÿÿýÿÿýÿÿþÿÿþÿÿþÿõóÿöóÿ÷óþõóþõóÿõôÿöõÿöõÿ÷õþöôþöôÿ÷õÿöôýóñëâÜ ¢N` Vh MdÈÌîðîþ÷öÿ÷õÿøõÿøöÿøöÿøøÿøøÿùùÿùøÿù÷ÿøøÿ÷÷ÿúùÿúùÿù÷þø÷þúøÿù÷üóïäÍÆ¢[ObQ\f¯±ÅÝÚûøõþøøÿùúÿúùÿùøþ÷÷õñîØÝÒo©RLP>F`§²ÍÝçþùùÿøúÿøúÿúûÿûúþúøþ÷õûóíОm>2eJRp«ŸÖåæþøøÿûùÿûùÿüúÿúøýøóàáÔyKU< FBl¢¢ÅÚÕüøöÿüþÿþþÿþþÿýþÿûúþúùùìèëPC6LC\yŽ±áìêþýüÿýüÿüüÿþþÿýýÿýüÿýûÿúúþ÷øòïæ¡ÃµRCWKVD£šººíòïÿûúÿüýÿüýÿýüÿüúþùøõïçµÄ®XNV}1G9§ œÐïóóÿþýÿÿþÿþþÿýþÿÿþÿþýÿüûýóïæŸÁ ®\B€£EH§\b²œÈæçÿýúÿÿþÿÿþÿÿþÿÿýÿÿÿÿÿþÿôóÿöôÿ÷ôþõóþõóÿõôÿôôÿöõÿ÷öÿ÷õÿöõÿöõþõôüôñæâÝŠ§R_Rj_i¢šÍÙõóñýõõÿøöÿøöÿùøÿùøÿøøÿøøÿùøÿø÷ÿø÷ÿøøÿøøÿúøÿúùÿù÷ÿøøÿúøþù÷úñîØÊŸsPL\Ncz®»ÞééþúùÿùúÿùúÿùúÿúùýöõðçèÅ·Œ^ UUJ;Hw·»âëðÿùúÿùûÿùûÿúüÿüúþù÷ýöõùòêÀ¯[/CWPcªÅëðñÿúúÿüùþûùþùøý÷õùõíÕáÃd¢J REJPyª®Ùäãÿüùÿýýÿþýÿþþÿýþÿüüþûøøñ௱GPCTPb¿ÄõøöÿÿýÿþýÿýýÿþþÿþýÿþýÿýüÿûúýôòåÎÊ¡SBUB Pc ¥ÐÉùùöÿüûÿüýÿüýÿýüÿüûþøöìÕÔ¢¥^ D{A/NT §Ôáø÷ùÿýýÿÿþÿþþÿþþÿÿþÿþýÿýüüôëÒŪhRJiyNXm·ÌàðóÿÿýÿÿÿÿÿÿÿÿþÿÿýÿÿÿÿÿþÿöóÿöôÿøóþôòþõòÿõôÿôôÿöõÿöôÿöôÿõôÿöóþõòúðìØÑÎz ^[T`kv ÁÓÜ÷óñýõõÿù÷ÿø÷ÿø÷ÿú÷ÿùùÿùøÿù÷ÿø÷ÿø÷ÿøøÿø÷ÿù÷ÿùøÿù÷ÿùøÿúøþù÷÷òïÉÎÂhUSUS]¬Áíïðÿùùÿùùÿ÷øÿöøÿúùý÷õîçæ°®³Y£DRI>WÀÅïñóÿùúÿúüÿüüÿüüÿüûþ÷÷ýõõóê姌¬L3R^Lc¢œÒöôöÿûüÿüùþüùþø÷ûôóõìåÅœ±T¡U^ TT P¡|œÌëððÿüúÿûýÿþýÿþþÿþþÿþýþýúðñß³VYBIKPªŠËÝýüùÿÿþÿþþÿýþÿÿþÿþþÿþýÿþýþúúûóðÜÎÄqA:PRMZ¢ŒŒÜäþüùÿýüÿýýÿýýÿýýÿüüýùøéàÛDJ MNVf¢¥³×äýúúÿýûÿþþÿÿþÿÿþÿÿþÿþüþûø÷æâµ·€YVMXšNW±£Ðáøúøÿÿþÿÿÿÿÿÿÿÿþÿÿþÿÿþÿÿþÿ÷ôÿ÷óÿöóþôòþõòÿõôÿõôÿõôþõóþôóþôóÿõóþõòöëäȹµfc[Z[hzšªÖâãúõóþøöÿøöÿø÷ÿøöÿù÷ÿøùÿøøÿùøÿùøÿùøÿøùÿø÷ÿù÷ÿùøÿùøÿùøÿø÷þøõôíêžÄŸf_XO_d¡ÀÏ÷ôõÿúùÿúùÿøøÿ÷ùÿúùþúøíêä²±P5RBRešÆÌ÷óôÿúúÿøúÿúúÿúúÿüûþúøýóòèÎÑ«I@Pb\g€ÎÝû÷ùÿûúÿüùÿüùþùøüôóñæÝ®€P `O¢VTbÇ×ùööÿüüÿüýÿýýÿýûÿþþÿþýýú÷çéÐ{µYO~^KLZ²°ÃßêÿýúÿþüÿýýÿûýÿÿÿÿþþÿþýÿþüþúúøóìÍÈ·iQND¥GNp¶ÖåëÿýüÿþûÿþþÿþýÿýýÿüüýøõÜØÕn? <<¡X~U~ÏãäþûûÿýûÿþþÿþþÿÿþÿÿþÿþüýöòäÉÈŽPX{VQ¥ntÀšÍèíÿýüÿþþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿÿÿöóÿöóÿõóÿôóþõóþôôÿõôÿöôþõôþõóþôóÿõôþõòñæÜŽ¬§W_U[Xe¿µæìéþøõÿø÷ÿù÷ÿùøÿùöÿúùÿøøÿöøÿø÷ÿùøÿùøÿúøÿøøÿøøÿøøÿúøÿúøÿø÷ýöôíÞÞ®] __YcnªµÕØýøøÿüûÿúùÿøøÿøùÿùùý÷ôçßÚ³¯R;O<Zm§šœÐÔûõõÿúúÿùûÿúûÿûûÿýûþüùüóðßÍÍtLK O^^n©£ÆÝäþøùÿüüÿýüÿüúþúùýøõðêà¥Oh\c>l¡²ÐâþøøÿýüÿýþÿýýÿýüÿýýþüüúðïÖº¹j^ CZH£Fn³œÔæíÿûùÿüüÿýýÿýýÿýýÿüüÿûûÿþüþûùõóí³ÎŒLFWJUFzšÄçîóÿüüÿûúÿýýÿýþÿþýþýûøóòÃÔÔQ>V<Y;£«r³°ßëêþúùÿüûÿûüÿýüÿþþÿýýþùöúëÝ°¯ciJV:¥y² ÇËíôôÿüúÿþýÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿþÿöóÿöôÿöòþôòþôóþôôÿôôÿöôÿöõÿ÷ôÿöôþ÷ôüôðëâÕªS]T\PdÆžîðêÿ÷õÿúøÿúøÿúøÿûøÿûùÿøøÿõ÷ÿ÷÷ÿùøÿúøÿúøÿùøÿøøÿ÷øÿúùÿûúÿùøý÷ôæÚÖWX]]`tªÎáÜÿøøÿûúÿùùÿøøÿøùÿøøüñíØŸ¿n¥€[VZKWtŽ°ÕááþøøÿûûÿûüÿûüÿûýÿýüþüúúôðÐËËk\£QMT]| £Ùæèÿúùÿýýÿþüÿýûÿüúþû÷ìíÞ§RcTdLt ÇÒãÿ÷öÿùøÿúúÿûùÿûúÿüüþûûúñíŶ³VSQXPR³ºåìîþùöÿüøÿýúÿýüÿýüÿüüÿûúÿüúþùøîßܬRS]KDI¡ÄÒôöùÿüüÿúøÿûýÿûýÿüüþúùïàݱ§±\(B ?JQ˯ô÷ðþúúÿüûÿûüÿùùÿøøþ÷öüÝØÞŒ¢AIB }T;g¹·ÞåýûúÿûúÿþýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿõóÿõóþöòþóñþõóþõôþôóÿõôÿöõÿöôþöôýöóúñíâÙ̬]^ZUWg®ÊÁõóîþöôÿù÷ÿùøÿùøÿúøÿúøþøøþ÷øÿùøÿùøÿú÷ÿûùÿúùÿùùÿøøÿûùÿüûþúùûöñÜÙÊuXNX`Y¢¢áèãÿøøÿùùÿúùÿùùÿùùþøøúïéÅŽ¬cQ^^WY·ŒæììÿúúÿúûÿûýÿúûÿùûÿüûþýúöôîžÊÁT[¢UJVe¯®ëïîÿûúÿüûÿþûÿþûÿýûýûøææÛ}S XZ_Ng§ÏÂÈþèÜþØÓÿîâÿ÷òÿúúÿùûþûú÷óñ»º¹\ _aH¢¡FI¬±ïêÚþñàÿõÚÿöêÿüúÿþýÿýýÿüýÿýüýúøèÖÕM¡WKbK^¢ ÑÛüùúÿýüÿýûÿþþÿýýÿüüþùøìäÚ¬¯?37ROS€Ë»úóìÿüúÿýüÿûûþøøýòìúèØåÕÄW¡U}HQGŠ£I©ªËÜìôôÿþüÿþûÿþýÿÿÿÿÿþÿÿþÿÿþÿÿÿÿÿÿþôòþôòþôòþóòÿ÷õþ÷ôþõôÿõôÿõôþôóþôóýôòøíêÕÇŸr£YSZS io€¡ÁÕÑùõòþöôÿø÷ÿùùÿùøÿù÷ÿù÷þøøþøøÿúøÿúøÿú÷ÿûúÿúúÿúúÿúùÿúùÿúúþùùùóìËÔŸcX VUkX °Žîîëÿùùÿúúÿûúÿúúÿúúþùøôí䯻§ZGVJR^ŸÌññòÿúúÿûüÿüýÿúûÿúúÿûúþú÷òå߀¶®PVPELZÈÀöõôÿûûÿûûÿûûÿþüÿþýýõòÜÉÊtš^R RGTRÝ̮۵€ÑÖÃðìçÿùøÿúüþúûöôò±ÈÃ`H[EUM|ÈÍ¢âħÙÐÛÃÅÿòóÿÿþÿþþÿþþÿþýýûøÞÜÛzZiS€bC§n£œÙÝþúúÿþýÿþýÿþþÿþþÿýýýúöãÛÈQ\ ?¢1E a²í·ŸþñâÿòóÿïñþÛß÷ØÇÛ§oC¡K3¡MG€£uµ·Éêîÿþûÿÿþÿÿÿÿÿÿÿÿþÿÿþÿÿþÿÿþÿÿÿÿÿÿþôòþôñþôòþôóÿ÷öÿ÷öÿ÷õÿöôÿõôþôóþôóýôòôêçÄ»·aSNZYnsµ¶Óãàú÷ôÿø÷ÿùøÿúøÿúøÿù÷ÿùøþùøþøøÿúøÿúøÿúùÿûúÿúùÿúùÿúùÿûùÿùøþ÷öóçà·¶¬\\hYla£ ËÆöôñÿúúÿûúÿúúÿûûÿûûþ÷öëßÚ¹¡\JKBL^€£ŽÍÞúö÷ÿûûÿýüÿûûÿúúÿúúþúùýõóéÜÑ©€OXMKP e¡¥·×Óý÷÷ÿýüÿýüÿýüÿýüÿûûýôòÕÆÊjRM WZ`Dg~ ¡®³ÐÝ×ÿúøÿûüþúûóñð¥ÃÂa=fASFMg v©©¶ñíìÿÿþÿÿþÿþýÿüûüúöÎßÑkQš¡LNbQ¥£©ÖæëÿýþÿþýÿýüÿýýÿþýÿýüüùõÑÝÅdAXD S| 1PS¢ŠÉÀ·Û¹áœŒÍ€µ®šS¢ WEX>¢QQ¯Å ×æúýüÿÿþÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿöóÿõóÿõóÿöôÿ÷õÿ÷õÿ÷ôÿöôÿöõÿ÷ôþöóýõòðé篎¶^PS^[m}žÀàééüùöÿùùÿùøÿúøÿúøÿûøÿûúÿúùÿúùÿúùÿùùÿúùÿúúÿûùÿûùÿûúÿúùÿù÷þ÷ôîâÚ€ _ad\bm¡®·ÙÚüøõÿúúÿüûÿüüÿýýþüüüõóâÑÐy®^PJPKkµ²ËÞêþùúÿüûÿýüÿûûÿúûÿúúþûùýõðÞÖÉn M¢`[RTr«ÎààÿúúÿþþÿþýÿþýÿýûþûúüóðÖÄÇjVHIcNNZY_hª§¹ÖËÿú÷ÿüüþûûôðî¥ÄÁaIaSgYcN£ST¢äÞßÿýýÿüýÿûüþúùøíè·ÃŽc^`]hN€ŠŸ³ìòòÿþÿÿþþÿýüÿûýÿþýþýüûìçÁ³p hWF30A^egn hQ£PU`kaK?¡¡Lº§ÏÝêöøÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿöôÿöôÿöôÿöôÿöôÿ÷õÿ÷ôÿ÷öÿø÷ÿùöþøõýôòêÜߎ·fQ`QRf»Ííððýøöÿùøÿùøÿúùÿúøÿûøÿûùÿúùÿúùÿùùÿùùÿûùÿûúÿüúÿûùÿûúÿúùÿúøýøôèä×^£XYdbtµÎàèþúùÿûûÿýüÿýýÿýüþüûûôòÒÈÈq©W\OZVµžàìñÿúüÿýüÿýýÿüüÿüûÿûúþúùûöïÎØÀaU jbWQ {£ºâêíÿýýÿþþÿýýÿüúÿûúþúùüõñÝÖÓsG OJdTªM H¡PSlšÏÁÿúóÿýýþüüùõóµÁÁh c e¡^Y XTd`bs«šÒØÓÿúøÿüûÿûüþøõðÙÓ¡¥O£OC[`iŠÊÉúú÷ÿþþÿþýÿýýÿûýÿýþþüüôäߧ£Yb K`KZQO9¢GG€M~N`C£NS«? ;gº ÎÝÝòõÿþýÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþöóÿöóÿöóÿöóÿöóÿöõÿ÷öÿøöÿù÷ÿøöþ÷õüòñàÏÖµfLhFQdšÄÖöóòý÷öÿù÷ÿùøÿûùÿûùÿûøÿûøÿùùÿùùÿùùÿûúÿûùÿúùÿüúÿûùÿúúÿúúÿüúýùöÚåØxZa[£ka¢}¥¿áêðÿüüÿüüÿþüÿýýÿýüþûûúöõÂÎÐnR[DTWŠš¿Âòõõÿûýÿýýÿþþÿýýÿûüÿüûþùù÷îé¶À¶a^TN \]¥ÀÒñõöÿþýÿýþÿýýÿüúÿýüÿýûýüøêçá£@ŠS@]X¡]N¥`UŠ¡g£Âœù÷óÿýýþüüüøõÉÖÐa°RHebiP€dI§Rf«²ÆÌÎÿú÷ÿýûÿüûþûöèáÒ~Q` @ bJšcš©ÐØýùøÿûûÿûúÿûýÿüýÿýýþúûîæáNi~NX?£[Xm~AM 5£OE§`PicŠW€I¹šÅØÝò÷ÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþõòÿöóÿ÷óÿöóÿöóÿöôÿöõÿøöÿùöÿ÷õþöõûóòÚÞâtœÉg«³U©±f©Sš\ªµmžŸÄÚäûöôÿù÷ÿúøÿúùÿüùÿûùÿûùÿûùÿúùÿùøÿúùÿúùÿúøÿúùÿýúÿüúÿûúÿûúÿüúýûøÔëäk±µ]£²m¥[®Žk²^·»ÈÖñõöÿüûÿýúÿýûÿýýÿýýþüüùùø¶ÖÝk ±V¬¶`š®TžœP³¹X»Â¥ÏÖûùøÿýýÿþýÿþþÿýýÿüüÿûúþúùôðì¥ÅÆ_Ž¶NŽŽK¯·J©³]§°i¯°¥Õâûûúÿþýÿþþÿýýÿüûÿûúÿÿýþþúùôò¿ÖÛVºÇ_UgC¢MN\ai§žÍôõöÿþýÿýýýüûèïïÍÒWšE¡fO¢WI^I`^µÃœ×âÿúúÿþýÿýüþüùáèß|°D³P²³9žŽLš®N«¬o€ÀÆÜîþûúÿûûÿüúÿýýÿýýÿûüþùùäèâxOQ?g L`4ŠŽQ«<©šYUq Yb;Eµ§Cœ³sÊךàëéööÿþýÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþôòÿöôÿøôÿöóÿöóÿöôÿöôÿøöÿøöÿøöþøöüöóèíî©×àÐØÐ×Ð×ÕÖ¢ÙÜÝßãìïý÷õþù÷ÿú÷ÿúøÿú÷ÿú÷ÿûøÿüùÿûùÿùøÿúùÿùøÿúøÿûúÿýùÿûøÿýûÿýûÿýûýüùçõð ÕÜÏÙ ÓÛ×ÝŠÜÞ¡ÜáÇçíûúúÿüúÿýúÿüúÿûúÿûûþûûûúùÔéíŠÐÛ×Þ€ÙÜ€ÞâÞâ€ÞäÓéîþûûÿþþÿþþÿÿþÿþþÿýüÿüûþûúúøöÏèè€ßáÝàÚÞÑÛ¡ÕÜšÙÞÓìðþýüÿþýÿþþÿþýÿýûÿýûÿþýÿþüýúùïö÷¯áæÁÈbŽŒXŽ¬E©²C²J©žc²¹n·ÂÉÕÅàìüûûÿþþÿþþþýýúúùÖíðÉÒX»ÂN®¹UŠ³[ ±Y£·]°µV·ÀtÀÇÔáßîõÿþýÿÿþÿþüþüùíöô§ØâÓÝÕÝÖàÖÝÑÝ¢ÓåçñøÿûûÿüüÿýûÿýýÿýýþûüüòòÕÆÐgO\JY¢AWµ©¢ØÚÎÒUŽÂjª©Qš«M·«@Œ±DºžG¿¿mÎÑ×âÎìóûÿýÿÿýÿÿýÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþôòÿöôÿøôÿõóÿöóÿöôÿøõÿøöÿøöÿøöÿøöþøõûöôïòòíóñëòðêñðêóòíôòðöóùöõü÷öþøõþøõÿø÷ÿøöÿùöÿú÷ÿüùÿûùÿúøÿúøÿùøÿûùÿüúÿüùÿùøÿýúÿüúÿüúþüúûüøêóõèòóéôôêõöìõöíø÷öúùÿýüÿýûÿýûÿüúÿûúÿûûÿûüþüû÷ù÷ëõõêõõëõõì÷÷íùùîøø÷úùÿüûÿüüÿþþÿþþÿÿþÿþýÿþýÿþüþýûöûùìø÷ëø÷ì÷÷èôöëõöë÷÷õøùÿþýÿþþÿþþÿÿýÿþüÿþüÿþýÿþýþþüýýüñø÷Öíí»ãæšÞàÔßÒà ×ä·àèÊçíæòóöúúÿþýÿþþÿþþÿþþþþýùüûâñïÂçë®àèÓáÑá Øå¯àçÂéîØðïêööúüýÿÿþÿÿþÿþýþþýýþüóúùðøöêõõð÷øòù÷ïø÷óøøüüüÿüýÿýýÿýýÿýýÿýýþüüøê廣«F FH bRWuŒ²äðîëôóÌëð«áéÞèÚæØé¬ãíŸéñÚóöùýûÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿöôÿ÷ôÿøôÿ÷ôÿ÷ôÿ÷ôÿøöÿøöÿøöÿøöÿøöÿù÷þøöþùõþùôýøõý÷ôþùöÿûöÿú÷ÿúøþú÷þøõþøôÿø÷ÿø÷ÿú÷ÿú÷ÿûøÿúøÿúøÿùøÿùøÿúøÿüúþüùþùøÿûúÿüúÿüúÿýûÿýúþûúþûúÿüûÿýüÿýüÿþüÿþýÿþýÿýûÿûùÿýüÿýüÿýüÿýþÿþýþþüþüûÿüúÿûúÿûüÿÿýÿþýÿýüÿüüÿûüÿþþÿþÿÿþþÿþþÿþþÿÿýÿÿýÿþýÿþüÿþýþþýþþüÿþýþýýþýýÿþýÿþþÿþþÿýýÿþüÿþüÿþþÿÿþÿÿþÿþýþüûûüúõøøðø÷êöøéöøî÷øóùúùûûýýüÿþüÿþýÿÿþÿÿþÿÿÿÿÿþþþþüýü÷üûôúúî÷øí÷øðùùôúúøûúûûúþþýÿþþÿÿþÿÿþÿÿþÿÿþÿÿþþþþþþþýþþþþþþýýþýýþþýÿþýÿýþÿþþÿþþÿþþÿþýþüüõí䥣£LozS]=¡T£ÄÆøù÷þýüýþýüþýûþýúþüúþüýþüþþýþþýþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿöôÿ÷ôÿùõÿøõÿøôÿøôÿùöÿøöÿøöÿùöÿùöÿù÷ÿù÷ÿûöÿûöÿû÷ÿú÷ÿûøÿüøÿûøÿú÷ÿú÷ÿú÷ÿøöÿù÷ÿúøÿú÷ÿùöÿù÷ÿùøÿùøÿùøÿùøÿû÷ÿûùþüùþúøÿúúÿýûÿýûÿýüÿþûÿýüÿýüÿþýÿÿýÿÿþÿþýÿþüÿþûÿýûÿüûÿþýÿþýÿþýÿþýÿÿýÿÿýÿþýÿýûÿüúÿüüÿÿþÿÿýÿþýÿýýÿýýÿþýÿþþÿþýÿþýÿþþÿÿþÿÿþÿÿþÿÿþÿÿÿÿÿþÿÿýÿÿþÿþýÿþþÿÿþÿþýÿþýÿýýÿþüÿþüÿþýÿýüÿþüÿþüÿýüÿþüÿýüÿþüÿþýÿþýÿþýÿþýÿþýÿþþÿþýÿþýÿþþÿýýÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿþýÿþþÿþýÿþýÿþýÿýüÿýüÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþÿþþÿÿþÿþýÿþýÿþþÿþþÿþþÿþþþüúîçÐCVENSc£©Æ×þüúÿþüÿÿþÿÿþþÿþþÿþþÿþÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷óÿ÷ôÿùõÿøõÿøõÿøöÿøöÿùöÿúöÿùöÿùöÿøöÿù÷ÿûøÿûøÿú÷ÿú÷ÿú÷ÿû÷ÿû÷ÿúøÿúøÿù÷ÿøöÿûùÿýùÿúøÿøõÿùöÿùøÿûùÿûùÿúøÿû÷ÿûùÿüúÿüúÿüúÿþûÿýüÿýûÿýûÿýûÿýûÿþûÿÿýÿÿþÿÿýÿþüÿþüÿýûÿþüÿþýÿþüÿþýÿþýÿþýÿÿýÿÿýÿþýÿþüÿþýÿÿþÿÿýÿÿþÿþþÿþýÿþýÿþþÿþýÿþýÿÿþÿÿþÿÿÿÿÿÿÿÿþÿÿþÿÿþÿÿþÿÿþÿÿýÿÿþÿÿþÿþýÿþýÿþýÿþýÿÿýÿþþÿþýÿþýÿþýÿþýÿþýÿþýÿÿýÿÿþÿÿþÿþþÿþþÿÿýÿÿþÿÿþÿÿþÿþþÿþýÿÿþÿÿþÿÿÿÿÿþÿÿþÿÿþÿÿÿÿÿþÿÿþÿþýÿþýÿþýÿÿþÿÿþÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿþþÿþþÿýþÿýþÿþþþþþýøóÞÛÃr] gVW¢YZ¶ÄËáíÿþýÿþýÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿþÿÿÿÿÿþÿÿÿÿÿÿÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþ÷óþõóÿùôÿùõÿúöÿùöÿøöÿùöÿøõÿøõÿù÷ÿøõÿøõÿú÷ÿú÷ÿú÷ÿùöÿùöÿúöÿûöÿúøþúøþø÷ÿøöÿýúÿüùÿúøÿùöÿûøÿúùÿýûÿüúÿûùÿûøÿýúÿýûÿýûÿüûÿýûÿýüÿýûÿýûÿýûÿýûÿþüÿÿþÿÿþÿÿýÿÿýÿþýÿýûÿþüÿþüÿþüÿþüÿþýÿþýÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿþþÿþþÿÿþÿÿþÿþþÿþþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿýÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿÿÿþþÿþþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿýÿÿþÿÿþÿÿÿÿÿþÿÿþÿÿþÿÿþÿÿýÿÿþÿÿþÿþýÿýûÿýûÿÿýÿÿýÿÿÿÿþþÿþþÿþþÿÿÿÿÿÿÿÿÿÿÿþÿþþÿþþÿþþÿþýþýýýïêС\^}S€L P€hlœÍáð÷ÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿþÿÿýÿÿþÿÿÿÿÿÿÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþøóþõóÿøôÿøõÿùöÿùöÿùöÿøöÿ÷õÿøõÿø÷ÿ÷õÿ÷õÿúöÿú÷ÿú÷ÿû÷þøöþ÷ôÿùöÿùøþúøþø÷ÿúøÿûøÿú÷ÿúùÿúøÿúùÿúúÿüúÿûúÿûùÿûùÿýúÿýûÿýûÿüûÿýûÿþýÿþûÿþûÿþüÿýúÿþýÿÿþÿÿþÿÿþÿþýÿýüÿýüÿþüÿþüÿþûÿýûÿþýÿþýÿÿþÿÿþÿÿþÿÿþÿÿþÿÿýÿÿýÿÿþÿÿþÿÿÿÿÿþÿþþÿþþÿþþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿýÿÿýÿÿþÿÿþÿÿþÿÿþÿÿýÿÿþÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿþÿÿþÿÿÿÿÿþÿþþÿþýÿÿþÿþþÿýþÿþþÿþþÿÿÿÿÿÿÿÿþÿÿþÿÿþÿÿþÿÿÿÿþþÿýüÿýüÿÿýÿÿþÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿþÿÿþÿÿþÿþýÿýüÿýüÿÿýÿÿýÿÿÿÿþþÿþþÿþþÿÿÿÿÿÿÿÿÿÿÿþÿþþÿþþÿþýÿþûþýýüõñ¹¶¯LjRnI¥£\~ÂÚòøúÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ôÿ÷óÿøôÿøôÿùöÿùöÿøöÿøöÿùöÿù÷ÿøöÿ÷õÿ÷õÿúöÿûøÿûøÿûöþøõþöóÿùõÿù÷þú÷þøøÿûøÿù÷ÿøöÿù÷þùöþøöÿûùÿúùÿúùÿúúÿýúÿýúÿýúÿýúÿýûÿýûÿþüÿþüÿþûÿþüÿýûÿýüÿÿýÿÿýÿÿýÿþüÿüúÿýúÿýûÿýüÿýûÿþüÿþýÿýüÿýüÿÿýÿÿýÿÿþÿÿþÿÿýÿÿýÿÿýÿþýÿþþÿÿþÿþþÿþþÿþþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿýÿÿýÿÿþÿÿþÿÿÿÿÿþÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿþÿÿþÿþýÿþýÿÿÿÿÿÿÿþþÿþýÿÿþÿþþÿþþÿþþÿþþÿÿÿÿÿÿÿÿþÿÿþÿþþÿþÿÿÿÿÿþþÿýüÿþüÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿÿþÿÿþÿÿþÿþþÿþýÿÿýÿÿþÿÿþÿÿÿÿÿþÿÿþÿþþÿþþÿÿÿÿÿÿÿþþÿüýÿüüÿþüþýüõòŠKcO¥U I¡j¡¿Öüüüÿÿýÿÿýÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþöóÿöòÿøóÿøôÿùöÿù÷ÿøöÿøöÿú÷ÿúöÿúöÿøöÿøöÿúöÿû÷ÿû÷ÿúöþù÷þøôÿøôþù÷þùöþø÷ÿúøÿúøÿù÷ÿøöþøõþ÷õÿøøþùøþùøÿúùÿüùÿüùÿýúÿüúÿûùÿûùÿüúÿýüÿýúÿýúÿýûÿýûÿÿüÿþûÿþüÿþüÿýûÿüúÿûúÿýüÿûúÿþýÿþüÿýûÿýûÿþûÿþûÿþýÿþþÿÿþÿþýÿýûÿþýÿþþÿÿþÿþþÿþþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿÿÿÿþÿÿýÿþþÿýýÿüýÿÿþÿÿýÿÿüÿþüÿþüÿÿÿÿÿÿÿÿþÿÿþÿÿþÿÿÿÿÿþÿÿþÿþýÿýüÿþþÿÿÿÿÿþÿþþÿþþÿÿÿÿþþÿþþÿÿþÿÿÿÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿþÿÿýÿÿþÿÿþÿÿþÿþþÿýýÿýýÿþþÿþþÿÿþÿþýÿüüÿýüÿþýþýüìîêx°¬SKW ZY¡Zª »Øãþýýÿÿýÿÿýÿÿþÿþþÿþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþöòþõòÿ÷òÿøõÿùöÿú÷ÿú÷ÿùöÿùöÿùõÿúöÿú÷ÿùöÿùöÿú÷ÿú÷ÿú÷ÿûøÿùõþöôþø÷þù÷þù÷ÿúøÿûùÿûùÿúùÿù÷þ÷õþ÷÷þùøþøøþøøÿúøÿúøÿüùÿýúÿûúÿûùÿùøÿûúÿýúÿþûÿþüÿþüÿþüÿþüÿþüÿþüÿþýÿýüÿûûÿþüÿüûÿýüÿþýÿþüÿýúÿýúÿýûÿýüÿþýÿþþÿÿýÿýüÿþýÿþþÿþþÿþýÿþýÿýýÿþýÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿýÿÿýÿÿþÿÿýÿÿýÿþþÿþýÿþýÿÿüÿÿüÿÿüÿþüÿþþÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿýþÿþþÿÿþÿþýÿýýÿþþÿÿÿÿÿþÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿÿþÿÿþÿÿþÿÿþÿÿþÿûûÿþýÿÿþÿÿþÿÿþÿÿþÿþþÿýýÿýýÿþþÿþþÿûûÿüüÿýýÿþýÿöòÛ²ÁecB€RJ£ _fŽ¡×êçþüüÿþþÿÿþÿÿþÿÿþÿþþÿþþÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþøóþöóÿøóÿùôÿùöÿúøÿú÷ÿùöÿøöÿøôÿù÷ÿûùÿúøÿùõÿû÷ÿùøÿúøÿúøÿúöþùöþùøÿúùÿúøÿúøÿúùÿûøÿúùÿù÷þú÷þùøþøøþøøþøøÿùøÿúøÿúùÿüúÿýûÿýúÿúùÿüúÿþûÿþüÿþüÿþüÿþýÿþýÿþüÿþüÿþüÿþüÿýûÿýûÿýüÿþýÿþþÿýûÿûùÿüûÿýüÿýýÿþþÿþþÿüúÿýüÿþýÿþþÿþþÿþýÿþýÿýýÿýýÿþþÿÿþÿÿþÿÿÿÿÿþÿÿþÿÿþÿÿýÿþýÿþýÿÿýÿÿýÿþýÿüýÿþýÿÿüÿÿüÿÿýÿûûÿûûÿþýÿÿþÿÿýÿÿýÿÿþÿþþÿþþÿÿÿÿÿþÿþþÿþÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿþÿþýÿþýÿþþÿþýÿþýÿÿþÿÿþÿÿþÿÿþÿÿþÿþýÿþýÿÿþÿÿÿÿþþÿþþÿþþÿÿýþøðÁ³¶E¢ŠPFf[¡iqž¹ìòòþýüÿþþÿÿüÿøóÿúùÿþýÿÿþÿÿÿÿþþÿþþÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿÿÿÿþÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷óÿøôÿøôÿ÷óÿøôÿù÷ÿú÷ÿùöÿøöÿøöÿù÷ÿûøÿúøÿùõÿúöÿ÷õÿùöÿù÷ÿù÷ÿú÷ÿú÷ÿúøþù÷þù÷ÿù÷ÿøöÿùøÿúøÿûùÿùùþøøýøøþøøÿùøÿùøÿúøÿüùÿüúÿüúÿûúÿûúÿüùÿýúÿýúÿýûÿþüÿþýÿþüÿþüÿþüÿþüÿûûÿüûÿýüÿþýÿþýÿýúÿúùÿüûÿûüÿþýÿüüÿüüÿüúÿþüÿþýÿþþÿüýÿþýÿþþÿþýÿþýÿþþÿÿþÿÿþÿÿþÿÿýÿÿýÿýüÿýüÿýýÿþýÿÿþÿÿþÿýýÿýýÿþýÿþûÿþýÿÿüÿýûÿýüÿþýÿþûÿþûÿÿüÿþýÿþþÿþÿÿÿÿÿÿþÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿþûÿüúÿüúÿþýÿÿþÿÿþÿÿþÿþþÿþýÿýýÿýýÿþýÿþþÿþþÿþþÿÿÿÿýýÿýýÿþûùùê°±£il?ª¡;®©WžUž±ÉÎúø÷þþýÿÿþÿýùùëæýóõþþýÿÿþÿÿÿÿþþÿþþÿÿÿÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿþÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷óÿøôÿøóþõóþ÷óÿùöÿùöÿùöÿùöÿùõÿùõÿú÷ÿúøÿú÷ÿùöþõóþøõÿùöÿùöÿúöÿú÷ÿú÷þùöþùöÿùöÿ÷öÿø÷ÿù÷ÿù÷ÿùøþøøþ÷øþøøÿù÷ÿù÷ÿùøÿúøÿúùÿûúÿûúÿûúÿüùÿüùÿýûÿýüÿýüÿýûÿýûÿýüÿýüÿþúÿûúÿüûÿüúÿüûÿýûÿüúÿúùÿüúÿûúÿýüýùùþúùÿþüÿÿýÿþýÿýýÿüýÿþþÿýþÿýüÿýüÿþþÿÿÿÿÿþÿÿüÿþûÿþýÿþýÿþýÿþýÿþþÿÿþÿþýÿûûÿüûÿýûÿýûÿþüÿþûÿýûÿþýÿÿýÿþûÿþüÿÿüÿþýÿþþÿþÿÿÿÿÿÿÿÿÿþÿÿþÿÿþÿÿþÿÿþÿÿÿÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿýÿþûÿþüÿþýÿþýÿÿþÿÿþÿÿþÿþþÿþýÿýýÿýýÿþýÿþýÿþýÿþþÿþýÿûûÿüûÿýúóùéĵQ¶»TœÊUÅÖcÇÚÕÜÚâÑêñýûùþþýÿÿþÿýùþøóþø÷þþýÿÿþÿÿþÿÿýÿÿþÿÿþÿÿýÿÿýÿþþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿøóÿøôÿøóþõóþøôÿøõÿøõÿùöÿøõÿøôÿøõÿùöÿù÷ÿù÷ÿúöþøõþú÷ÿúøÿù÷ÿú÷ÿú÷þù÷þøöþù÷ÿùøÿù÷ÿù÷ÿøöþ÷öþööþõ÷þø÷þúøÿù÷ÿù÷ÿúøÿùøÿúùÿûúÿüûÿüûÿýúÿüúÿýûÿýûÿüûÿûûÿýûÿýüÿýüÿýúÿûúÿûúÿüúÿüúÿýûÿüûÿüûÿýûÿýûÿýüþûúþûúÿþýÿÿþÿþýÿýýÿýýÿþþÿþþÿýüÿýüÿþþÿÿþÿÿþÿÿýÿþýÿþýÿÿþÿÿþÿÿþÿÿþÿÿþÿþýÿýýÿýüÿýûÿýüÿþüÿþüÿþýÿþýÿÿþÿÿýÿÿýÿÿýÿþýÿþþÿÿÿÿÿÿÿþýÿþþÿÿÿÿÿþÿÿþÿÿþÿÿþÿÿþÿýûÿúúÿýüÿþýÿÿþÿýþÿþþÿÿþÿþþÿþýÿÿýÿÿýÿÿþÿÿþÿÿþÿÿþÿÿþÿÿÿÿþýÿýýÿýýÿûúÿýüÿþýÿþþÿþýÿýýÿýýÿýúóúôØà¢ÞçŠàé»äðÙïõëööòøöûüûþýüÿþþÿþþÿýýÿþüÿýüÿþþÿÿÿÿÿþÿþýÿþýÿüûÿûûÿýýÿþþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿøôÿøõÿøóÿöóÿøôÿöõÿøõÿùöÿøôÿøôÿùõÿùöÿøöÿùöÿúöÿúöÿùöÿù÷ÿùöÿùöÿø÷þø÷ý÷öþ÷öþø÷ÿø÷ÿù÷ÿø÷þ÷öþõöþö÷þùøÿúùÿú÷ÿúøÿúøÿúøÿûùÿýúÿýúÿýûÿûùÿûùÿûúÿüûÿüûÿúúÿýúÿýûÿüûÿüúÿúùÿúùÿüúÿýûÿûûÿýüÿþýÿþýÿýüÿþýÿþüÿýüÿþûÿýüÿüüÿýýÿýüÿþüÿþýÿþýÿþýÿþþÿþüÿþýÿÿþÿÿþÿÿþÿÿþÿþþÿþþÿþþÿþûÿþýÿÿþÿþþÿþýÿþûÿýûÿþýÿÿþÿÿþÿÿþÿÿþÿÿýÿÿýÿþýÿþþÿÿÿÿÿþÿþýÿþþÿýýÿýýÿýýÿþýÿÿþÿÿþÿýüÿüùÿýüÿþýÿúúÿúúÿýýÿþýÿþýÿþþÿÿþÿÿþÿÿþÿÿÿÿÿþÿþýÿþþÿÿþÿþýÿþýÿûûÿúúÿýüÿýüÿýýÿþþÿþþÿþþÿþýýþýïùúòøøðõöôö÷ûûúýüûþýüþýüÿþýÿþþÿûüÿþýÿÿýÿþýÿþýÿþýÿþþÿþþÿþýÿýûÿýýÿÿÿÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþ \ No newline at end of file -- 1.5.6.5
13 years, 8 months
1
0
0
0
last-svn-commit-836-gf553aa7 configure.ac: Configure scribo/tests/estim.
by Guillaume Lazzara
--- ChangeLog | 10 +++++++--- configure.ac | 1 + 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 97445bc..31d498c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,10 @@ 2011-04-05 Guillaume Lazzara <z(a)lrde.epita.fr> - * configure.ac: configure scribo/tests/primitive/extract. + * configure.ac: Configure scribo/tests/estim. + +2011-04-05 Guillaume Lazzara <z(a)lrde.epita.fr> + + * configure.ac: Configure scribo/tests/primitive/extract. 2011-02-17 Guillaume Lazzara <z(a)lrde.epita.fr> @@ -8,11 +12,11 @@ 2011-02-17 Guillaume Lazzara <z(a)lrde.epita.fr> - * configure.ac: scribo/src/primitive/remove. + * configure.ac: Configure scribo/src/primitive/remove. 2011-02-17 Guillaume Lazzara <z(a)lrde.epita.fr> - * configure.ac: configure scribo/tests/convert. + * configure.ac: Configure scribo/tests/convert. 2011-03-14 Thierry GERAUD <thierry.geraud(a)lrde.epita.fr> diff --git a/configure.ac b/configure.ac index 9f4c16a..189d905 100644 --- a/configure.ac +++ b/configure.ac @@ -346,6 +346,7 @@ AC_CONFIG_FILES([ scribo/tests/binarization/Makefile scribo/tests/convert/Makefile scribo/tests/core/Makefile + scribo/tests/estim/Makefile scribo/tests/filter/Makefile scribo/tests/preprocessing/Makefile scribo/tests/primitive/Makefile -- 1.5.6.5
13 years, 8 months
1
0
0
0
last-svn-commit-834-gddcab20 mln/accu/stat/median_h.hh: Add missing operator=().
by Guillaume Lazzara
--- milena/ChangeLog | 4 ++++ milena/mln/accu/stat/median_h.hh | 19 ++++++++++++++++++- 2 files changed, 22 insertions(+), 1 deletions(-) diff --git a/milena/ChangeLog b/milena/ChangeLog index 360e77e..8008503 100644 --- a/milena/ChangeLog +++ b/milena/ChangeLog @@ -1,3 +1,7 @@ +2011-04-05 Guillaume Lazzara <z(a)lrde.epita.fr> + + * mln/accu/stat/median_h.hh: Add missing operator=(). + 2011-03-15 Guillaume Lazzara <z(a)lrde.epita.fr> Regen generated files. diff --git a/milena/mln/accu/stat/median_h.hh b/milena/mln/accu/stat/median_h.hh index edd36f1..b38955d 100644 --- a/milena/mln/accu/stat/median_h.hh +++ b/milena/mln/accu/stat/median_h.hh @@ -1,4 +1,5 @@ -// Copyright (C) 2007, 2008, 2009 EPITA Research and Development Laboratory (LRDE) +// Copyright (C) 2007, 2008, 2009, 2011 EPITA Research and Development +// Laboratory (LRDE) // // This file is part of Olena. // @@ -83,6 +84,7 @@ namespace mln typedef V argument; median_h(); + median_h& operator=(const median_h& rhs); /// Manipulators. /// \{ @@ -133,6 +135,21 @@ namespace mln template <typename V> inline + median_h<V>& + median_h<V>::operator=(const median_h<V>& rhs) + { + h_ = rhs.h_; + sum_minus_ = rhs.sum_minus_; + sum_plus_ = rhs.sum_plus_; + valid_ = rhs.valid_; + i_ = rhs.i_; + t_ = rhs.t_; + + return *this; + } + + template <typename V> + inline void median_h<V>::take(const argument& t) { -- 1.5.6.5
13 years, 8 months
1
0
0
0
last-svn-commit-833-gaf0fa02 configure.ac: configure scribo/tests/primitive/extract.
by Guillaume Lazzara
--- ChangeLog | 4 ++++ configure.ac | 1 + 2 files changed, 5 insertions(+), 0 deletions(-) diff --git a/ChangeLog b/ChangeLog index f634518..97445bc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-04-05 Guillaume Lazzara <z(a)lrde.epita.fr> + + * configure.ac: configure scribo/tests/primitive/extract. + 2011-02-17 Guillaume Lazzara <z(a)lrde.epita.fr> * build-aux/build_unit_test.sh: Define HAVE_* for unit-tests. diff --git a/configure.ac b/configure.ac index 44f359b..9f4c16a 100644 --- a/configure.ac +++ b/configure.ac @@ -349,6 +349,7 @@ AC_CONFIG_FILES([ scribo/tests/filter/Makefile scribo/tests/preprocessing/Makefile scribo/tests/primitive/Makefile + scribo/tests/primitive/extract/Makefile scribo/tests/primitive/link/Makefile scribo/tests/table/Makefile scribo/tests/text/Makefile -- 1.5.6.5
13 years, 8 months
1
0
0
0
last-svn-commit-831-g0012ddf Update dmax functors interface.
by Guillaume Lazzara
* scribo/primitive/link/internal/dmax_default.hh, * scribo/primitive/link/internal/dmax_width_and_height.hh, * scribo/primitive/link/internal/dmax_width_only.hh: Rename operator() as compute_(). * scribo/primitive/link/internal/dmax_functor_base.hh: Make use of compute_(). * scribo/primitive/link/internal/link_functor_base.hh: Add a fixme. --- scribo/ChangeLog | 13 +++++++++++++ .../scribo/primitive/link/internal/dmax_default.hh | 16 ++++++++++++++-- .../primitive/link/internal/dmax_functor_base.hh | 13 +++++-------- .../link/internal/dmax_width_and_height.hh | 11 ++++++----- .../primitive/link/internal/dmax_width_only.hh | 7 ++++--- .../primitive/link/internal/link_functor_base.hh | 7 +++++-- 6 files changed, 47 insertions(+), 20 deletions(-) diff --git a/scribo/ChangeLog b/scribo/ChangeLog index d388268..8acfc4e 100644 --- a/scribo/ChangeLog +++ b/scribo/ChangeLog @@ -1,5 +1,18 @@ 2011-04-05 Guillaume Lazzara <z(a)lrde.epita.fr> + Update dmax functors interface. + + * scribo/primitive/link/internal/dmax_default.hh, + * scribo/primitive/link/internal/dmax_width_and_height.hh, + * scribo/primitive/link/internal/dmax_width_only.hh: Rename + operator() as compute_(). + + * scribo/primitive/link/internal/dmax_functor_base.hh: Make use of compute_(). + + * scribo/primitive/link/internal/link_functor_base.hh: Add a fixme. + +2011-04-05 Guillaume Lazzara <z(a)lrde.epita.fr> + Various fixes in Scribo. * scribo/core/component_set.hh: Update FIXMEs. diff --git a/scribo/scribo/primitive/link/internal/dmax_default.hh b/scribo/scribo/primitive/link/internal/dmax_default.hh index b4106a9..8a86f7e 100644 --- a/scribo/scribo/primitive/link/internal/dmax_default.hh +++ b/scribo/scribo/primitive/link/internal/dmax_default.hh @@ -52,7 +52,8 @@ namespace scribo typedef dmax_functor_base<dmax_default> super_; public: - dmax_default(const float& dmax_factor); + dmax_default(float dmax_factor); + float compute_(const box2d& b) const; protected: using super_::dmax_factor_; @@ -63,12 +64,23 @@ namespace scribo inline - dmax_default::dmax_default(const float& dmax_factor) + dmax_default::dmax_default(float dmax_factor) : super_(dmax_factor) { } + inline + float + dmax_default::compute_(const box2d& b) const + { + float + w = b.width(), + h = b.height(); + + return (w / 2.0f) + (dmax_factor_ * h);//math::max(w, h)); + } + # endif // ! MLN_INCLUDE_ONLY diff --git a/scribo/scribo/primitive/link/internal/dmax_functor_base.hh b/scribo/scribo/primitive/link/internal/dmax_functor_base.hh index 334cc4d..21ac818 100644 --- a/scribo/scribo/primitive/link/internal/dmax_functor_base.hh +++ b/scribo/scribo/primitive/link/internal/dmax_functor_base.hh @@ -1,4 +1,5 @@ -// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE) +// Copyright (C) 2010, 2011 EPITA Research and Development Laboratory +// (LRDE) // // This file is part of Olena. // @@ -57,7 +58,7 @@ namespace scribo { public: - dmax_functor_base(const float& dmax_factor); + dmax_functor_base(float dmax_factor); float operator()(const box2d& b) const; protected: @@ -69,7 +70,7 @@ namespace scribo template <typename E> - dmax_functor_base<E>::dmax_functor_base(const float& dmax_factor) + dmax_functor_base<E>::dmax_functor_base(float dmax_factor) : dmax_factor_(dmax_factor) { } @@ -79,11 +80,7 @@ namespace scribo float dmax_functor_base<E>::operator()(const box2d& b) const { - float - w = b.width(), - h = b.height(); - - return (w / 2.0f) + (dmax_factor_ * h);//math::max(w, h)); + return exact(this)->compute_(b); } diff --git a/scribo/scribo/primitive/link/internal/dmax_width_and_height.hh b/scribo/scribo/primitive/link/internal/dmax_width_and_height.hh index 4c1d561..fa68836 100644 --- a/scribo/scribo/primitive/link/internal/dmax_width_and_height.hh +++ b/scribo/scribo/primitive/link/internal/dmax_width_and_height.hh @@ -1,4 +1,5 @@ -// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE) +// Copyright (C) 2010, 2011 EPITA Research and Development Laboratory +// (LRDE) // // This file is part of Olena. // @@ -55,8 +56,8 @@ namespace scribo public: - dmax_width_and_height(const float& dmax_factor); - float operator()(const box2d&) const; + dmax_width_and_height(float dmax_factor); + float compute_(const box2d&) const; protected: using super_::dmax_factor_; @@ -67,7 +68,7 @@ namespace scribo inline - dmax_width_and_height::dmax_width_and_height(const float& dmax_factor) + dmax_width_and_height::dmax_width_and_height(float dmax_factor) : super_(dmax_factor) { } @@ -75,7 +76,7 @@ namespace scribo inline float - dmax_width_and_height::operator()(const box2d& b) const + dmax_width_and_height::compute_(const box2d& b) const { float w = b.width(), diff --git a/scribo/scribo/primitive/link/internal/dmax_width_only.hh b/scribo/scribo/primitive/link/internal/dmax_width_only.hh index 1d882ba..03658bf 100644 --- a/scribo/scribo/primitive/link/internal/dmax_width_only.hh +++ b/scribo/scribo/primitive/link/internal/dmax_width_only.hh @@ -1,4 +1,5 @@ -// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE) +// Copyright (C) 2010, 2011 EPITA Research and Development Laboratory +// (LRDE) // // This file is part of Olena. // @@ -56,7 +57,7 @@ namespace scribo public: dmax_width_only(); - float operator()(const box2d&) const; + float compute_(const box2d&) const; protected: using super_::dmax_factor_; @@ -75,7 +76,7 @@ namespace scribo inline float - dmax_width_only::operator()(const box2d& b) const + dmax_width_only::compute_(const box2d& b) const { float w = b.width(); return (w / 2.0f) + (dmax_factor_ * w); diff --git a/scribo/scribo/primitive/link/internal/link_functor_base.hh b/scribo/scribo/primitive/link/internal/link_functor_base.hh index 5b4fefa..11066c5 100644 --- a/scribo/scribo/primitive/link/internal/link_functor_base.hh +++ b/scribo/scribo/primitive/link/internal/link_functor_base.hh @@ -1,5 +1,5 @@ -// Copyright (C) 2009, 2010 EPITA Research and Development Laboratory -// (LRDE) +// Copyright (C) 2009, 2010, 2011 EPITA Research and Development +// Laboratory (LRDE) // // This file is part of Olena. // @@ -30,6 +30,9 @@ /// \file /// /// Base class for link functors. +/// +/// \fixme type used for 'current_object' argument should be of type +/// mln_value(L) # include <mln/core/concept/image.hh> -- 1.5.6.5
13 years, 8 months
1
0
0
0
last-svn-commit-830-g9cfcb85 Various fixes in Scribo.
by Guillaume Lazzara
* scribo/core/component_set.hh: Update FIXMEs. (update_labeled_image_()): New method. * scribo/core/def/color_type.hh: Introduce a new global type. * scribo/core/line_info.hh: Compute line pixels area and order component list by localization. * scribo/core/line_set.hh: Add operator<<. * scribo/core/object_groups.hh, * scribo/core/object_links.hh (is_valid(unsigned)): new method. * scribo/debug/links_image.hh: Make bounding box drawing optional. * scribo/filter/object_groups_small.hh: Return a temporary result. * scribo/filter/objects_h_thick.hh, * scribo/filter/objects_h_thin.hh, * scribo/filter/objects_v_thick.hh, * scribo/filter/objects_v_thin.hh: Fix variable names and make these routines work properly. * scribo/toolchain/content_in_doc.hh, * scribo/preprocessing/rotate_90.hh: Fix preconditions. * scribo/primitive/extract/non_text.hh: Remove useless precondition. * scribo/primitive/link/internal/link_single_dmax_ratio_aligned_base.hh: Remove a useless method. * scribo/primitive/link/internal/link_single_dmax_ratio_base.hh: Remove a useless (void). * scribo/text/extract_lines.hh: Use dmax_default functor. * src/debug/show_groups_bboxes.cc: Check hratio while linking. * src/preprocessing/denoise_fg.cc: Fix usage. * scribo/tests/toolchain/nepomuk/Makefile.am: Check if Magick++ is available. --- scribo/ChangeLog | 47 ++++++++++++++++ scribo/scribo/core/component_set.hh | 21 ++++++-- .../core/def/color_type.hh} | 25 +++++---- scribo/scribo/core/line_info.hh | 56 ++++++++++++++++++- scribo/scribo/core/line_set.hh | 17 ++++++ scribo/scribo/core/object_groups.hh | 14 ++++- scribo/scribo/core/object_links.hh | 11 ++++ scribo/scribo/debug/links_image.hh | 9 ++- scribo/scribo/filter/object_groups_small.hh | 30 +++++++++-- scribo/scribo/filter/objects_h_thick.hh | 42 +++++++------- scribo/scribo/filter/objects_h_thin.hh | 6 +- scribo/scribo/filter/objects_v_thick.hh | 42 +++++++------- scribo/scribo/filter/objects_v_thin.hh | 6 +- scribo/scribo/preprocessing/rotate_90.hh | 2 + scribo/scribo/primitive/extract/non_text.hh | 2 - .../link_single_dmax_ratio_aligned_base.hh | 5 -- .../link/internal/link_single_dmax_ratio_base.hh | 3 +- scribo/scribo/text/extract_lines.hh | 8 ++-- scribo/scribo/toolchain/content_in_doc.hh | 4 +- scribo/src/debug/show_groups_bboxes.cc | 16 +++++- scribo/src/preprocessing/denoise_fg.cc | 6 ++- scribo/tests/toolchain/nepomuk/Makefile.am | 2 + 22 files changed, 277 insertions(+), 97 deletions(-) copy scribo/{demo/demat/src/process_args.hh => scribo/core/def/color_type.hh} (78%) diff --git a/scribo/ChangeLog b/scribo/ChangeLog index e81959d..d388268 100644 --- a/scribo/ChangeLog +++ b/scribo/ChangeLog @@ -1,5 +1,52 @@ 2011-04-05 Guillaume Lazzara <z(a)lrde.epita.fr> + Various fixes in Scribo. + + * scribo/core/component_set.hh: Update FIXMEs. + (update_labeled_image_()): New method. + + * scribo/core/def/color_type.hh: Introduce a new global type. + + * scribo/core/line_info.hh: Compute line pixels area and order + component list by localization. + + * scribo/core/line_set.hh: Add operator<<. + + * scribo/core/object_groups.hh, + * scribo/core/object_links.hh (is_valid(unsigned)): new method. + + * scribo/debug/links_image.hh: Make bounding box drawing optional. + + * scribo/filter/object_groups_small.hh: Return a temporary result. + + * scribo/filter/objects_h_thick.hh, + * scribo/filter/objects_h_thin.hh, + * scribo/filter/objects_v_thick.hh, + * scribo/filter/objects_v_thin.hh: Fix variable names and make + these routines work properly. + + * scribo/toolchain/content_in_doc.hh, + * scribo/preprocessing/rotate_90.hh: Fix preconditions. + + * scribo/primitive/extract/non_text.hh: Remove useless precondition. + + * scribo/primitive/link/internal/link_single_dmax_ratio_aligned_base.hh: + Remove a useless method. + + * scribo/primitive/link/internal/link_single_dmax_ratio_base.hh: + Remove a useless (void). + + * scribo/text/extract_lines.hh: Use dmax_default functor. + + * src/debug/show_groups_bboxes.cc: Check hratio while linking. + + * src/preprocessing/denoise_fg.cc: Fix usage. + + * scribo/tests/toolchain/nepomuk/Makefile.am: Check if Magick++ is + available. + +2011-04-05 Guillaume Lazzara <z(a)lrde.epita.fr> + * scribo/text/extract_lines_wo_merge.hh: New line extraction routine. diff --git a/scribo/scribo/core/component_set.hh b/scribo/scribo/core/component_set.hh index a63ed6c..d729802 100644 --- a/scribo/scribo/core/component_set.hh +++ b/scribo/scribo/core/component_set.hh @@ -223,6 +223,8 @@ namespace scribo // L& labeled_image_(); + void update_labeled_image_(const L& lbl); + /// Return the underlying labeled image where invalid components /// have been erased. /// @@ -232,7 +234,7 @@ namespace scribo /// @} - private: + protected: /// Duplicate the underlying image and create a new component_set. void init_(const component_set<L>& model); @@ -276,7 +278,7 @@ namespace scribo const mln_value(L)& ncomps) : ima_(ima), ncomps_(ncomps) { - initialize(separators_, ima); // FIXME: do we really want that? + initialize(separators_, ima); // FIXME: to be removed mln::data::fill(separators_, false); typedef mln::accu::shape::bbox<mln_site(L)> bbox_accu_t; @@ -299,7 +301,7 @@ namespace scribo component::Type type) : ima_(ima), ncomps_(ncomps) { - initialize(separators_, ima); // FIXME: do we really want that? + initialize(separators_, ima); // FIXME: to be removed mln::data::fill(separators_, false); fill_infos(attribs, type); @@ -313,7 +315,7 @@ namespace scribo component::Type type) : ima_(ima), ncomps_(ncomps) { - initialize(separators_, ima); // FIXME: do we really want that? + initialize(separators_, ima); // FIXME: to be removed mln::data::fill(separators_, false); fill_infos(attribs, type); @@ -326,7 +328,7 @@ namespace scribo const mln::util::array<scribo::component_info>& infos) : ima_(ima), ncomps_(ncomps), infos_(infos) { - initialize(separators_, ima); // FIXME: do we really want that? + initialize(separators_, ima); // FIXME: to be removed mln::data::fill(separators_, false); } @@ -528,6 +530,15 @@ namespace scribo template <typename L> inline + void + component_set<L>::update_labeled_image_(const L& lbl) + { + data_->ima_ = lbl; + } + + + template <typename L> + inline bool component_set<L>::is_valid() const { diff --git a/scribo/demo/demat/src/process_args.hh b/scribo/scribo/core/def/color_type.hh similarity index 78% copy from scribo/demo/demat/src/process_args.hh copy to scribo/scribo/core/def/color_type.hh index 5ca72cf..7acd334 100644 --- a/scribo/demo/demat/src/process_args.hh +++ b/scribo/scribo/core/def/color_type.hh @@ -1,4 +1,4 @@ -// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE) +// Copyright (C) 2011 EPITA Research and Development Laboratory (LRDE) // // This file is part of Olena. // @@ -23,25 +23,26 @@ // exception does not however invalidate any other reasons why the // executable file might be covered by the GNU General Public License. -#ifndef SCRIBO_DEMO_SHARED_SRC_PROCESS_ARGS_HH -# define SCRIBO_DEMO_SHARED_SRC_PROCESS_ARGS_HH +#ifndef SCRIBO_CORE_COLOR_TYPE_HH +# define SCRIBO_CORE_COLOR_TYPE_HH + +/// \file +/// +/// Global type definition for labels. + +# include <mln/value/rgb8.hh> namespace scribo { - namespace demo + namespace def { - struct process_args - { - unsigned scale; - }; + typedef mln::value::rgb8 color_type; - - } // end of namespace scribo::demo + } // end of namespace scribo::def } // end of namespace scribo - -#endif // !SCRIBO_DEMO_SHARED_SRC_PROCESS_ARGS_HH +#endif // ! SCRIBO_CORE_DEF_HH diff --git a/scribo/scribo/core/line_info.hh b/scribo/scribo/core/line_info.hh index 866e3f4..749e627 100644 --- a/scribo/scribo/core/line_info.hh +++ b/scribo/scribo/core/line_info.hh @@ -84,6 +84,9 @@ namespace scribo mln::box2d ebbox_; mln::util::array<component_id_t> components_; + // The number of pixels used for line characters. + unsigned pixel_area_; + // Values relative to the line bbox. int baseline_; int meanline_; @@ -176,6 +179,8 @@ namespace scribo const mln::util::array<component_id_t>& component_ids() const; unsigned card() const; + unsigned pixel_area() const; + int baseline() const; int meanline() const; int ascent() const; @@ -348,6 +353,26 @@ namespace scribo indented_ = false; } + + + // sort_comp_ids functor + + template <typename L> + sort_comp_ids<L>::sort_comp_ids(const component_set<L>& comp_set) + : comps_(comp_set) + { + } + + + template <typename L> + bool + sort_comp_ids<L>::operator()(const component_id_t& l, + const component_id_t& r) const + { + return comps_(l).bbox().pmin().col() < comps_(r).bbox().pmin().col() + && comps_(l).bbox().pmax().col() < comps_(r).bbox().pmax().col(); + } + } // end of namespace scribo::internal @@ -381,7 +406,7 @@ namespace scribo template <typename L> inline line_info<L>::line_info(const line_info<L>& other) - : id_(0) + : parent_t(other), id_(0) { //data_->hidden_ = false; copy_data(other); @@ -487,6 +512,7 @@ namespace scribo return data_->components_; } + template <typename L> unsigned line_info<L>::card() const @@ -496,6 +522,14 @@ namespace scribo template <typename L> + unsigned + line_info<L>::pixel_area() const + { + return data_->pixel_area_; + } + + + template <typename L> int line_info<L>::baseline() const { @@ -885,6 +919,8 @@ namespace scribo char_space, char_width; + unsigned pixel_area = 0; + mln::accu::shape::bbox<P> bbox; mln::def::coord ref_line = mln_max(mln::def::coord); @@ -899,7 +935,7 @@ namespace scribo // Ignore punctuation for stats computation but not for bbox // computation. - if (data_->holder_.components()(c).type() == component::Punctuation) + if (comp_set(c).type() == component::Punctuation) continue; ref_line = mln::math::min(comp_set(c).bbox().pmin().row(), ref_line); @@ -911,6 +947,8 @@ namespace scribo { unsigned c = data_->components_(i); + pixel_area += comp_set(c).card(); + const mln::box2d& bb = comp_set(c).bbox(); // Bounding box. @@ -918,7 +956,7 @@ namespace scribo // Ignore punctuation for stats computation but not for bbox // computation. - if (data_->holder_.components()(c).type() == component::Punctuation) + if (comp_set(c).type() == component::Punctuation) continue; @@ -965,9 +1003,21 @@ namespace scribo // Finalization { + // Tag data_->tag_ = line::None; + + // Bbox data_->bbox_ = bbox.to_result(); + // Pixel area + data_->pixel_area_ = pixel_area; + + // Order component ids according to component localization (left + // to right). + std::sort(data_->components_.hook_std_vector_().begin(), + data_->components_.hook_std_vector_().end(), + internal::sort_comp_ids<L>(comp_set)); + // Char space if (char_space.card() < 2) data_->char_space_ = 0; diff --git a/scribo/scribo/core/line_set.hh b/scribo/scribo/core/line_set.hh index bfa9240..f1e443b 100644 --- a/scribo/scribo/core/line_set.hh +++ b/scribo/scribo/core/line_set.hh @@ -174,6 +174,9 @@ namespace scribo mln::util::tracked_ptr< internal::line_set_data<L> > data_; }; + template <typename L> + std::ostream& + operator<<(std::ostream& ostr, const line_set<L>& lines); namespace make { @@ -435,6 +438,20 @@ namespace scribo } + + template <typename L> + std::ostream& + operator<<(std::ostream& ostr, const line_set<L>& lines) + { + ostr << "line_set[" << std::endl; + for_all_lines(i, lines) + ostr << lines(i); + ostr << "]" << std::endl; + + return ostr; + } + + // Make routines. namespace make diff --git a/scribo/scribo/core/object_groups.hh b/scribo/scribo/core/object_groups.hh index bbfaf6e..2a4b0b1 100644 --- a/scribo/scribo/core/object_groups.hh +++ b/scribo/scribo/core/object_groups.hh @@ -1,5 +1,5 @@ -// Copyright (C) 2009, 2010 EPITA Research and Development Laboratory -// (LRDE) +// Copyright (C) 2009, 2010, 2011 EPITA Research and Development +// Laboratory (LRDE) // // This file is part of Olena. // @@ -86,6 +86,7 @@ namespace scribo void init_(const object_links<L>& links); bool is_valid() const; + bool is_valid(unsigned comp_id) const; unsigned nelements() const; @@ -190,6 +191,15 @@ namespace scribo } template <typename L> + bool + object_groups<L>::is_valid(unsigned comp_id) const + { + mln_assertion(is_valid()); + mln_assertion(comp_id < data_->links_.nelements()); + return data_->links_(comp_id) != 0; + } + + template <typename L> unsigned object_groups<L>::nelements() const { diff --git a/scribo/scribo/core/object_links.hh b/scribo/scribo/core/object_links.hh index 2c2eea1..1fbcd5a 100644 --- a/scribo/scribo/core/object_links.hh +++ b/scribo/scribo/core/object_links.hh @@ -84,6 +84,7 @@ namespace scribo const component_set<L>& components() const; bool is_valid() const; + bool is_valid(unsigned comp_id) const; unsigned nelements() const; @@ -181,6 +182,16 @@ namespace scribo template <typename L> + bool + object_links<L>::is_valid(unsigned comp_id) const + { + mln_precondition(is_valid()); + mln_precondition(comp_id < data_->comp_to_link_.nelements()); + return data_->comp_to_link_(comp_id) != 0; + } + + + template <typename L> unsigned object_links<L>::nelements() const { diff --git a/scribo/scribo/debug/links_image.hh b/scribo/scribo/debug/links_image.hh index 76447b7..47394be 100644 --- a/scribo/scribo/debug/links_image.hh +++ b/scribo/scribo/debug/links_image.hh @@ -55,7 +55,8 @@ namespace scribo mln_ch_value(I,value::rgb8) links_image(const Image<I>& input_, const object_links<L>& links, - anchor::Type anchor); + anchor::Type anchor, + bool draw_bboxes = true); # ifndef MLN_INCLUDE_ONLY @@ -65,7 +66,8 @@ namespace scribo mln_ch_value(I,value::rgb8) links_image(const Image<I>& input_, const object_links<L>& links, - anchor::Type anchor) + anchor::Type anchor, + bool draw_bboxes) { trace::entering("scribo::debug::links_image"); const I& input = exact(input_); @@ -78,7 +80,8 @@ namespace scribo image2d<value::rgb8> links_image = data::convert(value::rgb8(), input); - scribo::draw::bounding_boxes(links_image, comps, literal::blue); + if (draw_bboxes) + scribo::draw::bounding_boxes(links_image, comps, literal::blue); for_all_links(l, links) if (links(l) != l) diff --git a/scribo/scribo/filter/object_groups_small.hh b/scribo/scribo/filter/object_groups_small.hh index f736a50..8dd244c 100644 --- a/scribo/scribo/filter/object_groups_small.hh +++ b/scribo/scribo/filter/object_groups_small.hh @@ -1,5 +1,5 @@ -// Copyright (C) 2009, 2010 EPITA Research and Development Laboratory -// (LRDE) +// Copyright (C) 2009, 2010, 2011 EPITA Research and Development +// Laboratory (LRDE) // // This file is part of Olena. // @@ -50,6 +50,7 @@ namespace scribo \param[in] groups Information about object groups. \param[in] n_links The minimum number of links per group. + \param[out] group_size Return the group sizes _before_ filtering. \return A copy of object group in which small groups have been removed. @@ -57,9 +58,17 @@ namespace scribo template <typename L> object_groups<L> object_groups_small(const object_groups<L>& groups, + unsigned n_links, + mln::util::array<unsigned>& group_size); + + // \overload + template <typename L> + object_groups<L> + object_groups_small(const object_groups<L>& groups, unsigned n_links); + # ifndef MLN_INCLUDE_ONLY @@ -67,14 +76,15 @@ namespace scribo inline object_groups<L> object_groups_small(const object_groups<L>& groups, - unsigned n_links) + unsigned n_links, + mln::util::array<unsigned>& group_size) { trace::entering("scribo::filter::object_groups_small"); mln_precondition(groups.is_valid()); // Counting the number of objects per group. - mln::util::array<unsigned> group_size(groups.nelements(), 0); + group_size = mln::util::array<unsigned>(groups.nelements(), 0); for_all_groups(i, group_size) ++group_size[groups(i)]; @@ -90,6 +100,18 @@ namespace scribo } + template <typename L> + inline + object_groups<L> + object_groups_small(const object_groups<L>& groups, + unsigned n_links) + { + mln::util::array<unsigned> group_size; + return object_groups_small(groups, n_links, group_size); + } + + + # endif // ! MLN_INCLUDE_ONLY } // end of namespace scribo::filter diff --git a/scribo/scribo/filter/objects_h_thick.hh b/scribo/scribo/filter/objects_h_thick.hh index 86dc8dc..06b75dc 100644 --- a/scribo/scribo/filter/objects_h_thick.hh +++ b/scribo/scribo/filter/objects_h_thick.hh @@ -1,5 +1,5 @@ -// Copyright (C) 2009, 2010 EPITA Research and Development Laboratory -// (LRDE) +// Copyright (C) 2009, 2010, 2011 EPITA Research and Development +// Laboratory (LRDE) // // This file is part of Olena. // @@ -46,12 +46,12 @@ namespace scribo using namespace mln; - /// Remove objects horizontaly thicker or equal to \p min_thickness. + /// Remove objects horizontaly thicker or equal to \p max_thickness. /// /// \param[in] input_ A binary image. /// \param[in] nbh_ A neighborhood used in labeling algorithms. /// \param[in] label_type The label type used for labeling. - /// \param[in] min_thickness The maximum thickness value. + /// \param[in] max_thickness The maximum thickness value. /// /// \result A binary image without thick objects. // @@ -61,13 +61,13 @@ namespace scribo objects_h_thick(const Image<I>& input_, const Neighborhood<N>& nbh_, const V& label_type, - unsigned min_thickness); + unsigned max_thickness); - /// Remove objects horizontaly thicker or equal to \p min_thickness. + /// Remove objects horizontaly thicker or equal to \p max_thickness. /// /// \param[in] comps Component data. - /// \param[in] min_thickness The minimum thickness value. + /// \param[in] max_thickness The minimum thickness value. /// /// \result A component data set without too thick components. // @@ -75,7 +75,7 @@ namespace scribo inline component_set<L> objects_h_thick(const component_set<L>& comps, - unsigned min_thickness); + unsigned max_thickness); @@ -95,20 +95,20 @@ namespace scribo /// Constructor /// /// \param[in] comps Component data. - /// \param[in] min_thickness the minimum thickness allowed. + /// \param[in] max_thickness the minimum thickness allowed. // h_thick_object_filter(const component_set<L>& comps, - unsigned min_thickness) - : comps_(comps), min_thickness_(min_thickness) + unsigned max_thickness) + : comps_(comps), max_thickness_(max_thickness) { } /// Constructor /// - /// \param[in] min_thickness the minimum thickness allowed. + /// \param[in] max_thickness the minimum thickness allowed. // - h_thick_object_filter(unsigned min_thickness) - : min_thickness_(min_thickness) + h_thick_object_filter(unsigned max_thickness) + : max_thickness_(max_thickness) { } @@ -120,14 +120,14 @@ namespace scribo } /// Return false if the component is thicker than - /// \p min_thickness_. + /// \p max_thickness_. /// /// \param[in] l An image value. bool operator()(const mln_value(L)& l) const { if (l == literal::zero) return false; - return comps_(l).bbox().height() > min_thickness_; + return comps_(l).bbox().width() < max_thickness_; } @@ -135,7 +135,7 @@ namespace scribo component_set<L> comps_; /// The minimum thickness. - unsigned min_thickness_; + unsigned max_thickness_; }; @@ -148,7 +148,7 @@ namespace scribo objects_thick(const Image<I>& input_, const Neighborhood<N>& nbh_, const V& label_type, - unsigned min_thickness) + unsigned max_thickness) { trace::entering("scribo::filter::objects_h_thick"); @@ -158,7 +158,7 @@ namespace scribo mln_precondition(input.is_valid()); mln_precondition(nbh.is_valid()); - internal::h_thick_object_filter<V> functor(min_thickness); + internal::h_thick_object_filter<V> functor(max_thickness); mln_concrete(I) output = internal::compute(input, nbh, label_type, functor); @@ -171,11 +171,11 @@ namespace scribo inline component_set<L> objects_h_thick(const component_set<L>& comps, - unsigned min_thickness) + unsigned max_thickness) { trace::entering("scribo::filter::objects_h_thick"); - internal::h_thick_object_filter<L> functor(comps, min_thickness); + internal::h_thick_object_filter<L> functor(comps, max_thickness); component_set<L> output = internal::compute(comps, functor); trace::exiting("scribo::filter::objects_h_thick"); diff --git a/scribo/scribo/filter/objects_h_thin.hh b/scribo/scribo/filter/objects_h_thin.hh index 43bcdfc..8caa2cc 100644 --- a/scribo/scribo/filter/objects_h_thin.hh +++ b/scribo/scribo/filter/objects_h_thin.hh @@ -1,5 +1,5 @@ -// Copyright (C) 2009, 2010 EPITA Research and Development Laboratory -// (LRDE) +// Copyright (C) 2009, 2010, 2011 EPITA Research and Development +// Laboratory (LRDE) // // This file is part of Olena. // @@ -129,7 +129,7 @@ namespace scribo { if (l == literal::zero) return false; - return comps_(l).bbox().ncols() > min_thinness_; + return comps_(l).bbox().width() > min_thinness_; } /// Component bounding boxes. diff --git a/scribo/scribo/filter/objects_v_thick.hh b/scribo/scribo/filter/objects_v_thick.hh index 1db00cb..ad1a4df 100644 --- a/scribo/scribo/filter/objects_v_thick.hh +++ b/scribo/scribo/filter/objects_v_thick.hh @@ -1,5 +1,5 @@ -// Copyright (C) 2009, 2010 EPITA Research and Development Laboratory -// (LRDE) +// Copyright (C) 2009, 2010, 2011 EPITA Research and Development +// Laboratory (LRDE) // // This file is part of Olena. // @@ -46,12 +46,12 @@ namespace scribo using namespace mln; - /// Remove components verticaly thicker or equal to \p min_thickness. + /// Remove components verticaly thicker or equal to \p max_thickness. /// /// \param[in] input_ A binary image. /// \param[in] nbh_ A neighborhood used in labeling algorithms. /// \param[in] label_type The label type used for labeling. - /// \param[in] min_thickness The maximum thickness value. + /// \param[in] max_thickness The maximum thickness value. /// /// \result A binary image without thick components. // @@ -61,13 +61,13 @@ namespace scribo objects_v_thick(const Image<I>& input_, const Neighborhood<N>& nbh_, const V& label_type, - unsigned min_thickness); + unsigned max_thickness); - /// Remove components verticaly thicker or equal to \p min_thickness. + /// Remove components verticaly thicker or equal to \p max_thickness. /// /// \param[in] comps A component set. - /// \param[in] min_thickness The maximum thickness value. + /// \param[in] max_thickness The maximum thickness value. /// /// \result An object image without too thick components. // @@ -75,7 +75,7 @@ namespace scribo inline component_set<L> objects_v_thick(const component_set<L>& comps, - unsigned min_thickness); + unsigned max_thickness); @@ -95,20 +95,20 @@ namespace scribo /// Constructor /// /// \param[in] comps A component set. - /// \param[in] min_thickness the maximum thickness allowed. + /// \param[in] max_thickness the maximum thickness allowed. // v_thick_object_filter(const component_set<L>& comps, - unsigned min_thickness) - : comps_(comps), min_thickness_(min_thickness) + unsigned max_thickness) + : comps_(comps), max_thickness_(max_thickness) { } /// Constructor /// - /// \param[in] min_thickness the maximum thickness allowed. + /// \param[in] max_thickness the maximum thickness allowed. // - v_thick_object_filter(unsigned min_thickness) - : min_thickness_(min_thickness) + v_thick_object_filter(unsigned max_thickness) + : max_thickness_(max_thickness) { } @@ -120,14 +120,14 @@ namespace scribo } /// Return false if the components is thicker than - /// \p min_thickness_. + /// \p max_thickness_. /// /// \param[in] l An image value. bool operator()(const mln_value(L)& l) const { if (l == literal::zero) return false; - return comps_(l).bbox().nrows() > min_thickness_; + return comps_(l).bbox().height() < max_thickness_; } @@ -135,7 +135,7 @@ namespace scribo component_set<L> comps_; /// The min thickness. - unsigned min_thickness_; + unsigned max_thickness_; }; @@ -148,7 +148,7 @@ namespace scribo objects_thick(const Image<I>& input_, const Neighborhood<N>& nbh_, const V& label_type, - unsigned min_thickness) + unsigned max_thickness) { trace::entering("scribo::filter::objects_v_thick"); @@ -158,7 +158,7 @@ namespace scribo mln_precondition(input.is_valid()); mln_precondition(nbh.is_valid()); - internal::v_thick_object_filter<V> functor(min_thickness); + internal::v_thick_object_filter<V> functor(max_thickness); mln_concrete(I) output = internal::compute(input, nbh, label_type, functor); @@ -171,11 +171,11 @@ namespace scribo inline component_set<L> objects_v_thick(const component_set<L>& comps, - unsigned min_thickness) + unsigned max_thickness) { trace::entering("scribo::filter::objects_v_thick"); - internal::v_thick_object_filter<L> functor(comps, min_thickness); + internal::v_thick_object_filter<L> functor(comps, max_thickness); component_set<L> output = internal::compute(comps, functor); trace::exiting("scribo::filter::objects_v_thick"); diff --git a/scribo/scribo/filter/objects_v_thin.hh b/scribo/scribo/filter/objects_v_thin.hh index de11cec..f2280eb 100644 --- a/scribo/scribo/filter/objects_v_thin.hh +++ b/scribo/scribo/filter/objects_v_thin.hh @@ -1,5 +1,5 @@ -// Copyright (C) 2009, 2010 EPITA Research and Development Laboratory -// (LRDE) +// Copyright (C) 2009, 2010, 2011 EPITA Research and Development +// Laboratory (LRDE) // // This file is part of Olena. // @@ -130,7 +130,7 @@ namespace scribo { if (l == literal::zero) return false; - return comps_.bbox(l).nrows() > min_thinness_; + return comps_(l).bbox().height() > min_thinness_; } /// Component bounding boxes. diff --git a/scribo/scribo/preprocessing/rotate_90.hh b/scribo/scribo/preprocessing/rotate_90.hh index 523b82f..8db703d 100644 --- a/scribo/scribo/preprocessing/rotate_90.hh +++ b/scribo/scribo/preprocessing/rotate_90.hh @@ -80,6 +80,8 @@ namespace scribo const I& input = exact(input_); mln_precondition(input.is_valid()); + mln_precondition(input.domain().pmin().row() > 0); + mln_precondition(input.domain().pmin().col() > 0); // Works only on one block images. mlc_is(mln_trait_image_value_access(I), diff --git a/scribo/scribo/primitive/extract/non_text.hh b/scribo/scribo/primitive/extract/non_text.hh index cbc6ea2..e2a6a03 100644 --- a/scribo/scribo/primitive/extract/non_text.hh +++ b/scribo/scribo/primitive/extract/non_text.hh @@ -308,8 +308,6 @@ namespace scribo t.start(); mln_precondition(doc.is_valid()); - - mln_precondition(doc.has_line_seps()); mln_precondition(doc.has_text()); // FIXME: Do these images exist elsewhere? diff --git a/scribo/scribo/primitive/link/internal/link_single_dmax_ratio_aligned_base.hh b/scribo/scribo/primitive/link/internal/link_single_dmax_ratio_aligned_base.hh index 56879bb..64c89ca 100644 --- a/scribo/scribo/primitive/link/internal/link_single_dmax_ratio_aligned_base.hh +++ b/scribo/scribo/primitive/link/internal/link_single_dmax_ratio_aligned_base.hh @@ -102,11 +102,6 @@ namespace scribo # endif // ! SCRIBO_NDEBUG } - void compute_next_site_(P& p) - { - ++p.col(); - } - mln_site(L) start_point_(unsigned current_object, anchor::Type anchor) diff --git a/scribo/scribo/primitive/link/internal/link_single_dmax_ratio_base.hh b/scribo/scribo/primitive/link/internal/link_single_dmax_ratio_base.hh index 3abe663..d99cbee 100644 --- a/scribo/scribo/primitive/link/internal/link_single_dmax_ratio_base.hh +++ b/scribo/scribo/primitive/link/internal/link_single_dmax_ratio_base.hh @@ -139,9 +139,8 @@ namespace scribo inline mln_site(L) link_single_dmax_ratio_base<L, F, E>::start_point_(unsigned current_object, - anchor::Type anchor) + anchor::Type anchor) { - (void) anchor; return internal::compute_anchor(this->components_, current_object, anchor); } diff --git a/scribo/scribo/text/extract_lines.hh b/scribo/scribo/text/extract_lines.hh index e69a249..53fd742 100644 --- a/scribo/scribo/text/extract_lines.hh +++ b/scribo/scribo/text/extract_lines.hh @@ -123,15 +123,15 @@ namespace scribo object_links<L> left_link = primitive::link::with_single_left_link_dmax_ratio( comps, - primitive::link::internal::dmax_width_and_height(1), -// primitive::link::internal::dmax_default(1), +// primitive::link::internal::dmax_width_and_height(1), + primitive::link::internal::dmax_default(1), anchor::MassCenter); object_links<L> right_link = primitive::link::with_single_right_link_dmax_ratio( comps, - primitive::link::internal::dmax_width_and_height(1), -// primitive::link::internal::dmax_default(1), +// primitive::link::internal::dmax_width_and_height(1), + primitive::link::internal::dmax_default(1), anchor::MassCenter); // Validating left and right links. diff --git a/scribo/scribo/toolchain/content_in_doc.hh b/scribo/scribo/toolchain/content_in_doc.hh index 4469afa..8f6f7a4 100644 --- a/scribo/scribo/toolchain/content_in_doc.hh +++ b/scribo/scribo/toolchain/content_in_doc.hh @@ -63,8 +63,8 @@ namespace scribo bool enable_ocr = true, const std::string& language = std::string("eng")) { - mln_precondition(input.is_valid()); - mln_precondition(input_preproc.is_valid()); + mln_precondition(exact(input).is_valid()); + mln_precondition(exact(input_preproc).is_valid()); internal::content_in_doc_functor<J> f("noname"); f.enable_denoising = denoise; diff --git a/scribo/src/debug/show_groups_bboxes.cc b/scribo/src/debug/show_groups_bboxes.cc index b323976..c7457ad 100644 --- a/scribo/src/debug/show_groups_bboxes.cc +++ b/scribo/src/debug/show_groups_bboxes.cc @@ -30,15 +30,18 @@ #include <scribo/primitive/link/merge_double_link.hh> #include <scribo/primitive/link/internal/dmax_width_and_height.hh> +#include <scribo/filter/object_links_bbox_h_ratio.hh> + int main(int argc, char *argv[]) { using namespace mln; using namespace scribo; using namespace scribo::primitive; - if (argc != 3) + if (argc != 3 && argc != 4) { - std::cerr << "Usage : " << argv[0] << " input.pbm out.pbm" << std::endl; + std::cerr << "Usage : " << argv[0] << " input.pbm out.pbm [hratio = 2.5]" << std::endl; + std::cerr << "Group components and makes sure size ratio is correct." << std::endl; return 1; } @@ -73,9 +76,16 @@ int main(int argc, char *argv[]) merged_links = primitive::link::merge_double_link(left_link, right_link); + float hratio = 2.5f; + if (argc == 4) + hratio = atof(argv[3]); + + object_links<L> hratio_filtered_links + = filter::object_links_bbox_h_ratio(merged_links, hratio); + object_groups<L> - groups = group::from_single_link(merged_links); + groups = group::from_single_link(hratio_filtered_links); line_set<L> lines(groups); diff --git a/scribo/src/preprocessing/denoise_fg.cc b/scribo/src/preprocessing/denoise_fg.cc index 307e8f6..a7a5bea 100644 --- a/scribo/src/preprocessing/denoise_fg.cc +++ b/scribo/src/preprocessing/denoise_fg.cc @@ -1,4 +1,5 @@ -// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE) +// Copyright (C) 2010, 2011 EPITA Research and Development Laboratory +// (LRDE) // // This file is part of Olena. // @@ -35,7 +36,8 @@ const char *args_desc[][2] = { { "input.pbm", "A binary image. 'True' for objects, 'False'\ for the background." }, - { "fg_min_card", "The minimum neighbor count to be set to false." }, + { "fg_min_card", "The minimum neighbor count to be set to false." + " (common value : 3 or 4)" }, {0, 0} }; diff --git a/scribo/tests/toolchain/nepomuk/Makefile.am b/scribo/tests/toolchain/nepomuk/Makefile.am index 331fb6f..ce75f17 100644 --- a/scribo/tests/toolchain/nepomuk/Makefile.am +++ b/scribo/tests/toolchain/nepomuk/Makefile.am @@ -26,6 +26,7 @@ check_PROGRAMS = if HAVE_QT if HAVE_TESSERACT +if HAVE_MAGICKXX check_PROGRAMS += text_extraction text_extraction_SOURCES = text_extraction.cc @@ -42,6 +43,7 @@ text_extraction_LDFLAGS = $(QT_LDFLAGS) $(LDFLAGS) \ -lpthread text_extraction_LDADD = $(QT_LIBS) $(LDADD) +endif HAVE_MAGICKXX endif HAVE_TESSERACT endif HAVE_QT -- 1.5.6.5
13 years, 8 months
1
0
0
0
last-svn-commit-829-g59dd554 scribo/text/extract_lines_wo_merge.hh: New line extraction routine.
by Guillaume Lazzara
--- scribo/ChangeLog | 5 ++ ...{extract_lines.hh => extract_lines_wo_merge.hh} | 65 ++++++++++++++------ 2 files changed, 51 insertions(+), 19 deletions(-) copy scribo/scribo/text/{extract_lines.hh => extract_lines_wo_merge.hh} (66%) diff --git a/scribo/ChangeLog b/scribo/ChangeLog index 048a289..e81959d 100644 --- a/scribo/ChangeLog +++ b/scribo/ChangeLog @@ -1,3 +1,8 @@ +2011-04-05 Guillaume Lazzara <z(a)lrde.epita.fr> + + * scribo/text/extract_lines_wo_merge.hh: New line extraction + routine. + 2011-03-22 Guillaume Lazzara <z(a)lrde.epita.fr> * demo/viewer/xml_widget.cc: Fix a warning. diff --git a/scribo/scribo/text/extract_lines.hh b/scribo/scribo/text/extract_lines_wo_merge.hh similarity index 66% copy from scribo/scribo/text/extract_lines.hh copy to scribo/scribo/text/extract_lines_wo_merge.hh index e69a249..0d90600 100644 --- a/scribo/scribo/text/extract_lines.hh +++ b/scribo/scribo/text/extract_lines_wo_merge.hh @@ -1,5 +1,4 @@ -// Copyright (C) 2009, 2010, 2011 EPITA Research and Development -// Laboratory (LRDE) +// Copyright (C) 2011 EPITA Research and Development Laboratory (LRDE) // // This file is part of Olena. // @@ -24,8 +23,8 @@ // exception does not however invalidate any other reasons why the // executable file might be covered by the GNU General Public License. -#ifndef SCRIBO_TEXT_EXTRACT_LINES_HH -# define SCRIBO_TEXT_EXTRACT_LINES_HH +#ifndef SCRIBO_TEXT_EXTRACT_LINES_WO_MERGE_HH +# define SCRIBO_TEXT_EXTRACT_LINES_WO_MERGE_HH /// \file /// @@ -36,6 +35,7 @@ # include <scribo/core/def/lbl_type.hh> # include <scribo/core/line_set.hh> +# include <scribo/core/document.hh> # include <scribo/primitive/extract/components.hh> @@ -72,33 +72,63 @@ namespace scribo */ template <typename I, typename N> line_set<mln_ch_value(I,scribo::def::lbl_type)> - extract_lines(const Image<I>& input_, const Neighborhood<N>& nbh_, - const mln_ch_value(I,bool)& separators); + extract_lines_wo_merge(const Image<I>& input_, const Neighborhood<N>& nbh_, + const mln_ch_value(I,bool)& separators); /// \overload template <typename I, typename N> line_set<mln_ch_value(I,scribo::def::lbl_type)> - extract_lines(const Image<I>& input, const Neighborhood<N>& nbh); + extract_lines_wo_merge(const Image<I>& input, const Neighborhood<N>& nbh); + /// \overload + template <typename L, typename N> + line_set<mln_ch_value(L,scribo::def::lbl_type)> + extract_lines_wo_merge(const document<L>& doc, const Neighborhood<N>& nbh); + + /// \overload + template <typename L, typename N> + line_set<mln_ch_value(L,scribo::def::lbl_type)> + extract_lines_wo_merge(const document<L>& doc, const Neighborhood<N>& nbh, + const mln_ch_value(L,bool)& separators); # ifndef MLN_INCLUDE_ONLY + template <typename L, typename N> + line_set<mln_ch_value(L,scribo::def::lbl_type)> + extract_lines_wo_merge(const document<L>& doc, const Neighborhood<N>& nbh) + { + mln_precondition(doc.is_valid()); + mln_ch_value(L,bool) seps; + return extract_lines_wo_merge(doc.binary_image(), nbh, seps); + } + + + template <typename L, typename N> + line_set<mln_ch_value(L,scribo::def::lbl_type)> + extract_lines_wo_merge(const document<L>& doc, const Neighborhood<N>& nbh, + const mln_ch_value(L,bool)& separators) + { + mln_precondition(doc.is_valid()); + return extract_lines_wo_merge(doc.binary_image(), nbh, separators); + } + + template <typename I, typename N> line_set<mln_ch_value(I,scribo::def::lbl_type)> - extract_lines(const Image<I>& input, const Neighborhood<N>& nbh) + extract_lines_wo_merge(const Image<I>& input, const Neighborhood<N>& nbh) { mln_ch_value(I,bool) seps; - return extract_lines(input, nbh, seps); + return extract_lines_wo_merge(input, nbh, seps); } template <typename I, typename N> line_set<mln_ch_value(I,scribo::def::lbl_type)> - extract_lines(const Image<I>& input_, const Neighborhood<N>& nbh_, - const mln_ch_value(I,bool)& separators) + extract_lines_wo_merge(const Image<I>& input_, const Neighborhood<N>& nbh_, + const mln_ch_value(I,bool)& separators) { - trace::entering("scribo::text::extract_lines"); + trace::entering("scribo::text::extract_lines_wo_merge"); const I& input = exact(input_); const N& nbh = exact(nbh_); @@ -123,15 +153,13 @@ namespace scribo object_links<L> left_link = primitive::link::with_single_left_link_dmax_ratio( comps, - primitive::link::internal::dmax_width_and_height(1), -// primitive::link::internal::dmax_default(1), + primitive::link::internal::dmax_default(1), anchor::MassCenter); object_links<L> right_link = primitive::link::with_single_right_link_dmax_ratio( comps, - primitive::link::internal::dmax_width_and_height(1), -// primitive::link::internal::dmax_default(1), + primitive::link::internal::dmax_default(1), anchor::MassCenter); // Validating left and right links. @@ -147,9 +175,8 @@ namespace scribo groups = primitive::group::from_single_link(hratio_filtered_links); line_set<L> lines(groups); - lines = text::merging(lines); - trace::exiting("scribo::text::extract_lines"); + trace::exiting("scribo::text::extract_lines_wo_merge"); return lines; } @@ -159,4 +186,4 @@ namespace scribo } // end of namespace scribo -#endif // ! SCRIBO_TEXT_EXTRACT_LINES_HH +#endif // ! SCRIBO_TEXT_EXTRACT_LINES_WO_MERGE_HH -- 1.5.6.5
13 years, 8 months
1
0
0
0
← Newer
1
...
8
9
10
11
Older →
Jump to page:
1
2
3
4
5
6
7
8
9
10
11
Results per page:
10
25
50
100
200