
* scribo/primitive/link/internal/link_single_dmax_ratio_aligned_base.hh, * scribo/primitive/link/with_single_left_link_dmax_ratio_aligned.hh: New. * scribo/primitive/link/with_single_right_link_dmax_ratio_aligned.hh: Cleanup. --- scribo/ChangeLog | 11 + .../link_single_dmax_ratio_aligned_base.hh | 268 ++++++++++++++++++++ ...=> with_single_left_link_dmax_ratio_aligned.hh} | 109 ++------ .../with_single_right_link_dmax_ratio_aligned.hh | 69 +----- 4 files changed, 317 insertions(+), 140 deletions(-) create mode 100644 scribo/scribo/primitive/link/internal/link_single_dmax_ratio_aligned_base.hh copy scribo/scribo/primitive/link/{with_single_right_link_dmax_ratio_aligned.hh => with_single_left_link_dmax_ratio_aligned.hh} (59%) diff --git a/scribo/ChangeLog b/scribo/ChangeLog index 10a8269..5705c05 100644 --- a/scribo/ChangeLog +++ b/scribo/ChangeLog @@ -1,5 +1,16 @@ 2011-03-14 Guillaume Lazzara <z@lrde.epita.fr> + Introduce a new component linking method. + + * scribo/primitive/link/internal/link_single_dmax_ratio_aligned_base.hh, + * scribo/primitive/link/with_single_left_link_dmax_ratio_aligned.hh: + New. + + * scribo/primitive/link/with_single_right_link_dmax_ratio_aligned.hh: + Cleanup. + +2011-03-14 Guillaume Lazzara <z@lrde.epita.fr> + Spread anchor value to more methods in link functors. * scribo/primitive/link/internal/find_link.hh, 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 new file mode 100644 index 0000000..56879bb --- /dev/null +++ b/scribo/scribo/primitive/link/internal/link_single_dmax_ratio_aligned_base.hh @@ -0,0 +1,268 @@ +// 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_PRIMITIVE_LINK_INTERNAL_LINK_SINGLE_DMAX_RATIO_ALIGNED_BASE_HH_ +# define SCRIBO_PRIMITIVE_LINK_INTERNAL_LINK_SINGLE_DMAX_RATIO_ALIGNED_BASE_HH_ + +/// \file +/// +/// \brief Base class for link functors using bounding box center, +/// a proportional max distance and alignment criterion. + + +# include <mln/accu/center.hh> +# include <mln/labeling/compute.hh> +# include <mln/math/abs.hh> +# include <mln/math/max.hh> +# include <mln/util/array.hh> +# include <mln/value/rgb8.hh> +# include <mln/draw/line.hh> +# include <mln/literal/colors.hh> +# include <mln/norm/l1.hh> + +# include <scribo/core/macros.hh> +# include <scribo/core/tag/anchor.hh> +# include <scribo/core/component_set.hh> +# include <scribo/core/object_links.hh> +# include <scribo/core/concept/dmax_functor.hh> + +# include <scribo/debug/logger.hh> + +# include <scribo/primitive/link/internal/link_single_dmax_ratio_base.hh> +# include <scribo/filter/internal/component_aligned.hh> + + +namespace scribo +{ + + namespace primitive + { + + namespace link + { + + namespace internal + { + using namespace scribo::debug; + + + template <typename L, typename F, typename E> + class link_single_dmax_ratio_aligned_base + : public link_single_dmax_ratio_base<L, F, E> + { + typedef link_single_dmax_ratio_base<L, F, E> super_; + + public: + typedef mln_site(L) P; + + link_single_dmax_ratio_aligned_base( + const component_set<L>& components, + const DMax_Functor<F>& dmax_f, + float min_angle, + float max_angle, + anchor::Type anchor) + : super_(components, anchor::Horizontal, exact(dmax_f)), + debug_anchor_(anchor) + { + min_alpha_rad = (min_angle / 180.0f) * math::pi; + max_alpha_rad = (max_angle / 180.0f) * math::pi; + +# ifndef SCRIBO_NDEBUG + if (scribo::debug::logger().is_at_level(debug::AuxiliaryResults)) + { + initialize(debug_, components.labeled_image()); + data::fill(debug_, literal::black); + data::fill((debug_ + | (pw::value(components.labeled_image()) != 0u)).rw(), + literal::white); + debug_angle_ = duplicate(debug_); + } +# endif // ! SCRIBO_NDEBUG + } + + void compute_next_site_(P& p) + { + ++p.col(); + } + + + mln_site(L) + start_point_(unsigned current_object, anchor::Type anchor) + { + return link::internal::compute_anchor(this->components_, + current_object, anchor); + } + + + inline + bool + valid_link_(unsigned current_object, + const P& start_point, + const P& p, + anchor::Type anchor) + { + if (!super_::valid_link_(current_object, start_point, p, anchor)) + return false; + + // Distance between the two components. + float dist;// = math::abs(p[this->direction_] - start_point[this->direction_]); + + box<P> b = this->components_(current_object).bbox(); + if (p[this->direction_] > b.pmax()[this->direction_]) + dist = math::abs(p[this->direction_] - b.pmax()[this->direction_]); + // current object is on the right. + else + dist = math::abs(p[this->direction_] - b.pmin()[this->direction_]); + + + unsigned ldist = this->components_(current_object).bbox().width() / 2; + + + // Components are really close, so the angle is more permissive. + if (dist < ldist * 3) + { + return + filter::internal::component_aligned_rad(this->components_, + current_object, + this->labeled_image_(p), + anchor, + max_alpha_rad); + } + + + // Components are really far, so the angle is less permissive. + return + filter::internal::component_aligned_rad(this->components_, + current_object, + this->labeled_image_(p), + anchor, + min_alpha_rad); + } + + + void validate_link_(unsigned current_object, + const P& start_point, + const P& p, + anchor::Type anchor) + { + super_::validate_link_(current_object, start_point, p, anchor); + +# ifndef SCRIBO_NDEBUG + if (logger().is_at_level(debug::AuxiliaryResults)) + { + mln_site(L) + p1 = link::internal::compute_anchor(this->components_, + current_object, debug_anchor_), + p2 = link::internal::compute_anchor(this->components_, + this->labeled_image_(p), + debug_anchor_); + mln::draw::line(debug_, p1, p2, literal::green); + + + float + angle = filter::internal::alignment_angle(this->components_, + current_object, + this->labeled_image_(p), + anchor); + angle = (angle * 180.0f) / math::pi; + angle = angle * 20.0f + 1.0f; + mln::draw::line(debug_angle_, p1, p2, + value::rgb8(unsigned(angle), + unsigned(angle), + unsigned(angle))); + } +# endif // ! SCRIBO_NDEBUG + } + + void invalidate_link_(unsigned current_object, + const P& start_point, + const P& p, + anchor::Type anchor) + { + super_::invalidate_link_(current_object, start_point, p, anchor); + +# ifndef SCRIBO_NDEBUG + if (logger().is_at_level(debug::AuxiliaryResults)) + { + if (this->labeled_image_.domain().has(p) && this->labeled_image_(p) != 0) + { + mln_site(L) + p1 = link::internal::compute_anchor(this->components_, + current_object, debug_anchor_), + p2 = link::internal::compute_anchor(this->components_, + this->labeled_image_(p), + debug_anchor_); + + // Arbitrary check to avoid large lines drawn over the whole page. + if (this->labeled_image_.domain().has(p2) + && norm::l1_distance(p1.to_vec(), p2.to_vec()) < 300) + { + mln::draw::line(debug_, p1, p2, literal::red); + } + + + float + angle = filter::internal::alignment_angle(this->components_, + current_object, + this->labeled_image_(p), + anchor); + angle = (angle * 180.0f) / math::pi; + angle = angle * 20.0f + 1.0f; + mln::draw::line(debug_angle_, p1, p2, + value::rgb8(unsigned(angle), + unsigned(angle), + unsigned(angle))); + } + } +# endif // ! SCRIBO_NDEBUG + } + + float min_alpha_rad; + float max_alpha_rad; + + // Anchor used for debug output! + anchor::Type debug_anchor_; + + mln_ch_value(L, value::rgb8) debug_; + mln_ch_value(L, value::rgb8) debug_angle_; + }; + + +# ifndef MLN_INCLUDE_ONLY + + +# endif // ! MLN_INCLUDE_ONLY + + + } // end of namespace scribo::primitive::link::internal + + } // end of namespace scribo::primitive::link + + } // end of namespace scribo::primitive + +} // end of namespace scribo + + +#endif // SCRIBO_PRIMITIVE_LINK_INTERNAL_LINK_SINGLE_DMAX_RATIO_ALIGNED_BASE_HH_ diff --git a/scribo/scribo/primitive/link/with_single_right_link_dmax_ratio_aligned.hh b/scribo/scribo/primitive/link/with_single_left_link_dmax_ratio_aligned.hh similarity index 59% copy from scribo/scribo/primitive/link/with_single_right_link_dmax_ratio_aligned.hh copy to scribo/scribo/primitive/link/with_single_left_link_dmax_ratio_aligned.hh index feba5f2..146ae17 100644 --- a/scribo/scribo/primitive/link/with_single_right_link_dmax_ratio_aligned.hh +++ b/scribo/scribo/primitive/link/with_single_left_link_dmax_ratio_aligned.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. // @@ -24,12 +24,12 @@ // exception does not however invalidate any other reasons why the // executable file might be covered by the GNU General Public License. -#ifndef SCRIBO_PRIMITIVE_LINK_WITH_SINGLE_RIGHT_LINK_DMAX_RATIO_ALIGNED_HH -# define SCRIBO_PRIMITIVE_LINK_WITH_SINGLE_RIGHT_LINK_DMAX_RATIO_ALIGNED_HH +#ifndef SCRIBO_PRIMITIVE_LINK_WITH_SINGLE_LEFT_LINK_DMAX_RATIO_ALIGNED_HH +# define SCRIBO_PRIMITIVE_LINK_WITH_SINGLE_LEFT_LINK_DMAX_RATIO_ALIGNED_HH /// \file /// -/// Link text objects with their right neighbor according to a maximum +/// Link text objects with their left neighbor according to a maximum /// distance. # include <mln/core/concept/image.hh> @@ -46,7 +46,7 @@ # include <scribo/primitive/link/internal/dmax_default.hh> # include <scribo/primitive/link/internal/find_link.hh> -# include <scribo/primitive/link/internal/link_single_dmax_ratio_base.hh> +# include <scribo/primitive/link/internal/link_single_dmax_ratio_aligned_base.hh> # include <scribo/primitive/link/compute.hh> @@ -62,7 +62,7 @@ namespace scribo namespace link { - /*! \brief Link objects with their right neighbor if exists. + /*! \brief Link objects with their left neighbor if exists. \param[in] components A component set. \param[in] dmax_ratio Size ratio defining the maximum lookup @@ -82,7 +82,7 @@ namespace scribo template <typename L> inline object_links<L> - with_single_right_link_dmax_ratio_aligned( + with_single_left_link_dmax_ratio_aligned( const component_set<L>& components, float dmax_ratio, float min_angle, float max_angle, @@ -93,7 +93,7 @@ namespace scribo template <typename L> inline object_links<L> - with_single_right_link_dmax_ratio_aligned( + with_single_left_link_dmax_ratio_aligned( const component_set<L>& components, float dmax_ratio, float min_angle, float max_angle); @@ -105,7 +105,7 @@ namespace scribo template <typename L> inline object_links<L> - with_single_right_link_dmax_ratio_aligned( + with_single_left_link_dmax_ratio_aligned( const component_set<L>& components); @@ -118,84 +118,33 @@ namespace scribo // Functor + template <typename L, typename F> - class single_right_dmax_ratio_aligned_functor - : public link_single_dmax_ratio_base<L, F, - single_right_dmax_ratio_aligned_functor<L,F> > + class single_left_dmax_ratio_aligned_functor + : public link_single_dmax_ratio_aligned_base<L, F, single_left_dmax_ratio_aligned_functor<L,F> > { - typedef single_right_dmax_ratio_aligned_functor<L,F> self_t; - typedef link_single_dmax_ratio_base<L, F, self_t> super_; + typedef single_left_dmax_ratio_aligned_functor<L,F> self_t; + typedef link_single_dmax_ratio_aligned_base<L, F, self_t> super_; public: typedef mln_site(L) P; - single_right_dmax_ratio_aligned_functor( + single_left_dmax_ratio_aligned_functor( const component_set<L>& components, const DMax_Functor<F>& dmax_f, float min_angle, float max_angle, - anchor::Type anchor_) - : super_(components, exact(dmax_f), anchor::Horizontal), - anchor(anchor_) + anchor::Type anchor) + : super_(components, dmax_f, min_angle, + max_angle, anchor) { - std::cout << "min_angle = " << min_angle - << " - max_angle = " << max_angle - << std::endl; - std::cout << "min_angle_rad = " << min_alpha_rad - << " - max_angle_rad = " << max_alpha_rad - << std::endl; - min_alpha_rad = (min_angle / 180.0f) * math::pi; - max_alpha_rad = (max_angle / 180.0f) * math::pi; } void compute_next_site_(P& p) { - ++p.col(); + --p.col(); } - - inline - bool - valid_link_(unsigned current_object, - const P& start_point, - const P& p) - { - bool super_b = super_::valid_link_(current_object, - start_point, p); - - // Distance between the two components. - float dist = math::abs(p[this->direction_] - start_point[this->direction_]); - - - unsigned ldist = this->components_(current_object).bbox().width() / 2; - - - // Components are really close, so the angle is more permissive. - if (dist < (ldist + ldist * 0.2)) - { - return super_b - && - filter::internal::component_aligned_rad(this->components_, - current_object, - this->labeled_image_(p), - anchor, - max_alpha_rad); - } - - - // Components are really far, so the angle is less permissive. - return super_b - && filter::internal::component_aligned_rad(this->components_, - current_object, - this->labeled_image_(p), - anchor, - min_alpha_rad); - } - - float min_alpha_rad; - float max_alpha_rad; - anchor::Type anchor; - }; } // end of namespace scribo::primitive::link::internal @@ -208,22 +157,22 @@ namespace scribo template <typename L, typename F> inline object_links<L> - with_single_right_link_dmax_ratio_aligned( + with_single_left_link_dmax_ratio_aligned( const component_set<L>& components, const DMax_Functor<F>& dmax_f, float min_angle, float max_angle, anchor::Type anchor) { - trace::entering("scribo::primitive::link::with_single_right_link_dmax_ratio_aligned"); + trace::entering("scribo::primitive::link::with_single_left_link_dmax_ratio_aligned"); mln_precondition(components.is_valid()); - internal::single_right_dmax_ratio_aligned_functor<L,F> + internal::single_left_dmax_ratio_aligned_functor<L,F> functor(components, dmax_f, min_angle, max_angle, anchor); object_links<L> output = compute(functor, anchor); - trace::exiting("scribo::primitive::link::with_single_right_link_dmax_ratio_aligned"); + trace::exiting("scribo::primitive::link::with_single_left_link_dmax_ratio_aligned"); return output; } @@ -232,13 +181,13 @@ namespace scribo template <typename L> inline object_links<L> - with_single_right_link_dmax_ratio_aligned( + with_single_left_link_dmax_ratio_aligned( const component_set<L>& components, float dmax_ratio, float min_angle, float max_angle) { return - with_single_right_link_dmax_ratio_aligned(components, + with_single_left_link_dmax_ratio_aligned(components, internal::dmax_default(dmax_ratio), min_angle, max_angle, @@ -249,11 +198,11 @@ namespace scribo template <typename L> inline object_links<L> - with_single_right_link_dmax_ratio_aligned( + with_single_left_link_dmax_ratio_aligned( const component_set<L>& components) { return - with_single_right_link_dmax_ratio_aligned(components, 3, 3, 10); + with_single_left_link_dmax_ratio_aligned(components, 3, 3, 10); } @@ -265,4 +214,4 @@ namespace scribo } // end of namespace scribo -#endif // ! SCRIBO_PRIMITIVE_LINK_WITH_SINGLE_RIGHT_LINK_DMAX_RATIO_ALIGNED_HH +#endif // ! SCRIBO_PRIMITIVE_LINK_WITH_SINGLE_LEFT_LINK_DMAX_RATIO_ALIGNED_HH diff --git a/scribo/scribo/primitive/link/with_single_right_link_dmax_ratio_aligned.hh b/scribo/scribo/primitive/link/with_single_right_link_dmax_ratio_aligned.hh index feba5f2..dcf804e 100644 --- a/scribo/scribo/primitive/link/with_single_right_link_dmax_ratio_aligned.hh +++ b/scribo/scribo/primitive/link/with_single_right_link_dmax_ratio_aligned.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,7 +46,7 @@ # include <scribo/primitive/link/internal/dmax_default.hh> # include <scribo/primitive/link/internal/find_link.hh> -# include <scribo/primitive/link/internal/link_single_dmax_ratio_base.hh> +# include <scribo/primitive/link/internal/link_single_dmax_ratio_aligned_base.hh> # include <scribo/primitive/link/compute.hh> @@ -118,13 +118,13 @@ namespace scribo // Functor + template <typename L, typename F> class single_right_dmax_ratio_aligned_functor - : public link_single_dmax_ratio_base<L, F, - single_right_dmax_ratio_aligned_functor<L,F> > + : public link_single_dmax_ratio_aligned_base<L, F, single_right_dmax_ratio_aligned_functor<L,F> > { typedef single_right_dmax_ratio_aligned_functor<L,F> self_t; - typedef link_single_dmax_ratio_base<L, F, self_t> super_; + typedef link_single_dmax_ratio_aligned_base<L, F, self_t> super_; public: typedef mln_site(L) P; @@ -134,18 +134,10 @@ namespace scribo const DMax_Functor<F>& dmax_f, float min_angle, float max_angle, - anchor::Type anchor_) - : super_(components, exact(dmax_f), anchor::Horizontal), - anchor(anchor_) + anchor::Type anchor) + : super_(components, dmax_f, min_angle, + max_angle, anchor) { - std::cout << "min_angle = " << min_angle - << " - max_angle = " << max_angle - << std::endl; - std::cout << "min_angle_rad = " << min_alpha_rad - << " - max_angle_rad = " << max_alpha_rad - << std::endl; - min_alpha_rad = (min_angle / 180.0f) * math::pi; - max_alpha_rad = (max_angle / 180.0f) * math::pi; } void compute_next_site_(P& p) @@ -153,49 +145,6 @@ namespace scribo ++p.col(); } - - inline - bool - valid_link_(unsigned current_object, - const P& start_point, - const P& p) - { - bool super_b = super_::valid_link_(current_object, - start_point, p); - - // Distance between the two components. - float dist = math::abs(p[this->direction_] - start_point[this->direction_]); - - - unsigned ldist = this->components_(current_object).bbox().width() / 2; - - - // Components are really close, so the angle is more permissive. - if (dist < (ldist + ldist * 0.2)) - { - return super_b - && - filter::internal::component_aligned_rad(this->components_, - current_object, - this->labeled_image_(p), - anchor, - max_alpha_rad); - } - - - // Components are really far, so the angle is less permissive. - return super_b - && filter::internal::component_aligned_rad(this->components_, - current_object, - this->labeled_image_(p), - anchor, - min_alpha_rad); - } - - float min_alpha_rad; - float max_alpha_rad; - anchor::Type anchor; - }; } // end of namespace scribo::primitive::link::internal -- 1.5.6.5