New algorithm to detect superpositions between two line sets.
* scribo/inverse_video/handle_collisions.hh: New.
---
scribo/ChangeLog | 6 +
scribo/scribo/inverse_video/handle_collisions.hh | 196 ++++++++++++++++++++++
2 files changed, 202 insertions(+), 0 deletions(-)
create mode 100644 scribo/scribo/inverse_video/handle_collisions.hh
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index 048a289..e868468 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,3 +1,9 @@
+2011-05-25 Coddy Levi <levi(a)lrde.epita.fr>
+
+ New algorithm to detect superpositions between two line sets.
+
+ * scribo/inverse_video/handle_collisions.hh: New.
+
2011-03-22 Guillaume Lazzara <z(a)lrde.epita.fr>
* demo/viewer/xml_widget.cc: Fix a warning.
diff --git a/scribo/scribo/inverse_video/handle_collisions.hh
b/scribo/scribo/inverse_video/handle_collisions.hh
new file mode 100644
index 0000000..54e585c
--- /dev/null
+++ b/scribo/scribo/inverse_video/handle_collisions.hh
@@ -0,0 +1,196 @@
+// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_INVERSE_VIDEO_HANDLE_COLLISIONS_HH
+# define SCRIBO_INVERSE_VIDEO_HANDLE_COLLISIONS_HH
+
+# include <set>
+# include <vector>
+# include <iostream>
+
+# include <mln/data/fill.hh>
+# include <mln/core/image/image2d.hh>
+# include <mln/util/array.hh>
+# include <scribo/core/line_set.hh>
+# include <mln/draw/box.hh>
+# include <mln/literal/colors.hh>
+
+namespace scribo
+{
+
+ namespace inverse_video
+ {
+
+ template <typename I,
+ typename L,
+ typename F>
+ void
+ handle_collisions(const image2d<I>& input,
+ scribo::line_set<L>& ls1,
+ scribo::line_set<L>& ls2,
+ F choose);
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace internal
+ {
+ template <typename L>
+ struct order_2_lines_id
+ {
+ order_2_lines_id(const scribo::line_set<L>& ls1,
+ const scribo::line_set<L>& ls2)
+ : ls1_(ls1),
+ ls2_(ls2)
+ {
+ ls1_size_ = ls1_.nelements();
+ }
+
+ bool operator()(const scribo::line_id_t& a,
+ const scribo::line_id_t& b)
+ {
+ const scribo::line_info<L>& la =
+ (a > ls1_size_ ? ls2_(a - ls1_size_ + 1) : ls1_(a));
+ const scribo::line_info<L>& lb =
+ (b > ls1_size_ ? ls2_(b - ls1_size_ + 1) : ls1_(b));
+
+ return la.bbox().nsites() < lb.bbox().nsites();
+ }
+
+ unsigned ls1_size_;
+ const scribo::line_set<L>& ls1_;
+ const scribo::line_set<L>& ls2_;
+ };
+ } // end of namespace scribo::text::internal
+
+ // Facade
+ template <typename I,
+ typename L,
+ typename F>
+ void
+ handle_collisions(image2d<I>& input,
+ scribo::line_set<L>& ls1,
+ scribo::line_set<L>& ls2,
+ F choose)
+ {
+ mln::trace::entering("scribo::inverse_video::handle_collisions");
+
+ mln::image2d<unsigned> billboard(input.domain());
+ mln::data::fill(billboard, 0);
+
+ internal::order_2_lines_id<L> func(ls1, ls2);
+
+ std::vector<scribo::line_id_t> v;
+
+ unsigned ls1_size = ls1.nelements();
+ unsigned n = ls1_size + ls2.nelements();
+ v.reserve(n);
+
+ for (unsigned i = 1; i < n; ++i)
+ v.push_back(i);
+
+ std::sort(v.begin(), v.end(), func);
+
+ for (int i = v.size() - 1; i > 0; --i)
+ {
+ bool inverse_video = (v[i] > ls1_size);
+
+ scribo::line_set<L>& ls = (inverse_video) ? ls2 : ls1;
+ scribo::line_id_t l = (inverse_video) ?
+ (scribo::line_id_t) (v[i] - ls1_size + 1)
+ : v[i];
+
+ if (!scribo::text::internal::looks_like_a_text_line(ls(l))
+ || !ls(l).is_valid())
+ continue;
+
+ unsigned tl, tr, bl, br;
+
+ box2d b = ls(l).bbox();
+
+ tl = billboard(b.pmin());
+ tr = billboard.at_(b.pmin().row(), b.pmax().col());
+ bl = billboard.at_(b.pmax().row(), b.pmin().col());
+ br = billboard(b.pmax());
+
+ std::set<unsigned> labels;
+ labels.insert(tl);
+ labels.insert(tl);
+ labels.insert(bl);
+ labels.insert(br);
+
+ bool chosen = true;
+ for (std::set<unsigned>::const_iterator it = labels.begin();
+ it != labels.end();
+ ++it)
+ {
+ if (*it == 0)
+ continue;
+
+ bool inverse_video_tested = (*it > ls1_size);
+
+ const scribo::line_info<L>& l_tested =
+ (inverse_video_tested ? ls2(*it - ls1_size + 1) : ls1(*it));
+
+ if (!scribo::text::internal::looks_like_a_text_line(l_tested)
+ || !l_tested.is_valid())
+ continue;
+
+ chosen = choose(ls(l), l_tested);
+ /*
+ if (inverse_video != inverse_video_tested)
+ {
+ if (inverse_video_tested)
+ mln::draw::box(input,
+ l_tested.bbox(),
+ mln::literal::blue);
+ else
+ mln::draw::box(input,
+ l_tested.bbox(),
+ mln::literal::green);
+
+ if (inverse_video)
+ mln::draw::box(input,
+ ls(l).bbox(),
+ mln::literal::blue);
+ else
+ mln::draw::box(input,
+ ls(l).bbox(),
+ mln::literal::green);
+ }*/
+ }
+
+ scribo::text::internal::draw_box(billboard, b, v[i]);
+ }
+
+ mln::trace::exiting("scribo::inverse_video::handle_collisions");
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace scribo::inverse_video
+
+} // end of namespace scribo
+
+#endif // ! SCRIBO_INVERSE_VIDEO_HANDLE_COLLISIONS_HH
--
1.5.6.5