Olena-patches
Threads by month
- ----- 2025 -----
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
November 2009
- 4 participants
- 70 discussions
* scribo/src/primitive/extract/Makefile.am: Add a new target.
* scribo/src/primitive/extract/lines_pattern.cc: New.
---
scribo/ChangeLog | 8 +++
scribo/src/primitive/extract/Makefile.am | 4 +-
scribo/src/primitive/extract/lines_pattern.cc | 76 +++++++++++++++++++++++++
3 files changed, 87 insertions(+), 1 deletions(-)
create mode 100644 scribo/src/primitive/extract/lines_pattern.cc
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index 279e1fd..4fed85c 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,5 +1,13 @@
2009-11-03 Guillaume Lazzara <z(a)lrde.epita.fr>
+ Add a new example in Scribo.
+
+ * scribo/src/primitive/extract/Makefile.am: Add a new target.
+
+ * scribo/src/primitive/extract/lines_pattern.cc: New.
+
+2009-11-03 Guillaume Lazzara <z(a)lrde.epita.fr>
+
First draft of multiscale Sauvola's binarization.
* scribo/src/binarization/Makefile.am: Add new target.
diff --git a/scribo/src/primitive/extract/Makefile.am b/scribo/src/primitive/extract/Makefile.am
index 636abc3..7e1ea78 100644
--- a/scribo/src/primitive/extract/Makefile.am
+++ b/scribo/src/primitive/extract/Makefile.am
@@ -25,11 +25,13 @@ bin_PROGRAMS = \
extract_discontinued_vlines \
extract_discontinued_hlines \
extract_thick_vlines \
- extract_thick_hlines
+ extract_thick_hlines \
+ lines_pattern
extract_discontinued_lines_SOURCES = extract_discontinued_lines.cc
extract_discontinued_vlines_SOURCES = extract_discontinued_vlines.cc
extract_discontinued_hlines_SOURCES = extract_discontinued_hlines.cc
extract_thick_vlines_SOURCES = extract_thick_vlines.cc
extract_thick_hlines_SOURCES = extract_thick_hlines.cc
+lines_pattern_SOURCES = lines_pattern.cc
diff --git a/scribo/src/primitive/extract/lines_pattern.cc b/scribo/src/primitive/extract/lines_pattern.cc
new file mode 100644
index 0000000..d794c71
--- /dev/null
+++ b/scribo/src/primitive/extract/lines_pattern.cc
@@ -0,0 +1,76 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#include <mln/core/image/image2d.hh>
+#include <mln/io/pbm/all.hh>
+#include <mln/pw/all.hh>
+#include <mln/data/fill.hh>
+#include <mln/core/image/dmorph/image_if.hh>
+
+#include <scribo/primitive/extract/lines_h_pattern.hh>
+#include <scribo/primitive/extract/lines_v_pattern.hh>
+#include <scribo/debug/usage.hh>
+
+
+const char *args_desc[][2] =
+{
+ { "input.pbm", "A binary image." },
+ { "length", " Minimum line length. (Common value : 51)" },
+ { "delta", " Distance between the object pixel and the background pixel (Common value : 5)" },
+ {0, 0}
+};
+
+
+int main(int argc, char *argv[])
+{
+ using namespace mln;
+
+ if (argc != 5)
+ return scribo::debug::usage(argv,
+ "Extract horizontal lines patterns",
+ "input.pbm length delta output.pbm",
+ args_desc,
+ "A binary image of lines.");
+
+ trace::entering("main");
+
+ image2d<bool> input;
+ io::pbm::load(input, argv[1]);
+
+ image2d<bool>
+ h_lines = scribo::primitive::extract::lines_h_pattern(input,
+ atoi(argv[2]),
+ atoi(argv[3]));
+ image2d<bool>
+ v_lines = scribo::primitive::extract::lines_v_pattern(input,
+ atoi(argv[2]),
+ atoi(argv[3]));
+
+ data::fill((v_lines | pw::value(h_lines)).rw(), true);
+
+ io::pbm::save(v_lines, argv[4]);
+
+ trace::exiting("main");
+}
--
1.5.6.5
1
0
* scribo/src/binarization/Makefile.am: Add new target.
* scribo/src/binarization/sauvola_ms.cc: New.
---
scribo/ChangeLog | 8 +
scribo/src/binarization/Makefile.am | 4 +-
scribo/src/binarization/sauvola_ms.cc | 406 +++++++++++++++++++++++++++++++++
3 files changed, 417 insertions(+), 1 deletions(-)
create mode 100644 scribo/src/binarization/sauvola_ms.cc
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index b04de6a..279e1fd 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,5 +1,13 @@
2009-11-03 Guillaume Lazzara <z(a)lrde.epita.fr>
+ First draft of multiscale Sauvola's binarization.
+
+ * scribo/src/binarization/Makefile.am: Add new target.
+
+ * scribo/src/binarization/sauvola_ms.cc: New.
+
+2009-11-03 Guillaume Lazzara <z(a)lrde.epita.fr>
+
Improve line pattern recognition routine.
* primitive/extract/lines_pattern.hh: Make it less tolerant.
diff --git a/scribo/src/binarization/Makefile.am b/scribo/src/binarization/Makefile.am
index ab982dc..531d4cf 100644
--- a/scribo/src/binarization/Makefile.am
+++ b/scribo/src/binarization/Makefile.am
@@ -21,10 +21,12 @@ include $(top_srcdir)/scribo/scribo.mk
bin_PROGRAMS = \
sauvola \
+ sauvola_ms \
sauvola_pgm \
simple
sauvola_SOURCES = sauvola.cc
+sauvola_ms_SOURCES = sauvola_ms.cc
sauvola_pgm_SOURCES = sauvola_pgm.cc
-simple_SOURCES = simple.cc
+simple_SOURCES = simple.cc
diff --git a/scribo/src/binarization/sauvola_ms.cc b/scribo/src/binarization/sauvola_ms.cc
new file mode 100644
index 0000000..747bc11
--- /dev/null
+++ b/scribo/src/binarization/sauvola_ms.cc
@@ -0,0 +1,406 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#include <mln/core/alias/neighb2d.hh>
+#include <mln/data/stretch.hh>
+#include <mln/debug/filename.hh>
+#include <mln/fun/i2v/array.hh>
+#include <mln/io/pbm/all.hh>
+#include <mln/io/pgm/all.hh>
+#include <mln/io/ppm/all.hh>
+#include <mln/literal/colors.hh>
+#include <mln/math/sqr.hh>
+#include <mln/subsampling/subsampling.hh>
+#include <mln/transform/influence_zone_geodesic.hh>
+#include <mln/util/timer.hh>
+#include <mln/value/int_u16.hh>
+#include <mln/value/int_u8.hh>
+#include <mln/value/label_16.hh>
+#include <mln/value/rgb8.hh>
+#include <mln/debug/filename.hh>
+
+#include <scribo/core/macros.hh>
+#include <scribo/core/object_image.hh>
+#include <scribo/filter/objects_small.hh>
+#include <scribo/filter/objects_large.hh>
+
+#include <scribo/filter/objects_thin.hh>
+#include <scribo/filter/objects_thick.hh>
+
+#include <scribo/primitive/extract/objects.hh>
+#include <scribo/binarization/sauvola_threshold.hh>
+#include <scribo/debug/usage.hh>
+#include <scribo/debug/save_object_diff.hh>
+
+namespace mln
+{
+
+
+// FIXME: do not use scribo's filters since they use object images.
+// Object images computes object bounding boxes which are not needed here.
+//
+// template <typename L>
+// mln_concrete(L)
+// filter_small_objects(const Image<L>& objects,
+// const mln_value(L)& nobjects, unsigned min_size)
+// {
+// card = labeling::compute(card_t(), objects, objects.nlabels());
+
+// mln_concrete(L) output;
+// initialize(output, objects);
+
+// fun::i2v::array<bool> f(nobjects.next(), 0);
+// for (unsigned i = 0; i < card.size(); ++i)
+
+// }
+
+ template <typename I, typename T>
+ mln_ch_value(I, bool)
+ apply_sauvola(const I& intensity, const T& threshold, unsigned s)
+ {
+ mln_precondition(intensity.domain() == threshold.domain());
+
+ mln_ch_value(I, bool) output;
+ initialize(output, intensity);
+
+ mln_piter(I) p(intensity.domain());
+ for_all(p)
+ output(p) = (intensity(p) <= threshold(p / s));
+
+ return output;
+ }
+
+
+ template <typename I>
+ mln_concrete(I)
+ enlarge(const Image<I>& input_, unsigned ratio)
+ {
+ const I& input = exact(input_);
+ mln_precondition(input.is_valid());
+
+ mln_domain(I) bbox(input.domain().pmin() * ratio,
+ input.domain().pmax() * ratio
+ + (ratio - 1) * mln::down_right);
+
+ mln_concrete(I) output(bbox);
+
+ mln_site(I) first_p = input.domain().pmin();
+ for (def::coord j = geom::min_col(input);
+ j <= geom::max_col(input); ++j)
+ for (def::coord i = geom::min_row(input);
+ i <= geom::max_row(input); ++i)
+ {
+ point2d p1(i, j);
+ point2d p2(first_p[0] + i * ratio, first_p[1] + j * ratio);
+
+ output(p2) = input(p1);
+ output(p2 + mln::right) = input(p1);
+ output(p2 + mln::down_right) = input(p1);
+ output(p2 + mln::down) = input(p1);
+ }
+
+ return output;
+ }
+
+ template <typename I>
+ object_image(mln_ch_value(I, value::label_16))
+ get_objects(const Image<I>& input_,
+ unsigned min_size, unsigned max_size,
+ unsigned ratio, unsigned w, unsigned scale)
+ {
+ const I& input = exact(input_);
+
+ mln_precondition(input.is_valid());
+
+ typedef mln_ch_value(I, value::label_16) L;
+
+ dpoint2d none(0, 0);
+ I input_sub = mln::subsampling::subsampling(input, none, ratio);
+
+ image2d<value::int_u8>
+ t = scribo::binarization::sauvola_threshold(input_sub, w);
+
+ image2d<bool> b = apply_sauvola(input_sub, t, 1);
+
+ value::label_16 nb;
+ object_image(L) lbl = scribo::primitive::extract::objects(b, c8(), nb);
+ object_image(L) lbl_raw(lbl);
+
+ if (min_size > 0)
+ lbl = scribo::filter::objects_small(lbl, min_size);
+ if (max_size > 0)
+ lbl = scribo::filter::objects_large(lbl, max_size);
+ scribo::debug::save_object_diff(lbl_raw, lbl,
+ mln::debug::filename("filter_diff.ppm", scale + 2));
+
+ return lbl;
+ }
+
+
+ bool
+ check_args(int argc, char * argv[])
+ {
+ if (argc < 7)
+ return false;
+
+ int nb_scale = atoi(argv[3]);
+ int s = atoi(argv[4]);
+ int q = atoi(argv[5]);
+
+ if (q < 2)
+ {
+ std::cout << "q must be greater than 2." << std::endl;
+ return false;
+ }
+ if (s < 1 || s < q)
+ {
+ std::cout << "s must be greater or equal to 1 and greater than q."
+ << std::endl;
+ return false;
+ }
+
+ if (nb_scale < 1)
+ {
+ std::cout << "Not enough scales." << std::endl;
+ return false;
+ }
+
+ if ((argc - 7) != (nb_scale - 1))
+ {
+ std::cout << "Not enough area threshold."
+ << "There must be nb_scale - 1 thresholds."
+ << std::endl;
+ return false;
+ }
+
+ return true;
+ }
+
+
+} // end of namespace mln;
+
+
+
+
+const char *args_desc[][2] =
+{
+ { "input.pgm", "A graylevel image." },
+ { "w", "Window size." },
+ { "nb_scale", "Number of scales (Common value: 3)." },
+ { "s", "First subsampling ratio (Common value: 2)." },
+ { "q", "Next subsampling ratio (Common value: 2)." },
+ { "<area threshold> (Common values: 200 800)", "Area threshold" },
+ {0, 0}
+};
+
+
+
+
+int main(int argc, char *argv[])
+{
+ using namespace mln;
+ using namespace scribo;
+ using value::rgb8;
+ using value::int_u8;
+ using value::int_u16;
+ using value::label_16;
+
+ typedef image2d<label_16> L;
+
+
+ if (!check_args(argc, argv))
+ return scribo::debug::usage(argv,
+ "Binarization of a color image based on Sauvola's algorithm.",
+ "input.pgm w nb_scale s q <area thresholds>",
+ args_desc, "A binary image.");
+
+ trace::entering("main");
+
+ mln::debug::internal::filename_prefix = argv[1];
+
+ // Window size.
+ unsigned w = atoi(argv[2]);
+
+ // First subsampling scale.
+ unsigned s = atoi(argv[4]);
+
+ // Number of subscales.
+ unsigned nb_subscale = atoi(argv[3]);
+
+ // Subscale step.
+ unsigned q = atoi(argv[5]);
+
+ std::cout << "Running Sauvola_ms with w = " << w
+ << ", s = " << s
+ << ", nb_subscale = " << nb_subscale
+ << ", q = " << q
+ << std::endl;
+
+ typedef image2d<value::int_u8> I;
+ dpoint2d none(0, 0);
+
+ mln::util::timer timer_;
+
+ timer_.start();
+ I input_full;
+ io::pgm::load(input_full, argv[1]);
+ std::cout << "Image loaded - " << timer_ << std::endl;
+
+ timer_.restart();
+
+ util::array<object_image(L)> lbls;
+
+
+
+ // First subsampling 1/s
+
+// std::cout << "1/" << s << std::endl;
+ timer_.start();
+ I input = mln::subsampling::subsampling(input_full, none, s);
+
+ integral_image<int_u8> simple, squared;
+ image2d<int_u8>
+ t_1 = scribo::binarization::sauvola_threshold(input, w, simple, squared);
+
+ label_16 nb1;
+ image2d<bool> b_1 = apply_sauvola(input, t_1, 1);
+
+ {
+ lbls.append(primitive::extract::objects(b_1, c8(), nb1));
+ object_image(L) lbl_raw(lbls[0]);
+ lbls[0] = filter::objects_large(lbls[0], atoi(argv[6]));
+ scribo::debug::save_object_diff(lbl_raw, lbls[0],
+ mln::debug::filename("filter_diff.ppm", 2));
+ }
+
+ std::cout << "Scale 2 - 1/" << s << " Done - " << timer_ << std::endl;
+
+
+
+
+ // Additional subscales.
+ for (unsigned i = 1; i < nb_subscale; ++i)
+ {
+ unsigned ratio = std::pow(q, i);
+// std::cout << "Scale " << 2 + i << " - 1/" << s * ratio << std::endl;
+ timer_.restart();
+ unsigned
+ min_size = atoi(argv[5 + i]) / ratio,
+ max_size;
+ if ((3 + i) == static_cast<unsigned>(argc))
+ max_size = 0; // Last subscale, so not max size limit.
+ else
+ max_size = atoi(argv[6 + i]) / ratio;
+
+ lbls.append(get_objects(input, min_size, max_size, ratio, w, i));
+ std::cout << "Scale " << 2 + i
+ << " - 1/" << s * ratio
+ << " Done - " << timer_ << std::endl;
+ }
+
+ std::cout << "--------" << std::endl;
+
+ // Constructing "scale image".
+ image2d<int_u8> e;
+ initialize(e, input);
+
+ data::fill(e, 0);
+
+ typedef object_image(L) obj_t;
+
+ for (int i = nb_subscale - 1; i >= 0; --i)
+ {
+ unsigned ratio = std::pow(q, i);
+
+ std::cout << "Scale " << 2 + i << " - 1/" << s * ratio << " merged" << std::endl;
+
+ mln_piter_(obj_t) p(lbls[i].domain());
+ for_all(p)
+ if (lbls[i](p) != 0 && e(p * ratio) == 0)
+ {
+ box2d b(p * ratio, p * ratio + mln::down_right * (ratio - 1));
+ data::fill((e | b).rw(), i + 1);
+ }
+ }
+
+ std::cout << "--------" << std::endl;
+
+ /// Saving "scale image".
+ {
+ mln::fun::i2v::array<value::int_u8> f(nb_subscale + 1, 0);
+ for (unsigned i = 1; i <= nb_subscale; ++i)
+ f(i) = 255 / nb_subscale * i;
+
+ io::pgm::save(e, "e_raw.pgm");
+ io::pgm::save(data::transform(e, f), "e.pgm");
+ }
+
+
+ /// Saving influence zone scale image.
+ image2d<int_u8>
+ e_ext = transform::influence_zone_geodesic(e, c8(), mln_max(unsigned));
+ io::pgm::save(e_ext, "e_ext.pgm");
+
+
+ /// Creating window size image
+ std::cout << "Creating window size image..." << std::endl;
+ mln::fun::i2v::array<value::int_u16> f(nb_subscale, 0);
+ for (unsigned i = 0; i < nb_subscale; ++i)
+ {
+ unsigned ratio = std::pow(q, i);
+ f(i) = ratio * w;
+ }
+
+ image2d<int_u16> wsize = data::transform(e_ext, f);
+ io::pgm::save(data::stretch(int_u8(), wsize), "wsize.pgm");
+
+
+
+ /// Constructing threshold image
+ image2d<int_u8> t;
+ initialize(t, input);
+
+ std::cout << "Computing threshold image..." << std::endl;
+ timer_.restart();
+ mln_piter_(L) p(input.domain());
+ for_all(p)
+ t(p) = binarization::internal::compute_sauvola_threshold(p,
+ simple,
+ squared,
+ wsize(p));
+ std::cout << "Compute t Done - " << timer_ << std::endl;
+
+ io::pgm::save(t, "t.pgm");
+
+
+ timer_.restart();
+
+ /// Applying threshold image and save.
+ io::pbm::save(apply_sauvola(input_full, t, s), argv[argc - 1]);
+ std::cout << "sauvola applied and saved Done - " << timer_ << std::endl;
+
+
+ trace::exiting("main");
+}
--
1.5.6.5
1
0
* lazzara/igr/gui/ui_display_seg.h,
* lazzara/igr/gui/ui_edit_seg.h,
* lazzara/igr/gui/ui_image_viewer.h,
* lazzara/igr/gui/ui_main_window.h: Remove.
---
milena/sandbox/ChangeLog | 9 ++
milena/sandbox/lazzara/igr/gui/ui_display_seg.h | 148 -------------------
milena/sandbox/lazzara/igr/gui/ui_edit_seg.h | 130 -----------------
milena/sandbox/lazzara/igr/gui/ui_image_viewer.h | 167 ----------------------
milena/sandbox/lazzara/igr/gui/ui_main_window.h | 92 ------------
5 files changed, 9 insertions(+), 537 deletions(-)
delete mode 100644 milena/sandbox/lazzara/igr/gui/ui_display_seg.h
delete mode 100644 milena/sandbox/lazzara/igr/gui/ui_edit_seg.h
delete mode 100644 milena/sandbox/lazzara/igr/gui/ui_image_viewer.h
delete mode 100644 milena/sandbox/lazzara/igr/gui/ui_main_window.h
diff --git a/milena/sandbox/ChangeLog b/milena/sandbox/ChangeLog
index 4191a7e..cd27478 100644
--- a/milena/sandbox/ChangeLog
+++ b/milena/sandbox/ChangeLog
@@ -1,3 +1,12 @@
+2009-11-03 Guillaume Lazzara <z(a)lrde.epita.fr>
+
+ Remove generated files from repository.
+
+ * lazzara/igr/gui/ui_display_seg.h,
+ * lazzara/igr/gui/ui_edit_seg.h,
+ * lazzara/igr/gui/ui_image_viewer.h,
+ * lazzara/igr/gui/ui_main_window.h: Remove.
+
2009-10-28 Guillaume Lazzara <z(a)lrde.epita.fr>
Fix compilation issues in IGR's code.
diff --git a/milena/sandbox/lazzara/igr/gui/ui_display_seg.h b/milena/sandbox/lazzara/igr/gui/ui_display_seg.h
deleted file mode 100644
index 5875534..0000000
--- a/milena/sandbox/lazzara/igr/gui/ui_display_seg.h
+++ /dev/null
@@ -1,148 +0,0 @@
-/********************************************************************************
-** Form generated from reading ui file 'display_seg.ui'
-**
-** Created: Wed Oct 28 12:45:22 2009
-** by: Qt User Interface Compiler version 4.4.3
-**
-** WARNING! All changes made in this file will be lost when recompiling ui file!
-********************************************************************************/
-
-#ifndef UI_DISPLAY_SEG_H
-#define UI_DISPLAY_SEG_H
-
-#include <QtCore/QVariant>
-#include <QtGui/QAction>
-#include <QtGui/QApplication>
-#include <QtGui/QButtonGroup>
-#include <QtGui/QGridLayout>
-#include <QtGui/QHBoxLayout>
-#include <QtGui/QLabel>
-#include <QtGui/QLineEdit>
-#include <QtGui/QPushButton>
-#include <QtGui/QSpacerItem>
-#include <QtGui/QVBoxLayout>
-#include <QtGui/QWidget>
-#include "src/image_viewer.hh"
-
-QT_BEGIN_NAMESPACE
-
-class Ui_DisplaySeg
-{
-public:
- QGridLayout *gridLayout;
- QVBoxLayout *verticalLayout;
- QHBoxLayout *horizontalLayout;
- QLabel *label;
- QLineEdit *filepath;
- QPushButton *browseBtn;
- QHBoxLayout *horizontalLayout_2;
- QLabel *label_2;
- QLineEdit *segfilepath;
- QPushButton *browseSegBtn;
- QHBoxLayout *horizontalLayout_3;
- QSpacerItem *horizontalSpacer;
- QPushButton *loadBtn;
- mln::demo::image_viewer *viewer;
-
- void setupUi(QWidget *DisplaySeg)
- {
- if (DisplaySeg->objectName().isEmpty())
- DisplaySeg->setObjectName(QString::fromUtf8("DisplaySeg"));
- DisplaySeg->resize(400, 300);
- gridLayout = new QGridLayout(DisplaySeg);
- gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
- verticalLayout = new QVBoxLayout();
- verticalLayout->setObjectName(QString::fromUtf8("verticalLayout"));
- horizontalLayout = new QHBoxLayout();
- horizontalLayout->setObjectName(QString::fromUtf8("horizontalLayout"));
- label = new QLabel(DisplaySeg);
- label->setObjectName(QString::fromUtf8("label"));
-
- horizontalLayout->addWidget(label);
-
- filepath = new QLineEdit(DisplaySeg);
- filepath->setObjectName(QString::fromUtf8("filepath"));
-
- horizontalLayout->addWidget(filepath);
-
- browseBtn = new QPushButton(DisplaySeg);
- browseBtn->setObjectName(QString::fromUtf8("browseBtn"));
-
- horizontalLayout->addWidget(browseBtn);
-
-
- verticalLayout->addLayout(horizontalLayout);
-
- horizontalLayout_2 = new QHBoxLayout();
- horizontalLayout_2->setObjectName(QString::fromUtf8("horizontalLayout_2"));
- label_2 = new QLabel(DisplaySeg);
- label_2->setObjectName(QString::fromUtf8("label_2"));
-
- horizontalLayout_2->addWidget(label_2);
-
- segfilepath = new QLineEdit(DisplaySeg);
- segfilepath->setObjectName(QString::fromUtf8("segfilepath"));
-
- horizontalLayout_2->addWidget(segfilepath);
-
- browseSegBtn = new QPushButton(DisplaySeg);
- browseSegBtn->setObjectName(QString::fromUtf8("browseSegBtn"));
-
- horizontalLayout_2->addWidget(browseSegBtn);
-
-
- verticalLayout->addLayout(horizontalLayout_2);
-
- horizontalLayout_3 = new QHBoxLayout();
- horizontalLayout_3->setObjectName(QString::fromUtf8("horizontalLayout_3"));
- horizontalSpacer = new QSpacerItem(48, 17, QSizePolicy::Expanding, QSizePolicy::Minimum);
-
- horizontalLayout_3->addItem(horizontalSpacer);
-
- loadBtn = new QPushButton(DisplaySeg);
- loadBtn->setObjectName(QString::fromUtf8("loadBtn"));
-
- horizontalLayout_3->addWidget(loadBtn);
-
-
- verticalLayout->addLayout(horizontalLayout_3);
-
- viewer = new mln::demo::image_viewer(DisplaySeg);
- viewer->setObjectName(QString::fromUtf8("viewer"));
- QSizePolicy sizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
- sizePolicy.setHorizontalStretch(0);
- sizePolicy.setVerticalStretch(0);
- sizePolicy.setHeightForWidth(viewer->sizePolicy().hasHeightForWidth());
- viewer->setSizePolicy(sizePolicy);
-
- verticalLayout->addWidget(viewer);
-
-
- gridLayout->addLayout(verticalLayout, 0, 0, 1, 1);
-
-
- retranslateUi(DisplaySeg);
-
- QMetaObject::connectSlotsByName(DisplaySeg);
- } // setupUi
-
- void retranslateUi(QWidget *DisplaySeg)
- {
- DisplaySeg->setWindowTitle(QApplication::translate("DisplaySeg", "Form", 0, QApplication::UnicodeUTF8));
- label->setText(QApplication::translate("DisplaySeg", "Image", 0, QApplication::UnicodeUTF8));
- browseBtn->setText(QApplication::translate("DisplaySeg", "&Browse", 0, QApplication::UnicodeUTF8));
- label_2->setText(QApplication::translate("DisplaySeg", "Segmentation", 0, QApplication::UnicodeUTF8));
- browseSegBtn->setText(QApplication::translate("DisplaySeg", "&Browse", 0, QApplication::UnicodeUTF8));
- loadBtn->setText(QApplication::translate("DisplaySeg", "&Load", 0, QApplication::UnicodeUTF8));
- Q_UNUSED(DisplaySeg);
- } // retranslateUi
-
-};
-
-namespace Ui {
- class DisplaySeg: public Ui_DisplaySeg {};
-} // namespace Ui
-
-QT_END_NAMESPACE
-
-#endif // UI_DISPLAY_SEG_H
diff --git a/milena/sandbox/lazzara/igr/gui/ui_edit_seg.h b/milena/sandbox/lazzara/igr/gui/ui_edit_seg.h
deleted file mode 100644
index 9d8e07e..0000000
--- a/milena/sandbox/lazzara/igr/gui/ui_edit_seg.h
+++ /dev/null
@@ -1,130 +0,0 @@
-/********************************************************************************
-** Form generated from reading ui file 'edit_seg.ui'
-**
-** Created: Wed Oct 28 12:45:22 2009
-** by: Qt User Interface Compiler version 4.4.3
-**
-** WARNING! All changes made in this file will be lost when recompiling ui file!
-********************************************************************************/
-
-#ifndef UI_EDIT_SEG_H
-#define UI_EDIT_SEG_H
-
-#include <QtCore/QVariant>
-#include <QtGui/QAction>
-#include <QtGui/QApplication>
-#include <QtGui/QButtonGroup>
-#include <QtGui/QGridLayout>
-#include <QtGui/QHBoxLayout>
-#include <QtGui/QLabel>
-#include <QtGui/QLineEdit>
-#include <QtGui/QPushButton>
-#include <QtGui/QSpacerItem>
-#include <QtGui/QVBoxLayout>
-#include <QtGui/QWidget>
-#include "src/image_viewer.hh"
-
-QT_BEGIN_NAMESPACE
-
-class Ui_EditSeg
-{
-public:
- QGridLayout *gridLayout;
- QVBoxLayout *verticalLayout;
- QHBoxLayout *horizontalLayout_2;
- QLabel *label_2;
- QLineEdit *filepath;
- QPushButton *browseBtn;
- QHBoxLayout *horizontalLayout_3;
- QSpacerItem *horizontalSpacer;
- QPushButton *reloadBtn;
- QPushButton *saveBtn;
- mln::demo::image_viewer *viewer;
-
- void setupUi(QWidget *EditSeg)
- {
- if (EditSeg->objectName().isEmpty())
- EditSeg->setObjectName(QString::fromUtf8("EditSeg"));
- EditSeg->resize(400, 300);
- gridLayout = new QGridLayout(EditSeg);
- gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
- verticalLayout = new QVBoxLayout();
- verticalLayout->setObjectName(QString::fromUtf8("verticalLayout"));
- horizontalLayout_2 = new QHBoxLayout();
- horizontalLayout_2->setObjectName(QString::fromUtf8("horizontalLayout_2"));
- label_2 = new QLabel(EditSeg);
- label_2->setObjectName(QString::fromUtf8("label_2"));
-
- horizontalLayout_2->addWidget(label_2);
-
- filepath = new QLineEdit(EditSeg);
- filepath->setObjectName(QString::fromUtf8("filepath"));
-
- horizontalLayout_2->addWidget(filepath);
-
- browseBtn = new QPushButton(EditSeg);
- browseBtn->setObjectName(QString::fromUtf8("browseBtn"));
-
- horizontalLayout_2->addWidget(browseBtn);
-
-
- verticalLayout->addLayout(horizontalLayout_2);
-
- horizontalLayout_3 = new QHBoxLayout();
- horizontalLayout_3->setObjectName(QString::fromUtf8("horizontalLayout_3"));
- horizontalSpacer = new QSpacerItem(48, 17, QSizePolicy::Expanding, QSizePolicy::Minimum);
-
- horizontalLayout_3->addItem(horizontalSpacer);
-
- reloadBtn = new QPushButton(EditSeg);
- reloadBtn->setObjectName(QString::fromUtf8("reloadBtn"));
-
- horizontalLayout_3->addWidget(reloadBtn);
-
- saveBtn = new QPushButton(EditSeg);
- saveBtn->setObjectName(QString::fromUtf8("saveBtn"));
- saveBtn->setEnabled(false);
-
- horizontalLayout_3->addWidget(saveBtn);
-
-
- verticalLayout->addLayout(horizontalLayout_3);
-
- viewer = new mln::demo::image_viewer(EditSeg);
- viewer->setObjectName(QString::fromUtf8("viewer"));
- QSizePolicy sizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
- sizePolicy.setHorizontalStretch(0);
- sizePolicy.setVerticalStretch(0);
- sizePolicy.setHeightForWidth(viewer->sizePolicy().hasHeightForWidth());
- viewer->setSizePolicy(sizePolicy);
-
- verticalLayout->addWidget(viewer);
-
-
- gridLayout->addLayout(verticalLayout, 0, 0, 1, 1);
-
-
- retranslateUi(EditSeg);
-
- QMetaObject::connectSlotsByName(EditSeg);
- } // setupUi
-
- void retranslateUi(QWidget *EditSeg)
- {
- EditSeg->setWindowTitle(QApplication::translate("EditSeg", "Form", 0, QApplication::UnicodeUTF8));
- label_2->setText(QApplication::translate("EditSeg", "Segmentation", 0, QApplication::UnicodeUTF8));
- browseBtn->setText(QApplication::translate("EditSeg", "&Browse", 0, QApplication::UnicodeUTF8));
- reloadBtn->setText(QApplication::translate("EditSeg", "&Reload", 0, QApplication::UnicodeUTF8));
- saveBtn->setText(QApplication::translate("EditSeg", "&Save changes", 0, QApplication::UnicodeUTF8));
- Q_UNUSED(EditSeg);
- } // retranslateUi
-
-};
-
-namespace Ui {
- class EditSeg: public Ui_EditSeg {};
-} // namespace Ui
-
-QT_END_NAMESPACE
-
-#endif // UI_EDIT_SEG_H
diff --git a/milena/sandbox/lazzara/igr/gui/ui_image_viewer.h b/milena/sandbox/lazzara/igr/gui/ui_image_viewer.h
deleted file mode 100644
index 01cc5df..0000000
--- a/milena/sandbox/lazzara/igr/gui/ui_image_viewer.h
+++ /dev/null
@@ -1,167 +0,0 @@
-/********************************************************************************
-** Form generated from reading ui file 'image_viewer.ui'
-**
-** Created: Wed Oct 28 12:45:22 2009
-** by: Qt User Interface Compiler version 4.4.3
-**
-** WARNING! All changes made in this file will be lost when recompiling ui file!
-********************************************************************************/
-
-#ifndef UI_IMAGE_VIEWER_H
-#define UI_IMAGE_VIEWER_H
-
-#include <QtCore/QVariant>
-#include <QtGui/QAction>
-#include <QtGui/QApplication>
-#include <QtGui/QButtonGroup>
-#include <QtGui/QGraphicsView>
-#include <QtGui/QHBoxLayout>
-#include <QtGui/QLabel>
-#include <QtGui/QPushButton>
-#include <QtGui/QSlider>
-#include <QtGui/QSpacerItem>
-#include <QtGui/QVBoxLayout>
-#include <QtGui/QWidget>
-
-QT_BEGIN_NAMESPACE
-
-class Ui_ImageViewer
-{
-public:
- QVBoxLayout *verticalLayout_2;
- QVBoxLayout *verticalLayout;
- QHBoxLayout *horizontalLayout_2;
- QSpacerItem *horizontalSpacer;
- QLabel *zoomLabel;
- QPushButton *zoomIn;
- QPushButton *zoomOut;
- QPushButton *zoomFixed;
- QPushButton *zoomOriginal;
- QSpacerItem *horizontalSpacer_2;
- QGraphicsView *image;
- QHBoxLayout *sliderLayout;
- QSlider *slider;
- QLabel *label_2;
- QLabel *frame_nb;
-
- void setupUi(QWidget *ImageViewer)
- {
- if (ImageViewer->objectName().isEmpty())
- ImageViewer->setObjectName(QString::fromUtf8("ImageViewer"));
- ImageViewer->resize(464, 350);
- QSizePolicy sizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
- sizePolicy.setHorizontalStretch(0);
- sizePolicy.setVerticalStretch(0);
- sizePolicy.setHeightForWidth(ImageViewer->sizePolicy().hasHeightForWidth());
- ImageViewer->setSizePolicy(sizePolicy);
- verticalLayout_2 = new QVBoxLayout(ImageViewer);
- verticalLayout_2->setObjectName(QString::fromUtf8("verticalLayout_2"));
- verticalLayout = new QVBoxLayout();
- verticalLayout->setObjectName(QString::fromUtf8("verticalLayout"));
- horizontalLayout_2 = new QHBoxLayout();
- horizontalLayout_2->setObjectName(QString::fromUtf8("horizontalLayout_2"));
- horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
-
- horizontalLayout_2->addItem(horizontalSpacer);
-
- zoomLabel = new QLabel(ImageViewer);
- zoomLabel->setObjectName(QString::fromUtf8("zoomLabel"));
- zoomLabel->setEnabled(false);
-
- horizontalLayout_2->addWidget(zoomLabel);
-
- zoomIn = new QPushButton(ImageViewer);
- zoomIn->setObjectName(QString::fromUtf8("zoomIn"));
- zoomIn->setEnabled(false);
-
- horizontalLayout_2->addWidget(zoomIn);
-
- zoomOut = new QPushButton(ImageViewer);
- zoomOut->setObjectName(QString::fromUtf8("zoomOut"));
- zoomOut->setEnabled(false);
-
- horizontalLayout_2->addWidget(zoomOut);
-
- zoomFixed = new QPushButton(ImageViewer);
- zoomFixed->setObjectName(QString::fromUtf8("zoomFixed"));
- zoomFixed->setEnabled(false);
-
- horizontalLayout_2->addWidget(zoomFixed);
-
- zoomOriginal = new QPushButton(ImageViewer);
- zoomOriginal->setObjectName(QString::fromUtf8("zoomOriginal"));
- zoomOriginal->setEnabled(false);
-
- horizontalLayout_2->addWidget(zoomOriginal);
-
- horizontalSpacer_2 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
-
- horizontalLayout_2->addItem(horizontalSpacer_2);
-
-
- verticalLayout->addLayout(horizontalLayout_2);
-
- image = new QGraphicsView(ImageViewer);
- image->setObjectName(QString::fromUtf8("image"));
- image->setInteractive(true);
- image->setRenderHints(QPainter::SmoothPixmapTransform|QPainter::TextAntialiasing);
-
- verticalLayout->addWidget(image);
-
- sliderLayout = new QHBoxLayout();
- sliderLayout->setObjectName(QString::fromUtf8("sliderLayout"));
- slider = new QSlider(ImageViewer);
- slider->setObjectName(QString::fromUtf8("slider"));
- slider->setOrientation(Qt::Horizontal);
- slider->setTickPosition(QSlider::TicksAbove);
-
- sliderLayout->addWidget(slider);
-
- label_2 = new QLabel(ImageViewer);
- label_2->setObjectName(QString::fromUtf8("label_2"));
-
- sliderLayout->addWidget(label_2);
-
- frame_nb = new QLabel(ImageViewer);
- frame_nb->setObjectName(QString::fromUtf8("frame_nb"));
- QFont font;
- font.setBold(true);
- font.setWeight(75);
- frame_nb->setFont(font);
-
- sliderLayout->addWidget(frame_nb);
-
-
- verticalLayout->addLayout(sliderLayout);
-
-
- verticalLayout_2->addLayout(verticalLayout);
-
-
- retranslateUi(ImageViewer);
-
- QMetaObject::connectSlotsByName(ImageViewer);
- } // setupUi
-
- void retranslateUi(QWidget *ImageViewer)
- {
- ImageViewer->setWindowTitle(QApplication::translate("ImageViewer", "Form", 0, QApplication::UnicodeUTF8));
- zoomLabel->setText(QApplication::translate("ImageViewer", "Zoom:", 0, QApplication::UnicodeUTF8));
- zoomIn->setText(QApplication::translate("ImageViewer", "+", 0, QApplication::UnicodeUTF8));
- zoomOut->setText(QApplication::translate("ImageViewer", "-", 0, QApplication::UnicodeUTF8));
- zoomFixed->setText(QApplication::translate("ImageViewer", "Fixed width", 0, QApplication::UnicodeUTF8));
- zoomOriginal->setText(QApplication::translate("ImageViewer", "Original size", 0, QApplication::UnicodeUTF8));
- label_2->setText(QApplication::translate("ImageViewer", "Current Frame :", 0, QApplication::UnicodeUTF8));
- frame_nb->setText(QApplication::translate("ImageViewer", "0", 0, QApplication::UnicodeUTF8));
- Q_UNUSED(ImageViewer);
- } // retranslateUi
-
-};
-
-namespace Ui {
- class ImageViewer: public Ui_ImageViewer {};
-} // namespace Ui
-
-QT_END_NAMESPACE
-
-#endif // UI_IMAGE_VIEWER_H
diff --git a/milena/sandbox/lazzara/igr/gui/ui_main_window.h b/milena/sandbox/lazzara/igr/gui/ui_main_window.h
deleted file mode 100644
index 0f1ce23..0000000
--- a/milena/sandbox/lazzara/igr/gui/ui_main_window.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/********************************************************************************
-** Form generated from reading ui file 'main_window.ui'
-**
-** Created: Wed Oct 28 13:14:49 2009
-** by: Qt User Interface Compiler version 4.4.3
-**
-** WARNING! All changes made in this file will be lost when recompiling ui file!
-********************************************************************************/
-
-#ifndef UI_MAIN_WINDOW_H
-#define UI_MAIN_WINDOW_H
-
-#include <QtCore/QVariant>
-#include <QtGui/QAction>
-#include <QtGui/QApplication>
-#include <QtGui/QButtonGroup>
-#include <QtGui/QGridLayout>
-#include <QtGui/QMainWindow>
-#include <QtGui/QMenuBar>
-#include <QtGui/QStatusBar>
-#include <QtGui/QTabWidget>
-#include <QtGui/QWidget>
-#include "src/display_seg.hh"
-#include "src/edit_seg.hh"
-
-QT_BEGIN_NAMESPACE
-
-class Ui_MainWindow
-{
-public:
- QWidget *centralwidget;
- QGridLayout *gridLayout;
- QTabWidget *tabWidget;
- mln::demo::display_seg *Visualization;
- mln::demo::edit_seg *Edition;
- QMenuBar *menubar;
- QStatusBar *statusbar;
-
- void setupUi(QMainWindow *MainWindow)
- {
- if (MainWindow->objectName().isEmpty())
- MainWindow->setObjectName(QString::fromUtf8("MainWindow"));
- MainWindow->resize(487, 335);
- centralwidget = new QWidget(MainWindow);
- centralwidget->setObjectName(QString::fromUtf8("centralwidget"));
- gridLayout = new QGridLayout(centralwidget);
- gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
- tabWidget = new QTabWidget(centralwidget);
- tabWidget->setObjectName(QString::fromUtf8("tabWidget"));
- Visualization = new mln::demo::display_seg();
- Visualization->setObjectName(QString::fromUtf8("Visualization"));
- tabWidget->addTab(Visualization, QString());
- Edition = new mln::demo::edit_seg();
- Edition->setObjectName(QString::fromUtf8("Edition"));
- tabWidget->addTab(Edition, QString());
-
- gridLayout->addWidget(tabWidget, 0, 0, 1, 1);
-
- MainWindow->setCentralWidget(centralwidget);
- menubar = new QMenuBar(MainWindow);
- menubar->setObjectName(QString::fromUtf8("menubar"));
- menubar->setGeometry(QRect(0, 0, 487, 31));
- MainWindow->setMenuBar(menubar);
- statusbar = new QStatusBar(MainWindow);
- statusbar->setObjectName(QString::fromUtf8("statusbar"));
- MainWindow->setStatusBar(statusbar);
-
- retranslateUi(MainWindow);
-
- tabWidget->setCurrentIndex(0);
-
-
- QMetaObject::connectSlotsByName(MainWindow);
- } // setupUi
-
- void retranslateUi(QMainWindow *MainWindow)
- {
- MainWindow->setWindowTitle(QApplication::translate("MainWindow", "Segmentation tools", 0, QApplication::UnicodeUTF8));
- tabWidget->setTabText(tabWidget->indexOf(Visualization), QApplication::translate("MainWindow", "Visualization", 0, QApplication::UnicodeUTF8));
- tabWidget->setTabText(tabWidget->indexOf(Edition), QApplication::translate("MainWindow", "Edition", 0, QApplication::UnicodeUTF8));
- Q_UNUSED(MainWindow);
- } // retranslateUi
-
-};
-
-namespace Ui {
- class MainWindow: public Ui_MainWindow {};
-} // namespace Ui
-
-QT_END_NAMESPACE
-
-#endif // UI_MAIN_WINDOW_H
--
1.5.6.5
1
0
---
milena/ChangeLog | 4 +++
milena/mln/value/label_32.hh | 52 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 56 insertions(+), 0 deletions(-)
create mode 100644 milena/mln/value/label_32.hh
diff --git a/milena/ChangeLog b/milena/ChangeLog
index a21863f..f8e112a 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,3 +1,7 @@
+2009-11-03 Guillaume Lazzara <z(a)lrde.epita.fr>
+
+ * mln/value/label_32.hh: New.
+
2009-10-02 Roland Levillain <roland(a)lrde.epita.fr>
Add ISMM 2009 input images and generate outputs.
diff --git a/milena/mln/value/label_32.hh b/milena/mln/value/label_32.hh
new file mode 100644
index 0000000..a4603e1
--- /dev/null
+++ b/milena/mln/value/label_32.hh
@@ -0,0 +1,52 @@
+// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef MLN_VALUE_LABEL_32_HH
+# define MLN_VALUE_LABEL_32_HH
+
+/// \file
+///
+/// Define the alias value::label_32.
+
+# include <mln/value/label.hh>
+
+
+namespace mln
+{
+
+ namespace value
+ {
+
+
+ /// Alias for 32-bit integers.
+ typedef label<32> label_32;
+
+
+ } // end of namespace mln::value
+
+} // end of namespace mln
+
+
+#endif // ! MLN_VALUE_LABEL_32_HH
--
1.5.6.5
1
0
* primitive/extract/lines_pattern.hh: Make it less tolerant.
---
scribo/ChangeLog | 6 ++++++
scribo/primitive/extract/lines_pattern.hh | 19 ++++++++++++++++---
2 files changed, 22 insertions(+), 3 deletions(-)
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index 42d59dd..b04de6a 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,5 +1,11 @@
2009-11-03 Guillaume Lazzara <z(a)lrde.epita.fr>
+ Improve line pattern recognition routine.
+
+ * primitive/extract/lines_pattern.hh: Make it less tolerant.
+
+2009-11-03 Guillaume Lazzara <z(a)lrde.epita.fr>
+
Add new debug tools.
* src/debug/Makefile.am: Add new targets.
diff --git a/scribo/primitive/extract/lines_pattern.hh b/scribo/primitive/extract/lines_pattern.hh
index 6a69a4a..57958ec 100644
--- a/scribo/primitive/extract/lines_pattern.hh
+++ b/scribo/primitive/extract/lines_pattern.hh
@@ -62,6 +62,7 @@ namespace scribo
/// \param[in] win_ A window corresponding to the line pattern.
///
/// \return A image with lines of direction \p dir.
+ ///
//
template <typename I, typename W>
mln_concrete(I)
@@ -92,19 +93,31 @@ namespace scribo
mln_piter(I) p(input.domain());
mln_qiter(window2d) q(win, p);
+ bool is_foreground;
for_all(p)
{
+
+ // If the foreground part of the pattern has more than 20%
+ // of background pixels, the current pixel is considered as
+ // background pixel.
if (length - tmp(p) > (0.2f * length))
{
output(p) = false;
continue;
}
- unsigned bg_count = 0;
+ // If the background parts of the pattern have less than 95%
+ // of foreground pixels, the current pixel is considered as
+ // part of the background.
+ is_foreground = true;
for_all(q)
- bg_count += tmp(q);
+ if ((length - tmp(q)) < (length * 0.95f))
+ {
+ is_foreground = false;
+ break;
+ }
- output(p) = (2 * length - bg_count) > (2 * length * 0.90f);
+ output(p) = is_foreground;
}
--
1.5.6.5
1
0
* src/debug/Makefile.am: Add new targets.
* src/debug/show_links_bbox_h_ratio.cc,
* src/debug/show_links_bbox_overlap.cc,
* src/debug/show_links_bottom_aligned.cc,
* src/debug/show_links_center_aligned.cc,
* src/debug/show_links_non_h_aligned.cc,
* src/debug/show_links_several_right.cc,
* src/debug/show_links_several_right_overlap.cc,
* src/debug/show_links_single_left.cc,
* src/debug/show_links_single_left_dmax_ratio.cc,
* src/debug/show_links_single_right.cc,
* src/debug/show_links_single_right_dmax_ratio.cc,
* src/debug/show_links_top_aligned.cc,
* src/debug/show_objects_large_small.cc,
* src/debug/show_objects_thick.cc: New debug tools.
* src/debug/show_objects_thin.cc: Write it.
---
scribo/ChangeLog | 23 ++++
scribo/src/debug/Makefile.am | 36 +++++-
..._single_right.cc => show_links_bbox_h_ratio.cc} | 57 +++------
...k_single_left.cc => show_links_bbox_overlap.cc} | 57 +++------
...ingle_right.cc => show_links_bottom_aligned.cc} | 59 +++-------
...ingle_right.cc => show_links_center_aligned.cc} | 56 +++------
...single_right.cc => show_links_non_h_aligned.cc} | 57 +++------
...single_right.cc => show_links_several_right.cc} | 38 ++-----
...ight.cc => show_links_several_right_overlap.cc} | 124 +++++++++++++------
...nk_single_left.cc => show_links_single_left.cc} | 117 +++++++++++++------
...eft.cc => show_links_single_left_dmax_ratio.cc} | 121 +++++++++++++-------
..._single_right.cc => show_links_single_right.cc} | 117 +++++++++++++------
...ht.cc => show_links_single_right_dmax_ratio.cc} | 121 +++++++++++++-------
...k_single_right.cc => show_links_top_aligned.cc} | 58 +++------
..._single_left.cc => show_objects_large_small.cc} | 69 ++++-------
...w_link_single_left.cc => show_objects_thick.cc} | 61 +++--------
scribo/src/debug/show_objects_thin.cc | 84 +++++++++++++
17 files changed, 703 insertions(+), 552 deletions(-)
copy scribo/src/debug/{show_link_single_right.cc => show_links_bbox_h_ratio.cc} (65%)
copy scribo/src/debug/{show_link_single_left.cc => show_links_bbox_overlap.cc} (65%)
copy scribo/src/debug/{show_link_single_right.cc => show_links_bottom_aligned.cc} (64%)
copy scribo/src/debug/{show_link_single_right.cc => show_links_center_aligned.cc} (65%)
copy scribo/src/debug/{show_link_single_right.cc => show_links_non_h_aligned.cc} (65%)
copy scribo/src/debug/{show_link_single_right.cc => show_links_several_right.cc} (76%)
copy scribo/src/debug/{show_link_single_right.cc => show_links_several_right_overlap.cc} (54%)
copy scribo/src/debug/{show_link_single_left.cc => show_links_single_left.cc} (57%)
copy scribo/src/debug/{show_link_single_left.cc => show_links_single_left_dmax_ratio.cc} (54%)
copy scribo/src/debug/{show_link_single_right.cc => show_links_single_right.cc} (57%)
copy scribo/src/debug/{show_link_single_right.cc => show_links_single_right_dmax_ratio.cc} (54%)
rename scribo/src/debug/{show_link_single_right.cc => show_links_top_aligned.cc} (64%)
copy scribo/src/debug/{show_link_single_left.cc => show_objects_large_small.cc} (58%)
rename scribo/src/debug/{show_link_single_left.cc => show_objects_thick.cc} (59%)
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index 2a3c71e..42d59dd 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,5 +1,28 @@
2009-11-03 Guillaume Lazzara <z(a)lrde.epita.fr>
+ Add new debug tools.
+
+ * src/debug/Makefile.am: Add new targets.
+
+ * src/debug/show_links_bbox_h_ratio.cc,
+ * src/debug/show_links_bbox_overlap.cc,
+ * src/debug/show_links_bottom_aligned.cc,
+ * src/debug/show_links_center_aligned.cc,
+ * src/debug/show_links_non_h_aligned.cc,
+ * src/debug/show_links_several_right.cc,
+ * src/debug/show_links_several_right_overlap.cc,
+ * src/debug/show_links_single_left.cc,
+ * src/debug/show_links_single_left_dmax_ratio.cc,
+ * src/debug/show_links_single_right.cc,
+ * src/debug/show_links_single_right_dmax_ratio.cc,
+ * src/debug/show_links_top_aligned.cc,
+ * src/debug/show_objects_large_small.cc,
+ * src/debug/show_objects_thick.cc: New debug tools.
+
+ * src/debug/show_objects_thin.cc: Write it.
+
+2009-11-03 Guillaume Lazzara <z(a)lrde.epita.fr>
+
Add new link filters.
* filter/internal/compute.hh: New routine to compute filter
diff --git a/scribo/src/debug/Makefile.am b/scribo/src/debug/Makefile.am
index 1d396a5..28839dc 100644
--- a/scribo/src/debug/Makefile.am
+++ b/scribo/src/debug/Makefile.am
@@ -20,17 +20,41 @@
include $(top_srcdir)/scribo/scribo.mk
bin_PROGRAMS = \
- show_objects_large \
show_left_right_links_validation \
- show_link_single_left \
- show_link_single_right \
+ show_links_bbox_h_ratio \
+ show_links_bbox_overlap \
+ show_links_bottom_aligned \
+ show_links_center_aligned \
+ show_links_non_h_aligned \
+ show_links_several_right \
+ show_links_several_right_overlap \
+ show_links_single_left \
+ show_links_single_left_dmax_ratio \
+ show_links_single_right \
+ show_links_single_right_dmax_ratio \
+ show_links_top_aligned \
+ show_objects_large \
+ show_objects_large_small \
show_objects_small \
+ show_objects_thick \
show_objects_thin
-show_objects_large_SOURCES = show_objects_large.cc
show_left_right_links_validation_SOURCES = show_left_right_links_validation.cc
-show_link_single_left_SOURCES = show_link_single_left.cc
-show_link_single_right_SOURCES = show_link_single_right.cc
+show_links_bbox_h_ratio_SOURCES = show_links_bbox_h_ratio.cc
+show_links_bbox_overlap_SOURCES = show_links_bbox_overlap.cc
+show_links_bottom_aligned_SOURCES = show_links_bottom_aligned.cc
+show_links_center_aligned_SOURCES = show_links_center_aligned.cc
+show_links_non_h_aligned_SOURCES = show_links_non_h_aligned.cc
+show_links_several_right_SOURCES = show_links_several_right.cc
+show_links_several_right_overlap_SOURCES = show_links_several_right_overlap.cc
+show_links_single_left_SOURCES = show_links_single_left.cc
+show_links_single_left_dmax_ratio_SOURCES = show_links_single_left_dmax_ratio.cc
+show_links_single_right_SOURCES = show_links_single_right.cc
+show_links_single_right_dmax_ratio_SOURCES = show_links_single_right_dmax_ratio.cc
+show_links_top_aligned_SOURCES = show_links_top_aligned.cc
+show_objects_large_SOURCES = show_objects_large.cc
+show_objects_large_small_SOURCES = show_objects_large_small.cc
show_objects_small_SOURCES = show_objects_small.cc
+show_objects_thick_SOURCES = show_objects_thick.cc
show_objects_thin_SOURCES = show_objects_thin.cc
diff --git a/scribo/src/debug/show_link_single_right.cc b/scribo/src/debug/show_links_bbox_h_ratio.cc
similarity index 65%
copy from scribo/src/debug/show_link_single_right.cc
copy to scribo/src/debug/show_links_bbox_h_ratio.cc
index 5f1001a..86841c6 100644
--- a/scribo/src/debug/show_link_single_right.cc
+++ b/scribo/src/debug/show_links_bbox_h_ratio.cc
@@ -39,10 +39,11 @@
#include <scribo/primitive/extract/objects.hh>
#include <scribo/primitive/link/with_single_right_link.hh>
+#include <scribo/primitive/link/with_single_left_link.hh>
+#include <scribo/filter/object_links_bbox_h_ratio.hh>
-#include <scribo/draw/bounding_boxes.hh>
-
-#include <scribo/debug/save_linked_bboxes_image.hh>
+#include <scribo/debug/decision_image.hh>
+#include <scribo/debug/links_decision_image.hh>
#include <scribo/debug/usage.hh>
@@ -50,7 +51,7 @@
const char *args_desc[][2] =
{
{ "input.pbm", "A binary image. True for objects and False for the background." },
- { "max_nbh_dist", " Maximum distance for neighborhood search. (common value : 30)" },
+ { "height_ratio", "Min height ratio between two bboxes. (common value : 2)" },
{0, 0}
};
@@ -63,8 +64,8 @@ int main(int argc, char* argv[])
if (argc != 4)
return scribo::debug::usage(argv,
- "Show sucessful/unsuccessful right links between components.",
- "input.pbm max_nbh_dist output.ppm",
+ "Show valid or invalid links according the bboxes height ratio.",
+ "input.pbm height_ratio output.ppm",
args_desc,
"A color image. Valid links are drawn in green, invalid ones in red.");
@@ -77,41 +78,21 @@ int main(int argc, char* argv[])
object_image(L) objects
= scribo::primitive::extract::objects(input, c8(), nbboxes);
- // Finding right links.
- object_links<L> right_link
- = primitive::link::with_single_right_link(objects, atoi(argv[2]));
-
-
- // Preparing output image.
- image2d<value::rgb8> output = data::convert(value::rgb8(), input);
- scribo::draw::bounding_boxes(output, objects, literal::blue);
-
-
- // Drawing links.
- mln::util::array<mln_result_(accu::center<mln_psite_(L)>)>
- mass_centers = labeling::compute(accu::meta::center(),
- objects, objects.nlabels());
-
- for_all_ncomponents(i, objects.nlabels())
- {
- unsigned midcol = (objects.bbox(i).pmax().col()
- - objects.bbox(i).pmin().col()) / 2;
- int dmax = midcol + atoi(argv[2]);
- mln_site_(L) c = mass_centers(i);
+ // Finding right links.
+ object_links<L> right_links
+ = primitive::link::with_single_right_link(objects);
- mln_site_(L) p = c + mln::right;
+ // Filtering.
+ object_links<L> hratio_filtered_links
+ = filter::object_links_bbox_h_ratio(objects, right_links, atof(argv[2]));
- while (is_invalid_link(objects, right_link, p, i, c, dmax))
- {
- if (right_link[i] != i)
- output(p) = literal::green;
- else
- output(p) = literal::red;
- ++p.col();
- }
- }
+ // Debug image.
+ image2d<value::rgb8> hratio_decision_image
+ = scribo::debug::links_decision_image(input,
+ right_links,
+ hratio_filtered_links);
+ io::ppm::save(hratio_decision_image, argv[3]);
- io::ppm::save(output, argv[3]);
}
diff --git a/scribo/src/debug/show_link_single_left.cc b/scribo/src/debug/show_links_bbox_overlap.cc
similarity index 65%
copy from scribo/src/debug/show_link_single_left.cc
copy to scribo/src/debug/show_links_bbox_overlap.cc
index a8b42f2..eae1cd3 100644
--- a/scribo/src/debug/show_link_single_left.cc
+++ b/scribo/src/debug/show_links_bbox_overlap.cc
@@ -38,11 +38,12 @@
#include <mln/io/ppm/save.hh>
#include <scribo/primitive/extract/objects.hh>
+#include <scribo/primitive/link/with_single_right_link.hh>
#include <scribo/primitive/link/with_single_left_link.hh>
+#include <scribo/filter/object_links_bbox_overlap.hh>
-#include <scribo/draw/bounding_boxes.hh>
-
-#include <scribo/debug/save_linked_bboxes_image.hh>
+#include <scribo/debug/decision_image.hh>
+#include <scribo/debug/links_decision_image.hh>
#include <scribo/debug/usage.hh>
@@ -50,7 +51,7 @@
const char *args_desc[][2] =
{
{ "input.pbm", "A binary image. True for objects and False for the background." },
- { "max_nbh_dist", " Maximum distance for neighborhood search. (common value : 30)" },
+ { "ratio", "Maximum bounding boxes overlap ratio. (common value : 0.7)" },
{0, 0}
};
@@ -63,8 +64,8 @@ int main(int argc, char* argv[])
if (argc != 4)
return scribo::debug::usage(argv,
- "Show sucessful/unsuccessful left links between components.",
- "input.pbm max_nbh_dist output.ppm",
+ "Show valid or invalid links according the bboxes overlap.",
+ "input.pbm ratio output.ppm",
args_desc,
"A color image. Valid links are drawn in green, invalid ones in red.");
@@ -77,41 +78,21 @@ int main(int argc, char* argv[])
object_image(L) objects
= scribo::primitive::extract::objects(input, c8(), nbboxes);
- // Finding left links.
- object_links<L> left_link
- = primitive::link::with_single_left_link(objects, atoi(argv[2]));
-
-
-
- // Preparing output image.
- image2d<value::rgb8> output = data::convert(value::rgb8(), input);
- scribo::draw::bounding_boxes(output, objects, literal::blue);
-
-
- // Drawing links.
- mln::util::array<mln_result_(accu::center<mln_psite_(L)>)>
- mass_centers = labeling::compute(accu::meta::center(),
- objects, objects.nlabels());
- for_all_ncomponents(i, objects.nlabels())
- {
- unsigned midcol = (objects.bbox(i).pmax().col()
- - objects.bbox(i).pmin().col()) / 2;
- int dmax = midcol + atoi(argv[2]);
- mln_site_(L) c = mass_centers(i);
+ // Finding right links.
+ object_links<L> right_links
+ = primitive::link::with_single_right_link(objects);
- mln_site_(L) p = c + mln::left;
+ // Filtering.
+ object_links<L> hratio_filtered_links
+ = filter::object_links_bbox_overlap(objects, right_links, atof(argv[2]));
- while (is_invalid_link(objects, left_link, p, i, c, dmax))
- {
- if (left_link[i] != i)
- output(p) = literal::green;
- else
- output(p) = literal::red;
- --p.col();
- }
- }
+ // Debug image.
+ image2d<value::rgb8> hratio_decision_image
+ = scribo::debug::links_decision_image(input,
+ right_links,
+ hratio_filtered_links);
+ io::ppm::save(hratio_decision_image, argv[3]);
- io::ppm::save(output, argv[3]);
}
diff --git a/scribo/src/debug/show_link_single_right.cc b/scribo/src/debug/show_links_bottom_aligned.cc
similarity index 64%
copy from scribo/src/debug/show_link_single_right.cc
copy to scribo/src/debug/show_links_bottom_aligned.cc
index 5f1001a..4751308 100644
--- a/scribo/src/debug/show_link_single_right.cc
+++ b/scribo/src/debug/show_links_bottom_aligned.cc
@@ -38,11 +38,10 @@
#include <mln/io/ppm/save.hh>
#include <scribo/primitive/extract/objects.hh>
-#include <scribo/primitive/link/with_single_right_link.hh>
+#include <scribo/primitive/link/with_single_right_link_bottom.hh>
+#include <scribo/filter/object_links_bottom_aligned.hh>
-#include <scribo/draw/bounding_boxes.hh>
-
-#include <scribo/debug/save_linked_bboxes_image.hh>
+#include <scribo/debug/alignment_decision_image.hh>
#include <scribo/debug/usage.hh>
@@ -50,7 +49,7 @@
const char *args_desc[][2] =
{
{ "input.pbm", "A binary image. True for objects and False for the background." },
- { "max_nbh_dist", " Maximum distance for neighborhood search. (common value : 30)" },
+ { "max_alpha", "Max angle between two object bottoms. (common value : 5)" },
{0, 0}
};
@@ -63,8 +62,8 @@ int main(int argc, char* argv[])
if (argc != 4)
return scribo::debug::usage(argv,
- "Show sucessful/unsuccessful right links between components.",
- "input.pbm max_nbh_dist output.ppm",
+ "Show valid or invalid links according the horizontal alignment (based on bottom line).",
+ "input.pbm max_alpha output.ppm",
args_desc,
"A color image. Valid links are drawn in green, invalid ones in red.");
@@ -77,41 +76,21 @@ int main(int argc, char* argv[])
object_image(L) objects
= scribo::primitive::extract::objects(input, c8(), nbboxes);
- // Finding right links.
- object_links<L> right_link
- = primitive::link::with_single_right_link(objects, atoi(argv[2]));
-
-
-
- // Preparing output image.
- image2d<value::rgb8> output = data::convert(value::rgb8(), input);
- scribo::draw::bounding_boxes(output, objects, literal::blue);
+ // Finding right links.
+ object_links<L> right_links
+ = primitive::link::with_single_right_link_bottom(objects);
- // Drawing links.
- mln::util::array<mln_result_(accu::center<mln_psite_(L)>)>
- mass_centers = labeling::compute(accu::meta::center(),
- objects, objects.nlabels());
-
- for_all_ncomponents(i, objects.nlabels())
- {
- unsigned midcol = (objects.bbox(i).pmax().col()
- - objects.bbox(i).pmin().col()) / 2;
- int dmax = midcol + atoi(argv[2]);
- mln_site_(L) c = mass_centers(i);
-
- mln_site_(L) p = c + mln::right;
-
- while (is_invalid_link(objects, right_link, p, i, c, dmax))
- {
- if (right_link[i] != i)
- output(p) = literal::green;
- else
- output(p) = literal::red;
- ++p.col();
- }
+ // Filtering.
+ object_links<L> filtered_links
+ = filter::object_links_bottom_aligned(objects, right_links, atof(argv[2]));
- }
+ // Debug image.
+ image2d<value::rgb8> decision_image
+ = scribo::debug::alignment_decision_image(input,
+ right_links,
+ filtered_links,
+ scribo::debug::bottom);
+ io::ppm::save(decision_image, argv[3]);
- io::ppm::save(output, argv[3]);
}
diff --git a/scribo/src/debug/show_link_single_right.cc b/scribo/src/debug/show_links_center_aligned.cc
similarity index 65%
copy from scribo/src/debug/show_link_single_right.cc
copy to scribo/src/debug/show_links_center_aligned.cc
index 5f1001a..dfcb775 100644
--- a/scribo/src/debug/show_link_single_right.cc
+++ b/scribo/src/debug/show_links_center_aligned.cc
@@ -39,10 +39,9 @@
#include <scribo/primitive/extract/objects.hh>
#include <scribo/primitive/link/with_single_right_link.hh>
+#include <scribo/filter/object_links_center_aligned.hh>
-#include <scribo/draw/bounding_boxes.hh>
-
-#include <scribo/debug/save_linked_bboxes_image.hh>
+#include <scribo/debug/alignment_decision_image.hh>
#include <scribo/debug/usage.hh>
@@ -50,7 +49,7 @@
const char *args_desc[][2] =
{
{ "input.pbm", "A binary image. True for objects and False for the background." },
- { "max_nbh_dist", " Maximum distance for neighborhood search. (common value : 30)" },
+ { "max_alpha", "Max angle between two object bottoms. (common value : 5)" },
{0, 0}
};
@@ -63,8 +62,8 @@ int main(int argc, char* argv[])
if (argc != 4)
return scribo::debug::usage(argv,
- "Show sucessful/unsuccessful right links between components.",
- "input.pbm max_nbh_dist output.ppm",
+ "Show valid or invalid links according the horizontal alignment (based on center line).",
+ "input.pbm max_alpha output.ppm",
args_desc,
"A color image. Valid links are drawn in green, invalid ones in red.");
@@ -77,41 +76,22 @@ int main(int argc, char* argv[])
object_image(L) objects
= scribo::primitive::extract::objects(input, c8(), nbboxes);
- // Finding right links.
- object_links<L> right_link
- = primitive::link::with_single_right_link(objects, atoi(argv[2]));
-
-
- // Preparing output image.
- image2d<value::rgb8> output = data::convert(value::rgb8(), input);
- scribo::draw::bounding_boxes(output, objects, literal::blue);
-
-
- // Drawing links.
- mln::util::array<mln_result_(accu::center<mln_psite_(L)>)>
- mass_centers = labeling::compute(accu::meta::center(),
- objects, objects.nlabels());
-
- for_all_ncomponents(i, objects.nlabels())
- {
- unsigned midcol = (objects.bbox(i).pmax().col()
- - objects.bbox(i).pmin().col()) / 2;
- int dmax = midcol + atoi(argv[2]);
- mln_site_(L) c = mass_centers(i);
+ // Finding right links.
+ object_links<L> right_links
+ = primitive::link::with_single_right_link(objects);
- mln_site_(L) p = c + mln::right;
+ // Filtering.
+ object_links<L> filtered_links
+ = filter::object_links_center_aligned(objects, right_links, atof(argv[2]));
- while (is_invalid_link(objects, right_link, p, i, c, dmax))
- {
- if (right_link[i] != i)
- output(p) = literal::green;
- else
- output(p) = literal::red;
- ++p.col();
- }
+ // Debug image.
+ image2d<value::rgb8> decision_image
+ = scribo::debug::alignment_decision_image(input,
+ right_links,
+ filtered_links,
+ scribo::debug::center);
- }
+ io::ppm::save(decision_image, argv[3]);
- io::ppm::save(output, argv[3]);
}
diff --git a/scribo/src/debug/show_link_single_right.cc b/scribo/src/debug/show_links_non_h_aligned.cc
similarity index 65%
copy from scribo/src/debug/show_link_single_right.cc
copy to scribo/src/debug/show_links_non_h_aligned.cc
index 5f1001a..04d3de5 100644
--- a/scribo/src/debug/show_link_single_right.cc
+++ b/scribo/src/debug/show_links_non_h_aligned.cc
@@ -39,10 +39,11 @@
#include <scribo/primitive/extract/objects.hh>
#include <scribo/primitive/link/with_single_right_link.hh>
+#include <scribo/primitive/link/with_single_left_link.hh>
+#include <scribo/filter/object_links_non_h_aligned.hh>
-#include <scribo/draw/bounding_boxes.hh>
-
-#include <scribo/debug/save_linked_bboxes_image.hh>
+#include <scribo/debug/decision_image.hh>
+#include <scribo/debug/links_decision_image.hh>
#include <scribo/debug/usage.hh>
@@ -50,7 +51,7 @@
const char *args_desc[][2] =
{
{ "input.pbm", "A binary image. True for objects and False for the background." },
- { "max_nbh_dist", " Maximum distance for neighborhood search. (common value : 30)" },
+ { "delta", "Max delta for horizontal alignment. (common value : 5)" },
{0, 0}
};
@@ -63,8 +64,8 @@ int main(int argc, char* argv[])
if (argc != 4)
return scribo::debug::usage(argv,
- "Show sucessful/unsuccessful right links between components.",
- "input.pbm max_nbh_dist output.ppm",
+ "Show valid or invalid links according the horizontal alignment (based on top and bottom lines).",
+ "input.pbm delta output.ppm",
args_desc,
"A color image. Valid links are drawn in green, invalid ones in red.");
@@ -77,41 +78,21 @@ int main(int argc, char* argv[])
object_image(L) objects
= scribo::primitive::extract::objects(input, c8(), nbboxes);
- // Finding right links.
- object_links<L> right_link
- = primitive::link::with_single_right_link(objects, atoi(argv[2]));
-
-
- // Preparing output image.
- image2d<value::rgb8> output = data::convert(value::rgb8(), input);
- scribo::draw::bounding_boxes(output, objects, literal::blue);
-
-
- // Drawing links.
- mln::util::array<mln_result_(accu::center<mln_psite_(L)>)>
- mass_centers = labeling::compute(accu::meta::center(),
- objects, objects.nlabels());
-
- for_all_ncomponents(i, objects.nlabels())
- {
- unsigned midcol = (objects.bbox(i).pmax().col()
- - objects.bbox(i).pmin().col()) / 2;
- int dmax = midcol + atoi(argv[2]);
- mln_site_(L) c = mass_centers(i);
+ // Finding right links.
+ object_links<L> right_links
+ = primitive::link::with_single_right_link(objects);
- mln_site_(L) p = c + mln::right;
+ // Filtering.
+ object_links<L> filtered_links
+ = filter::object_links_non_h_aligned(objects, right_links, atoi(argv[2]));
- while (is_invalid_link(objects, right_link, p, i, c, dmax))
- {
- if (right_link[i] != i)
- output(p) = literal::green;
- else
- output(p) = literal::red;
- ++p.col();
- }
- }
+ // Debug image.
+ image2d<value::rgb8> decision_image
+ = scribo::debug::links_decision_image(input,
+ right_links,
+ filtered_links);
+ io::ppm::save(decision_image, argv[3]);
- io::ppm::save(output, argv[3]);
}
diff --git a/scribo/src/debug/show_link_single_right.cc b/scribo/src/debug/show_links_several_right.cc
similarity index 76%
copy from scribo/src/debug/show_link_single_right.cc
copy to scribo/src/debug/show_links_several_right.cc
index 5f1001a..05e4a74 100644
--- a/scribo/src/debug/show_link_single_right.cc
+++ b/scribo/src/debug/show_links_several_right.cc
@@ -38,11 +38,11 @@
#include <mln/io/ppm/save.hh>
#include <scribo/primitive/extract/objects.hh>
-#include <scribo/primitive/link/with_single_right_link.hh>
+#include <scribo/primitive/link/with_several_right_links.hh>
#include <scribo/draw/bounding_boxes.hh>
-#include <scribo/debug/save_linked_bboxes_image.hh>
+#include <scribo/debug/several_links_decision_image.hh>
#include <scribo/debug/usage.hh>
@@ -79,39 +79,17 @@ int main(int argc, char* argv[])
// Finding right links.
object_links<L> right_link
- = primitive::link::with_single_right_link(objects, atoi(argv[2]));
-
-
-
- // Preparing output image.
- image2d<value::rgb8> output = data::convert(value::rgb8(), input);
- scribo::draw::bounding_boxes(output, objects, literal::blue);
-
+ = primitive::link::with_several_right_links(objects, atoi(argv[2]));
// Drawing links.
mln::util::array<mln_result_(accu::center<mln_psite_(L)>)>
mass_centers = labeling::compute(accu::meta::center(),
objects, objects.nlabels());
- for_all_ncomponents(i, objects.nlabels())
- {
- unsigned midcol = (objects.bbox(i).pmax().col()
- - objects.bbox(i).pmin().col()) / 2;
- int dmax = midcol + atoi(argv[2]);
- mln_site_(L) c = mass_centers(i);
-
- mln_site_(L) p = c + mln::right;
-
- while (is_invalid_link(objects, right_link, p, i, c, dmax))
- {
- if (right_link[i] != i)
- output(p) = literal::green;
- else
- output(p) = literal::red;
- ++p.col();
- }
-
- }
+ image2d<value::rgb8> decision_image
+ = scribo::debug::several_links_decision_image(input,
+ right_link,
+ right_link);
- io::ppm::save(output, argv[3]);
+ io::ppm::save(decision_image, argv[3]);
}
diff --git a/scribo/src/debug/show_link_single_right.cc b/scribo/src/debug/show_links_several_right_overlap.cc
similarity index 54%
copy from scribo/src/debug/show_link_single_right.cc
copy to scribo/src/debug/show_links_several_right_overlap.cc
index 5f1001a..6b2a66a 100644
--- a/scribo/src/debug/show_link_single_right.cc
+++ b/scribo/src/debug/show_links_several_right_overlap.cc
@@ -37,8 +37,12 @@
#include <mln/io/pbm/load.hh>
#include <mln/io/ppm/save.hh>
+#include <mln/draw/line.hh>
+
#include <scribo/primitive/extract/objects.hh>
-#include <scribo/primitive/link/with_single_right_link.hh>
+#include <scribo/primitive/link/internal/link_several_dmax_base.hh>
+#include <scribo/primitive/link/internal/anchors_3.hh>
+#include <scribo/primitive/link/compute_several.hh>
#include <scribo/draw/bounding_boxes.hh>
@@ -46,11 +50,83 @@
#include <scribo/debug/usage.hh>
+namespace scribo
+{
+
+ template <typename I, typename L>
+ struct several_right_overlap_debug_functor
+ : public primitive::link::internal::link_several_dmax_base<L, several_right_overlap_debug_functor<I, L> >
+ {
+ typedef several_right_overlap_debug_functor<I, L> self_t;
+ typedef
+ primitive::link::internal::link_several_dmax_base<L, self_t> super_;
+
+ typedef
+ mln::util::array<mln::util::couple<unsigned, mln_site(L)>
+ potential_links_t;
+
+ public:
+ typedef mln_site(L) P;
+
+ several_right_overlap_debug_functor(const I& input,
+ const object_image(L)& objects,
+ float dmax)
+ : super_(objects, dmax, 3)
+ {
+ output_ = data::convert(value::rgb8(), input);
+ scribo::draw::bounding_boxes(output_, objects, literal::blue);
+ mln_postcondition(output_.is_valid());
+ }
+
+
+ void validate_link_(unsigned current_object,
+ const P& start_point,
+ const P& p,
+ unsigned anchor)
+ {
+ mln::draw::line(output_, start_point, p, literal::green);
+
+ super_::validate_link_(current_object, start_point, p, anchor);
+ }
+
+
+
+ void invalidate_link_(unsigned current_object,
+ const P& start_point,
+ const P& p,
+ unsigned anchor)
+ {
+ if (output_.domain().has(p))
+ mln::draw::line(output_, start_point, p, literal::red);
+ else
+ {
+ P tmp = p;
+ ++tmp.col();
+ mln::draw::line(output_, start_point, tmp, literal::red);
+ }
+
+ super_::invalidate_link_(current_object, start_point, p, anchor);
+ }
+
+
+
+ void compute_next_site_(P& p)
+ {
+ ++p.col();
+ }
+
+
+ image2d<value::rgb8> output_;
+ };
+
+
+}
+
const char *args_desc[][2] =
{
{ "input.pbm", "A binary image. True for objects and False for the background." },
- { "max_nbh_dist", " Maximum distance for neighborhood search. (common value : 30)" },
+ { "max_nbh_dist", "The maximum lookup distance. (common value : 30)" },
{0, 0}
};
@@ -68,7 +144,8 @@ int main(int argc, char* argv[])
args_desc,
"A color image. Valid links are drawn in green, invalid ones in red.");
- image2d<bool> input;
+ typedef image2d<bool> I;
+ I input;
io::pbm::load(input, argv[1]);
// Finding objects.
@@ -77,41 +154,10 @@ int main(int argc, char* argv[])
object_image(L) objects
= scribo::primitive::extract::objects(input, c8(), nbboxes);
- // Finding right links.
- object_links<L> right_link
- = primitive::link::with_single_right_link(objects, atoi(argv[2]));
-
-
-
- // Preparing output image.
- image2d<value::rgb8> output = data::convert(value::rgb8(), input);
- scribo::draw::bounding_boxes(output, objects, literal::blue);
-
-
- // Drawing links.
- mln::util::array<mln_result_(accu::center<mln_psite_(L)>)>
- mass_centers = labeling::compute(accu::meta::center(),
- objects, objects.nlabels());
-
- for_all_ncomponents(i, objects.nlabels())
- {
- unsigned midcol = (objects.bbox(i).pmax().col()
- - objects.bbox(i).pmin().col()) / 2;
- int dmax = midcol + atoi(argv[2]);
- mln_site_(L) c = mass_centers(i);
-
- mln_site_(L) p = c + mln::right;
-
- while (is_invalid_link(objects, right_link, p, i, c, dmax))
- {
- if (right_link[i] != i)
- output(p) = literal::green;
- else
- output(p) = literal::red;
- ++p.col();
- }
-
- }
+ // Write debug image.
+ several_right_overlap_debug_functor<I, L> functor(input,
+ objects, atof(argv[2]));
+ primitive::link::compute_several(functor);
- io::ppm::save(output, argv[3]);
+ io::ppm::save(functor.output_, argv[3]);
}
diff --git a/scribo/src/debug/show_link_single_left.cc b/scribo/src/debug/show_links_single_left.cc
similarity index 57%
copy from scribo/src/debug/show_link_single_left.cc
copy to scribo/src/debug/show_links_single_left.cc
index a8b42f2..094ca85 100644
--- a/scribo/src/debug/show_link_single_left.cc
+++ b/scribo/src/debug/show_links_single_left.cc
@@ -37,8 +37,12 @@
#include <mln/io/pbm/load.hh>
#include <mln/io/ppm/save.hh>
+#include <mln/draw/line.hh>
+
#include <scribo/primitive/extract/objects.hh>
#include <scribo/primitive/link/with_single_left_link.hh>
+#include <scribo/primitive/link/internal/link_ms_dmax_base.hh>
+#include <scribo/primitive/link/compute.hh>
#include <scribo/draw/bounding_boxes.hh>
@@ -46,11 +50,79 @@
#include <scribo/debug/usage.hh>
+namespace scribo
+{
+
+ template <typename I, typename L>
+ struct single_left_link_debug_functor
+ : primitive::link::internal::link_ms_dmax_base<L,
+ single_left_link_debug_functor<I, L> >
+ {
+ typedef single_left_link_debug_functor<I, L> self_t;
+ typedef
+ primitive::link::internal::link_ms_dmax_base<L, self_t> super_;
+
+ public:
+ typedef mln_site(L) P;
+
+ single_left_link_debug_functor(const I& input,
+ const object_image(L)& objects,
+ float dmax)
+ : super_(objects, dmax)
+ {
+ output_ = data::convert(value::rgb8(), input);
+ scribo::draw::bounding_boxes(output_, objects, literal::blue);
+ mln_postcondition(output_.is_valid());
+ }
+
+ void validate_link_(unsigned current_object,
+ const P& start_point,
+ const P& p,
+ unsigned anchor)
+ {
+ mln::draw::line(output_, start_point, p, literal::green);
+
+ super_::validate_link_(current_object, start_point, p, anchor);
+ }
+
+
+
+ void invalidate_link_(unsigned current_object,
+ const P& start_point,
+ const P& p,
+ unsigned anchor)
+ {
+ if (output_.domain().has(p))
+ mln::draw::line(output_, start_point, p, literal::red);
+ else
+ {
+ P tmp = p;
+ ++tmp.col();
+ mln::draw::line(output_, start_point, tmp, literal::red);
+ }
+
+ super_::invalidate_link_(current_object, start_point, p, anchor);
+ }
+
+
+
+ void compute_next_site_(P& p)
+ {
+ --p.col();
+ }
+
+
+ image2d<value::rgb8> output_;
+ };
+
+
+}
+
const char *args_desc[][2] =
{
{ "input.pbm", "A binary image. True for objects and False for the background." },
- { "max_nbh_dist", " Maximum distance for neighborhood search. (common value : 30)" },
+ { "max_nbh_dist", "The maximum lookup distance. (common value : 30)" },
{0, 0}
};
@@ -68,7 +140,8 @@ int main(int argc, char* argv[])
args_desc,
"A color image. Valid links are drawn in green, invalid ones in red.");
- image2d<bool> input;
+ typedef image2d<bool> I;
+ I input;
io::pbm::load(input, argv[1]);
// Finding objects.
@@ -77,41 +150,9 @@ int main(int argc, char* argv[])
object_image(L) objects
= scribo::primitive::extract::objects(input, c8(), nbboxes);
- // Finding left links.
- object_links<L> left_link
- = primitive::link::with_single_left_link(objects, atoi(argv[2]));
-
-
-
- // Preparing output image.
- image2d<value::rgb8> output = data::convert(value::rgb8(), input);
- scribo::draw::bounding_boxes(output, objects, literal::blue);
-
-
- // Drawing links.
- mln::util::array<mln_result_(accu::center<mln_psite_(L)>)>
- mass_centers = labeling::compute(accu::meta::center(),
- objects, objects.nlabels());
-
- for_all_ncomponents(i, objects.nlabels())
- {
- unsigned midcol = (objects.bbox(i).pmax().col()
- - objects.bbox(i).pmin().col()) / 2;
- int dmax = midcol + atoi(argv[2]);
- mln_site_(L) c = mass_centers(i);
-
- mln_site_(L) p = c + mln::left;
-
- while (is_invalid_link(objects, left_link, p, i, c, dmax))
- {
- if (left_link[i] != i)
- output(p) = literal::green;
- else
- output(p) = literal::red;
- --p.col();
- }
-
- }
+ // Write debug image.
+ single_left_link_debug_functor<I, L> functor(input, objects, atof(argv[2]));
+ primitive::link::compute(functor);
- io::ppm::save(output, argv[3]);
+ io::ppm::save(functor.output_, argv[3]);
}
diff --git a/scribo/src/debug/show_link_single_left.cc b/scribo/src/debug/show_links_single_left_dmax_ratio.cc
similarity index 54%
copy from scribo/src/debug/show_link_single_left.cc
copy to scribo/src/debug/show_links_single_left_dmax_ratio.cc
index a8b42f2..2ba0ace 100644
--- a/scribo/src/debug/show_link_single_left.cc
+++ b/scribo/src/debug/show_links_single_left_dmax_ratio.cc
@@ -37,8 +37,12 @@
#include <mln/io/pbm/load.hh>
#include <mln/io/ppm/save.hh>
+#include <mln/draw/line.hh>
+
#include <scribo/primitive/extract/objects.hh>
-#include <scribo/primitive/link/with_single_left_link.hh>
+#include <scribo/primitive/link/with_single_left_link_dmax_ratio.hh>
+#include <scribo/primitive/link/internal/link_ms_dmax_ratio_base.hh>
+#include <scribo/primitive/link/compute.hh>
#include <scribo/draw/bounding_boxes.hh>
@@ -46,11 +50,79 @@
#include <scribo/debug/usage.hh>
+namespace scribo
+{
+
+ template <typename I, typename L>
+ struct single_left_link_debug_functor
+ : primitive::link::internal::link_ms_dmax_ratio_base<L,
+ single_left_link_debug_functor<I, L> >
+ {
+ typedef single_left_link_debug_functor<I, L> self_t;
+ typedef
+ primitive::link::internal::link_ms_dmax_ratio_base<L, self_t> super_;
+
+ public:
+ typedef mln_site(L) P;
+
+ single_left_link_debug_functor(const I& input,
+ const object_image(L)& objects,
+ float dmax_ratio)
+ : super_(objects, dmax_ratio)
+ {
+ output_ = data::convert(value::rgb8(), input);
+ scribo::draw::bounding_boxes(output_, objects, literal::blue);
+ mln_postcondition(output_.is_valid());
+ }
+
+ void validate_link_(unsigned current_object,
+ const P& start_point,
+ const P& p,
+ unsigned anchor)
+ {
+ mln::draw::line(output_, start_point, p, literal::green);
+
+ super_::validate_link_(current_object, start_point, p, anchor);
+ }
+
+
+
+ void invalidate_link_(unsigned current_object,
+ const P& start_point,
+ const P& p,
+ unsigned anchor)
+ {
+ if (output_.domain().has(p))
+ mln::draw::line(output_, start_point, p, literal::red);
+ else
+ {
+ P tmp = p;
+ ++tmp.col();
+ mln::draw::line(output_, start_point, tmp, literal::red);
+ }
+
+ super_::invalidate_link_(current_object, start_point, p, anchor);
+ }
+
+
+
+ void compute_next_site_(P& p)
+ {
+ --p.col();
+ }
+
+
+ image2d<value::rgb8> output_;
+ };
+
+
+}
+
const char *args_desc[][2] =
{
{ "input.pbm", "A binary image. True for objects and False for the background." },
- { "max_nbh_dist", " Maximum distance for neighborhood search. (common value : 30)" },
+ { "max_nbh_dist_ratio", "Size ratio defining the maximum lookup distance. (common value : 3)" },
{0, 0}
};
@@ -64,11 +136,12 @@ int main(int argc, char* argv[])
if (argc != 4)
return scribo::debug::usage(argv,
"Show sucessful/unsuccessful left links between components.",
- "input.pbm max_nbh_dist output.ppm",
+ "input.pbm max_nbh_dist_ratio output.ppm",
args_desc,
"A color image. Valid links are drawn in green, invalid ones in red.");
- image2d<bool> input;
+ typedef image2d<bool> I;
+ I input;
io::pbm::load(input, argv[1]);
// Finding objects.
@@ -77,41 +150,9 @@ int main(int argc, char* argv[])
object_image(L) objects
= scribo::primitive::extract::objects(input, c8(), nbboxes);
- // Finding left links.
- object_links<L> left_link
- = primitive::link::with_single_left_link(objects, atoi(argv[2]));
-
-
-
- // Preparing output image.
- image2d<value::rgb8> output = data::convert(value::rgb8(), input);
- scribo::draw::bounding_boxes(output, objects, literal::blue);
-
-
- // Drawing links.
- mln::util::array<mln_result_(accu::center<mln_psite_(L)>)>
- mass_centers = labeling::compute(accu::meta::center(),
- objects, objects.nlabels());
-
- for_all_ncomponents(i, objects.nlabels())
- {
- unsigned midcol = (objects.bbox(i).pmax().col()
- - objects.bbox(i).pmin().col()) / 2;
- int dmax = midcol + atoi(argv[2]);
- mln_site_(L) c = mass_centers(i);
-
- mln_site_(L) p = c + mln::left;
-
- while (is_invalid_link(objects, left_link, p, i, c, dmax))
- {
- if (left_link[i] != i)
- output(p) = literal::green;
- else
- output(p) = literal::red;
- --p.col();
- }
-
- }
+ // Write debug image.
+ single_left_link_debug_functor<I, L> functor(input, objects, atof(argv[2]));
+ primitive::link::compute(functor);
- io::ppm::save(output, argv[3]);
+ io::ppm::save(functor.output_, argv[3]);
}
diff --git a/scribo/src/debug/show_link_single_right.cc b/scribo/src/debug/show_links_single_right.cc
similarity index 57%
copy from scribo/src/debug/show_link_single_right.cc
copy to scribo/src/debug/show_links_single_right.cc
index 5f1001a..c121cce 100644
--- a/scribo/src/debug/show_link_single_right.cc
+++ b/scribo/src/debug/show_links_single_right.cc
@@ -37,8 +37,12 @@
#include <mln/io/pbm/load.hh>
#include <mln/io/ppm/save.hh>
+#include <mln/draw/line.hh>
+
#include <scribo/primitive/extract/objects.hh>
#include <scribo/primitive/link/with_single_right_link.hh>
+#include <scribo/primitive/link/internal/link_ms_dmax_base.hh>
+#include <scribo/primitive/link/compute.hh>
#include <scribo/draw/bounding_boxes.hh>
@@ -46,11 +50,79 @@
#include <scribo/debug/usage.hh>
+namespace scribo
+{
+
+ template <typename I, typename L>
+ struct single_right_link_debug_functor
+ : primitive::link::internal::link_ms_dmax_base<L,
+ single_right_link_debug_functor<I, L> >
+ {
+ typedef single_right_link_debug_functor<I, L> self_t;
+ typedef
+ primitive::link::internal::link_ms_dmax_base<L, self_t> super_;
+
+ public:
+ typedef mln_site(L) P;
+
+ single_right_link_debug_functor(const I& input,
+ const object_image(L)& objects,
+ float dmax)
+ : super_(objects, dmax)
+ {
+ output_ = data::convert(value::rgb8(), input);
+ scribo::draw::bounding_boxes(output_, objects, literal::blue);
+ mln_postcondition(output_.is_valid());
+ }
+
+ void validate_link_(unsigned current_object,
+ const P& start_point,
+ const P& p,
+ unsigned anchor)
+ {
+ mln::draw::line(output_, start_point, p, literal::green);
+
+ super_::validate_link_(current_object, start_point, p, anchor);
+ }
+
+
+
+ void invalidate_link_(unsigned current_object,
+ const P& start_point,
+ const P& p,
+ unsigned anchor)
+ {
+ if (output_.domain().has(p))
+ mln::draw::line(output_, start_point, p, literal::red);
+ else
+ {
+ P tmp = p;
+ ++tmp.col();
+ mln::draw::line(output_, start_point, tmp, literal::red);
+ }
+
+ super_::invalidate_link_(current_object, start_point, p, anchor);
+ }
+
+
+
+ void compute_next_site_(P& p)
+ {
+ --p.col();
+ }
+
+
+ image2d<value::rgb8> output_;
+ };
+
+
+}
+
const char *args_desc[][2] =
{
{ "input.pbm", "A binary image. True for objects and False for the background." },
- { "max_nbh_dist", " Maximum distance for neighborhood search. (common value : 30)" },
+ { "max_nbh_dist", "The maximum lookup distance. (common value : 30)" },
{0, 0}
};
@@ -68,7 +140,8 @@ int main(int argc, char* argv[])
args_desc,
"A color image. Valid links are drawn in green, invalid ones in red.");
- image2d<bool> input;
+ typedef image2d<bool> I;
+ I input;
io::pbm::load(input, argv[1]);
// Finding objects.
@@ -77,41 +150,9 @@ int main(int argc, char* argv[])
object_image(L) objects
= scribo::primitive::extract::objects(input, c8(), nbboxes);
- // Finding right links.
- object_links<L> right_link
- = primitive::link::with_single_right_link(objects, atoi(argv[2]));
-
-
-
- // Preparing output image.
- image2d<value::rgb8> output = data::convert(value::rgb8(), input);
- scribo::draw::bounding_boxes(output, objects, literal::blue);
-
-
- // Drawing links.
- mln::util::array<mln_result_(accu::center<mln_psite_(L)>)>
- mass_centers = labeling::compute(accu::meta::center(),
- objects, objects.nlabels());
-
- for_all_ncomponents(i, objects.nlabels())
- {
- unsigned midcol = (objects.bbox(i).pmax().col()
- - objects.bbox(i).pmin().col()) / 2;
- int dmax = midcol + atoi(argv[2]);
- mln_site_(L) c = mass_centers(i);
-
- mln_site_(L) p = c + mln::right;
-
- while (is_invalid_link(objects, right_link, p, i, c, dmax))
- {
- if (right_link[i] != i)
- output(p) = literal::green;
- else
- output(p) = literal::red;
- ++p.col();
- }
-
- }
+ // Write debug image.
+ single_right_link_debug_functor<I, L> functor(input, objects, atof(argv[2]));
+ primitive::link::compute(functor);
- io::ppm::save(output, argv[3]);
+ io::ppm::save(functor.output_, argv[3]);
}
diff --git a/scribo/src/debug/show_link_single_right.cc b/scribo/src/debug/show_links_single_right_dmax_ratio.cc
similarity index 54%
copy from scribo/src/debug/show_link_single_right.cc
copy to scribo/src/debug/show_links_single_right_dmax_ratio.cc
index 5f1001a..81415bc 100644
--- a/scribo/src/debug/show_link_single_right.cc
+++ b/scribo/src/debug/show_links_single_right_dmax_ratio.cc
@@ -37,8 +37,12 @@
#include <mln/io/pbm/load.hh>
#include <mln/io/ppm/save.hh>
+#include <mln/draw/line.hh>
+
#include <scribo/primitive/extract/objects.hh>
-#include <scribo/primitive/link/with_single_right_link.hh>
+#include <scribo/primitive/link/with_single_right_link_dmax_ratio.hh>
+#include <scribo/primitive/link/internal/link_ms_dmax_ratio_base.hh>
+#include <scribo/primitive/link/compute.hh>
#include <scribo/draw/bounding_boxes.hh>
@@ -46,11 +50,79 @@
#include <scribo/debug/usage.hh>
+namespace scribo
+{
+
+ template <typename I, typename L>
+ struct single_right_link_debug_functor
+ : primitive::link::internal::link_ms_dmax_ratio_base<L,
+ single_right_link_debug_functor<I, L> >
+ {
+ typedef single_right_link_debug_functor<I, L> self_t;
+ typedef
+ primitive::link::internal::link_ms_dmax_ratio_base<L, self_t> super_;
+
+ public:
+ typedef mln_site(L) P;
+
+ single_right_link_debug_functor(const I& input,
+ const object_image(L)& objects,
+ float dmax_ratio)
+ : super_(objects, dmax_ratio)
+ {
+ output_ = data::convert(value::rgb8(), input);
+ scribo::draw::bounding_boxes(output_, objects, literal::blue);
+ mln_postcondition(output_.is_valid());
+ }
+
+ void validate_link_(unsigned current_object,
+ const P& start_point,
+ const P& p,
+ unsigned anchor)
+ {
+ mln::draw::line(output_, start_point, p, literal::green);
+
+ super_::validate_link_(current_object, start_point, p, anchor);
+ }
+
+
+
+ void invalidate_link_(unsigned current_object,
+ const P& start_point,
+ const P& p,
+ unsigned anchor)
+ {
+ if (output_.domain().has(p))
+ mln::draw::line(output_, start_point, p, literal::red);
+ else
+ {
+ P tmp = p;
+ --tmp.col();
+ mln::draw::line(output_, start_point, tmp, literal::red);
+ }
+
+ super_::invalidate_link_(current_object, start_point, p, anchor);
+ }
+
+
+
+ void compute_next_site_(P& p)
+ {
+ ++p.col();
+ }
+
+
+ image2d<value::rgb8> output_;
+ };
+
+
+}
+
const char *args_desc[][2] =
{
{ "input.pbm", "A binary image. True for objects and False for the background." },
- { "max_nbh_dist", " Maximum distance for neighborhood search. (common value : 30)" },
+ { "max_nbh_dist_ratio", "Size ratio defining the maximum lookup distance. (common value : 3)" },
{0, 0}
};
@@ -64,11 +136,12 @@ int main(int argc, char* argv[])
if (argc != 4)
return scribo::debug::usage(argv,
"Show sucessful/unsuccessful right links between components.",
- "input.pbm max_nbh_dist output.ppm",
+ "input.pbm max_nbh_dist_ratio output.ppm",
args_desc,
"A color image. Valid links are drawn in green, invalid ones in red.");
- image2d<bool> input;
+ typedef image2d<bool> I;
+ I input;
io::pbm::load(input, argv[1]);
// Finding objects.
@@ -77,41 +150,9 @@ int main(int argc, char* argv[])
object_image(L) objects
= scribo::primitive::extract::objects(input, c8(), nbboxes);
- // Finding right links.
- object_links<L> right_link
- = primitive::link::with_single_right_link(objects, atoi(argv[2]));
-
-
-
- // Preparing output image.
- image2d<value::rgb8> output = data::convert(value::rgb8(), input);
- scribo::draw::bounding_boxes(output, objects, literal::blue);
-
-
- // Drawing links.
- mln::util::array<mln_result_(accu::center<mln_psite_(L)>)>
- mass_centers = labeling::compute(accu::meta::center(),
- objects, objects.nlabels());
-
- for_all_ncomponents(i, objects.nlabels())
- {
- unsigned midcol = (objects.bbox(i).pmax().col()
- - objects.bbox(i).pmin().col()) / 2;
- int dmax = midcol + atoi(argv[2]);
- mln_site_(L) c = mass_centers(i);
-
- mln_site_(L) p = c + mln::right;
-
- while (is_invalid_link(objects, right_link, p, i, c, dmax))
- {
- if (right_link[i] != i)
- output(p) = literal::green;
- else
- output(p) = literal::red;
- ++p.col();
- }
-
- }
+ // Write debug image.
+ single_right_link_debug_functor<I, L> functor(input, objects, atof(argv[2]));
+ primitive::link::compute(functor);
- io::ppm::save(output, argv[3]);
+ io::ppm::save(functor.output_, argv[3]);
}
diff --git a/scribo/src/debug/show_link_single_right.cc b/scribo/src/debug/show_links_top_aligned.cc
similarity index 64%
rename from scribo/src/debug/show_link_single_right.cc
rename to scribo/src/debug/show_links_top_aligned.cc
index 5f1001a..97b4a3b 100644
--- a/scribo/src/debug/show_link_single_right.cc
+++ b/scribo/src/debug/show_links_top_aligned.cc
@@ -38,11 +38,10 @@
#include <mln/io/ppm/save.hh>
#include <scribo/primitive/extract/objects.hh>
-#include <scribo/primitive/link/with_single_right_link.hh>
+#include <scribo/primitive/link/with_single_right_link_top.hh>
+#include <scribo/filter/object_links_top_aligned.hh>
-#include <scribo/draw/bounding_boxes.hh>
-
-#include <scribo/debug/save_linked_bboxes_image.hh>
+#include <scribo/debug/alignment_decision_image.hh>
#include <scribo/debug/usage.hh>
@@ -50,7 +49,7 @@
const char *args_desc[][2] =
{
{ "input.pbm", "A binary image. True for objects and False for the background." },
- { "max_nbh_dist", " Maximum distance for neighborhood search. (common value : 30)" },
+ { "max_alpha", "Max angle between two object tops. (common value : 5)" },
{0, 0}
};
@@ -63,8 +62,8 @@ int main(int argc, char* argv[])
if (argc != 4)
return scribo::debug::usage(argv,
- "Show sucessful/unsuccessful right links between components.",
- "input.pbm max_nbh_dist output.ppm",
+ "Show valid or invalid links according the horizontal alignment (based on top line).",
+ "input.pbm max_alpha output.ppm",
args_desc,
"A color image. Valid links are drawn in green, invalid ones in red.");
@@ -77,41 +76,22 @@ int main(int argc, char* argv[])
object_image(L) objects
= scribo::primitive::extract::objects(input, c8(), nbboxes);
- // Finding right links.
- object_links<L> right_link
- = primitive::link::with_single_right_link(objects, atoi(argv[2]));
-
-
- // Preparing output image.
- image2d<value::rgb8> output = data::convert(value::rgb8(), input);
- scribo::draw::bounding_boxes(output, objects, literal::blue);
-
-
- // Drawing links.
- mln::util::array<mln_result_(accu::center<mln_psite_(L)>)>
- mass_centers = labeling::compute(accu::meta::center(),
- objects, objects.nlabels());
-
- for_all_ncomponents(i, objects.nlabels())
- {
- unsigned midcol = (objects.bbox(i).pmax().col()
- - objects.bbox(i).pmin().col()) / 2;
- int dmax = midcol + atoi(argv[2]);
- mln_site_(L) c = mass_centers(i);
+ // Finding right links.
+ object_links<L> right_links
+ = primitive::link::with_single_right_link_top(objects);
- mln_site_(L) p = c + mln::right;
+ // Filtering.
+ object_links<L> filtered_links
+ = filter::object_links_top_aligned(objects, right_links, atof(argv[2]));
- while (is_invalid_link(objects, right_link, p, i, c, dmax))
- {
- if (right_link[i] != i)
- output(p) = literal::green;
- else
- output(p) = literal::red;
- ++p.col();
- }
- }
+ // Debug image.
+ image2d<value::rgb8> decision_image
+ = scribo::debug::alignment_decision_image(input,
+ right_links,
+ filtered_links,
+ scribo::debug::top);
+ io::ppm::save(decision_image, argv[3]);
- io::ppm::save(output, argv[3]);
}
diff --git a/scribo/src/debug/show_link_single_left.cc b/scribo/src/debug/show_objects_large_small.cc
similarity index 58%
copy from scribo/src/debug/show_link_single_left.cc
copy to scribo/src/debug/show_objects_large_small.cc
index a8b42f2..e72e5e1 100644
--- a/scribo/src/debug/show_link_single_left.cc
+++ b/scribo/src/debug/show_objects_large_small.cc
@@ -30,88 +30,71 @@
#include <mln/data/convert.hh>
-#include <mln/value/rgb8.hh>
#include <mln/value/label_16.hh>
+#include <mln/value/rgb8.hh>
#include <mln/literal/colors.hh>
#include <mln/io/pbm/load.hh>
#include <mln/io/ppm/save.hh>
#include <scribo/primitive/extract/objects.hh>
-#include <scribo/primitive/link/with_single_left_link.hh>
-
+#include <scribo/filter/objects_large.hh>
+#include <scribo/filter/objects_small.hh>
#include <scribo/draw/bounding_boxes.hh>
-
-#include <scribo/debug/save_linked_bboxes_image.hh>
#include <scribo/debug/usage.hh>
-
+#include <scribo/debug/save_object_diff.hh>
const char *args_desc[][2] =
{
{ "input.pbm", "A binary image. True for objects and False for the background." },
- { "max_nbh_dist", " Maximum distance for neighborhood search. (common value : 30)" },
+ { "min_card", " Minimum cardinality in a component." },
+ { "max_card", " Maximum cardinality in a component." },
{0, 0}
};
-int main(int argc, char* argv[])
+int main(int argc, char *argv[])
{
- using namespace scribo;
- using namespace scribo::primitive::internal;
using namespace mln;
- if (argc != 4)
+ if (argc != 5)
return scribo::debug::usage(argv,
- "Show sucessful/unsuccessful left links between components.",
- "input.pbm max_nbh_dist output.ppm",
+ "Show components not being too small nor too large.",
+ "input.pbm min_card max_card output.ppm",
args_desc,
- "A color image. Valid links are drawn in green, invalid ones in red.");
+ "A color image. Too small components are drawn in red, too large components in orange and others in green.");
+
+ trace::entering("main");
image2d<bool> input;
io::pbm::load(input, argv[1]);
- // Finding objects.
value::label_16 nbboxes;
typedef image2d<value::label_16> L;
object_image(L) objects
= scribo::primitive::extract::objects(input, c8(), nbboxes);
- // Finding left links.
- object_links<L> left_link
- = primitive::link::with_single_left_link(objects, atoi(argv[2]));
-
+ object_image(L) filter(objects);
+ if (atoi(argv[2]) != 0)
+ filter = scribo::filter::objects_small(filter, atoi(argv[2]));
- // Preparing output image.
- image2d<value::rgb8> output = data::convert(value::rgb8(), input);
- scribo::draw::bounding_boxes(output, objects, literal::blue);
+ if (atoi(argv[3]) != 0)
+ filter = scribo::filter::objects_large(filter, atoi(argv[3]));
+ image2d<value::rgb8> output;
+ initialize(output, objects);
- // Drawing links.
- mln::util::array<mln_result_(accu::center<mln_psite_(L)>)>
- mass_centers = labeling::compute(accu::meta::center(),
- objects, objects.nlabels());
+ data::fill(output, literal::black);
- for_all_ncomponents(i, objects.nlabels())
- {
- unsigned midcol = (objects.bbox(i).pmax().col()
- - objects.bbox(i).pmin().col()) / 2;
- int dmax = midcol + atoi(argv[2]);
- mln_site_(L) c = mass_centers(i);
+ for_all_components(i, objects.bboxes())
+ data::fill(((output | objects.bbox(i)).rw() | (pw::value(objects) == i)).rw(), literal::red);
- mln_site_(L) p = c + mln::left;
+ for_all_components(i, filter.bboxes())
+ data::fill(((output | filter.bbox(i)).rw() | (pw::value(filter) == i)).rw(), literal::green);
- while (is_invalid_link(objects, left_link, p, i, c, dmax))
- {
- if (left_link[i] != i)
- output(p) = literal::green;
- else
- output(p) = literal::red;
- --p.col();
- }
- }
- io::ppm::save(output, argv[3]);
+ io::ppm::save(output, argv[4]);
}
diff --git a/scribo/src/debug/show_link_single_left.cc b/scribo/src/debug/show_objects_thick.cc
similarity index 59%
rename from scribo/src/debug/show_link_single_left.cc
rename to scribo/src/debug/show_objects_thick.cc
index a8b42f2..4157ac3 100644
--- a/scribo/src/debug/show_link_single_left.cc
+++ b/scribo/src/debug/show_objects_thick.cc
@@ -30,88 +30,55 @@
#include <mln/data/convert.hh>
-#include <mln/value/rgb8.hh>
#include <mln/value/label_16.hh>
+#include <mln/value/rgb8.hh>
#include <mln/literal/colors.hh>
#include <mln/io/pbm/load.hh>
#include <mln/io/ppm/save.hh>
#include <scribo/primitive/extract/objects.hh>
-#include <scribo/primitive/link/with_single_left_link.hh>
-
+#include <scribo/filter/objects_thin.hh>
#include <scribo/draw/bounding_boxes.hh>
-
-#include <scribo/debug/save_linked_bboxes_image.hh>
#include <scribo/debug/usage.hh>
-
const char *args_desc[][2] =
{
- { "input.pbm", "A binary image. True for objects and False for the background." },
- { "max_nbh_dist", " Maximum distance for neighborhood search. (common value : 30)" },
+ { "input.pbm", " A binary image. True for objects and False for the background." },
+ { "max_thickness", "Maximum bounding box thickness. (common value: 300)" },
{0, 0}
};
-int main(int argc, char* argv[])
+int main(int argc, char *argv[])
{
- using namespace scribo;
- using namespace scribo::primitive::internal;
using namespace mln;
if (argc != 4)
return scribo::debug::usage(argv,
- "Show sucessful/unsuccessful left links between components.",
- "input.pbm max_nbh_dist output.ppm",
+ "Show components being to thick.",
+ "input.pbm max_thickness output.ppm",
args_desc,
- "A color image. Valid links are drawn in green, invalid ones in red.");
+ "A color image. Too thick components have their bounding boxes drawn in red.");
+
+ trace::entering("main");
image2d<bool> input;
io::pbm::load(input, argv[1]);
- // Finding objects.
value::label_16 nbboxes;
typedef image2d<value::label_16> L;
object_image(L) objects
= scribo::primitive::extract::objects(input, c8(), nbboxes);
- // Finding left links.
- object_links<L> left_link
- = primitive::link::with_single_left_link(objects, atoi(argv[2]));
-
-
- // Preparing output image.
image2d<value::rgb8> output = data::convert(value::rgb8(), input);
- scribo::draw::bounding_boxes(output, objects, literal::blue);
-
-
- // Drawing links.
- mln::util::array<mln_result_(accu::center<mln_psite_(L)>)>
- mass_centers = labeling::compute(accu::meta::center(),
- objects, objects.nlabels());
-
- for_all_ncomponents(i, objects.nlabels())
- {
- unsigned midcol = (objects.bbox(i).pmax().col()
- - objects.bbox(i).pmin().col()) / 2;
- int dmax = midcol + atoi(argv[2]);
- mln_site_(L) c = mass_centers(i);
-
- mln_site_(L) p = c + mln::left;
-
- while (is_invalid_link(objects, left_link, p, i, c, dmax))
- {
- if (left_link[i] != i)
- output(p) = literal::green;
- else
- output(p) = literal::red;
- --p.col();
- }
+ scribo::draw::bounding_boxes(output, objects, literal::red);
- }
+ object_image(L) filtered_objects
+ = scribo::filter::objects_thin(objects, atoi(argv[2]));
+ scribo::draw::bounding_boxes(output, filtered_objects, literal::green);
io::ppm::save(output, argv[3]);
}
diff --git a/scribo/src/debug/show_objects_thin.cc b/scribo/src/debug/show_objects_thin.cc
index e69de29..4223fef 100644
--- a/scribo/src/debug/show_objects_thin.cc
+++ b/scribo/src/debug/show_objects_thin.cc
@@ -0,0 +1,84 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#include <iostream>
+
+#include <mln/core/image/image2d.hh>
+#include <mln/core/alias/neighb2d.hh>
+
+#include <mln/data/convert.hh>
+
+#include <mln/value/label_16.hh>
+#include <mln/value/rgb8.hh>
+#include <mln/literal/colors.hh>
+
+#include <mln/io/pbm/load.hh>
+#include <mln/io/ppm/save.hh>
+
+#include <scribo/primitive/extract/objects.hh>
+#include <scribo/filter/objects_thin.hh>
+#include <scribo/draw/bounding_boxes.hh>
+#include <scribo/debug/usage.hh>
+
+
+const char *args_desc[][2] =
+{
+ { "input.pbm", " A binary image. True for objects and False for the background." },
+ { "min_thickness", "Minimum bounding box thickness. (common value: 1)" },
+ {0, 0}
+};
+
+
+int main(int argc, char *argv[])
+{
+ using namespace mln;
+
+ if (argc != 4)
+ return scribo::debug::usage(argv,
+ "Show components being to thin.",
+ "input.pbm min_thickness output.ppm",
+ args_desc,
+ "A color image. Too thin components have their bounding boxes drawn in red.");
+
+ trace::entering("main");
+
+ image2d<bool> input;
+ io::pbm::load(input, argv[1]);
+
+ value::label_16 nbboxes;
+ typedef image2d<value::label_16> L;
+ object_image(L) objects
+ = scribo::primitive::extract::objects(input, c8(), nbboxes);
+
+
+ image2d<value::rgb8> output = data::convert(value::rgb8(), input);
+ scribo::draw::bounding_boxes(output, objects, literal::red);
+
+ object_image(L) filtered_objects
+ = scribo::filter::objects_thin(objects, atoi(argv[2]));
+ scribo::draw::bounding_boxes(output, filtered_objects, literal::green);
+
+ io::ppm::save(output, argv[3]);
+}
--
1.5.6.5
1
0
* filter/internal/compute.hh: New routine to compute filter
results.
* filter/object_links_center_aligned.hh,
* filter/object_links_top_aligned.hh,
* filter/objects_h_thick.hh,
* filter/objects_v_thick.hh: New filters.
---
scribo/ChangeLog | 12 ++
scribo/filter/internal/compute.hh | 147 +++++++++++++++++++
scribo/filter/object_links_center_aligned.hh | 113 +++++++++++++++
scribo/filter/object_links_top_aligned.hh | 121 ++++++++++++++++
scribo/filter/objects_h_thick.hh | 196 ++++++++++++++++++++++++++
scribo/filter/objects_v_thick.hh | 196 ++++++++++++++++++++++++++
6 files changed, 785 insertions(+), 0 deletions(-)
create mode 100644 scribo/filter/internal/compute.hh
create mode 100644 scribo/filter/object_links_center_aligned.hh
create mode 100644 scribo/filter/object_links_top_aligned.hh
create mode 100644 scribo/filter/objects_h_thick.hh
create mode 100644 scribo/filter/objects_v_thick.hh
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index bb22ef9..2a3c71e 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,5 +1,17 @@
2009-11-03 Guillaume Lazzara <z(a)lrde.epita.fr>
+ Add new link filters.
+
+ * filter/internal/compute.hh: New routine to compute filter
+ results.
+
+ * filter/object_links_center_aligned.hh,
+ * filter/object_links_top_aligned.hh,
+ * filter/objects_h_thick.hh,
+ * filter/objects_v_thick.hh: New filters.
+
+2009-11-03 Guillaume Lazzara <z(a)lrde.epita.fr>
+
Revamp code related to object linking.
* core/concept/link_functor.hh: New concept.
diff --git a/scribo/filter/internal/compute.hh b/scribo/filter/internal/compute.hh
new file mode 100644
index 0000000..346cee8
--- /dev/null
+++ b/scribo/filter/internal/compute.hh
@@ -0,0 +1,147 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_FILTER_INTERNAL_COMPUTE_HH
+# define SCRIBO_FILTER_INTERNAL_COMPUTE_HH
+
+/// \file
+///
+/// Compute filters.
+
+# include <mln/core/concept/image.hh>
+# include <mln/core/concept/neighborhood.hh>
+
+# include <mln/util/array.hh>
+
+# include <scribo/core/object_image.hh>
+# include <scribo/primitive/extract/objects.hh>
+
+
+
+namespace scribo
+{
+
+ namespace filter
+ {
+
+ namespace internal
+ {
+
+
+ using namespace mln;
+
+ /// Apply a filter to an image.
+ ///
+ /// \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] filter A filter.
+ ///
+ /// \result A filtered binary image.
+ //
+ template <typename I, typename N, typename V, typename F>
+ mln_concrete(I)
+ compute(const Image<I>& input_,
+ const Neighborhood<N>& nbh_,
+ const V& label_type,
+ const Function_v2b<F>& filter);
+
+
+ /// Filter an object image.
+ ///
+ /// \param[in] objects An object image.
+ /// \param[in] filter A filter functor.
+ ///
+ /// \result A filtered object image.
+ //
+ template <typename L, typename F>
+ object_image(L)
+ compute(const object_image(L)& objects,
+ const Function_v2b<F>& filter);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ template <typename I, typename N, typename V, typename F>
+ inline
+ mln_concrete(I)
+ compute(const Image<I>& input_,
+ const Neighborhood<N>& nbh_,
+ const V& label_type,
+ const Function_v2b<F>& filter)
+ {
+ trace::entering("scribo::filter::internal::compute");
+
+ const I& input = exact(input_);
+ const N& nbh = exact(nbh_);
+
+ mln_precondition(input.is_valid());
+ mln_precondition(nbh.is_valid());
+
+ V nlabels;
+ typedef mln_ch_value(I,V) lbl_t;
+ object_image(lbl_t) objects
+ = primitive::extract::objects(input, nbh, nlabels);
+
+ filter.update_objects(objects);
+ objects.relabel(filter);
+
+ mln_concrete(I) output = duplicate(input);
+ data::fill((output | pw::value(objects) == literal::zero).rw(), false);
+
+ trace::exiting("scribo::filter::internal::compute");
+ return output;
+ }
+
+
+ template <typename L, typename F>
+ inline
+ object_image(L)
+ compute(const object_image(L)& objects,
+ const Function_v2b<F>& filter)
+ {
+ trace::entering("scribo::filter::internal::compute");
+
+ mln_precondition(objects.is_valid());
+
+ object_image(L) output;
+ output.init_from_(objects);
+ output.relabel(filter);
+
+ trace::exiting("scribo::filter::internal::compute");
+ return output;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace scribo::filter::internal
+
+ } // end of namespace scribo::filter
+
+} // end of namespace scribo
+
+
+#endif // ! SCRIBO_FILTER_INTERNAL_COMPUTE_HH
diff --git a/scribo/filter/object_links_center_aligned.hh b/scribo/filter/object_links_center_aligned.hh
new file mode 100644
index 0000000..e44f3cd
--- /dev/null
+++ b/scribo/filter/object_links_center_aligned.hh
@@ -0,0 +1,113 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_FILTER_OBJECT_LINKS_CENTER_ALIGNED_HH
+# define SCRIBO_FILTER_OBJECT_LINKS_CENTER_ALIGNED_HH
+
+/// \file
+///
+/// Invalidate links between two objects if their center are not
+/// aligned.
+
+
+# include <mln/util/array.hh>
+
+# include <scribo/core/macros.hh>
+# include <scribo/core/object_links.hh>
+# include <scribo/core/object_image.hh>
+
+# include <scribo/filter/object_links_non_aligned_simple.hh>
+
+namespace scribo
+{
+
+ namespace filter
+ {
+
+ using namespace mln;
+
+ /*! \brief Invalidate links between two objects if their center are not
+ aligned.
+
+ \param[in] objects An object image.
+ \param[in] links Object links information.
+ \param[in] max_alpha Maximum angle value (degrees).
+
+ \verbatim
+
+ ------ ------
+ | | | | v
+ | x ~| ~ ~ ~ | ~ ~|~ ~
+ | ~| ~ | | | => Alpha
+ | | ~ ~ | x ~|~ ~
+ ------ | | ^
+ object1 | |
+ ------
+ object2
+
+ \endverbatim
+
+ The angle between the two bottoms must be lower than \p max_alpha.
+
+ */
+ template <typename L>
+ object_links<L>
+ object_links_center_aligned(const object_image(L)& objects,
+ const object_links<L>& links,
+ float max_alpha);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ template <typename L>
+ object_links<L>
+ object_links_center_aligned(const object_image(L)& objects,
+ const object_links<L>& links,
+ float max_alpha)
+ {
+ trace::entering("scribo::filter::object_links_center_aligned");
+
+ mln_precondition(objects.is_valid());
+ mln_precondition(links.is_valid());
+
+ object_links<L>
+ output = object_links_non_aligned_simple(objects, links,
+ 2, max_alpha);
+
+ trace::exiting("scribo::filter::object_links_center_aligned");
+ return output;
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+
+ } // end of namespace scribo::filter
+
+} // end of namespace scribo
+
+
+#endif // ! SCRIBO_FILTER_OBJECT_LINKS_CENTER_ALIGNED_HH
diff --git a/scribo/filter/object_links_top_aligned.hh b/scribo/filter/object_links_top_aligned.hh
new file mode 100644
index 0000000..47e26c8
--- /dev/null
+++ b/scribo/filter/object_links_top_aligned.hh
@@ -0,0 +1,121 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_FILTER_OBJECT_LINKS_TOP_ALIGNED_HH
+# define SCRIBO_FILTER_OBJECT_LINKS_TOP_ALIGNED_HH
+
+/// \file
+///
+/// Invalidate links between two objects if their top are not
+/// aligned.
+
+
+# include <mln/util/array.hh>
+
+# include <scribo/core/macros.hh>
+# include <scribo/core/object_links.hh>
+# include <scribo/core/object_image.hh>
+
+# include <scribo/filter/object_links_non_aligned_simple.hh>
+
+namespace scribo
+{
+
+ namespace filter
+ {
+
+ using namespace mln;
+
+ /*! \brief Invalidate links between two objects if their top are not
+ aligned.
+
+ \param[in] objects An object image.
+ \param[in] links Object links information.
+ \param[in] max_alpha Maximum angle value (degrees).
+
+ \verbatim
+
+
+ ~
+ ~ ^
+ ~ |
+ ~ |
+ ~------ | Alpha
+ ~ | | |
+ ~ | | |
+ ~ | | v
+ ------ ~ ~ ~ | ~ ~| ~
+ | | | |
+ | x------------x |
+ | | | |
+ ------ | |
+ object1 | |
+ ------
+ object2
+
+ \endverbatim
+
+ The angle between the two tops must be lower than \p max_alpha.
+ */
+ template <typename L>
+ object_links<L>
+ object_links_top_aligned(const object_image(L)& objects,
+ const object_links<L>& links,
+ float max_alpha);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ template <typename L>
+ object_links<L>
+ object_links_top_aligned(const object_image(L)& objects,
+ const object_links<L>& links,
+ float max_alpha)
+ {
+ trace::entering("scribo::filter::object_links_top_aligned");
+
+ mln_precondition(objects.is_valid());
+ mln_precondition(links.is_valid());
+
+ object_links<L>
+ output = object_links_non_aligned_simple(objects, links,
+ 0,
+ max_alpha);
+
+ trace::exiting("scribo::filter::object_links_top_aligned");
+ return output;
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+
+ } // end of namespace scribo::filter
+
+} // end of namespace scribo
+
+
+#endif // ! SCRIBO_FILTER_OBJECT_LINKS_TOP_ALIGNED_HH
diff --git a/scribo/filter/objects_h_thick.hh b/scribo/filter/objects_h_thick.hh
new file mode 100644
index 0000000..9709346
--- /dev/null
+++ b/scribo/filter/objects_h_thick.hh
@@ -0,0 +1,196 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_FILTER_OBJECTS_H_THICK_HH
+# define SCRIBO_FILTER_OBJECTS_H_THICK_HH
+
+/// \file
+///
+/// Remove too horizontaly thick objects.
+
+# include <mln/core/concept/image.hh>
+# include <mln/core/concept/neighborhood.hh>
+
+# include <mln/util/array.hh>
+
+# include <scribo/core/object_image.hh>
+# include <scribo/primitive/extract/objects.hh>
+# include <scribo/filter/internal/compute.hh>
+
+
+namespace scribo
+{
+
+ namespace filter
+ {
+
+ using namespace mln;
+
+ /// 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] max_thickness The maximum thickness value.
+ ///
+ /// \result A binary image without thick objects.
+ //
+ template <typename I, typename N, typename V>
+ inline
+ mln_concrete(I)
+ objects_h_thick(const Image<I>& input_,
+ const Neighborhood<N>& nbh_,
+ const V& label_type,
+ unsigned max_thickness);
+
+
+ /// Remove objects horizontaly thicker or equal to \p max_thickness.
+ ///
+ /// \param[in] objects An object image.
+ /// \param[in] max_thickness The maximum thickness value.
+ ///
+ /// \result An object image without too thick objects.
+ //
+ template <typename L>
+ inline
+ object_image(L)
+ objects_h_thick(const object_image(L)& objects,
+ unsigned max_thickness);
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ namespace internal
+ {
+
+ /// Filter Functor. Return false for all objects which are too
+ /// large.
+ template <typename L>
+ struct h_thick_object_filter
+ : Function_v2b< h_thick_object_filter<L> >
+ {
+
+ /// Constructor
+ ///
+ /// \param[in] objects An object image.
+ /// \param[in] max_thickness the maximum thickness allowed.
+ //
+ h_thick_object_filter(const object_image(L)& objects,
+ unsigned max_thickness)
+ : objects_(objects), max_thickness_(max_thickness)
+ {
+ }
+
+ /// Constructor
+ ///
+ /// \param[in] max_thickness the maximum thickness allowed.
+ //
+ h_thick_object_filter(unsigned max_thickness)
+ : max_thickness_(max_thickness)
+ {
+ }
+
+ /// Set the underlying object image.
+ //
+ void update_objects(const object_image(L)& objects)
+ {
+ objects_ = objects;
+ }
+
+ /// Return false if the objects is thicker than
+ /// \p max_thickness_.
+ ///
+ /// \param[in] l An image value.
+ bool operator()(const mln_value(L)& l) const
+ {
+ if (l == literal::zero)
+ return true;
+ return objects_.bbox(l).nrows() < max_thickness_;
+ }
+
+
+ /// An object image.
+ object_image(L) objects_;
+
+ /// The maximum thickness.
+ unsigned max_thickness_;
+ };
+
+
+ } // end of namespace scribo::filter::internal
+
+
+ template <typename I, typename N, typename V>
+ inline
+ mln_concrete(I)
+ objects_thick(const Image<I>& input_,
+ const Neighborhood<N>& nbh_,
+ const V& label_type,
+ unsigned max_thickness)
+ {
+ trace::entering("scribo::filter::objects_h_thick");
+
+ const I& input = exact(input_);
+ const N& nbh = exact(nbh_);
+
+ mln_precondition(input.is_valid());
+ mln_precondition(nbh.is_valid());
+
+ internal::h_thick_object_filter<V> functor(max_thickness);
+ mln_concrete(I)
+ output = internal::compute(input, nbh, label_type, functor);
+
+ trace::exiting("scribo::filter::objects_h_thick");
+ return output;
+ }
+
+
+ template <typename L>
+ inline
+ object_image(L)
+ objects_h_thick(const object_image(L)& objects,
+ unsigned max_thickness)
+ {
+ trace::entering("scribo::filter::objects_h_thick");
+
+ mln_precondition(objects.is_valid());
+
+ internal::h_thick_object_filter<L> functor(objects, max_thickness);
+ object_image(L) output = internal::compute(objects, functor);
+
+ trace::exiting("scribo::filter::objects_h_thick");
+ return output;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace scribo::filter
+
+} // end of namespace scribo
+
+
+#endif // ! SCRIBO_FILTER_OBJECTS_H_THICK_HH
diff --git a/scribo/filter/objects_v_thick.hh b/scribo/filter/objects_v_thick.hh
new file mode 100644
index 0000000..730e144
--- /dev/null
+++ b/scribo/filter/objects_v_thick.hh
@@ -0,0 +1,196 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_FILTER_OBJECTS_V_THICK_HH
+# define SCRIBO_FILTER_OBJECTS_V_THICK_HH
+
+/// \file
+///
+/// Remove too verticaly thick objects.
+
+# include <mln/core/concept/image.hh>
+# include <mln/core/concept/neighborhood.hh>
+
+# include <mln/util/array.hh>
+
+# include <scribo/core/object_image.hh>
+# include <scribo/primitive/extract/objects.hh>
+# include <scribo/filter/internal/compute.hh>
+
+
+namespace scribo
+{
+
+ namespace filter
+ {
+
+ using namespace mln;
+
+ /// Remove objects 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] max_thickness The maximum thickness value.
+ ///
+ /// \result A binary image without thick objects.
+ //
+ template <typename I, typename N, typename V>
+ inline
+ mln_concrete(I)
+ objects_v_thick(const Image<I>& input_,
+ const Neighborhood<N>& nbh_,
+ const V& label_type,
+ unsigned max_thickness);
+
+
+ /// Remove objects verticaly thicker or equal to \p max_thickness.
+ ///
+ /// \param[in] objects An object image.
+ /// \param[in] max_thickness The maximum thickness value.
+ ///
+ /// \result An object image without too thick objects.
+ //
+ template <typename L>
+ inline
+ object_image(L)
+ objects_v_thick(const object_image(L)& objects,
+ unsigned max_thickness);
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ namespace internal
+ {
+
+ /// Filter Functor. Return false for all objects which are too
+ /// large.
+ template <typename L>
+ struct v_thick_object_filter
+ : Function_v2b< v_thick_object_filter<L> >
+ {
+
+ /// Constructor
+ ///
+ /// \param[in] objects An object image.
+ /// \param[in] max_thickness the maximum thickness allowed.
+ //
+ v_thick_object_filter(const object_image(L)& objects,
+ unsigned max_thickness)
+ : objects_(objects), max_thickness_(max_thickness)
+ {
+ }
+
+ /// Constructor
+ ///
+ /// \param[in] max_thickness the maximum thickness allowed.
+ //
+ v_thick_object_filter(unsigned max_thickness)
+ : max_thickness_(max_thickness)
+ {
+ }
+
+ /// Set the underlying object image.
+ //
+ void update_objects(const object_image(L)& objects)
+ {
+ objects_ = objects;
+ }
+
+ /// Return false if the objects is thicker than
+ /// \p max_thickness_.
+ ///
+ /// \param[in] l An image value.
+ bool operator()(const mln_value(L)& l) const
+ {
+ if (l == literal::zero)
+ return true;
+ return objects_.bbox(l).nrows() < max_thickness_;
+ }
+
+
+ /// An object image.
+ object_image(L) objects_;
+
+ /// The maximum thickness.
+ unsigned max_thickness_;
+ };
+
+
+ } // end of namespace scribo::filter::internal
+
+
+ template <typename I, typename N, typename V>
+ inline
+ mln_concrete(I)
+ objects_thick(const Image<I>& input_,
+ const Neighborhood<N>& nbh_,
+ const V& label_type,
+ unsigned max_thickness)
+ {
+ trace::entering("scribo::filter::objects_v_thick");
+
+ const I& input = exact(input_);
+ const N& nbh = exact(nbh_);
+
+ mln_precondition(input.is_valid());
+ mln_precondition(nbh.is_valid());
+
+ internal::v_thick_object_filter<V> functor(max_thickness);
+ mln_concrete(I)
+ output = internal::compute(input, nbh, label_type, functor);
+
+ trace::exiting("scribo::filter::objects_v_thick");
+ return output;
+ }
+
+
+ template <typename L>
+ inline
+ object_image(L)
+ objects_v_thick(const object_image(L)& objects,
+ unsigned max_thickness)
+ {
+ trace::entering("scribo::filter::objects_v_thick");
+
+ mln_precondition(objects.is_valid());
+
+ internal::v_thick_object_filter<L> functor(objects, max_thickness);
+ object_image(L) output = internal::compute(objects, functor);
+
+ trace::exiting("scribo::filter::objects_v_thick");
+ return output;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace scribo::filter
+
+} // end of namespace scribo
+
+
+#endif // ! SCRIBO_FILTER_OBJECTS_V_THICK_HH
--
1.5.6.5
1
0
* core/concept/link_functor.hh: New concept.
* core/internal/link_functor_base.hh: New Base class for link
functor.
* primitive/link/compute.hh,
* primitive/link/compute_several.hh,
* primitive/link/internal/anchors_3.hh,
* primitive/link/internal/find_link.hh,
* primitive/link/internal/find_several_links.hh,
* primitive/link/with_several_right_closest_links.hh,
* primitive/link/with_several_right_links_overlap.hh,
* primitive/link/with_single_left_link_dmax_ratio.hh,
* primitive/link/with_single_right_link_bottom.hh,
* primitive/link/with_single_right_link_dmax_ratio.hh,
* primitive/link/with_single_right_link_top.hh: New routines.
* primitive/link/internal/link_center_dmax_base.hh,
* primitive/link/internal/link_center_dmax_ratio_base.hh,
* primitive/link/internal/link_functor_base.hh,
* primitive/link/internal/link_ms_dmax_base.hh,
* primitive/link/internal/link_ms_dmax_ratio_base.hh: New functors.
* primitive/link/with_several_left_links.hh,
* primitive/link/with_several_right_links.hh: Use the new routines.
* primitive/link/with_single_left_link.hh,
* primitive/link/with_single_right_link.hh: Revamp and use the new
routines.
---
scribo/ChangeLog | 86 ++++
scribo/core/concept/link_functor.hh | 53 ++
scribo/core/internal/link_functor_base.hh | 119 +++++
scribo/primitive/link/compute.hh | 115 +++++
scribo/primitive/link/compute_several.hh | 117 +++++
scribo/primitive/link/internal/anchors_3.hh | 146 ++++++
scribo/primitive/link/internal/find_link.hh | 116 +++++
.../primitive/link/internal/find_several_links.hh | 124 +++++
.../link/internal/link_center_dmax_base.hh | 179 +++++++
.../link/internal/link_center_dmax_ratio_base.hh | 175 +++++++
.../primitive/link/internal/link_functor_base.hh | 518 ++++++++++++++++++++
.../primitive/link/internal/link_ms_dmax_base.hh | 165 +++++++
.../link/internal/link_ms_dmax_ratio_base.hh | 168 +++++++
scribo/primitive/link/with_several_left_links.hh | 32 +-
.../link/with_several_right_closest_links.hh | 215 ++++++++
scribo/primitive/link/with_several_right_links.hh | 27 +-
...inks.hh => with_several_right_links_overlap.hh} | 134 +++---
scribo/primitive/link/with_single_left_link.hh | 94 +++-
.../link/with_single_left_link_dmax_ratio.hh | 167 +++++++
scribo/primitive/link/with_single_right_link.hh | 98 +++--
...ht_link.hh => with_single_right_link_bottom.hh} | 115 +++--
.../link/with_single_right_link_dmax_ratio.hh | 167 +++++++
...right_link.hh => with_single_right_link_top.hh} | 113 +++--
23 files changed, 3030 insertions(+), 213 deletions(-)
create mode 100644 scribo/core/concept/link_functor.hh
create mode 100644 scribo/core/internal/link_functor_base.hh
create mode 100644 scribo/primitive/link/compute.hh
create mode 100644 scribo/primitive/link/compute_several.hh
create mode 100644 scribo/primitive/link/internal/anchors_3.hh
create mode 100644 scribo/primitive/link/internal/find_link.hh
create mode 100644 scribo/primitive/link/internal/find_several_links.hh
create mode 100644 scribo/primitive/link/internal/link_center_dmax_base.hh
create mode 100644 scribo/primitive/link/internal/link_center_dmax_ratio_base.hh
create mode 100644 scribo/primitive/link/internal/link_functor_base.hh
create mode 100644 scribo/primitive/link/internal/link_ms_dmax_base.hh
create mode 100644 scribo/primitive/link/internal/link_ms_dmax_ratio_base.hh
create mode 100644 scribo/primitive/link/with_several_right_closest_links.hh
copy scribo/primitive/link/{with_several_right_links.hh => with_several_right_links_overlap.hh} (53%)
create mode 100644 scribo/primitive/link/with_single_left_link_dmax_ratio.hh
copy scribo/primitive/link/{with_single_right_link.hh => with_single_right_link_bottom.hh} (55%)
create mode 100644 scribo/primitive/link/with_single_right_link_dmax_ratio.hh
copy scribo/primitive/link/{with_single_right_link.hh => with_single_right_link_top.hh} (57%)
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index 5e2d69e..bb22ef9 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,3 +1,89 @@
+2009-11-03 Guillaume Lazzara <z(a)lrde.epita.fr>
+
+ Revamp code related to object linking.
+
+ * core/concept/link_functor.hh: New concept.
+
+ * core/internal/link_functor_base.hh: New Base class for link
+ functor.
+
+ * primitive/link/compute.hh,
+ * primitive/link/compute_several.hh,
+ * primitive/link/internal/anchors_3.hh,
+ * primitive/link/internal/find_link.hh,
+ * primitive/link/internal/find_several_links.hh,
+ * primitive/link/with_several_right_closest_links.hh,
+ * primitive/link/with_several_right_links_overlap.hh,
+ * primitive/link/with_single_left_link_dmax_ratio.hh,
+ * primitive/link/with_single_right_link_bottom.hh,
+ * primitive/link/with_single_right_link_dmax_ratio.hh,
+ * primitive/link/with_single_right_link_top.hh: New routines.
+
+ * primitive/link/internal/link_center_dmax_base.hh,
+ * primitive/link/internal/link_center_dmax_ratio_base.hh,
+ * primitive/link/internal/link_functor_base.hh,
+ * primitive/link/internal/link_ms_dmax_base.hh,
+ * primitive/link/internal/link_ms_dmax_ratio_base.hh: New functors.
+
+ * primitive/link/with_several_left_links.hh,
+ * primitive/link/with_several_right_links.hh: Use the new routines.
+
+ * primitive/link/with_single_left_link.hh,
+ * primitive/link/with_single_right_link.hh: Revamp and use the new
+ routines.
+
+2009-11-03 Guillaume Lazzara <z(a)lrde.epita.fr>
+
+ Small fixes in Scribo.
+
+ * debug/decision_image.hh: Fix precondition.
+
+ * filter/object_links_bbox_h_ratio.hh,
+ * filter/objects_thick.hh,
+ * primitive/internal/have_link_valid.hh,
+ * primitive/internal/is_link_valid.hh: Fix doc.
+
+ * filter/object_links_bbox_ratio.hh: Fix doc and invert ratio.
+
+ * filter/object_links_bottom_aligned.hh: Fix doc and use a float
+ angle value.
+
+ * filter/object_links_non_aligned.hh: Use absolute values.
+
+ * filter/object_links_non_aligned_simple.hh: Add special cases.
+
+ * filter/object_links_non_h_aligned.hh: Fix call to an underlying
+ routine.
+
+ * filter/objects_small.hh,
+ * filter/objects_thin.hh,
+ * filter/objects_v_thin.hh,
+ * primitive/extract/lines_discontinued.hh,
+ * primitive/extract/lines_h_single.hh,
+ * primitive/extract/lines_h_thick_and_single.hh,
+ * primitive/extract/lines_thick.hh,
+ * primitive/extract/lines_v_discontinued.hh,
+ * primitive/extract/lines_v_single.hh,
+ * primitive/extract/lines_v_thick_and_single.hh,
+ * primitive/internal/is_invalid_link.hh,
+ * src/multi_scale/find_lines.cc,
+ * src/primitive/group/group_from_rag.cc,
+ * src/table/rebuild_opening.cc,
+ * src/table/rebuild_rank.cc,
+ * text/clean.hh: Avoid warnings.
+
+ * primitive/internal/find_left_link.hh,
+ * primitive/internal/find_right_link.hh,
+ * primitive/internal/update_link_array.hh: Make the routine return
+ a value.
+
+ * src/binarization/sauvola.cc,
+ * src/binarization/sauvola_pgm.cc: Fix call to Sauvola's algorithm.
+
+ * src/primitive/group/group_from_graph.cc,
+ * src/primitive/group/group_from_several_graph.cc: Change
+ arguments values while calling with_several_graphes.
+
2009-10-22 Guillaume Lazzara <z(a)lrde.epita.fr>
Add new debug routines.
diff --git a/scribo/core/concept/link_functor.hh b/scribo/core/concept/link_functor.hh
new file mode 100644
index 0000000..f51843a
--- /dev/null
+++ b/scribo/core/concept/link_functor.hh
@@ -0,0 +1,53 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_CORE_INTERNAL_LINK_FUNCTOR_HH
+# define SCRIBO_CORE_INTERNAL_LINK_FUNCTOR_HH
+
+/// \file
+///
+/// Link functor concept.
+
+# include <mln/core/concept/object.hh>
+
+# define scribo_support(T) typename T::support
+# define scribo_support_(T) T::support
+
+namespace scribo
+{
+
+ /// \brief Link functor concept.
+ template <typename E>
+ class Link_Functor : public mln::Object<E>
+ {
+
+ // typedef L support
+
+ };
+
+
+} // end of namespace scribo
+
+#endif // SCRIBO_CORE_INTERNAL_LINK_FUNCTOR_HH
diff --git a/scribo/core/internal/link_functor_base.hh b/scribo/core/internal/link_functor_base.hh
new file mode 100644
index 0000000..addba06
--- /dev/null
+++ b/scribo/core/internal/link_functor_base.hh
@@ -0,0 +1,119 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_PRIMITIVE_LINK_INTERNAL_LINK_FUNCTOR_BASE_HH
+# define SCRIBO_PRIMITIVE_LINK_INTERNAL_LINK_FUNCTOR_BASE_HH
+
+/// \file
+///
+/// Base class for link functors.
+
+# include <mln/core/concept/image.hh>
+
+# include <mln/math/abs.hh>
+
+# include <mln/util/array.hh>
+# include <mln/util/couple.hh>
+
+# include <scribo/core/concept/link_functor.hh>
+
+# include <scribo/core/object_image.hh>
+# include <scribo/core/object_links.hh>
+
+# include <scribo/primitive/internal/init_link_array.hh>
+
+
+namespace scribo
+{
+
+ namespace internal
+ {
+
+ /// \brief Base class for link functors.
+ template <typename L, typename E>
+ class link_functor_base : public Link_Functor<E>
+ {
+ public:
+
+ typedef L support;
+
+ link_functor_base(const object_image(L)& objects);
+
+ const object_links<L>& links() const;
+
+ unsigned link(unsigned object) const;
+ const object_image(L)& objects() const;
+
+ protected:
+ object_links<L> links_;
+ const object_image(L) objects_;
+ };
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename L, typename E>
+ inline
+ link_functor_base<L,E>::link_functor_base(const object_image(L)& objects)
+ : links_(objects, static_cast<unsigned>(objects.nlabels()) + 1),
+ objects_(objects)
+ {
+ primitive::internal::init_link_array(links_);
+ }
+
+ template <typename L, typename E>
+ inline
+ const object_links<L>&
+ link_functor_base<L,E>::links() const
+ {
+ return links_;
+ }
+
+ template <typename L, typename E>
+ inline
+ unsigned
+ link_functor_base<L,E>::link(unsigned object) const
+ {
+ return links_[object];
+ }
+
+ template <typename L, typename E>
+ inline
+ const object_image(L)&
+ link_functor_base<L,E>::objects() const
+ {
+ return objects_;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+
+ } // end of namespace scribo::internal
+
+} // end of namespace scribo
+
+
+#endif // ! SCRIBO_PRIMITIVE_LINK_INTERNAL_LINK_FUNCTOR_BASE_HH
diff --git a/scribo/primitive/link/compute.hh b/scribo/primitive/link/compute.hh
new file mode 100644
index 0000000..bf94787
--- /dev/null
+++ b/scribo/primitive/link/compute.hh
@@ -0,0 +1,115 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_PRIMITIVE_LINK_COMPUTE_HH
+# define SCRIBO_PRIMITIVE_LINK_COMPUTE_HH
+
+/// \file
+///
+/// Compute links between objects according a given functor.
+
+
+# include <scribo/core/macros.hh>
+# include <scribo/core/object_links.hh>
+# include <scribo/core/concept/link_functor.hh>
+# include <scribo/primitive/link/internal/find_link.hh>
+
+namespace scribo
+{
+
+ namespace primitive
+ {
+
+ namespace link
+ {
+
+ /*! \brief Compute links between objects according a given functor.
+
+ \param[in,out] functor Linking policy.
+
+ \return Object links.
+
+
+ Functors must implement the following interface :
+
+
+ bool is_potential_link(unsigned current_object,
+ const P& start_point, const P& p) const
+
+ bool valid_link(unsigned current_object,
+ const P& start_point, const P& p)
+
+ bool verify_link_criterion(unsigned current_object,
+ const P& start_point, const P& p)
+
+ void validate_link(unsigned current_object,
+ const P& start_point, const P& p)
+
+ void invalidate_link(unsigned current_object,
+ const P& start_point, const P& p)
+
+ void compute_next_site(P& p)
+
+ const mln_site(L)& start_point(unsigned current_object)
+
+ void start_processing_object(unsigned current_object)
+
+ */
+ template <typename F>
+ object_links<scribo_support(F)>
+ compute(Link_Functor<F>& functor);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ template <typename F>
+ object_links<scribo_support(F)>
+ compute(Link_Functor<F>& functor_)
+ {
+ trace::entering("scribo::primitive::link::compute");
+
+ F& functor = exact(functor_);
+
+ for_all_ncomponents(current_object, functor.objects().nlabels())
+ {
+ functor.start_processing_object(current_object); //<-- start_processing_object
+ primitive::internal::find_link(functor, current_object);
+ }
+
+ trace::exiting("scribo::primitive::link::compute");
+ return functor.links();
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace scribo::primitive::link
+
+ } // end of namespace scribo::primitive
+
+} // end of namespace scribo
+
+#endif // ! SCRIBO_PRIMITIVE_LINK_COMPUTE_HH
diff --git a/scribo/primitive/link/compute_several.hh b/scribo/primitive/link/compute_several.hh
new file mode 100644
index 0000000..0597d99
--- /dev/null
+++ b/scribo/primitive/link/compute_several.hh
@@ -0,0 +1,117 @@
+
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_PRIMITIVE_LINK_COMPUTE_SEVERAL_HH
+# define SCRIBO_PRIMITIVE_LINK_COMPUTE_SEVERAL_HH
+
+/// \file
+///
+/// Compute_Several links between objects according a given functor.
+
+
+# include <scribo/core/macros.hh>
+# include <scribo/core/object_links.hh>
+# include <scribo/core/concept/link_functor.hh>
+# include <scribo/primitive/link/internal/find_several_links.hh>
+
+namespace scribo
+{
+
+ namespace primitive
+ {
+
+ namespace link
+ {
+
+ /*! \brief Compute_Several links between objects according a given functor.
+
+ \param[in,out] functor Linking policy.
+
+ \return Object links.
+
+
+ Functors must implement the following interface :
+
+
+ bool verify_link_criterion_(unsigned current_object,
+ const P& start_point, const P& p) const;
+
+ void start_processing_object_(unsigned current_object);
+
+
+ mln_site(L) start_point_(unsigned current_object, unsigned anchor);
+
+
+ void validate_link_(unsigned current_object, const P& start_point,
+ const P& p, unsigned anchor);
+ void invalidate_link_(unsigned current_object, const P& start_point,
+ const P& p, unsigned anchor);
+
+ void initialize_link_(unsigned current_object);
+ void finalize_link_(unsigned current_object);
+
+ bool is_potential_link(unsigned current_object,
+ const P& start_point, const P& p) const
+
+ void compute_next_site(P& p)
+
+ */
+ template <typename F>
+ object_links<scribo_support(F)>
+ compute_several(Link_Functor<F>& functor);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ template <typename F>
+ object_links<scribo_support(F)>
+ compute_several(Link_Functor<F>& functor_)
+ {
+ trace::entering("scribo::primitive::link::compute_several");
+
+ F& functor = exact(functor_);
+
+ for_all_ncomponents(current_object, functor.objects().nlabels())
+ {
+ functor.start_processing_object(current_object); //<-- start_processing_object
+ primitive::internal::find_several_links(functor, current_object);
+ }
+
+ trace::exiting("scribo::primitive::link::compute_several");
+ return functor.links();
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace scribo::primitive::link
+
+ } // end of namespace scribo::primitive
+
+} // end of namespace scribo
+
+#endif // ! SCRIBO_PRIMITIVE_LINK_COMPUTE_SEVERAL_HH
diff --git a/scribo/primitive/link/internal/anchors_3.hh b/scribo/primitive/link/internal/anchors_3.hh
new file mode 100644
index 0000000..85fa80b
--- /dev/null
+++ b/scribo/primitive/link/internal/anchors_3.hh
@@ -0,0 +1,146 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_PRIMITIVE_LINK_INTERNAL_ANCHORS_3_HH
+# define SCRIBO_PRIMITIVE_LINK_INTERNAL_ANCHORS_3_HH
+
+/// \file
+///
+/// Routine providing 3 anchors for neighbor seeking.
+
+# include <mln/math/min.hh>
+
+# include <scribo/core/object_image.hh>
+
+
+namespace scribo
+{
+
+ namespace primitive
+ {
+
+ namespace link
+ {
+
+ namespace internal
+ {
+
+ /*! \brief Return the proper anchor used to find a neighbor.
+
+ This routine provides up to 3 different anchors.
+
+ \param[in] objects An object image.
+ \param[in] mass_centers Object mass centers.
+ \param[in] current_object An object id.
+ \param[in] anchor The expected anchor.
+
+ Anchor can take one of the following values:
+ - 0, top anchor.
+ - 1, center anchor. It is the mass center.
+ - 2, bottom anchor.
+
+
+ Top and bottom anchors are respectively computed from the
+ bbox pmin and the bbox pmax, P.
+
+ Then the output anchor coordinates are computed as follows:
+
+ out.col = bbox.center.col
+
+ if object height, h, is lower than 30.
+ out.row = P.row + min(2, (h + 1) / 2 - 1)
+ else
+ out.row = P.row - min(10, h /10)
+
+ */
+ template <typename L, typename P>
+ mln_site(L)
+ anchors_3(const object_image(L)& objects,
+ const mln::util::array<P>& mass_centers,
+ unsigned current_object, unsigned anchor);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename L, typename P>
+ mln_site(L)
+ anchors_3(const object_image(L)& objects,
+ const mln::util::array<P>& mass_centers,
+ unsigned current_object, unsigned anchor)
+ {
+ unsigned h = objects.bbox(current_object).pmax().row()
+ - objects.bbox(current_object).pmin().row();
+
+ mln_site(L) sp = objects.bbox(current_object).center();
+ def::coord r;
+
+ switch (anchor)
+ {
+ // Top
+ case 0:
+ if (h < 30)
+ r = objects.bbox(current_object).pmin().row()
+ + math::min(2u, (h + 1) / 2 - 1);
+ else
+ r = objects.bbox(current_object).pmin().row()
+ - math::min(10u, h /10);
+ break;
+
+
+ // Center
+ case 1:
+ return mass_centers(current_object);
+
+
+ // Bottom
+ case 2:
+ if (h < 30)
+ r = objects.bbox(current_object).pmax().row()
+ + math::min(2u, (h + 1) / 2 - 1);
+ else
+ r = objects.bbox(current_object).pmax().row()
+ - math::min(10u, h /10);
+ break;
+
+ default:
+ trace::warning("Non handled anchor");
+ mln_assertion(anchor > 2);
+ }
+
+ sp.row() = r;
+ return sp;
+ }
+
+# 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_ANCHORS_3_HH
diff --git a/scribo/primitive/link/internal/find_link.hh b/scribo/primitive/link/internal/find_link.hh
new file mode 100644
index 0000000..8a2544e
--- /dev/null
+++ b/scribo/primitive/link/internal/find_link.hh
@@ -0,0 +1,116 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_PRIMITIVE_INTERNAL_FIND_LINK_HH
+# define SCRIBO_PRIMITIVE_INTERNAL_FIND_LINK_HH
+
+/// \file
+///
+/// Find the neighbor of a line of text if exists.
+
+# include <mln/core/concept/image.hh>
+
+# include <mln/math/abs.hh>
+
+# include <mln/util/array.hh>
+# include <mln/util/couple.hh>
+
+# include <scribo/core/concept/link_functor.hh>
+# include <scribo/core/object_image.hh>
+# include <scribo/core/object_links.hh>
+# include <scribo/primitive/internal/update_link_array.hh>
+# include <scribo/primitive/internal/init_link_array.hh>
+# include <scribo/primitive/internal/is_invalid_link.hh>
+
+
+namespace scribo
+{
+
+ namespace primitive
+ {
+
+ namespace internal
+ {
+
+ /*! \brief Find the neighbor of a line of text if exists.
+
+ \param[in,out] functor Functor used to compute the
+ links. Stores the results.
+ \param[in] current_object Current object id.
+
+ \return A couple. The first argument tells whether a valid
+ link has been found, the second one is link anchor if exists.
+ */
+ template <typename F>
+ mln::util::couple<bool, mln_site(scribo_support_(F))>
+ find_link(Link_Functor<F>& functor, unsigned current_object);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename F>
+ mln::util::couple<bool, mln_site(scribo_support_(F))>
+ find_link(Link_Functor<F>& functor_, unsigned current_object)
+ {
+ F& functor = exact(functor_);
+
+ functor.initialize_link(current_object); // <-- initialize_link
+
+ mln_site(scribo_support_(F))
+ start_point = functor.start_point(current_object),
+ p = start_point;
+
+ mln_postcondition(p == start_point);
+
+ // is_potential_link
+ // verify_link_criterion
+ while (functor.objects().domain().has(p)
+ && ! functor.is_potential_link(current_object,
+ start_point, p)
+ && functor.verify_link_criterion(current_object, start_point, p))
+ functor.compute_next_site(p); // <-- compute_next_site
+
+ if (functor.valid_link(current_object, start_point, p)) // <-- valid_link
+ functor.validate_link(current_object, start_point, p); // <-- validate_link
+ else
+ functor.invalidate_link(current_object, start_point, p); // <-- invalidate_link
+
+ functor.finalize_link(current_object); // <-- finalize_link
+
+ bool b = (functor.link(current_object) != current_object);
+ return mln::make::couple(b, p);
+ }
+
+# endif // MLN_INCLUDE_ONLY
+
+
+ } // end of namespace scribo::primitive::internal
+
+ } // end of namespace scribo::primitive
+
+} // end of namespace scribo
+
+
+#endif // ! SCRIBO_PRIMITIVE_INTERNAL_FIND_LINK_HH
diff --git a/scribo/primitive/link/internal/find_several_links.hh b/scribo/primitive/link/internal/find_several_links.hh
new file mode 100644
index 0000000..a07ee70
--- /dev/null
+++ b/scribo/primitive/link/internal/find_several_links.hh
@@ -0,0 +1,124 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_PRIMITIVE_INTERNAL_FIND_SEVERAL_LINKS_HH
+# define SCRIBO_PRIMITIVE_INTERNAL_FIND_SEVERAL_LINKS_HH
+
+/// \file
+///
+/// Find the neighbor of a line of text if exists.
+
+# include <mln/core/concept/image.hh>
+
+# include <mln/math/abs.hh>
+
+# include <mln/util/array.hh>
+# include <mln/util/couple.hh>
+
+# include <scribo/core/concept/link_functor.hh>
+# include <scribo/core/object_image.hh>
+# include <scribo/core/object_links.hh>
+# include <scribo/primitive/internal/update_link_array.hh>
+# include <scribo/primitive/internal/init_link_array.hh>
+# include <scribo/primitive/internal/is_invalid_link.hh>
+
+
+namespace scribo
+{
+
+ namespace primitive
+ {
+
+ namespace internal
+ {
+
+ /*! Find the neighbor of a line of text if exists.
+
+ \param[in,out] functor Functor used to compute the
+ links. Stores the results.
+ \param current_object Current object id.
+
+ \return A couple. The first argument tells whether a valid
+ link has been found, the second one is link anchor if exists.
+ */
+ template <typename F>
+ mln::util::couple<bool, mln_site(scribo_support_(F))>
+ find_several_links(Link_Functor<F>& functor,
+ unsigned current_object);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename F>
+ mln::util::couple<bool, mln_site(scribo_support_(F))>
+ find_several_links(Link_Functor<F>& functor_,
+ unsigned current_object)
+ {
+ F& functor = exact(functor_);
+
+ typedef mln_site(scribo_support_(F)) P;
+ typedef mln::util::couple<unsigned, P> link_t;
+
+ P lp = functor.initialize_link(current_object); // <-- initialize_link
+
+ for (unsigned anchor = 0; anchor < functor.nanchors(); ++anchor) // <-- nanchor
+ {
+ mln_site(scribo_support_(F))
+ start_point = functor.start_point(current_object, anchor), // <-- start_point
+ p = start_point;
+
+ mln_postcondition(p == start_point);
+
+ while (functor.objects().domain().has(p)
+ && ! functor.is_potential_link(current_object,
+ start_point, p) // <-- is_potential_link
+ && functor.verify_link_criterion(current_object,
+ start_point, p)) // <-- verify_link_criterion
+ functor.compute_next_site(p); // <-- compute_next_site
+
+ if (functor.valid_link(current_object, start_point, p)) // <-- valid_link
+ functor.validate_link(current_object, start_point, p, anchor); // <-- validate_link
+ else
+ functor.invalidate_link(current_object, start_point, p, anchor); // <-- invalidate_link
+
+ }
+
+ P lp = functor.finalize_link(current_object);
+
+ bool b = (functor.link(current_object) != current_object); // <-- link
+ return mln::make::couple(b, lp);
+ }
+
+# endif // MLN_INCLUDE_ONLY
+
+
+ } // end of namespace scribo::primitive::internal
+
+ } // end of namespace scribo::primitive
+
+} // end of namespace scribo
+
+
+#endif // ! SCRIBO_PRIMITIVE_INTERNAL_FIND_SEVERAL_LINKS_HH
diff --git a/scribo/primitive/link/internal/link_center_dmax_base.hh b/scribo/primitive/link/internal/link_center_dmax_base.hh
new file mode 100644
index 0000000..1a7a48d
--- /dev/null
+++ b/scribo/primitive/link/internal/link_center_dmax_base.hh
@@ -0,0 +1,179 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_PRIMITIVE_LINK_INTERNAL_LINK_CENTER_DMAX_HH_
+# define SCRIBO_PRIMITIVE_LINK_INTERNAL_LINK_CENTER_DMAX_HH_
+
+/// \file
+///
+/// Base class for link functors using center sites and a given max
+/// distance.
+
+
+# include <mln/accu/center.hh>
+# include <mln/labeling/compute.hh>
+# include <mln/math/abs.hh>
+# include <mln/util/array.hh>
+
+# include <scribo/core/macros.hh>
+# include <scribo/core/object_image.hh>
+# include <scribo/core/object_links.hh>
+
+# include <scribo/primitive/link/internal/find_link.hh>
+# include <scribo/primitive/link/internal/link_functor_base.hh>
+
+# include <scribo/primitive/link/compute.hh>
+
+
+namespace scribo
+{
+
+ namespace primitive
+ {
+
+ namespace link
+ {
+
+ namespace internal
+ {
+
+ /// \brief Base class for link functors using mass centers and
+ /// a given max distance.
+ //
+ template <typename L, typename E>
+ class link_center_dmax_base
+ : public link_functor_base<L, E>
+ {
+ typedef link_functor_base<L,E> super_;
+
+ public:
+
+ typedef mln_site(L) P;
+
+
+ /*!
+
+ center_type can have the following values:
+ 0 - top bounding box center
+ 1 - bounding box center
+ 2 - bottom bounding box center
+
+ */
+ link_center_dmax_base(const object_image(L)& objects,
+ unsigned neighb_max_distance,
+ unsigned center_type);
+
+
+ bool verify_link_criterion_(unsigned current_object,
+ const P& start_point, const P& p) const;
+
+ mln_site(L) start_point_(unsigned current_object,
+ unsigned anchor);
+
+ void start_processing_object_(unsigned current_object);
+
+ private:
+ float dmax_;
+ float neighb_max_distance_;
+ unsigned center_type_;
+ };
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ template <typename L, typename E>
+ inline
+ link_center_dmax_base<L, E>::link_center_dmax_base(
+ const object_image(L)& objects,
+ unsigned neighb_max_distance,
+ unsigned center_type)
+
+ : super_(objects),
+ dmax_(0),
+ neighb_max_distance_(neighb_max_distance),
+ center_type_(center_type)
+ {
+ }
+
+
+ template <typename L, typename E>
+ inline
+ bool
+ link_center_dmax_base<L, E>::verify_link_criterion_(
+ unsigned current_object,
+ const P& start_point,
+ const P& p) const
+ {
+ (void) current_object;
+
+ float dist = math::abs(p.col() - start_point.col());
+ return dist <= dmax_; // Not too far
+ }
+
+
+ template <typename L, typename E>
+ inline
+ mln_site(L)
+ link_center_dmax_base<L, E>::start_point_(unsigned current_object,
+ unsigned anchor)
+ {
+ (void) anchor;
+ mln_site(L) sp = this->objects_.bbox(current_object).center();
+ if (center_type_ == 0)
+ sp.row() = this->objects_.bbox(current_object).pmin().row();
+ else if (center_type_ == 2)
+ sp.row() = this->objects_.bbox(current_object).pmax().row();
+
+ return sp;
+ }
+
+
+ template <typename L, typename E>
+ inline
+ void
+ link_center_dmax_base<L, E>::start_processing_object_(
+ unsigned current_object)
+ {
+ float
+ midcol = (this->objects_.bbox(current_object).pmax().col()
+ - this->objects_.bbox(current_object).pmin().col()) / 2;
+ dmax_ = midcol + neighb_max_distance_;
+ }
+
+
+# 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_CENTER_DMAX_HH_
diff --git a/scribo/primitive/link/internal/link_center_dmax_ratio_base.hh b/scribo/primitive/link/internal/link_center_dmax_ratio_base.hh
new file mode 100644
index 0000000..0740ec9
--- /dev/null
+++ b/scribo/primitive/link/internal/link_center_dmax_ratio_base.hh
@@ -0,0 +1,175 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_PRIMITIVE_LINK_INTERNAL_LINK_CENTER_DMAX_RATIO_BASE_HH_
+# define SCRIBO_PRIMITIVE_LINK_INTERNAL_LINK_CENTER_DMAX_RATIO_BASE_HH_
+
+/// \file
+///
+/// \brief Base class for link functors using bounding box center and
+/// a proportional max distance.
+
+
+# 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 <scribo/core/macros.hh>
+# include <scribo/core/object_image.hh>
+# include <scribo/core/object_links.hh>
+
+# include <scribo/primitive/link/internal/find_link.hh>
+# include <scribo/primitive/link/internal/link_functor_base.hh>
+
+# include <scribo/primitive/link/compute.hh>
+
+
+namespace scribo
+{
+
+ namespace primitive
+ {
+
+ namespace link
+ {
+
+ namespace internal
+ {
+
+ /// \brief Base class for link functors using bounding box
+ /// center and a proportional max distance.
+ //
+ template <typename L, typename E>
+ class link_center_dmax_ratio_base
+ : public link_functor_base<L, E>
+ {
+ typedef link_functor_base<L,E> super_;
+ typedef mln_result(accu::center<mln_psite(L)>) ms_t;
+
+ public:
+
+ typedef mln_site(L) P;
+
+
+ link_center_dmax_ratio_base(const object_image(L)& objects,
+ float dmax_ratio,
+ unsigned center_type_);
+
+
+
+ bool verify_link_criterion_(unsigned current_object,
+ const P& start_point, const P& p) const;
+
+ mln_site(L) start_point_(unsigned current_object,
+ unsigned anchor);
+
+ void start_processing_object_(unsigned current_object);
+
+ private:
+ float dmax_ratio_;
+ float dmax_;
+ unsigned center_type_;
+ };
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ template <typename L, typename E>
+ inline
+ link_center_dmax_ratio_base<L, E>::link_center_dmax_ratio_base(
+ const object_image(L)& objects,
+ float dmax_ratio,
+ unsigned center_type)
+
+ : super_(objects),
+ dmax_ratio_(dmax_ratio),
+ dmax_(0),
+ center_type_(center_type)
+ {
+ }
+
+ template <typename L, typename E>
+ inline
+ bool
+ link_center_dmax_ratio_base<L, E>::verify_link_criterion_(
+ unsigned current_object,
+ const P& start_point,
+ const P& p) const
+ {
+ (void) current_object;
+
+ float dist = math::abs(p.col() - start_point.col());
+ return dist <= dmax_; // Not too far
+ }
+
+
+ template <typename L, typename E>
+ inline
+ mln_site(L)
+ link_center_dmax_ratio_base<L, E>::start_point_(unsigned current_object,
+ unsigned anchor)
+ {
+ (void) anchor;
+ mln_site(L) sp = this->objects_.bbox(current_object).center();
+ if (center_type_ == 0)
+ sp.row() = this->objects_.bbox(current_object).pmin().row();
+ else if (center_type_ == 2)
+ sp.row() = this->objects_.bbox(current_object).pmax().row();
+
+ return sp;
+ }
+
+
+ template <typename L, typename E>
+ inline
+ void
+ link_center_dmax_ratio_base<L, E>::start_processing_object_(
+ unsigned current_object)
+ {
+ float
+ w = (this->objects_.bbox(current_object).pmax().col()
+ - this->objects_.bbox(current_object).pmin().col()),
+ h = (this->objects_.bbox(current_object).pmax().row()
+ - this->objects_.bbox(current_object).pmin().row());
+ dmax_ = (w / 2.0f) + (dmax_ratio_ * math::max(w, h));
+ }
+
+
+# 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_CENTER_DMAX_RATIO_BASE_HH_
diff --git a/scribo/primitive/link/internal/link_functor_base.hh b/scribo/primitive/link/internal/link_functor_base.hh
new file mode 100644
index 0000000..e35f52d
--- /dev/null
+++ b/scribo/primitive/link/internal/link_functor_base.hh
@@ -0,0 +1,518 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_CORE_INTERNAL_LINK_FUNCTOR_BASE_HH
+# define SCRIBO_CORE_INTERNAL_LINK_FUNCTOR_BASE_HH
+
+/// \file
+///
+/// Base class for link functors.
+
+# include <mln/core/concept/image.hh>
+
+# include <mln/math/abs.hh>
+
+# include <mln/util/array.hh>
+# include <mln/util/couple.hh>
+
+# include <scribo/core/object_image.hh>
+# include <scribo/core/object_links.hh>
+# include <scribo/core/concept/link_functor.hh>
+# include <scribo/primitive/internal/update_link_array.hh>
+# include <scribo/primitive/internal/init_link_array.hh>
+# include <scribo/primitive/internal/is_invalid_link.hh>
+
+
+# define scribo_support(T) typename T::support
+# define scribo_support_(T) T::support
+
+namespace scribo
+{
+
+ namespace primitive
+ {
+
+ namespace link
+ {
+
+ namespace internal
+ {
+
+ /// \brief Base class for link functors.
+ template <typename L, typename E>
+ class link_functor_base : public Link_Functor<E>
+ {
+ public:
+
+ typedef L support;
+ typedef mln_site(L) P;
+
+ link_functor_base(const object_image(L)& objects, unsigned nanchors);
+
+ /// \overload
+ /// \p nanchors is set to 1.
+ link_functor_base(const object_image(L)& objects);
+
+
+ unsigned nanchors() const;
+
+ const object_links<L>& links() const;
+
+ unsigned link(unsigned object) const;
+ const object_image(L)& objects() const;
+
+
+ void initialize_link(unsigned current_object);
+ mln_site(L) finalize_link(unsigned current_object);
+
+
+ bool verify_link_criterion(unsigned current_object,
+ const P& start_point, const P& p) const;
+
+ bool is_potential_link(unsigned current_object,
+ const P& start_point, const P& p) const;
+
+ bool valid_link(unsigned current_object,
+ const P& start_point, const P& p);
+
+
+
+ //FIXME: there's a probleme here. We may not want to provide
+ //both interfaces (with multiple and single anchors)for
+ //every functors...
+
+ void validate_link(unsigned current_object,
+ const P& start_point,
+ const P& p,
+ unsigned anchor);
+
+ /// \overload
+ /// \p anchor is set to 0.
+ void validate_link(unsigned current_object,
+ const P& start_point, const P& p);
+
+ void invalidate_link(unsigned current_object,
+ const P& start_point, const P& p,
+ unsigned anchor);
+
+ /// \overload
+ /// \p anchor is set to 0
+ void invalidate_link(unsigned current_object,
+ const P& start_point, const P& p);
+
+
+
+
+
+
+ void compute_next_site(P& p);
+
+
+ mln_site(L) start_point(unsigned current_object, unsigned anchor);
+
+ /// \overload
+ /// \p anchor is set to 0.
+ mln_site(L) start_point(unsigned current_object);
+
+
+ void start_processing_object(unsigned current_object);
+
+
+
+
+ // Default implementation for possibly not overridden
+ // methods.
+
+ void initialize_link_(unsigned current_object);
+ mln_site(L) finalize_link_(unsigned current_object);
+
+ bool is_potential_link_(unsigned current_object,
+ const P& start_point, const P& p) const;
+
+ bool verify_link_criterion_(unsigned current_object,
+ const P& start_point, const P& p) const;
+
+ bool valid_link_(unsigned current_object,
+ const P& start_point, const P& p);
+
+ void validate_link_(unsigned current_object,
+ const P& start_point, const P& p,
+ unsigned anchor);
+
+ void invalidate_link_(unsigned current_object,
+ const P& start_point, const P& p,
+ unsigned anchor);
+
+ void compute_next_site_(P& p);
+
+ void start_processing_object_(unsigned current_object);
+
+
+ protected:
+ object_links<L> links_;
+ const object_image(L) objects_;
+ unsigned nanchors_;
+ };
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ template <typename L, typename E>
+ inline
+ link_functor_base<L,E>::link_functor_base(
+ const object_image(L)& objects,
+ unsigned nanchors)
+ : links_(objects, static_cast<unsigned>(objects.nlabels()) + 1),
+ objects_(objects),
+ nanchors_(nanchors)
+ {
+ primitive::internal::init_link_array(links_);
+ }
+
+
+ template <typename L, typename E>
+ inline
+ link_functor_base<L,E>::link_functor_base(
+ const object_image(L)& objects)
+ : links_(objects, static_cast<unsigned>(objects.nlabels()) + 1),
+ objects_(objects),
+ nanchors_(1)
+ {
+ primitive::internal::init_link_array(links_);
+ }
+
+
+ template <typename L, typename E>
+ inline
+ unsigned
+ link_functor_base<L,E>::nanchors() const
+ {
+ return nanchors_;
+ }
+
+
+ template <typename L, typename E>
+ inline
+ const object_links<L>&
+ link_functor_base<L,E>::links() const
+ {
+ return links_;
+ }
+
+ template <typename L, typename E>
+ inline
+ unsigned
+ link_functor_base<L,E>::link(unsigned object) const
+ {
+ return links_[object];
+ }
+
+ template <typename L, typename E>
+ inline
+ const object_image(L)&
+ link_functor_base<L,E>::objects() const
+ {
+ return objects_;
+ }
+
+
+
+
+ template <typename L, typename E>
+ inline
+ bool
+ link_functor_base<L,E>::is_potential_link(unsigned current_object,
+ const P& start_point,
+ const P& p) const
+ {
+ (void) start_point;
+ return this->objects_(p) != literal::zero // Not the background
+ && this->objects_(p) != current_object // Not the current component
+ && this->links_[this->objects_(p)] != current_object; // No loops
+ }
+
+
+ template <typename L, typename E>
+ inline
+ void
+ link_functor_base<L,E>::initialize_link(unsigned current_object)
+ {
+ exact(this)->initialize_link_(current_object);
+ }
+
+ template <typename L, typename E>
+ inline
+ mln_site(L)
+ link_functor_base<L,E>::finalize_link(unsigned current_object)
+ {
+ return exact(this)->finalize_link_(current_object);
+ }
+
+
+
+ template <typename L, typename E>
+ inline
+ bool
+ link_functor_base<L,E>::verify_link_criterion(unsigned current_object,
+ const P& start_point,
+ const P& p) const
+ {
+ return exact(this)->verify_link_criterion_(current_object,
+ start_point, p);
+ }
+
+ template <typename L, typename E>
+ inline
+ bool
+ link_functor_base<L,E>::valid_link(unsigned current_object,
+ const P& start_point,
+ const P& p)
+ {
+ return this->objects_.domain().has(p)
+ && exact(this)->valid_link_(current_object, start_point, p);
+ }
+
+
+ template <typename L, typename E>
+ inline
+ void
+ link_functor_base<L,E>::validate_link(unsigned current_object,
+ const P& start_point,
+ const P& p,
+ unsigned anchor)
+ {
+ exact(this)->validate_link_(current_object, start_point, p, anchor);
+ }
+
+
+
+ template <typename L, typename E>
+ inline
+ void
+ link_functor_base<L,E>::validate_link(unsigned current_object,
+ const P& start_point,
+ const P& p)
+ {
+ validate_link(current_object, start_point, p, 0);
+ }
+
+
+ template <typename L, typename E>
+ inline
+ void
+ link_functor_base<L,E>::invalidate_link(unsigned current_object,
+ const P& start_point,
+ const P& p,
+ unsigned anchor)
+ {
+ exact(this)->invalidate_link_(current_object, start_point, p, anchor);
+ }
+
+
+ template <typename L, typename E>
+ inline
+ void
+ link_functor_base<L,E>::invalidate_link(unsigned current_object,
+ const P& start_point,
+ const P& p)
+ {
+ invalidate_link(current_object, start_point, p, 0);
+ }
+
+
+
+
+
+ template <typename L, typename E>
+ inline
+ void
+ link_functor_base<L,E>::compute_next_site(P& p)
+ {
+ // No-op
+ exact(this)->compute_next_site_(p);
+ }
+
+
+ template <typename L, typename E>
+ inline
+ mln_site(L)
+ link_functor_base<L,E>::start_point(unsigned current_object,
+ unsigned anchor)
+ {
+ return exact(this)->start_point_(current_object, anchor);
+ }
+
+
+ template <typename L, typename E>
+ inline
+ mln_site(L)
+ link_functor_base<L,E>::start_point(unsigned current_object)
+ {
+ return start_point(current_object, 0);
+ }
+
+
+ template <typename L, typename E>
+ inline
+ void
+ link_functor_base<L,E>::start_processing_object(
+ unsigned current_object)
+ {
+ (void) current_object;
+ // No-Op
+ exact(this)->start_processing_object_(current_object);
+ }
+
+
+
+
+ // Default implementation for delegated methods.
+
+ template <typename L, typename E>
+ inline
+ void
+ link_functor_base<L,E>::initialize_link_(unsigned current_object)
+ {
+ (void) current_object;
+ // No-Op
+ }
+
+
+ template <typename L, typename E>
+ inline
+ mln_site(L)
+ link_functor_base<L,E>::finalize_link_(unsigned current_object)
+ {
+ (void) current_object;
+ // No-Op
+ return P();
+ }
+
+
+ template <typename L, typename E>
+ inline
+ bool
+ link_functor_base<L,E>::is_potential_link_(unsigned current_object,
+ const P& start_point,
+ const P& p) const
+ {
+ (void) current_object;
+ (void) start_point;
+ (void) p;
+ // No-Op
+ return true;
+ }
+
+ template <typename L, typename E>
+ inline
+ bool
+ link_functor_base<L,E>::verify_link_criterion_(unsigned current_object,
+ const P& start_point,
+ const P& p) const
+ {
+ (void) current_object;
+ (void) start_point;
+ (void) p;
+ // No-Op
+ return true;
+ }
+
+
+ template <typename L, typename E>
+ inline
+ bool
+ link_functor_base<L,E>::valid_link_(unsigned current_object,
+ const P& start_point,
+ const P& p)
+ {
+ return is_potential_link(current_object, start_point, p)
+ && verify_link_criterion(current_object, start_point, p);
+ }
+
+
+ template <typename L, typename E>
+ inline
+ void
+ link_functor_base<L,E>::validate_link_(unsigned current_object,
+ const P& start_point,
+ const P& p,
+ unsigned anchor)
+ {
+ (void) start_point;
+ (void) anchor;
+ this->links_[current_object] = this->objects_(p);
+ }
+
+
+ template <typename L, typename E>
+ inline
+ void
+ link_functor_base<L,E>::invalidate_link_(unsigned current_object,
+ const P& start_point,
+ const P& p,
+ unsigned anchor)
+ {
+ (void) current_object;
+ (void) start_point;
+ (void) p;
+ (void) anchor;
+ // No-op
+ }
+
+
+ template <typename L, typename E>
+ inline
+ void
+ link_functor_base<L,E>::compute_next_site_(P& p)
+ {
+ (void) p;
+ // No-Op
+ }
+
+ template <typename L, typename E>
+ inline
+ void
+ link_functor_base<L,E>::start_processing_object_(
+ unsigned current_object)
+ {
+ // No-Op
+ }
+
+
+# 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_CORE_INTERNAL_LINK_FUNCTOR_BASE_HH
diff --git a/scribo/primitive/link/internal/link_ms_dmax_base.hh b/scribo/primitive/link/internal/link_ms_dmax_base.hh
new file mode 100644
index 0000000..80a9a13
--- /dev/null
+++ b/scribo/primitive/link/internal/link_ms_dmax_base.hh
@@ -0,0 +1,165 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_PRIMITIVE_LINK_INTERNAL_LINK_MS_DMAX_HH_
+# define SCRIBO_PRIMITIVE_LINK_INTERNAL_LINK_MS_DMAX_HH_
+
+/// \file
+///
+/// Base class for link functors using mass centers and a given max
+/// distance.
+
+
+# include <mln/accu/center.hh>
+# include <mln/labeling/compute.hh>
+# include <mln/math/abs.hh>
+# include <mln/util/array.hh>
+
+# include <scribo/core/macros.hh>
+# include <scribo/core/object_image.hh>
+# include <scribo/core/object_links.hh>
+
+# include <scribo/primitive/link/internal/find_link.hh>
+# include <scribo/primitive/link/internal/link_functor_base.hh>
+
+# include <scribo/primitive/link/compute.hh>
+
+
+namespace scribo
+{
+
+ namespace primitive
+ {
+
+ namespace link
+ {
+
+ namespace internal
+ {
+
+ /// \brief Base class for link functors using mass centers and
+ /// a given max distance.
+ //
+ template <typename L, typename E>
+ class link_ms_dmax_base
+ : public link_functor_base<L, E>
+ {
+ typedef link_functor_base<L,E> super_;
+ typedef mln_result(accu::center<mln_psite(L)>) ms_t;
+
+ public:
+
+ typedef mln_site(L) P;
+
+
+ link_ms_dmax_base(const object_image(L)& objects,
+ unsigned neighb_max_distance);
+
+
+
+ bool verify_link_criterion_(unsigned current_object,
+ const P& start_point, const P& p) const;
+
+ mln_site(L) start_point_(unsigned current_object,
+ unsigned anchor);
+
+ void start_processing_object_(unsigned current_object);
+
+ private:
+ mln::util::array<ms_t> mass_centers_;
+ float dmax_;
+ float neighb_max_distance_;
+ };
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ template <typename L, typename E>
+ inline
+ link_ms_dmax_base<L, E>::link_ms_dmax_base(
+ const object_image(L)& objects,
+ unsigned neighb_max_distance)
+
+ : super_(objects),
+ dmax_(0),
+ neighb_max_distance_(neighb_max_distance)
+ {
+
+ mass_centers_ = labeling::compute(accu::meta::center(),
+ objects, objects.nlabels());
+ }
+
+ template <typename L, typename E>
+ inline
+ bool
+ link_ms_dmax_base<L, E>::verify_link_criterion_(unsigned current_object,
+ const P& start_point,
+ const P& p) const
+ {
+ (void) current_object;
+
+ float dist = math::abs(p.col() - start_point.col());
+ return dist <= dmax_; // Not too far
+ }
+
+
+ template <typename L, typename E>
+ inline
+ mln_site(L)
+ link_ms_dmax_base<L, E>::start_point_(unsigned current_object,
+ unsigned anchor)
+ {
+ (void) anchor;
+ return mass_centers_(current_object);
+ }
+
+
+ template <typename L, typename E>
+ inline
+ void
+ link_ms_dmax_base<L, E>::start_processing_object_(
+ unsigned current_object)
+ {
+ float
+ midcol = (this->objects_.bbox(current_object).pmax().col()
+ - this->objects_.bbox(current_object).pmin().col()) / 2;
+ dmax_ = midcol + neighb_max_distance_;
+ }
+
+
+# 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_MS_DMAX_HH_
diff --git a/scribo/primitive/link/internal/link_ms_dmax_ratio_base.hh b/scribo/primitive/link/internal/link_ms_dmax_ratio_base.hh
new file mode 100644
index 0000000..414e0b2
--- /dev/null
+++ b/scribo/primitive/link/internal/link_ms_dmax_ratio_base.hh
@@ -0,0 +1,168 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_PRIMITIVE_LINK_INTERNAL_LINK_MS_DMAX_RATIO_BASE_HH_
+# define SCRIBO_PRIMITIVE_LINK_INTERNAL_LINK_MS_DMAX_RATIO_BASE_HH_
+
+/// \file
+///
+/// \brief Base class for link functors using mass centers and a
+/// proportional max distance.
+
+
+# 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 <scribo/core/macros.hh>
+# include <scribo/core/object_image.hh>
+# include <scribo/core/object_links.hh>
+
+# include <scribo/primitive/link/internal/find_link.hh>
+# include <scribo/primitive/link/internal/link_functor_base.hh>
+
+# include <scribo/primitive/link/compute.hh>
+
+
+namespace scribo
+{
+
+ namespace primitive
+ {
+
+ namespace link
+ {
+
+ namespace internal
+ {
+
+ /// \brief Base class for link functors using mass centers and
+ /// a proportional max distance.
+ //
+ template <typename L, typename E>
+ class link_ms_dmax_ratio_base
+ : public link_functor_base<L, E>
+ {
+ typedef link_functor_base<L,E> super_;
+ typedef mln_result(accu::center<mln_psite(L)>) ms_t;
+
+ public:
+
+ typedef mln_site(L) P;
+
+
+ link_ms_dmax_ratio_base(const object_image(L)& objects,
+ float dmax_ratio);
+
+
+
+ bool verify_link_criterion_(unsigned current_object,
+ const P& start_point, const P& p) const;
+
+ mln_site(L) start_point_(unsigned current_object,
+ unsigned anchor);
+
+ void start_processing_object_(unsigned current_object);
+
+ private:
+ mln::util::array<ms_t> mass_centers_;
+ float dmax_ratio_;
+ float dmax_;
+ };
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ template <typename L, typename E>
+ inline
+ link_ms_dmax_ratio_base<L, E>::link_ms_dmax_ratio_base(
+ const object_image(L)& objects,
+ float dmax_ratio)
+
+ : super_(objects),
+ dmax_ratio_(dmax_ratio),
+ dmax_(0)
+ {
+ mass_centers_ = labeling::compute(accu::meta::center(),
+ objects, objects.nlabels());
+ }
+
+ template <typename L, typename E>
+ inline
+ bool
+ link_ms_dmax_ratio_base<L, E>::verify_link_criterion_(
+ unsigned current_object,
+ const P& start_point,
+ const P& p) const
+ {
+ (void) current_object;
+
+ float dist = math::abs(p.col() - start_point.col());
+ return dist <= dmax_; // Not too far
+ }
+
+
+ template <typename L, typename E>
+ inline
+ mln_site(L)
+ link_ms_dmax_ratio_base<L, E>::start_point_(unsigned current_object,
+ unsigned anchor)
+ {
+ (void) anchor;
+ return mass_centers_(current_object);
+ }
+
+
+ template <typename L, typename E>
+ inline
+ void
+ link_ms_dmax_ratio_base<L, E>::start_processing_object_(
+ unsigned current_object)
+ {
+ float
+ w = (this->objects_.bbox(current_object).pmax().col()
+ - this->objects_.bbox(current_object).pmin().col()),
+ h = (this->objects_.bbox(current_object).pmax().row()
+ - this->objects_.bbox(current_object).pmin().row());
+ dmax_ = (w / 2.0f) + (dmax_ratio_ * math::max(w, h));
+ }
+
+
+# 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_MS_DMAX_RATIO_BASE_HH_
diff --git a/scribo/primitive/link/with_several_left_links.hh b/scribo/primitive/link/with_several_left_links.hh
index c2c6c83..2de4cee 100644
--- a/scribo/primitive/link/with_several_left_links.hh
+++ b/scribo/primitive/link/with_several_left_links.hh
@@ -29,8 +29,6 @@
/// \file
///
/// Link text bounding boxes with their left neighbor.
-///
-/// Merge code with primitive::link::with_single_right_link.hh
# include <mln/core/concept/image.hh>
# include <mln/core/concept/neighborhood.hh>
@@ -64,6 +62,14 @@ namespace scribo
with_several_left_links(const object_image(L)& objects,
unsigned neighb_max_distance);
+
+ /// \overload
+ template <typename L>
+ inline
+ object_links<L>
+ with_several_left_links(const object_image(L)& objects);
+
+
# ifndef MLN_INCLUDE_ONLY
template <typename L>
@@ -82,9 +88,9 @@ namespace scribo
link_3(objects, objects.nlabels().next()),
final_link(objects, objects.nlabels().next());
- internal::init_link_array(link_1);
- internal::init_link_array(link_2);
- internal::init_link_array(link_3);
+ primitive::internal::init_link_array(link_1);
+ primitive::internal::init_link_array(link_2);
+ primitive::internal::init_link_array(link_3);
mln::util::array<mln_result(accu::center<mln_psite(L)>)>
mass_centers = labeling::compute(accu::meta::center(),
@@ -110,15 +116,16 @@ namespace scribo
/// Left link from the top anchor.
mln_site(L) a1 = c;
a1.row() = objects.bbox(i).pmin().row() + (c.row() - objects.bbox(i).pmin().row()) / 4;
- internal::find_left_link(objects, link_1, i, dmax, a1);
+ primitive::internal::find_left_link(objects, link_1, i, dmax, a1);
/// Left link from the central site
- internal::find_left_link(objects, link_2, i, dmax, mass_centers[i]);
+ primitive::internal::find_left_link(objects, link_2, i,
+ dmax, mass_centers[i]);
/// Left link from the bottom anchor.
mln_site(L) a2 = c;
a2.row() = objects.bbox(i).pmax().row() - (c.row() - objects.bbox(i).pmin().row()) / 4;
- internal::find_left_link(objects, link_3, i, dmax, a2);
+ primitive::internal::find_left_link(objects, link_3, i, dmax, a2);
}
for_all_ncomponents(i, objects.nlabels())
@@ -139,6 +146,15 @@ namespace scribo
return final_link;
}
+
+ template <typename L>
+ inline
+ object_links<L>
+ with_several_left_links(const object_image(L)& objects)
+ {
+ return with_several_left_links(objects);
+ }
+
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace scribo::primitive::link
diff --git a/scribo/primitive/link/with_several_right_closest_links.hh b/scribo/primitive/link/with_several_right_closest_links.hh
new file mode 100644
index 0000000..629d0b0
--- /dev/null
+++ b/scribo/primitive/link/with_several_right_closest_links.hh
@@ -0,0 +1,215 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_PRIMITIVE_LINK_WITH_SEVERAL_RIGHT_CLOSEST_LINKS_HH
+# define SCRIBO_PRIMITIVE_LINK_WITH_SEVERAL_RIGHT_CLOSEST_LINKS_HH
+
+/// \file
+///
+/// Link text bounding boxes with their right neighbor.
+///
+/// Merge code with primitive::link::with_single_right_link.hh
+///
+/// \todo Factor code with primitive::link::with_several_right_links
+
+# include <mln/core/concept/image.hh>
+# include <mln/core/concept/neighborhood.hh>
+
+# include <mln/extension/fill.hh>
+
+# include <mln/util/array.hh>
+
+# include <scribo/core/object_links.hh>
+# include <scribo/core/object_image.hh>
+# include <scribo/core/macros.hh>
+# include <scribo/primitive/internal/init_link_array.hh>
+# include <scribo/primitive/internal/find_right_link.hh>
+# include <scribo/util/text.hh>
+
+
+namespace scribo
+{
+
+ namespace primitive
+ {
+
+ namespace link
+ {
+
+ using namespace mln;
+
+
+ /// Map each character bounding box to its right bounding box
+ /// neighbor if possible. If there are several right neighbor,
+ /// the closest one is chosen.
+ ///
+ /// \return an mln::util::array. Map a bounding box to its right
+ /// neighbor.
+ //
+ template <typename L>
+ inline
+ object_links<L>
+ with_several_right_closest_links(const object_image(L)& objects,
+ unsigned neighb_max_distance);
+
+ /// \overload
+ template <typename L>
+ inline
+ object_links<L>
+ with_several_right_closest_links(const object_image(L)& objects);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+
+ namespace internal
+ {
+
+ template <unsigned n, typename P>
+ inline
+ unsigned
+ find_closest(const algebra::vec<n,
+ mln::util::couple<bool, P> >& res,
+ const P& c)
+ {
+ algebra::vec<3, unsigned> dist;
+ for (unsigned j = 0; j < 3; ++j)
+ dist[j] = math::abs(res[j].second().col() - c.col());
+
+ unsigned idx = 0;
+ for (unsigned i = 1; i < n; ++i)
+ if (dist[i] < dist[idx])
+ idx = i;
+
+ return idx;
+ }
+
+ } // end of namespace scribo::primitive::link::internal
+
+
+
+ template <typename L>
+ inline
+ object_links<L>
+ with_several_right_closest_links(const object_image(L)& objects,
+ unsigned neighb_max_distance)
+ {
+ trace::entering("scribo::primitive::link::with_several_right_closest_links");
+
+ mln_precondition(objects.is_valid());
+
+ extension::fill(objects, 0);
+
+ object_links<L>
+ link_1(objects, objects.nlabels().next()),
+ link_2(objects, objects.nlabels().next()),
+ link_3(objects, objects.nlabels().next()),
+ final_link(objects, objects.nlabels().next());
+
+ primitive::internal::init_link_array(link_1);
+ primitive::internal::init_link_array(link_2);
+ primitive::internal::init_link_array(link_3);
+
+ mln::util::array<mln_result(accu::center<mln_psite(L)>)>
+ mass_centers = labeling::compute(accu::meta::center(),
+ objects, objects.nlabels());
+
+
+ for_all_ncomponents(i, objects.nlabels())
+ {
+ // -------
+ // | a1------->
+ // | |
+ // | |
+ // | mc------->
+ // | |
+ // | |
+ // | a2------->
+ // -------
+
+ float midcol = (objects.bbox(i).pmax().col()
+ - objects.bbox(i).pmin().col()) / 2;
+ float dmax = midcol + neighb_max_distance;
+
+ mln_site(L) c = objects.bbox(i).center();
+
+ algebra::vec<3, mln::util::couple<bool, mln_site(L)> > res;
+
+ // Right link from the top anchor.
+ mln_site(L) a1 = c;
+ a1.row() = objects.bbox(i).pmin().row()
+ + (c.row() - objects.bbox(i).pmin().row()) / 4;
+ res[0] = primitive::internal::find_right_link(objects, link_1,
+ i, dmax, a1);
+
+ // Right link from the central site
+ res[1] = primitive::internal::find_right_link(objects, link_2,
+ i, dmax,
+ mass_centers[i]);
+
+ // Right link from the bottom anchor.
+ mln_site(L) a2 = c;
+ a2.row() = objects.bbox(i).pmax().row()
+ - (c.row() - objects.bbox(i).pmin().row()) / 4;
+ res[2] = primitive::internal::find_right_link(objects, link_3,
+ i, dmax, a2);
+
+ // Try to find the closest object.
+
+ unsigned closest_idx = internal::find_closest(res, c);
+
+
+ // If there exists a link and the site is not outside the
+ // image domain.
+ if (res[closest_idx].first())
+ final_link[i] = objects(res[closest_idx].second());
+ else
+ final_link[i] = i;
+ }
+
+ trace::exiting("scribo::primitive::link::with_several_right_closest_links");
+ return final_link;
+ }
+
+
+ template <typename L>
+ inline
+ object_links<L>
+ with_several_right_closest_links(const object_image(L)& objects)
+ {
+ return with_several_right_closest_links(objects, mln_max(unsigned));
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace scribo::primitive::link
+
+ } // end of namespace scribo::primitive
+
+} // end of namespace scribo
+
+#endif // ! SCRIBO_PRIMITIVE_LINK_WITH_SEVERAL_RIGHT_CLOSEST_LINKS_HH
diff --git a/scribo/primitive/link/with_several_right_links.hh b/scribo/primitive/link/with_several_right_links.hh
index 17e00cc..b302dcb 100644
--- a/scribo/primitive/link/with_several_right_links.hh
+++ b/scribo/primitive/link/with_several_right_links.hh
@@ -67,6 +67,13 @@ namespace scribo
with_several_right_links(const object_image(L)& objects,
unsigned neighb_max_distance);
+ /// \overload
+ template <typename L>
+ inline
+ object_links<L>
+ with_several_right_links(const object_image(L)& objects);
+
+
# ifndef MLN_INCLUDE_ONLY
template <typename L>
@@ -105,9 +112,9 @@ namespace scribo
// | |
// | X------->
// -------
- unsigned midcol = (objects.bbox(i).pmax().col()
- - objects.bbox(i).pmin().col()) / 2;
- int dmax = midcol + neighb_max_distance;
+ float midcol = (objects.bbox(i).pmax().col()
+ - objects.bbox(i).pmin().col()) / 2;
+ float dmax = midcol + neighb_max_distance;
mln_site(L) c = objects.bbox(i).center();
@@ -123,10 +130,8 @@ namespace scribo
mln_site(L) a2 = c;
a2.row() = objects.bbox(i).pmax().row() - (c.row() - objects.bbox(i).pmin().row()) / 4;
internal::find_right_link(objects, link_3, i, dmax, a2);
- }
- for_all_ncomponents(i, objects.nlabels())
- {
+
if (link_2[i] != i)
final_link[i] = link_2[i];
else if (link_1[i] == link_3[i])
@@ -143,6 +148,16 @@ namespace scribo
return final_link;
}
+
+ template <typename L>
+ inline
+ object_links<L>
+ with_several_right_links(const object_image(L)& objects)
+ {
+ return with_several_right_links(objects, mln_max(unsigned));
+ }
+
+
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace scribo::primitive::link
diff --git a/scribo/primitive/link/with_several_right_links.hh b/scribo/primitive/link/with_several_right_links_overlap.hh
similarity index 53%
copy from scribo/primitive/link/with_several_right_links.hh
copy to scribo/primitive/link/with_several_right_links_overlap.hh
index 17e00cc..27d9d49 100644
--- a/scribo/primitive/link/with_several_right_links.hh
+++ b/scribo/primitive/link/with_several_right_links_overlap.hh
@@ -23,14 +23,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_SEVERAL_RIGHT_LINKS_HH
-# define SCRIBO_PRIMITIVE_LINK_WITH_SEVERAL_RIGHT_LINKS_HH
+#ifndef SCRIBO_PRIMITIVE_LINK_WITH_SEVERAL_RIGHT_LINKS_OVERLAP_HH
+# define SCRIBO_PRIMITIVE_LINK_WITH_SEVERAL_RIGHT_LINKS_OVERLAP_HH
/// \file
///
/// Link text bounding boxes with their right neighbor.
-///
-/// Merge code with primitive::link::with_single_right_link.hh
# include <mln/core/concept/image.hh>
# include <mln/core/concept/neighborhood.hh>
@@ -64,85 +62,85 @@ namespace scribo
template <typename L>
inline
object_links<L>
- with_several_right_links(const object_image(L)& objects,
- unsigned neighb_max_distance);
+ with_several_right_links_overlap(const object_image(L)& objects,
+ unsigned neighb_max_distance);
+
+ /// \overload
+ template <typename L>
+ inline
+ object_links<L>
+ with_several_right_links_overlap(const object_image(L)& objects);
+
# ifndef MLN_INCLUDE_ONLY
+ namespace internal
+ {
+
+ template <typename L>
+ class several_right_overlap_functor
+ : public link_several_dmax_base<L, several_right_overlap_functor<L> >
+ {
+ typedef
+ link_several_dmax_base<L, several_right_overlap_functor<L> >
+ super_;
+
+ public:
+ typedef mln_site(L) P;
+
+ several_right_overlap_functor(const object_image(L)& objects,
+ unsigned dmax)
+ : super_(objects, dmax, 3)
+ {
+ }
+
+ template <typename L, typename E>
+ inline
+ mln_site(L)
+ start_point_(unsigned current_object, unsigned anchor)
+ {
+ return anchors_3(this->objects_, this->mass_centers_,
+ current_object, anchor);
+ }
+
+
+ void compute_next_site_(P& p)
+ {
+ ++p.col();
+ }
+
+ } // end of namespace scribo::primitive::link::internal
+
+
template <typename L>
inline
object_links<L>
- with_several_right_links(const object_image(L)& objects,
- unsigned neighb_max_distance)
+ with_several_right_links_overlap(const object_image(L)& objects,
+ unsigned neighb_max_distance)
{
- trace::entering("scribo::primitive::link::with_several_right_links");
+ trace::entering("scribo::primitive::link::with_several_right_links_overlap");
mln_precondition(objects.is_valid());
- object_links<L>
- link_1(objects, objects.nlabels().next()),
- link_2(objects, objects.nlabels().next()),
- link_3(objects, objects.nlabels().next()),
- final_link(objects, objects.nlabels().next());
+ several_right_overlap_functor<L> functor(objects, neighb_max_distance);
- internal::init_link_array(link_1);
- internal::init_link_array(link_2);
- internal::init_link_array(link_3);
+ for_all_ncomponents(current_object, objects.nlabels())
+ internal::find_several_links(functor, current_object);
- mln::util::array<mln_result(accu::center<mln_psite(L)>)>
- mass_centers = labeling::compute(accu::meta::center(),
- objects, objects.nlabels());
+ trace::exiting("scribo::primitive::link::with_several_right_links_overlap");
+ return functor.links();
+ }
- for_all_ncomponents(i, objects.nlabels())
- {
- // -------
- // | X------->
- // | |
- // | |
- // | X------->
- // | |
- // | |
- // | X------->
- // -------
- unsigned midcol = (objects.bbox(i).pmax().col()
- - objects.bbox(i).pmin().col()) / 2;
- int dmax = midcol + neighb_max_distance;
-
- mln_site(L) c = objects.bbox(i).center();
-
- /// Right link from the top anchor.
- mln_site(L) a1 = c;
- a1.row() = objects.bbox(i).pmin().row() + (c.row() - objects.bbox(i).pmin().row()) / 4;
- internal::find_right_link(objects, link_1, i, dmax, a1);
-
- /// Right link from the central site
- internal::find_right_link(objects, link_2, i, dmax, mass_centers[i]);
-
- /// Right link from the bottom anchor.
- mln_site(L) a2 = c;
- a2.row() = objects.bbox(i).pmax().row() - (c.row() - objects.bbox(i).pmin().row()) / 4;
- internal::find_right_link(objects, link_3, i, dmax, a2);
- }
-
- for_all_ncomponents(i, objects.nlabels())
- {
- if (link_2[i] != i)
- final_link[i] = link_2[i];
- else if (link_1[i] == link_3[i])
- final_link[i] = link_1[i];
- else if (link_1[i] != i && link_3[i] == i)
- final_link[i] = link_1[i];
- else if (link_3[i] != i && link_1[i] == i)
- final_link[i] = link_3[i];
- else
- final_link[i] = i;
- }
-
- trace::exiting("scribo::primitive::link::with_several_right_links");
- return final_link;
+ template <typename L>
+ inline
+ object_links<L>
+ with_several_right_links_overlap(const object_image(L)& objects)
+ {
+ return with_several_right_links_overlap(objects, mln_max(unsigned));
}
+
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace scribo::primitive::link
@@ -151,4 +149,4 @@ namespace scribo
} // end of namespace scribo
-#endif // ! SCRIBO_PRIMITIVE_LINK_WITH_SEVERAL_RIGHT_LINKS_HH
+#endif // ! SCRIBO_PRIMITIVE_LINK_WITH_SEVERAL_RIGHT_LINKS_OVERLAP_HH
diff --git a/scribo/primitive/link/with_single_left_link.hh b/scribo/primitive/link/with_single_left_link.hh
index 03cb870..bef9ea3 100644
--- a/scribo/primitive/link/with_single_left_link.hh
+++ b/scribo/primitive/link/with_single_left_link.hh
@@ -29,8 +29,6 @@
/// \file
///
/// Link text objects with their left neighbor.
-///
-/// Merge code with primitive::link::with_single_right_link.hh
# include <mln/core/concept/image.hh>
# include <mln/core/concept/neighborhood.hh>
@@ -43,14 +41,16 @@
# include <mln/util/array.hh>
-# include <scribo/core/object_links.hh>
+
# include <scribo/core/macros.hh>
# include <scribo/core/object_image.hh>
-# include <scribo/primitive/internal/init_link_array.hh>
-# include <scribo/primitive/internal/find_left_link.hh>
+# include <scribo/core/object_links.hh>
+
+# include <scribo/primitive/link/internal/find_link.hh>
+# include <scribo/primitive/link/internal/link_ms_dmax_base.hh>
+
+# include <scribo/primitive/link/compute.hh>
-//FIXME: not generic.
-# include <mln/core/alias/dpoint2d.hh>
namespace scribo
{
@@ -61,14 +61,12 @@ namespace scribo
namespace link
{
- /// Map each text object to its left bounding box neighbor
- /// if possible.
- /// Iterate to the right but link boxes to the left.
+ /// \brief Link objects with their left neighbor if exists.
///
/// \param[in] objects An object image.
/// \param[in] The maximum distance allowed to seach a neighbor object.
///
- /// \return an mln::util::array. Map a bounding box to its left neighbor.
+ /// \return Object links data.
//
template <typename L>
inline
@@ -76,40 +74,80 @@ namespace scribo
with_single_left_link(const object_image(L)& objects,
unsigned neighb_max_distance);
+
+ /// \overload
+ /// Max distance is set to mln_max(unsigned).
+ template <typename L>
+ inline
+ object_links<L>
+ with_single_left_link(const object_image(L)& objects);
+
+
# ifndef MLN_INCLUDE_ONLY
+
+ namespace internal
+ {
+
+ // Functor
+
+ template <typename L>
+ class single_left_functor
+ : public internal::link_ms_dmax_base<L, single_left_functor<L> >
+ {
+ typedef
+ internal::link_ms_dmax_base<L, single_left_functor<L> > super_;
+
+ public:
+ typedef mln_site(L) P;
+
+ single_left_functor(const object_image(L)& objects, unsigned dmax)
+ : super_(objects, dmax)
+ {
+ }
+
+ void compute_next_site_(P& p)
+ {
+ --p.col();
+ }
+
+ };
+
+ } // end of namespace scribo::primitive::link::internal
+
+
+
+ // Facades
+
template <typename L>
inline
object_links<L>
with_single_left_link(const object_image(L)& objects,
- unsigned neighb_max_distance)
+ unsigned neighb_max_distance)
{
trace::entering("scribo::primitive::link::with_single_left_link");
mln_precondition(objects.is_valid());
- object_links<L> left_link(objects, objects.nlabels().next());
- internal::init_link_array(left_link);
+ internal::single_left_functor<L>
+ functor(objects, neighb_max_distance);
- mln::util::array<mln_result(accu::center<mln_psite(L)>)>
- mass_centers = labeling::compute(accu::meta::center(),
- objects, objects.nlabels());
+ object_links<L> output = compute(functor);
- for_all_ncomponents(i, objects.nlabels())
- {
- unsigned midcol = (objects.bbox(i).pmax().col()
- - objects.bbox(i).pmin().col()) / 2;
- int dmax = midcol + neighb_max_distance;
- mln_site(L) c = mass_centers(i);
+ trace::exiting("scribo::primitive::link::with_single_left_link");
+ return output;
+ }
- /// Find a neighbor on the left
- internal::find_left_link(objects, left_link, i, dmax, c);
- }
- trace::exiting("scribo::primitive::link::with_single_left_link");
- return left_link;
+ template <typename L>
+ inline
+ object_links<L>
+ with_single_left_link(const object_image(L)& objects)
+ {
+ return with_single_left_link(objects, mln_max(unsigned));
}
+
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace scribo::primitive::link
diff --git a/scribo/primitive/link/with_single_left_link_dmax_ratio.hh b/scribo/primitive/link/with_single_left_link_dmax_ratio.hh
new file mode 100644
index 0000000..587fb6c
--- /dev/null
+++ b/scribo/primitive/link/with_single_left_link_dmax_ratio.hh
@@ -0,0 +1,167 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_PRIMITIVE_LINK_WITH_SINGLE_LEFT_LINK_DMAX_RATIO_HH
+# define SCRIBO_PRIMITIVE_LINK_WITH_SINGLE_LEFT_LINK_DMAX_RATIO_HH
+
+/// \file
+///
+/// Link text objects with their left neighbor according to a maximum
+/// distance.
+
+# include <mln/core/concept/image.hh>
+# include <mln/core/concept/neighborhood.hh>
+
+# include <mln/accu/center.hh>
+# include <mln/labeling/compute.hh>
+# include <mln/math/abs.hh>
+# include <mln/util/array.hh>
+
+# include <scribo/core/macros.hh>
+# include <scribo/core/object_image.hh>
+# include <scribo/core/object_links.hh>
+
+# include <scribo/primitive/link/internal/find_link.hh>
+# include <scribo/primitive/link/internal/link_ms_dmax_ratio_base.hh>
+
+# include <scribo/primitive/link/compute.hh>
+
+
+namespace scribo
+{
+
+ namespace primitive
+ {
+
+ namespace link
+ {
+
+ /*! \brief Link objects with their left neighbor if exists.
+
+ \param[in] objects An object image.
+ \param[in] dmax_ratio
+
+ \return Object links data.
+
+
+ Look for a neighbor until a maximum distance defined by :
+
+ dmax = w / 2 + dmax_ratio * max(h, w)
+
+ where w is the bounding box width and h the bounding box height.
+
+ */
+ template <typename L>
+ inline
+ object_links<L>
+ with_single_left_link_dmax_ratio(const object_image(L)& objects,
+ float dmax_ratio);
+
+
+ /// \overload
+ /// dmax_ratio is set to 3.
+ template <typename L>
+ inline
+ object_links<L>
+ with_single_left_link_dmax_ratio(const object_image(L)& objects);
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ namespace internal
+ {
+
+ // Functor
+
+ template <typename L>
+ class single_left_dmax_ratio_functor
+ : public internal::link_ms_dmax_ratio_base<L,
+ single_left_dmax_ratio_functor<L> >
+ {
+ typedef single_left_dmax_ratio_functor<L> self_t;
+ typedef internal::link_ms_dmax_ratio_base<L, self_t> super_;
+
+ public:
+ typedef mln_site(L) P;
+
+ single_left_dmax_ratio_functor(const object_image(L)& objects,
+ unsigned dmax)
+ : super_(objects, dmax)
+ {
+ }
+
+ void compute_next_site_(P& p)
+ {
+ --p.col();
+ }
+
+ };
+
+ } // end of namespace scribo::primitive::link::internal
+
+
+
+ // Facades
+
+ template <typename L>
+ inline
+ object_links<L>
+ with_single_left_link_dmax_ratio(const object_image(L)& objects,
+ float dmax_ratio)
+ {
+ trace::entering("scribo::primitive::link::with_single_left_link_dmax_ratio");
+
+ mln_precondition(objects.is_valid());
+
+ internal::single_left_dmax_ratio_functor<L>
+ functor(objects, dmax_ratio);
+
+ object_links<L> output = compute(functor);
+
+ trace::exiting("scribo::primitive::link::with_single_left_link_dmax_ratio");
+ return output;
+ }
+
+
+ template <typename L>
+ inline
+ object_links<L>
+ with_single_left_link_dmax_ratio(const object_image(L)& objects)
+ {
+ return with_single_left_link_dmax_ratio(objects, 3);
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace scribo::primitive::link
+
+ } // end of namespace scribo::primitive
+
+} // end of namespace scribo
+
+#endif // ! SCRIBO_PRIMITIVE_LINK_WITH_SINGLE_LEFT_LINK_DMAX_RATIO_HH
diff --git a/scribo/primitive/link/with_single_right_link.hh b/scribo/primitive/link/with_single_right_link.hh
index bd15698..236884b 100644
--- a/scribo/primitive/link/with_single_right_link.hh
+++ b/scribo/primitive/link/with_single_right_link.hh
@@ -29,28 +29,25 @@
/// \file
///
/// Link text objects with their right neighbor.
-///
-/// \todo Merge code with primitive::link::with_single_right_link.hh
+
# include <mln/core/concept/image.hh>
# include <mln/core/concept/neighborhood.hh>
# include <mln/accu/center.hh>
-
# include <mln/labeling/compute.hh>
-
# include <mln/math/abs.hh>
-
# include <mln/util/array.hh>
-# include <scribo/core/object_links.hh>
# include <scribo/core/macros.hh>
# include <scribo/core/object_image.hh>
-# include <scribo/primitive/internal/init_link_array.hh>
-# include <scribo/primitive/internal/find_right_link.hh>
+# include <scribo/core/object_links.hh>
+
+# include <scribo/primitive/link/internal/find_link.hh>
+# include <scribo/primitive/link/internal/link_ms_dmax_base.hh>
+
+# include <scribo/primitive/link/compute.hh>
-//FIXME: not generic.
-# include <mln/core/alias/dpoint2d.hh>
namespace scribo
{
@@ -61,22 +58,66 @@ namespace scribo
namespace link
{
- /// Map each text object to its right bounding box neighbor
- /// if possible.
- /// Iterate to the right but link boxes to the right.
+ /// \brief Link objects with their right neighbor if exists.
+ /// Lookup startup point is the object mass center.
///
/// \param[in] objects An object image.
/// \param[in] The maximum distance allowed to seach a neighbor object.
///
- /// \return an mln::util::array. Map a bounding box to its right neighbor.
+ /// \return Object links data.
+ //
template <typename L>
inline
object_links<L>
with_single_right_link(const object_image(L)& objects,
unsigned neighb_max_distance);
+
+ /// \overload
+ /// Max distance is set to mln_max(unsigned).
+ template <typename L>
+ inline
+ object_links<L>
+ with_single_right_link(const object_image(L)& objects);
+
+
+
# ifndef MLN_INCLUDE_ONLY
+
+ namespace internal
+ {
+
+ // Functor
+
+ template <typename L>
+ class single_right_functor
+ : public internal::link_ms_dmax_base<L, single_right_functor<L> >
+ {
+ typedef
+ internal::link_ms_dmax_base<L, single_right_functor<L> > super_;
+
+ public:
+ typedef mln_site(L) P;
+
+ single_right_functor(const object_image(L)& objects, unsigned dmax)
+ : super_(objects, dmax)
+ {
+ }
+
+ void compute_next_site_(P& p)
+ {
+ ++p.col();
+ }
+
+ };
+
+ } // end of namespace scribo::primitive::link::internal
+
+
+
+ // Facades
+
template <typename L>
inline
object_links<L>
@@ -87,28 +128,25 @@ namespace scribo
mln_precondition(objects.is_valid());
- object_links<L> right_link(objects, objects.nlabels().next());
- internal::init_link_array(right_link);
+ internal::single_right_functor<L>
+ functor(objects, neighb_max_distance);
- mln::util::array<mln_result(accu::center<mln_psite(L)>)>
- mass_centers = labeling::compute(accu::meta::center(),
- objects, objects.nlabels());
+ object_links<L> output = compute(functor);
- for_all_ncomponents(i, objects.nlabels())
- {
- unsigned midcol = (objects.bbox(i).pmax().col()
- - objects.bbox(i).pmin().col()) / 2;
- int dmax = midcol + neighb_max_distance;
- mln_site(L) c = mass_centers(i);
+ trace::exiting("scribo::primitive::link::with_single_right_link");
+ return output;
+ }
- /// Find a neighbor on the right
- internal::find_right_link(objects, right_link, i, dmax, c);
- }
- trace::exiting("scribo::primitive::link::with_single_right_link");
- return right_link;
+ template <typename L>
+ inline
+ object_links<L>
+ with_single_right_link(const object_image(L)& objects)
+ {
+ return with_single_right_link(objects, mln_max(unsigned));
}
+
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace scribo::primitive::link
diff --git a/scribo/primitive/link/with_single_right_link.hh b/scribo/primitive/link/with_single_right_link_bottom.hh
similarity index 55%
copy from scribo/primitive/link/with_single_right_link.hh
copy to scribo/primitive/link/with_single_right_link_bottom.hh
index bd15698..5976f22 100644
--- a/scribo/primitive/link/with_single_right_link.hh
+++ b/scribo/primitive/link/with_single_right_link_bottom.hh
@@ -23,34 +23,31 @@
// 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_HH
-# define SCRIBO_PRIMITIVE_LINK_WITH_SINGLE_RIGHT_LINK_HH
+#ifndef SCRIBO_PRIMITIVE_LINK_WITH_SINGLE_RIGHT_LINK_BOTTOM_HH
+# define SCRIBO_PRIMITIVE_LINK_WITH_SINGLE_RIGHT_LINK_BOTTOM_HH
/// \file
///
/// Link text objects with their right neighbor.
-///
-/// \todo Merge code with primitive::link::with_single_right_link.hh
+
# include <mln/core/concept/image.hh>
# include <mln/core/concept/neighborhood.hh>
# include <mln/accu/center.hh>
-
# include <mln/labeling/compute.hh>
-
# include <mln/math/abs.hh>
-
# include <mln/util/array.hh>
-# include <scribo/core/object_links.hh>
# include <scribo/core/macros.hh>
# include <scribo/core/object_image.hh>
-# include <scribo/primitive/internal/init_link_array.hh>
-# include <scribo/primitive/internal/find_right_link.hh>
+# include <scribo/core/object_links.hh>
+
+# include <scribo/primitive/link/internal/find_link.hh>
+# include <scribo/primitive/link/internal/link_center_dmax_base.hh>
+
+# include <scribo/primitive/link/compute.hh>
-//FIXME: not generic.
-# include <mln/core/alias/dpoint2d.hh>
namespace scribo
{
@@ -61,54 +58,98 @@ namespace scribo
namespace link
{
- /// Map each text object to its right bounding box neighbor
- /// if possible.
- /// Iterate to the right but link boxes to the right.
+ /// \brief Link objects with their right neighbor if exists.
+ /// Lookup startup point is the object bottom center.
///
/// \param[in] objects An object image.
/// \param[in] The maximum distance allowed to seach a neighbor object.
///
- /// \return an mln::util::array. Map a bounding box to its right neighbor.
+ /// \return Object links data.
+ //
template <typename L>
inline
object_links<L>
- with_single_right_link(const object_image(L)& objects,
+ with_single_right_link_bottom(const object_image(L)& objects,
unsigned neighb_max_distance);
+
+ /// \overload
+ /// Max distance is set to mln_max(unsigned).
+ template <typename L>
+ inline
+ object_links<L>
+ with_single_right_link_bottom(const object_image(L)& objects);
+
+
+
# ifndef MLN_INCLUDE_ONLY
+
+ namespace internal
+ {
+
+ // Functor
+
+ template <typename L>
+ class single_right_bottom_functor
+ : public link_center_dmax_base<L,
+ single_right_bottom_functor<L> >
+ {
+ typedef
+ link_center_dmax_base<L, single_right_bottom_functor<L> >
+ super_;
+
+ public:
+ typedef mln_site(L) P;
+
+ single_right_bottom_functor(const object_image(L)& objects,
+ unsigned dmax)
+ : super_(objects, dmax, 2)
+ {
+ }
+
+ void compute_next_site_(P& p)
+ {
+ ++p.col();
+ }
+
+ };
+
+ } // end of namespace scribo::primitive::link::internal
+
+
+
+ // Facades
+
template <typename L>
inline
object_links<L>
- with_single_right_link(const object_image(L)& objects,
- unsigned neighb_max_distance)
+ with_single_right_link_bottom(const object_image(L)& objects,
+ unsigned neighb_max_distance)
{
- trace::entering("scribo::primitive::link::with_single_right_link");
+ trace::entering("scribo::primitive::link::with_single_right_link_bottom");
mln_precondition(objects.is_valid());
- object_links<L> right_link(objects, objects.nlabels().next());
- internal::init_link_array(right_link);
+ internal::single_right_bottom_functor<L>
+ functor(objects, neighb_max_distance);
- mln::util::array<mln_result(accu::center<mln_psite(L)>)>
- mass_centers = labeling::compute(accu::meta::center(),
- objects, objects.nlabels());
+ object_links<L> output = compute(functor);
- for_all_ncomponents(i, objects.nlabels())
- {
- unsigned midcol = (objects.bbox(i).pmax().col()
- - objects.bbox(i).pmin().col()) / 2;
- int dmax = midcol + neighb_max_distance;
- mln_site(L) c = mass_centers(i);
+ trace::exiting("scribo::primitive::link::with_single_right_link_bottom");
+ return output;
+ }
- /// Find a neighbor on the right
- internal::find_right_link(objects, right_link, i, dmax, c);
- }
- trace::exiting("scribo::primitive::link::with_single_right_link");
- return right_link;
+ template <typename L>
+ inline
+ object_links<L>
+ with_single_right_link_bottom(const object_image(L)& objects)
+ {
+ return with_single_right_link_bottom(objects, mln_max(unsigned));
}
+
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace scribo::primitive::link
@@ -117,4 +158,4 @@ namespace scribo
} // end of namespace scribo
-#endif // ! SCRIBO_PRIMITIVE_LINK_WITH_SINGLE_RIGHT_LINK_HH
+#endif // ! SCRIBO_PRIMITIVE_LINK_WITH_SINGLE_RIGHT_LINK_BOTTOM_HH
diff --git a/scribo/primitive/link/with_single_right_link_dmax_ratio.hh b/scribo/primitive/link/with_single_right_link_dmax_ratio.hh
new file mode 100644
index 0000000..ac6ef31
--- /dev/null
+++ b/scribo/primitive/link/with_single_right_link_dmax_ratio.hh
@@ -0,0 +1,167 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_PRIMITIVE_LINK_WITH_SINGLE_RIGHT_LINK_DMAX_RATIO_HH
+# define SCRIBO_PRIMITIVE_LINK_WITH_SINGLE_RIGHT_LINK_DMAX_RATIO_HH
+
+/// \file
+///
+/// Link text objects with their right neighbor according to a maximum
+/// distance.
+
+# include <mln/core/concept/image.hh>
+# include <mln/core/concept/neighborhood.hh>
+
+# include <mln/accu/center.hh>
+# include <mln/labeling/compute.hh>
+# include <mln/math/abs.hh>
+# include <mln/util/array.hh>
+
+# include <scribo/core/macros.hh>
+# include <scribo/core/object_image.hh>
+# include <scribo/core/object_links.hh>
+
+# include <scribo/primitive/link/internal/find_link.hh>
+# include <scribo/primitive/link/internal/link_ms_dmax_ratio_base.hh>
+
+# include <scribo/primitive/link/compute.hh>
+
+
+namespace scribo
+{
+
+ namespace primitive
+ {
+
+ namespace link
+ {
+
+ /*! \brief Link objects with their right neighbor if exists.
+
+ \param[in] objects An object image.
+ \param[in] dmax_ratio
+
+ \return Object links data.
+
+
+ Look for a neighbor until a maximum distance defined by :
+
+ dmax = w / 2 + dmax_ratio * max(h, w)
+
+ where w is the bounding box width and h the bounding box height.
+
+ */
+ template <typename L>
+ inline
+ object_links<L>
+ with_single_right_link_dmax_ratio(const object_image(L)& objects,
+ float dmax_ratio);
+
+
+ /// \overload
+ /// dmax_ratio is set to 3.
+ template <typename L>
+ inline
+ object_links<L>
+ with_single_right_link_dmax_ratio(const object_image(L)& objects);
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ namespace internal
+ {
+
+ // Functor
+
+ template <typename L>
+ class single_right_dmax_ratio_functor
+ : public link_ms_dmax_ratio_base<L,
+ single_right_dmax_ratio_functor<L> >
+ {
+ typedef single_right_dmax_ratio_functor<L> self_t;
+ typedef link_ms_dmax_ratio_base<L, self_t> super_;
+
+ public:
+ typedef mln_site(L) P;
+
+ single_right_dmax_ratio_functor(const object_image(L)& objects,
+ unsigned dmax)
+ : super_(objects, dmax)
+ {
+ }
+
+ void compute_next_site_(P& p)
+ {
+ ++p.col();
+ }
+
+ };
+
+ } // end of namespace scribo::primitive::link::internal
+
+
+
+ // Facades
+
+ template <typename L>
+ inline
+ object_links<L>
+ with_single_right_link_dmax_ratio(const object_image(L)& objects,
+ float dmax_ratio)
+ {
+ trace::entering("scribo::primitive::link::with_single_right_link_dmax_ratio");
+
+ mln_precondition(objects.is_valid());
+
+ internal::single_right_dmax_ratio_functor<L>
+ functor(objects, dmax_ratio);
+
+ object_links<L> output = compute(functor);
+
+ trace::exiting("scribo::primitive::link::with_single_right_link_dmax_ratio");
+ return output;
+ }
+
+
+ template <typename L>
+ inline
+ object_links<L>
+ with_single_right_link_dmax_ratio(const object_image(L)& objects)
+ {
+ return with_single_right_link_dmax_ratio(objects, 3);
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace scribo::primitive::link
+
+ } // end of namespace scribo::primitive
+
+} // end of namespace scribo
+
+#endif // ! SCRIBO_PRIMITIVE_LINK_WITH_SINGLE_RIGHT_LINK_DMAX_RATIO_HH
diff --git a/scribo/primitive/link/with_single_right_link.hh b/scribo/primitive/link/with_single_right_link_top.hh
similarity index 57%
copy from scribo/primitive/link/with_single_right_link.hh
copy to scribo/primitive/link/with_single_right_link_top.hh
index bd15698..13bb583 100644
--- a/scribo/primitive/link/with_single_right_link.hh
+++ b/scribo/primitive/link/with_single_right_link_top.hh
@@ -23,34 +23,31 @@
// 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_HH
-# define SCRIBO_PRIMITIVE_LINK_WITH_SINGLE_RIGHT_LINK_HH
+#ifndef SCRIBO_PRIMITIVE_LINK_WITH_SINGLE_RIGHT_LINK_TOP_HH
+# define SCRIBO_PRIMITIVE_LINK_WITH_SINGLE_RIGHT_LINK_TOP_HH
/// \file
///
/// Link text objects with their right neighbor.
-///
-/// \todo Merge code with primitive::link::with_single_right_link.hh
+
# include <mln/core/concept/image.hh>
# include <mln/core/concept/neighborhood.hh>
# include <mln/accu/center.hh>
-
# include <mln/labeling/compute.hh>
-
# include <mln/math/abs.hh>
-
# include <mln/util/array.hh>
-# include <scribo/core/object_links.hh>
# include <scribo/core/macros.hh>
# include <scribo/core/object_image.hh>
-# include <scribo/primitive/internal/init_link_array.hh>
-# include <scribo/primitive/internal/find_right_link.hh>
+# include <scribo/core/object_links.hh>
+
+# include <scribo/primitive/link/internal/find_link.hh>
+# include <scribo/primitive/link/internal/link_center_dmax_base.hh>
+
+# include <scribo/primitive/link/compute.hh>
-//FIXME: not generic.
-# include <mln/core/alias/dpoint2d.hh>
namespace scribo
{
@@ -61,54 +58,98 @@ namespace scribo
namespace link
{
- /// Map each text object to its right bounding box neighbor
- /// if possible.
- /// Iterate to the right but link boxes to the right.
+ /// \brief Link objects with their right neighbor if exists.
+ /// Lookup startup point is the object top center.
///
/// \param[in] objects An object image.
/// \param[in] The maximum distance allowed to seach a neighbor object.
///
- /// \return an mln::util::array. Map a bounding box to its right neighbor.
+ /// \return Object links data.
+ //
template <typename L>
inline
object_links<L>
- with_single_right_link(const object_image(L)& objects,
+ with_single_right_link_top(const object_image(L)& objects,
unsigned neighb_max_distance);
+
+ /// \overload
+ /// Max distance is set to mln_max(unsigned).
+ template <typename L>
+ inline
+ object_links<L>
+ with_single_right_link_top(const object_image(L)& objects);
+
+
+
# ifndef MLN_INCLUDE_ONLY
+
+ namespace internal
+ {
+
+ // Functor
+
+ template <typename L>
+ class single_right_top_functor
+ : public link_center_dmax_base<L,
+ single_right_top_functor<L> >
+ {
+ typedef
+ link_center_dmax_base<L, single_right_top_functor<L> >
+ super_;
+
+ public:
+ typedef mln_site(L) P;
+
+ single_right_top_functor(const object_image(L)& objects,
+ unsigned dmax)
+ : super_(objects, dmax, 0)
+ {
+ }
+
+ void compute_next_site_(P& p)
+ {
+ ++p.col();
+ }
+
+ };
+
+ } // end of namespace scribo::primitive::link::internal
+
+
+
+ // Facades
+
template <typename L>
inline
object_links<L>
- with_single_right_link(const object_image(L)& objects,
+ with_single_right_link_top(const object_image(L)& objects,
unsigned neighb_max_distance)
{
- trace::entering("scribo::primitive::link::with_single_right_link");
+ trace::entering("scribo::primitive::link::with_single_right_link_top");
mln_precondition(objects.is_valid());
- object_links<L> right_link(objects, objects.nlabels().next());
- internal::init_link_array(right_link);
+ internal::single_right_top_functor<L>
+ functor(objects, neighb_max_distance);
- mln::util::array<mln_result(accu::center<mln_psite(L)>)>
- mass_centers = labeling::compute(accu::meta::center(),
- objects, objects.nlabels());
+ object_links<L> output = compute(functor);
- for_all_ncomponents(i, objects.nlabels())
- {
- unsigned midcol = (objects.bbox(i).pmax().col()
- - objects.bbox(i).pmin().col()) / 2;
- int dmax = midcol + neighb_max_distance;
- mln_site(L) c = mass_centers(i);
+ trace::exiting("scribo::primitive::link::with_single_right_link_top");
+ return output;
+ }
- /// Find a neighbor on the right
- internal::find_right_link(objects, right_link, i, dmax, c);
- }
- trace::exiting("scribo::primitive::link::with_single_right_link");
- return right_link;
+ template <typename L>
+ inline
+ object_links<L>
+ with_single_right_link_top(const object_image(L)& objects)
+ {
+ return with_single_right_link_top(objects, mln_max(unsigned));
}
+
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace scribo::primitive::link
@@ -117,4 +158,4 @@ namespace scribo
} // end of namespace scribo
-#endif // ! SCRIBO_PRIMITIVE_LINK_WITH_SINGLE_RIGHT_LINK_HH
+#endif // ! SCRIBO_PRIMITIVE_LINK_WITH_SINGLE_RIGHT_LINK_TOP_HH
--
1.5.6.5
1
0
* debug/decision_image.hh: Fix precondition.
* filter/object_links_bbox_h_ratio.hh,
* filter/objects_thick.hh,
* primitive/internal/have_link_valid.hh,
* primitive/internal/is_link_valid.hh: Fix doc.
* filter/object_links_bbox_ratio.hh: Fix doc and invert ratio.
* filter/object_links_bottom_aligned.hh: Fix doc and use a float
angle value.
* filter/object_links_non_aligned.hh: Use absolute values.
* filter/object_links_non_aligned_simple.hh: Add special cases.
* filter/object_links_non_h_aligned.hh: Fix call to an underlying
routine.
* filter/objects_small.hh,
* filter/objects_thin.hh,
* filter/objects_v_thin.hh,
* primitive/extract/lines_discontinued.hh,
* primitive/extract/lines_h_single.hh,
* primitive/extract/lines_h_thick_and_single.hh,
* primitive/extract/lines_thick.hh,
* primitive/extract/lines_v_discontinued.hh,
* primitive/extract/lines_v_single.hh,
* primitive/extract/lines_v_thick_and_single.hh,
* primitive/internal/is_invalid_link.hh,
* src/multi_scale/find_lines.cc,
* src/primitive/group/group_from_rag.cc,
* src/table/rebuild_opening.cc,
* src/table/rebuild_rank.cc,
* text/clean.hh: Avoid warnings.
* primitive/internal/find_left_link.hh,
* primitive/internal/find_right_link.hh,
* primitive/internal/update_link_array.hh: Make the routine return
a value.
* src/binarization/sauvola.cc,
* src/binarization/sauvola_pgm.cc: Fix call to Sauvola's algorithm.
* src/primitive/group/group_from_graph.cc,
* src/primitive/group/group_from_several_graph.cc: Change
arguments values while calling with_several_graphes.
---
scribo/debug/decision_image.hh | 2 +-
scribo/filter/object_links_bbox_h_ratio.hh | 14 ++--
scribo/filter/object_links_bbox_ratio.hh | 31 ++++----
scribo/filter/object_links_bottom_aligned.hh | 33 +++++----
scribo/filter/object_links_non_aligned.hh | 6 +-
scribo/filter/object_links_non_aligned_simple.hh | 73 ++++++++++++++-----
scribo/filter/object_links_non_h_aligned.hh | 6 +-
scribo/filter/objects_small.hh | 4 +-
scribo/filter/objects_thick.hh | 2 +-
scribo/filter/objects_thin.hh | 5 +-
scribo/filter/objects_v_thin.hh | 3 +-
scribo/primitive/extract/lines_discontinued.hh | 3 +
scribo/primitive/extract/lines_h_single.hh | 4 +-
.../primitive/extract/lines_h_thick_and_single.hh | 4 +
scribo/primitive/extract/lines_thick.hh | 3 +
scribo/primitive/extract/lines_v_discontinued.hh | 3 +
scribo/primitive/extract/lines_v_single.hh | 4 +-
.../primitive/extract/lines_v_thick_and_single.hh | 4 +
scribo/primitive/internal/find_left_link.hh | 16 +++--
scribo/primitive/internal/find_right_link.hh | 18 +++--
scribo/primitive/internal/have_link_valid.hh | 3 +-
scribo/primitive/internal/is_invalid_link.hh | 9 ++-
scribo/primitive/internal/is_link_valid.hh | 3 +-
scribo/primitive/internal/update_link_array.hh | 18 +++--
scribo/primitive/link/merge_double_link.hh | 2 +-
scribo/src/binarization/sauvola.cc | 5 +-
scribo/src/binarization/sauvola_pgm.cc | 12 ++--
scribo/src/multi_scale/find_lines.cc | 3 +-
scribo/src/primitive/group/group_from_graph.cc | 2 +-
scribo/src/primitive/group/group_from_rag.cc | 2 +-
.../primitive/group/group_from_several_graph.cc | 2 +-
scribo/src/table/rebuild_opening.cc | 2 +-
scribo/src/table/rebuild_rank.cc | 4 +-
scribo/text/clean.hh | 1 +
34 files changed, 199 insertions(+), 107 deletions(-)
diff --git a/scribo/debug/decision_image.hh b/scribo/debug/decision_image.hh
index 447d3b0..34401ba 100644
--- a/scribo/debug/decision_image.hh
+++ b/scribo/debug/decision_image.hh
@@ -104,7 +104,7 @@ namespace scribo
mln_precondition(groups.is_valid());
mln_precondition(filtered_groups.is_valid());
mln_precondition(groups.size() == filtered_groups.size());
- mln_precondition(groups.objects_id() != filtered_groups.objects_id());
+ mln_precondition(groups.objects_id_() != filtered_groups.objects_id_());
/// Fixme: check that objects has been computed from input.
image2d<value::rgb8>
diff --git a/scribo/filter/object_links_bbox_h_ratio.hh b/scribo/filter/object_links_bbox_h_ratio.hh
index 6ced8e6..e030a86 100644
--- a/scribo/filter/object_links_bbox_h_ratio.hh
+++ b/scribo/filter/object_links_bbox_h_ratio.hh
@@ -28,8 +28,10 @@
/// \file
///
-/// Invalidate links between two objects with too different height or
-/// width.
+/// Invalidate links between two objects with too different height.
+///
+/// \todo rename to object_links_bbox_v_ratio (v for vertical) to be
+/// consistent with other routine names.
# include <mln/util/array.hh>
@@ -52,7 +54,7 @@ namespace scribo
\param[in] objects An object image.
\param[in] links Link objects information.
- \param[in] min_h_ratio The minimum height ratio of two linked
+ \param[in] max_h_ratio The maximum height ratio of two linked
bounding boxes.
\result A filtered object link information.
@@ -61,7 +63,7 @@ namespace scribo
object_links<L>
object_links_bbox_h_ratio(const object_image(L)& objects,
const object_links<L>& links,
- float min_h_ratio);
+ float max_h_ratio);
# ifndef MLN_INCLUDE_ONLY
@@ -71,7 +73,7 @@ namespace scribo
object_links<L>
object_links_bbox_h_ratio(const object_image(L)& objects,
const object_links<L>& links,
- float min_h_ratio)
+ float max_h_ratio)
{
trace::entering("scribo::filter::object_links_bbox_h_ratio");
@@ -79,7 +81,7 @@ namespace scribo
mln_precondition(links.is_valid());
object_links<L>
- output = object_links_bbox_ratio(objects, links, 0, min_h_ratio);
+ output = object_links_bbox_ratio(objects, links, 0, max_h_ratio);
trace::exiting("scribo::filter::object_links_bbox_h_ratio");
return output;
diff --git a/scribo/filter/object_links_bbox_ratio.hh b/scribo/filter/object_links_bbox_ratio.hh
index 3cd0c7e..2d9e507 100644
--- a/scribo/filter/object_links_bbox_ratio.hh
+++ b/scribo/filter/object_links_bbox_ratio.hh
@@ -52,7 +52,7 @@ namespace scribo
\param[in] objects An object image.
\param[in] links Link objects information.
\param[in] dim The dimension to use to compare bbox length.
- \param[in] min_ratio The minimum length ratio of two linked
+ \param[in] max_ratio The maximum length ratio of two linked
bounding boxes.
\result A filtered object link information.
@@ -62,7 +62,7 @@ namespace scribo
object_links_bbox_ratio(const object_image(L)& objects,
const object_links<L>& links,
unsigned dim,
- float min_ratio);
+ float max_ratio);
# ifndef MLN_INCLUDE_ONLY
@@ -73,7 +73,7 @@ namespace scribo
object_links_bbox_ratio(const object_image(L)& objects,
const object_links<L>& links,
unsigned dim,
- float min_ratio)
+ float max_ratio)
{
trace::entering("scribo::filter::object_links_bbox_ratio");
@@ -82,18 +82,19 @@ namespace scribo
object_links<L> output(links);
for (unsigned i = 1; i < links.size(); ++i)
- {
- float
- lmin = objects.bbox(i).pmax()[dim] - objects.bbox(i).pmin()[dim],
- lmax = objects.bbox(links(i)).pmax()[dim]
- - objects.bbox(links(i)).pmin()[dim];
-
- if (lmin > lmax)
- std::swap(lmin, lmax);
-
- if (lmin / lmax < min_ratio)
- output(i) = i;
- }
+ if (links[i] != i)
+ {
+ float
+ lmin = objects.bbox(i).pmax()[dim] - objects.bbox(i).pmin()[dim],
+ lmax = objects.bbox(links(i)).pmax()[dim]
+ - objects.bbox(links(i)).pmin()[dim];
+
+ if (lmin > lmax)
+ std::swap(lmin, lmax);
+
+ if ((lmax/ lmin) > max_ratio)
+ output(i) = i;
+ }
trace::exiting("scribo::filter::object_links_bbox_ratio");
return output;
diff --git a/scribo/filter/object_links_bottom_aligned.hh b/scribo/filter/object_links_bottom_aligned.hh
index 0846203..d950a6e 100644
--- a/scribo/filter/object_links_bottom_aligned.hh
+++ b/scribo/filter/object_links_bottom_aligned.hh
@@ -53,31 +53,37 @@ namespace scribo
\param[in] objects An object image.
\param[in] links Object links information.
- \param[in] dim Choose the dimension on which applying the
- filter.
- \param[in] max_delta Maximum delta.
+ \param[in] max_alpha Maximum angle value (degrees).
\verbatim
+
------
| |
------ | |
| | | |
| x------------x |
- | | | | v
- ------ ~ ~ ~ |~ ~ | ~ ~ ~
- object1 | | | => delta, must be < to max_delta
- ------ ~ ~ ~
- object2 ^
-
+ | | | |
+ ------~ ~ ~ ~| ~ ~| ~ ~
+ object1 ~ | | ^
+ ~ | | |
+ ~------ |
+ object2 | Alpha
+ ~ |
+ ~ |
+ ~ |
+ ~ v
+ ~
\endverbatim
+ The angle between the two bottoms must be lower than \p max_alpha.
+
*/
template <typename L>
object_links<L>
object_links_bottom_aligned(const object_image(L)& objects,
const object_links<L>& links,
- unsigned max_delta);
+ float max_alpha);
# ifndef MLN_INCLUDE_ONLY
@@ -87,7 +93,7 @@ namespace scribo
object_links<L>
object_links_bottom_aligned(const object_image(L)& objects,
const object_links<L>& links,
- unsigned max_delta)
+ float max_alpha)
{
trace::entering("scribo::filter::object_links_bottom_aligned");
@@ -96,8 +102,7 @@ namespace scribo
object_links<L>
output = object_links_non_aligned_simple(objects, links,
- 1, 1,
- max_delta);
+ 1, max_alpha);
trace::exiting("scribo::filter::object_links_bottom_aligned");
return output;
@@ -112,4 +117,4 @@ namespace scribo
} // end of namespace scribo
-#endif // ! SCRIBO_FILTER_OBJECT_LINKS_NON_ALIGNED_SIMPLE_HH
+#endif // ! SCRIBO_FILTER_OBJECT_LINKS_BOTTOM_ALIGNED_HH
diff --git a/scribo/filter/object_links_non_aligned.hh b/scribo/filter/object_links_non_aligned.hh
index 5d7e99a..b81a0ab 100644
--- a/scribo/filter/object_links_non_aligned.hh
+++ b/scribo/filter/object_links_non_aligned.hh
@@ -31,6 +31,7 @@
/// Invalidate links between two non aligned objects.
+# include <mln/math/abs.hh>
# include <mln/util/array.hh>
# include <scribo/core/macros.hh>
@@ -115,9 +116,10 @@ namespace scribo
hmax = i;
}
- if ((bboxes[hmin].pmin()[dim] - (float)bboxes[hmax].pmin()[dim]) > max_delta
- || (bboxes[hmin].pmax()[dim] - (float) bboxes[hmax].pmax()[dim]) > max_delta)
+ if (static_cast<unsigned>(math::abs((bboxes[hmin].pmin()[dim] - bboxes[hmax].pmin()[dim]))) > max_delta
+ || static_cast<unsigned>(math::abs((bboxes[hmin].pmax()[dim] - bboxes[hmax].pmax()[dim]))) > max_delta)
output[i] = i;
+
}
trace::exiting("scribo::filter::object_links_non_aligned");
diff --git a/scribo/filter/object_links_non_aligned_simple.hh b/scribo/filter/object_links_non_aligned_simple.hh
index e302fcf..032b4d0 100644
--- a/scribo/filter/object_links_non_aligned_simple.hh
+++ b/scribo/filter/object_links_non_aligned_simple.hh
@@ -32,6 +32,8 @@
# include <mln/util/array.hh>
+# include <mln/math/abs.hh>
+# include <mln/math/pi.hh>
# include <scribo/core/macros.hh>
# include <scribo/core/object_links.hh>
@@ -50,9 +52,7 @@ namespace scribo
\param[in] objects An object image.
\param[in] links Object links information.
- \param[in] dim Choose the dimension on which applying the
- filter.
- \param[in] max_delta Maximum delta.
+ \param[in] max_alpha Maximum angle value (degrees).
Exemple with dim == 1 and edge == 1 (bottom
@@ -65,22 +65,33 @@ namespace scribo
------ | |
| | | |
| x------------x |
- | | | | v
- ------ ~ ~ ~ |~ ~ | ~ ~ ~
- object1 | | | => delta, must be < to max_delta
- ------ ~ ~ ~
- object2 ^
-
+ | | | |
+ ------~ ~ ~ ~| ~ ~| ~ ~
+ object1 ~ | | ^
+ ~ | | |
+ ~------ |
+ object2 | Alpha
+ ~ |
+ ~ |
+ ~ |
+ ~ v
+ ~
\endverbatim
+ The angle between the two bottoms must be lower than \p alpha.
+
+ edge values :
+ 0 = top
+ 1 = bottom
+ 2 = center
+
*/
template <typename L>
object_links<L>
object_links_non_aligned_simple(const object_image(L)& objects,
const object_links<L>& links,
- unsigned dim,
unsigned edge,
- unsigned max_delta);
+ float max_alpha);
# ifndef MLN_INCLUDE_ONLY
@@ -90,9 +101,8 @@ namespace scribo
object_links<L>
object_links_non_aligned_simple(const object_image(L)& objects,
const object_links<L>& links,
- unsigned dim,
unsigned edge,
- unsigned max_delta)
+ float max_alpha)
{
trace::entering("scribo::filter::object_links_non_aligned_simple");
@@ -102,34 +112,59 @@ namespace scribo
typedef typename object_image(L)::bbox_t bbox_t;
const mln::util::array<bbox_t>& bboxes = objects.bboxes();
object_links<L> output(links);
- unsigned delta;
+ float dr, dc;
+ float max_alpha_rad = (max_alpha / 180.0f) * math::pi;
+
+ // Top
if (edge == 0)
{
for_all_components(i, objects.bboxes())
if (links[i] != i)
{
- delta = bboxes[i].pmin()[dim] - bboxes[i].pmin()[dim];
+ dr = math::abs(bboxes[i].pmin().row()
+ - bboxes[links[i]].pmin().row());
+ dc = math::abs(bboxes[i].center().col()
+ - bboxes[links[i]].center().col());
- if (delta > max_delta)
+ if (std::atan(dr / dc) > max_alpha_rad)
output[i] = i;
}
}
+ // Bottom
else if (edge == 1)
for_all_components(i, objects.bboxes())
{
if (links[i] != i)
{
- delta = bboxes[i].pmax()[dim] - bboxes[i].pmax()[dim];
+ dr = math::abs(bboxes[i].pmax().row()
+ - bboxes[links[i]].pmax().row());
+ dc = math::abs(bboxes[i].center().col()
+ - bboxes[links[i]].center().col());
+
+ if (std::atan(dr / dc) > max_alpha_rad)
+ output[i] = i;
+ }
+ }
+ // Center
+ else if (edge == 2)
+ for_all_components(i, objects.bboxes())
+ {
+ if (links[i] != i)
+ {
+ dr = math::abs(bboxes[i].center().row()
+ - bboxes[links[i]].center().row());
+ dc = math::abs(bboxes[i].center().col()
+ - bboxes[links[i]].center().col());
- if (delta > max_delta)
+ if (std::atan(dr / dc) > max_alpha_rad)
output[i] = i;
}
}
else
{
- trace::warning("Invalid edge value...");
+ trace::warning("Invalid edge value... Aborting computation.");
trace::exiting("scribo::filter::object_links_non_aligned_simple");
return output;
}
diff --git a/scribo/filter/object_links_non_h_aligned.hh b/scribo/filter/object_links_non_h_aligned.hh
index cae84a9..8216316 100644
--- a/scribo/filter/object_links_non_h_aligned.hh
+++ b/scribo/filter/object_links_non_h_aligned.hh
@@ -76,7 +76,7 @@ namespace scribo
object_links<L>
object_links_non_h_aligned(const object_image(L)& objects,
const object_links<L>& links,
- float ratio);
+ float max_delta);
# ifndef MLN_INCLUDE_ONLY
@@ -85,14 +85,14 @@ namespace scribo
object_links<L>
object_links_non_h_aligned(const object_image(L)& objects,
const object_links<L>& links,
- float ratio)
+ float max_delta)
{
trace::entering("scribo::filter::object_links_non_h_aligned");
mln_precondition(objects.is_valid());
object_links<L>
- output = object_links_non_aligned(objects, links, 1, ratio);
+ output = object_links_non_aligned(objects, links, 0, max_delta);
trace::exiting("scribo::filter::object_links_non_h_aligned");
return output;
diff --git a/scribo/filter/objects_small.hh b/scribo/filter/objects_small.hh
index cb65136..d1a0cf3 100644
--- a/scribo/filter/objects_small.hh
+++ b/scribo/filter/objects_small.hh
@@ -34,6 +34,7 @@
# include <mln/core/concept/image.hh>
# include <mln/core/concept/neighborhood.hh>
# include <mln/core/concept/function.hh>
+# include <mln/core/image/dmorph/image_if.hh>
# include <mln/labeling/blobs.hh>
# include <mln/labeling/relabel.hh>
@@ -110,6 +111,7 @@ namespace scribo
mln_precondition(input.is_valid());
mln_precondition(nbh.is_valid());
+ (void) label_type;
V nlabels;
typedef mln_ch_value(I,V) lbl_t;
@@ -120,7 +122,7 @@ namespace scribo
lbl.relabel(fv2b);
mln_concrete(I) output = duplicate(input);
- data::fill((output | pw::value(lbl) == pw::cst(literal::zero)).rw(),
+ data::fill((output | (pw::value(lbl) == pw::cst(literal::zero))).rw(),
false);
trace::exiting("scribo::filter::objects_small");
diff --git a/scribo/filter/objects_thick.hh b/scribo/filter/objects_thick.hh
index 519bd8c..5fe884e 100644
--- a/scribo/filter/objects_thick.hh
+++ b/scribo/filter/objects_thick.hh
@@ -66,7 +66,7 @@ namespace scribo
unsigned max_thickness);
- /// Remove lines of text thicker or equal to \p max_thickness.
+ /// Remove objects thicker or equal to \p max_thickness.
///
/// \param[in] objects An object image.
/// \param[in] max_thickness The maximum thickness value.
diff --git a/scribo/filter/objects_thin.hh b/scribo/filter/objects_thin.hh
index 510a64f..e9c869b 100644
--- a/scribo/filter/objects_thin.hh
+++ b/scribo/filter/objects_thin.hh
@@ -32,6 +32,8 @@
# include <mln/core/concept/image.hh>
# include <mln/core/concept/neighborhood.hh>
+# include <mln/core/image/dmorph/image_if.hh>
+# include <mln/pw/all.hh>
# include <mln/util/array.hh>
@@ -140,6 +142,7 @@ namespace scribo
mln_precondition(input.is_valid());
mln_precondition(nbh.is_valid());
+ (void) label_type;
V nlabels;
typedef mln_ch_value(I,V) lbl_t;
@@ -151,7 +154,7 @@ namespace scribo
objects.relabel(fv2b);
mln_concrete(I) output = duplicate(input);
- data::fill((output | pw::value(objects) == pw::cst(literal::zero)).rw(),
+ data::fill((output | (pw::value(objects) == pw::cst(literal::zero))).rw(),
false);
trace::exiting("scribo::filter::objects_thin");
diff --git a/scribo/filter/objects_v_thin.hh b/scribo/filter/objects_v_thin.hh
index bcf6726..6564d30 100644
--- a/scribo/filter/objects_v_thin.hh
+++ b/scribo/filter/objects_v_thin.hh
@@ -137,6 +137,7 @@ namespace scribo
{
trace::entering("scribo::filter::objects_v_thin");
+ (void) label_type;
const I& input = exact(input_);
const N& nbh = exact(nbh_);
@@ -153,7 +154,7 @@ namespace scribo
objects.relabel(fv2b);
mln_concrete(I) output = duplicate(input);
- data::fill((output | pw::value(objects) == pw::cst(literal::zero)).rw(),
+ data::fill((output | (pw::value(objects) == pw::cst(literal::zero))).rw(),
false);
trace::exiting("scribo::filter::objects_v_thin");
diff --git a/scribo/primitive/extract/lines_discontinued.hh b/scribo/primitive/extract/lines_discontinued.hh
index 8ced7e3..2ea7de6 100644
--- a/scribo/primitive/extract/lines_discontinued.hh
+++ b/scribo/primitive/extract/lines_discontinued.hh
@@ -98,6 +98,9 @@ namespace scribo
mln_precondition(exact(nbh).is_valid());
mln_precondition(exact(win).is_valid());
+ (void) input;
+ (void) nbh;
+ (void) win;
(void) nlines;
(void) rank_k;
}
diff --git a/scribo/primitive/extract/lines_h_single.hh b/scribo/primitive/extract/lines_h_single.hh
index 9b6d7c4..4e9cb74 100644
--- a/scribo/primitive/extract/lines_h_single.hh
+++ b/scribo/primitive/extract/lines_h_single.hh
@@ -108,8 +108,8 @@ namespace scribo
is_line_h_single(const object_image(L)& objects,
float w_h_ratio, unsigned min_line_length)
- : objects_(objects),
- w_h_ratio_(w_h_ratio), min_line_length_(min_line_length)
+ : w_h_ratio_(w_h_ratio), min_line_length_(min_line_length),
+ objects_(objects)
{
}
diff --git a/scribo/primitive/extract/lines_h_thick_and_single.hh b/scribo/primitive/extract/lines_h_thick_and_single.hh
index 969acf5..3b3185b 100644
--- a/scribo/primitive/extract/lines_h_thick_and_single.hh
+++ b/scribo/primitive/extract/lines_h_thick_and_single.hh
@@ -104,6 +104,10 @@ namespace scribo
mln_precondition(exact(input).is_valid());
mln_precondition(exact(nbh).is_valid());
+ (void) input;
+ (void) nbh;
+ (void) min_line_length;
+ (void) h_w_ratio;
(void) nlines;
}
diff --git a/scribo/primitive/extract/lines_thick.hh b/scribo/primitive/extract/lines_thick.hh
index f54e9b0..230b63c 100644
--- a/scribo/primitive/extract/lines_thick.hh
+++ b/scribo/primitive/extract/lines_thick.hh
@@ -93,6 +93,9 @@ namespace scribo
mln_precondition(exact(nbh).is_valid());
mln_precondition(exact(win).is_valid());
+ (void) input;
+ (void) nbh;
+ (void) win;
(void) nlines;
}
diff --git a/scribo/primitive/extract/lines_v_discontinued.hh b/scribo/primitive/extract/lines_v_discontinued.hh
index 8463111..8f64472 100644
--- a/scribo/primitive/extract/lines_v_discontinued.hh
+++ b/scribo/primitive/extract/lines_v_discontinued.hh
@@ -87,6 +87,9 @@ namespace scribo
mln_precondition(exact(nbh).is_valid());
mln_precondition(line_length % 2);
+ (void) input;
+ (void) nbh;
+ (void) line_length;
(void) nlines;
(void) rank_k;
}
diff --git a/scribo/primitive/extract/lines_v_single.hh b/scribo/primitive/extract/lines_v_single.hh
index f700dd0..74391f6 100644
--- a/scribo/primitive/extract/lines_v_single.hh
+++ b/scribo/primitive/extract/lines_v_single.hh
@@ -107,8 +107,8 @@ namespace scribo
is_line_v_single(const object_image(L)& objects,
float h_w_ratio, unsigned min_line_length)
- : objects_(objects),
- h_w_ratio_(h_w_ratio), min_line_length_(min_line_length)
+ : h_w_ratio_(h_w_ratio), min_line_length_(min_line_length),
+ objects_(objects)
{
}
diff --git a/scribo/primitive/extract/lines_v_thick_and_single.hh b/scribo/primitive/extract/lines_v_thick_and_single.hh
index 7ddd25f..eba25ab 100644
--- a/scribo/primitive/extract/lines_v_thick_and_single.hh
+++ b/scribo/primitive/extract/lines_v_thick_and_single.hh
@@ -103,6 +103,10 @@ namespace scribo
mln_precondition(exact(input).is_valid());
mln_precondition(exact(nbh).is_valid());
+ (void) input;
+ (void) nbh;
+ (void) min_line_length;
+ (void) h_w_ratio;
(void) nlines;
}
diff --git a/scribo/primitive/internal/find_left_link.hh b/scribo/primitive/internal/find_left_link.hh
index 243ac99..4f30e36 100644
--- a/scribo/primitive/internal/find_left_link.hh
+++ b/scribo/primitive/internal/find_left_link.hh
@@ -29,12 +29,15 @@
/// \file
///
/// Find the left neighbor of a line of text if exists.
+///
+/// \todo To be deleted.
# include <mln/core/concept/image.hh>
# include <mln/math/abs.hh>
# include <mln/util/array.hh>
+# include <mln/util/couple.hh>
# include <scribo/core/object_image.hh>
# include <scribo/primitive/internal/update_link_array.hh>
@@ -61,22 +64,22 @@ namespace scribo
/// \param c The lookup start point.
//
template <typename L>
- void
+ mln::util::couple<bool, mln_site(L)>
find_left_link(const object_image(L)& objects,
mln::util::array<unsigned>& left_link,
unsigned current_comp,
- int dmax,
+ float dmax,
const mln_site(L)& c);
# ifndef MLN_INCLUDE_ONLY
template <typename L>
- void
+ mln::util::couple<bool, mln_site(L)>
find_left_link(const object_image(L)& objects,
mln::util::array<unsigned>& left_link,
unsigned current_comp,
- int dmax,
+ float dmax,
const mln_site(L)& c)
{
///FIXME: the following code is not generic...
@@ -87,7 +90,10 @@ namespace scribo
current_comp, c, dmax))
--p.col();
- update_link_array(objects, left_link, p, c, current_comp, dmax);
+ bool
+ b = update_link_array(objects, left_link, p, c, current_comp, dmax);
+
+ return mln::make::couple(b, p);
}
# endif // MLN_INCLUDE_ONLY
diff --git a/scribo/primitive/internal/find_right_link.hh b/scribo/primitive/internal/find_right_link.hh
index 1964a6d..09e60f9 100644
--- a/scribo/primitive/internal/find_right_link.hh
+++ b/scribo/primitive/internal/find_right_link.hh
@@ -29,12 +29,15 @@
/// \file
///
/// Find the right neighbor of a line of text if exists.
+///
+/// \todo To be deleted.
# include <mln/core/concept/image.hh>
# include <mln/math/abs.hh>
# include <mln/util/array.hh>
+# include <mln/util/couple.hh>
# include <scribo/core/object_image.hh>
# include <scribo/primitive/internal/update_link_array.hh>
@@ -61,25 +64,25 @@ namespace scribo
/// \param c The lookup start point.
//
template <typename L>
- void
+ mln::util::couple<bool, mln_site(L)>
find_right_link(const object_image(L)& objects,
mln::util::array<unsigned>& right_link,
unsigned current_comp,
- int dmax,
+ float dmax,
const mln_site(L)& c);
# ifndef MLN_INCLUDE_ONLY
template <typename L>
- void
+ mln::util::couple<bool, mln_site(L)>
find_right_link(const object_image(L)& objects,
mln::util::array<unsigned>& right_link,
unsigned current_comp,
- int dmax,
+ float dmax,
const mln_site(L)& c)
{
- ///FIXME: the following code is not generic...
+ /// FIXME: the following code is not generic...
/// First site on the right of the central site
mln_site(L) p = c + mln::right;
@@ -87,7 +90,10 @@ namespace scribo
current_comp, c, dmax))
++p.col();
- update_link_array(objects, right_link, p, c, current_comp, dmax);
+ bool
+ b = update_link_array(objects, right_link, p, c, current_comp, dmax);
+
+ return mln::make::couple(b, p);
}
# endif // MLN_INCLUDE_ONLY
diff --git a/scribo/primitive/internal/have_link_valid.hh b/scribo/primitive/internal/have_link_valid.hh
index 3425745..accf7ff 100644
--- a/scribo/primitive/internal/have_link_valid.hh
+++ b/scribo/primitive/internal/have_link_valid.hh
@@ -29,7 +29,8 @@
/// \file
///
/// Tells whether a component have at least one valid link
-
+///
+/// \todo To be deleted ?.
# include <mln/util/array.hh>
# include <mln/util/couple.hh>
diff --git a/scribo/primitive/internal/is_invalid_link.hh b/scribo/primitive/internal/is_invalid_link.hh
index dbabe72..e6343fd 100644
--- a/scribo/primitive/internal/is_invalid_link.hh
+++ b/scribo/primitive/internal/is_invalid_link.hh
@@ -29,7 +29,8 @@
/// \file
///
/// Check whether an objects link is invalid or not.
-
+///
+/// \todo To be deleted.
# include <mln/math/abs.hh>
# include <mln/literal/zero.hh>
@@ -64,7 +65,7 @@ namespace scribo
const mln_site(L)& p,
unsigned current_comp,
const mln_site(L)& c,
- int dmax);
+ float dmax);
# ifndef MLN_INCLUDE_ONLY
@@ -76,13 +77,13 @@ namespace scribo
const mln_site(L)& p,
unsigned current_comp,
const mln_site(L)& c,
- int dmax)
+ float dmax)
{
return (objects.domain().has(p) // Not outside image domain
&& (objects(p) == literal::zero // Is the background
|| objects(p) == current_comp // Is the current component
|| link_array[objects(p)] == current_comp) // Creates a loop
- && math::abs(p.col() - c.col()) < dmax); // Not too far
+ && static_cast<float>(math::abs(p.col() - c.col())) < dmax); // Not too far
}
# endif // ! MLN_INCLUDE_ONLY
diff --git a/scribo/primitive/internal/is_link_valid.hh b/scribo/primitive/internal/is_link_valid.hh
index 69fe484..34c27b8 100644
--- a/scribo/primitive/internal/is_link_valid.hh
+++ b/scribo/primitive/internal/is_link_valid.hh
@@ -29,7 +29,8 @@
/// \file
///
/// Validate a link from two different links.
-
+///
+/// \todo To be deleted ?.
# include <mln/util/array.hh>
# include <mln/util/couple.hh>
diff --git a/scribo/primitive/internal/update_link_array.hh b/scribo/primitive/internal/update_link_array.hh
index 5e30bb5..f7fdf44 100644
--- a/scribo/primitive/internal/update_link_array.hh
+++ b/scribo/primitive/internal/update_link_array.hh
@@ -30,7 +30,8 @@
///
/// Update a lookup table if a neighbor is found on the right of
/// the current bbox.
-
+///
+/// \todo To be deleted.
# include <mln/core/concept/image.hh>
# include <mln/util/array.hh>
@@ -58,21 +59,21 @@ namespace scribo
/// \param[in] c A site of \p lbl.
//
template <typename I>
- void
+ bool
update_link_array(const Image<I>& lbl,
mln::util::array<unsigned>& link_array,
const mln_site(I)& p, const mln_site(I)& c,
- unsigned i, int dmax);
+ unsigned i, float dmax);
# ifndef MLN_INCLUDE_ONLY
template <typename I>
inline
- void
+ bool
update_link_array(const Image<I>& lbl_,
mln::util::array<unsigned>& link_array,
const mln_site(I)& p, const mln_site(I)& c,
- unsigned i, int dmax)
+ unsigned i, float dmax)
{
const I& lbl = exact(lbl_);
@@ -82,9 +83,14 @@ namespace scribo
if (lbl.domain().has(p) // Not outside image domain
&& lbl(p) != literal::zero // Not the background
&& lbl(p) != i // Not the current component
- && (math::abs(p.col() - c.col())) < dmax // Not too far
+ && static_cast<float>((math::abs(p.col() - c.col()))) < dmax // Not too far
&& link_array[lbl(p)] != i) // Not creating a loop
+ {
link_array[i] = lbl(p);
+ return true;
+ }
+
+ return false;
}
# endif // ! MLN_INCLUDE_ONLY
diff --git a/scribo/primitive/link/merge_double_link.hh b/scribo/primitive/link/merge_double_link.hh
index 3181117..f826048 100644
--- a/scribo/primitive/link/merge_double_link.hh
+++ b/scribo/primitive/link/merge_double_link.hh
@@ -101,7 +101,7 @@ namespace scribo
for_all_ncomponents(i, objects.nlabels())
{
mln::util::couple<bool, unsigned>
- nbh = internal::is_link_valid(left_link, right_link, i);
+ nbh = primitive::internal::is_link_valid(left_link, right_link, i);
if (!nbh.first())
merge[i] = i;
}
diff --git a/scribo/src/binarization/sauvola.cc b/scribo/src/binarization/sauvola.cc
index 9b34597..28d3ae7 100644
--- a/scribo/src/binarization/sauvola.cc
+++ b/scribo/src/binarization/sauvola.cc
@@ -25,6 +25,7 @@
#include <mln/io/ppm/load.hh>
#include <mln/io/pbm/save.hh>
+#include <mln/value/rgb8.hh>
#include <scribo/binarization/sauvola.hh>
#include <scribo/debug/usage.hh>
@@ -52,9 +53,7 @@ int main(int argc, char *argv[])
image2d<rgb8> input;
io::ppm::load(input, argv[1]);
-
- io::pbm::save(scribo::binarization::sauvola(input),
- argv[2]);
+ io::pbm::save(scribo::binarization::sauvola(input), argv[2]);
trace::exiting("main");
diff --git a/scribo/src/binarization/sauvola_pgm.cc b/scribo/src/binarization/sauvola_pgm.cc
index cac71e1..f05ed5f 100644
--- a/scribo/src/binarization/sauvola_pgm.cc
+++ b/scribo/src/binarization/sauvola_pgm.cc
@@ -29,9 +29,11 @@
#include <scribo/binarization/sauvola.hh>
#include <scribo/debug/usage.hh>
+
const char *args_desc[][2] =
{
{ "input.pgm", "A gray level image." },
+ { "w", "Window size." },
{0, 0}
};
@@ -41,20 +43,20 @@ int main(int argc, char *argv[])
using namespace mln;
using value::int_u8;
- if (argc != 3)
+ if (argc != 4)
return scribo::debug::usage(argv,
"Binarization of a gray level image based on Sauvola's algorithm.",
- "input.pgm output.pbm",
+ "input.pgm w output.pbm",
args_desc, "A binary image.");
trace::entering("main");
+ unsigned w = atoi(argv[2]);
+
image2d<int_u8> input;
io::pgm::load(input, argv[1]);
-
- io::pbm::save(scribo::binarization::sauvola(input),
- argv[2]);
+ io::pbm::save(scribo::binarization::sauvola(input, w), argv[3]);
trace::exiting("main");
diff --git a/scribo/src/multi_scale/find_lines.cc b/scribo/src/multi_scale/find_lines.cc
index f91c2da..c5a2f97 100644
--- a/scribo/src/multi_scale/find_lines.cc
+++ b/scribo/src/multi_scale/find_lines.cc
@@ -65,6 +65,8 @@ namespace mln
process(const I& input, const std::string& filename,
unsigned length, unsigned delta, unsigned ratio)
{
+ (void) filename;
+
I hlines = scribo::primitive::extract::lines_h_pattern(input,
length,
delta);
@@ -72,7 +74,6 @@ namespace mln
value::label_16 nhlines;
hlines = scribo::filter::objects_v_thin(hlines, c8(),
nhlines, delta * ratio);
-
// I vlines = scribo::primitive::extract::lines_v_pattern(input,
// length,
// delta);
diff --git a/scribo/src/primitive/group/group_from_graph.cc b/scribo/src/primitive/group/group_from_graph.cc
index 8b99c1b..833c4d4 100644
--- a/scribo/src/primitive/group/group_from_graph.cc
+++ b/scribo/src/primitive/group/group_from_graph.cc
@@ -66,7 +66,7 @@ int main(int argc, char* argv[])
typedef object_image(L) text_t;
text_t text = primitive::extract::objects(input, c8(), nbboxes);
- mln::util::graph g = primitive::link::with_graph(text, 30);
+ mln::util::graph g = primitive::link::with_graph(text, 255);
std::cout << "BEFORE - nbboxes = " << nbboxes.next() << std::endl;
scribo::debug::save_linked_bboxes_image(input,
diff --git a/scribo/src/primitive/group/group_from_rag.cc b/scribo/src/primitive/group/group_from_rag.cc
index e354d09..23827a9 100644
--- a/scribo/src/primitive/group/group_from_rag.cc
+++ b/scribo/src/primitive/group/group_from_rag.cc
@@ -90,7 +90,7 @@ namespace scribo
mln_precondition(lbl.is_valid());
util::array<mln_result(A)>
- values = labeling::compute(accu, lbl_, nlabels);
+ values = labeling::compute(accu, lbl, nlabels);
vertex_image<void, mln_result(A), G>
v_ima = mln::make::vertex_image(g, values);
diff --git a/scribo/src/primitive/group/group_from_several_graph.cc b/scribo/src/primitive/group/group_from_several_graph.cc
index 946e80f..3bba3ab 100644
--- a/scribo/src/primitive/group/group_from_several_graph.cc
+++ b/scribo/src/primitive/group/group_from_several_graph.cc
@@ -73,7 +73,7 @@ int main(int argc, char* argv[])
typedef object_image(L) text_t;
text_t text = scribo::primitive::extract::objects(input, c8(), nbboxes);
- mln::util::graph g = primitive::link::with_several_graphes(text, 30);
+ mln::util::graph g = primitive::link::with_several_graphes(text, 128);
std::cout << "BEFORE - nbboxes = " << nbboxes.next() << std::endl;
scribo::debug::save_linked_bboxes_image(input,
diff --git a/scribo/src/table/rebuild_opening.cc b/scribo/src/table/rebuild_opening.cc
index a13a00f..60d43e0 100644
--- a/scribo/src/table/rebuild_opening.cc
+++ b/scribo/src/table/rebuild_opening.cc
@@ -88,7 +88,7 @@ int main(int argc, char* argv[])
io::pgm::save(tables, scribo::make::debug_filename("table_cells.pgm"));
image2d<value::rgb8> input_rgb = data::convert(value::rgb8(), input);
- data::fill((input_rgb | pw::value(tables) == pw::cst(0u)).rw(), literal::red);
+ data::fill((input_rgb | (pw::value(tables) == pw::cst(0u))).rw(), literal::red);
io::ppm::save(input_rgb, scribo::make::debug_filename("table_superposed.ppm"));
image2d<bool> in_wo_tables = table::erase(input, hlines, vlines);
diff --git a/scribo/src/table/rebuild_rank.cc b/scribo/src/table/rebuild_rank.cc
index 1c6b921..b04dac9 100644
--- a/scribo/src/table/rebuild_rank.cc
+++ b/scribo/src/table/rebuild_rank.cc
@@ -92,7 +92,7 @@ int main(int argc, char* argv[])
value::label_8 bg = data::compute(accu::maj_h<value::label_8>(), tables);
image2d<value::rgb8> sup = data::convert(value::rgb8(), input);
- data::paste((table_color | pw::value(tables) != pw::cst(bg))
+ data::paste((table_color | (pw::value(tables) != pw::cst(bg)))
| (pw::value(sup) == pw::cst(literal::black)), sup);
io::ppm::save(sup, scribo::make::debug_filename("table_color_sup.ppm"));
@@ -101,7 +101,7 @@ int main(int argc, char* argv[])
io::pgm::save(tables, scribo::make::debug_filename("table_cells.pgm"));
image2d<value::rgb8> input_rgb = data::convert(value::rgb8(), input);
- data::fill((input_rgb | pw::value(tables) == pw::cst(0u)).rw(), literal::red);
+ data::fill((input_rgb | (pw::value(tables) == pw::cst(0u))).rw(), literal::red);
io::ppm::save(input_rgb, scribo::make::debug_filename("table_superposed.ppm"));
image2d<bool> in_wo_tables = table::erase(input, hlines, vlines);
diff --git a/scribo/text/clean.hh b/scribo/text/clean.hh
index e934241..cd8657e 100644
--- a/scribo/text/clean.hh
+++ b/scribo/text/clean.hh
@@ -105,6 +105,7 @@ namespace scribo
mlc_equal(mln_value(I),bool)::check();
mln_precondition(input.is_valid());
mln_precondition(dmap_win.is_valid());
+ (void) dmap_win;
// Resize
--
1.5.6.5
1
0

[PATCH 10/10] Adjust the initialization of the SWIG Python Milena wrappers.
by Roland Levillain 03 Nov '09
by Roland Levillain 03 Nov '09
03 Nov '09
* swig/mln.i: Call dyn::mln::initialize in %init section.
---
dynamic-use-of-static-c++/ChangeLog | 6 ++++++
dynamic-use-of-static-c++/swig/mln.i | 6 ++++++
2 files changed, 12 insertions(+), 0 deletions(-)
diff --git a/dynamic-use-of-static-c++/ChangeLog b/dynamic-use-of-static-c++/ChangeLog
index dfbb444..9de4a05 100644
--- a/dynamic-use-of-static-c++/ChangeLog
+++ b/dynamic-use-of-static-c++/ChangeLog
@@ -1,5 +1,11 @@
2009-11-03 Roland Levillain <roland(a)lrde.epita.fr>
+ Adjust the initialization of the SWIG Python Milena wrappers.
+
+ * swig/mln.i: Call dyn::mln::initialize in %init section.
+
+2009-11-03 Roland Levillain <roland(a)lrde.epita.fr>
+
Make the initialization of Milena wrappers deterministic.
* src/wrappers/milena.cc (dyn::mln::init_type): Remove class.
diff --git a/dynamic-use-of-static-c++/swig/mln.i b/dynamic-use-of-static-c++/swig/mln.i
index e5598ab..dcfe644 100644
--- a/dynamic-use-of-static-c++/swig/mln.i
+++ b/dynamic-use-of-static-c++/swig/mln.i
@@ -37,3 +37,9 @@
%}
%include "wrappers/milena.hh"
+
+%init
+%{
+ // Set up header paths.
+ dyn::mln::initialize();
+%}
--
1.6.5
1
0