Olena-patches
Threads by month
- ----- 2025 -----
- November
- October
- September
- 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
- 9625 discussions
---
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
[PATCH 09/10] Make the initialization of Milena wrappers deterministic.
by Roland Levillain 03 Nov '09
by Roland Levillain 03 Nov '09
03 Nov '09
* src/wrappers/milena.cc (dyn::mln::init_type): Remove class.
Replace it by...
* src/wrappers/milena.hh, src/wrappers/milena.cc
(dyn::mln::initialize): ...this (new) function.
* test/wrappers/test-milena.cc (main): Call dyn::mln::initialize()
before calling wrappers.
---
dynamic-use-of-static-c++/ChangeLog | 11 +++++++
dynamic-use-of-static-c++/src/wrappers/milena.cc | 32 ++++---------------
dynamic-use-of-static-c++/src/wrappers/milena.hh | 21 +++++++++++++
.../test/wrappers/test-milena.cc | 2 +
4 files changed, 41 insertions(+), 25 deletions(-)
diff --git a/dynamic-use-of-static-c++/ChangeLog b/dynamic-use-of-static-c++/ChangeLog
index 400c9bb..dfbb444 100644
--- a/dynamic-use-of-static-c++/ChangeLog
+++ b/dynamic-use-of-static-c++/ChangeLog
@@ -1,5 +1,16 @@
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.
+ Replace it by...
+ * src/wrappers/milena.hh, src/wrappers/milena.cc
+ (dyn::mln::initialize): ...this (new) function.
+ * test/wrappers/test-milena.cc (main): Call dyn::mln::initialize()
+ before calling wrappers.
+
+2009-11-03 Roland Levillain <roland(a)lrde.epita.fr>
+
Help Mac OS X's Mach-O dynamic linker (dyld) find libdynmilena.
* swig/run.in: Remove symlink, and replace it by an actual copy of
diff --git a/dynamic-use-of-static-c++/src/wrappers/milena.cc b/dynamic-use-of-static-c++/src/wrappers/milena.cc
index 3ad7a95..9baf0e7 100644
--- a/dynamic-use-of-static-c++/src/wrappers/milena.cc
+++ b/dynamic-use-of-static-c++/src/wrappers/milena.cc
@@ -41,32 +41,14 @@ namespace dyn
| Initialization. |
`-----------------*/
- /* This initialization relies on ctors of the fact that
- constructors of global objects called before `main', or more
- precisely:
-
- [...] the constructor of a global object is called either
- before the first statement of main or may be deferred until
- after the first statement of main but before the first use of
- any object or function in the same translation unit as the
- global object is defined in.
-
- according to this page:
- http://en.allexperts.com/q/C-1040/Constructors-Global-Object.htm. */
-
- struct init_type
+ void initialize()
{
- init_type()
- {
- dyn::include_dir(MILENA_DIR);
- dyn::include("mln/core/image/image2d.hh");
- dyn::include("mln/data/fill.hh");
- dyn::include("mln/debug/iota.hh");
- dyn::include("mln/debug/println.hh");
- }
- };
-
- init_type init;
+ dyn::include_dir(MILENA_DIR);
+ dyn::include("mln/core/image/image2d.hh");
+ dyn::include("mln/data/fill.hh");
+ dyn::include("mln/debug/iota.hh");
+ dyn::include("mln/debug/println.hh");
+ }
/*-------------------------.
diff --git a/dynamic-use-of-static-c++/src/wrappers/milena.hh b/dynamic-use-of-static-c++/src/wrappers/milena.hh
index b0ba1ed..ed4b702 100644
--- a/dynamic-use-of-static-c++/src/wrappers/milena.hh
+++ b/dynamic-use-of-static-c++/src/wrappers/milena.hh
@@ -40,6 +40,27 @@ namespace dyn
namespace mln
{
+ /*-----------------.
+ | Initialization. |
+ `-----------------*/
+
+ /* FIXME: This is not really elegant, but this is a lot safer than
+ the previous approach relying on the (implementation-defined)
+ order of initialization of global objects' ctors. We can
+ probably improve this by reworking dyn::function_loader. See
+ also hints and advice from
+ http://en.allexperts.com/q/C-1040/Constructors-Global-Object.htm. */
+
+ // This function *must* be called prior to any call to the wrapped
+ // routines below in order to find the headers of the functions
+ // they wrap.
+ void initialize();
+
+
+ /*-------------------------.
+ | A few wrapped routines. |
+ `-------------------------*/
+
extern dyn::language::ctor mk_image2d_int;
extern dyn::language::fun fill;
diff --git a/dynamic-use-of-static-c++/test/wrappers/test-milena.cc b/dynamic-use-of-static-c++/test/wrappers/test-milena.cc
index d24d216..831c9db 100644
--- a/dynamic-use-of-static-c++/test/wrappers/test-milena.cc
+++ b/dynamic-use-of-static-c++/test/wrappers/test-milena.cc
@@ -30,6 +30,8 @@
int main()
{
+ dyn::mln::initialize();
+
dyn::language::var ima = dyn::mln::mk_image2d_int(3, 3);
dyn::mln::fill(ima, 0);
dyn::mln::println("ima (before) =", ima);
--
1.6.5
1
0
* swig/python/milena-libdynmilena.py: New.
* swig/python/milena.py: Rename as...
* swig/python/milena-libdyn.py: ...this.
Add comments.
* swig/python/Makefile.am (TESTS): s/milena.py/milena-libdyn.py/
Add milena-libdynmilena.py.
---
dynamic-use-of-static-c++/ChangeLog | 11 +++++++
dynamic-use-of-static-c++/swig/python/Makefile.am | 2 +-
.../swig/python/{milena.py => milena-libdyn.py} | 6 +++-
.../python/{milena.py => milena-libdynmilena.py} | 30 +++++++------------
4 files changed, 28 insertions(+), 21 deletions(-)
copy dynamic-use-of-static-c++/swig/python/{milena.py => milena-libdyn.py} (90%)
rename dynamic-use-of-static-c++/swig/python/{milena.py => milena-libdynmilena.py} (61%)
diff --git a/dynamic-use-of-static-c++/ChangeLog b/dynamic-use-of-static-c++/ChangeLog
index 81c90c3..400c9bb 100644
--- a/dynamic-use-of-static-c++/ChangeLog
+++ b/dynamic-use-of-static-c++/ChangeLog
@@ -8,6 +8,17 @@
2009-11-02 Roland Levillain <roland(a)lrde.epita.fr>
+ Exercise the SWIG (Python) Milena wrappers.
+
+ * swig/python/milena-libdynmilena.py: New.
+ * swig/python/milena.py: Rename as...
+ * swig/python/milena-libdyn.py: ...this.
+ Add comments.
+ * swig/python/Makefile.am (TESTS): s/milena.py/milena-libdyn.py/
+ Add milena-libdynmilena.py.
+
+2009-11-02 Roland Levillain <roland(a)lrde.epita.fr>
+
Expose the Milena wrappers to SWIG.
* swig/mln.i: New.
diff --git a/dynamic-use-of-static-c++/swig/python/Makefile.am b/dynamic-use-of-static-c++/swig/python/Makefile.am
index 86611e3..f704065 100644
--- a/dynamic-use-of-static-c++/swig/python/Makefile.am
+++ b/dynamic-use-of-static-c++/swig/python/Makefile.am
@@ -119,7 +119,7 @@ $(srcdir)/run.stamp: $(RUN_IN)
# and a test. Alas, the script `run' expects a file name with an
# extension as argument. We could improve this by adding options such
# as `--python' to `run'.
-TESTS = milena.py
+TESTS = milena-libdyn.py milena-libdynmilena.py
# FIXME: Is this really needed?
EXTRA_DIST += $(TESTS)
diff --git a/dynamic-use-of-static-c++/swig/python/milena.py b/dynamic-use-of-static-c++/swig/python/milena-libdyn.py
similarity index 90%
copy from dynamic-use-of-static-c++/swig/python/milena.py
copy to dynamic-use-of-static-c++/swig/python/milena-libdyn.py
index 93c384b..65e6fe9 100644
--- a/dynamic-use-of-static-c++/swig/python/milena.py
+++ b/dynamic-use-of-static-c++/swig/python/milena-libdyn.py
@@ -17,24 +17,28 @@
# along with Olena. If not, see <http://www.gnu.org/licenses/>.
# \file
-# \brief A Python version of test/test_olena.cc.
+# \brief A Python version of test/test_milena.cc using libdyn (directly).
import ltihooks
import dyn
import config
+# Set up paths.
dyn.include_dir(config.abs_milena_dir)
dyn.include("mln/core/image/image2d.hh")
dyn.include("mln/data/fill.hh")
dyn.include("mln/debug/iota.hh")
dyn.include("mln/debug/println.hh")
+# Instantiate functors.
mk_image2d_int = dyn.ctor("mln::image2d<int>")
fill = dyn.fun("mln::data::fill")
iota = dyn.fun("mln::debug::iota")
println = dyn.fun("mln::debug::println")
+# Use them (by compiling them on-the-fly).
+
# We'd like to be able to write this:
#
# ima = mk_image2d_int(3, 3)
diff --git a/dynamic-use-of-static-c++/swig/python/milena.py b/dynamic-use-of-static-c++/swig/python/milena-libdynmilena.py
similarity index 61%
rename from dynamic-use-of-static-c++/swig/python/milena.py
rename to dynamic-use-of-static-c++/swig/python/milena-libdynmilena.py
index 93c384b..037a429 100644
--- a/dynamic-use-of-static-c++/swig/python/milena.py
+++ b/dynamic-use-of-static-c++/swig/python/milena-libdynmilena.py
@@ -17,35 +17,27 @@
# along with Olena. If not, see <http://www.gnu.org/licenses/>.
# \file
-# \brief A Python version of test/test_olena.cc.
+# \brief A Python version of test/test_milena.cc using libdynmilena.
import ltihooks
import dyn
-import config
-
-dyn.include_dir(config.abs_milena_dir)
-dyn.include("mln/core/image/image2d.hh")
-dyn.include("mln/data/fill.hh")
-dyn.include("mln/debug/iota.hh")
-dyn.include("mln/debug/println.hh")
-
-mk_image2d_int = dyn.ctor("mln::image2d<int>")
-fill = dyn.fun("mln::data::fill")
-iota = dyn.fun("mln::debug::iota")
-println = dyn.fun("mln::debug::println")
+import mln
# We'd like to be able to write this:
#
-# ima = mk_image2d_int(3, 3)
+# ima = mln.mk_image2d_int(3, 3)
#
# but we just can't. `mk_image2d_int' only accept `dyn.data' as
# arguments, so we have to encapsulate integers in `dyn.data' objects
# (likewise for strings).
+#
+# Moreover, mk_image2d_int is a global object (functor), registered as
+# an attribute of the `mln.cvar' object.
-ima = mk_image2d_int(dyn.data(3), dyn.data(3))
+ima = mln.cvar.mk_image2d_int(dyn.data(3), dyn.data(3))
-fill(ima, dyn.data(0))
-println(dyn.data("ima (before) ="), ima)
-iota(ima)
-println(dyn.data("ima (after) ="), ima)
+mln.cvar.fill(ima, dyn.data(0))
+mln.cvar.println(dyn.data("ima (before) ="), ima)
+mln.cvar.iota(ima)
+mln.cvar.println(dyn.data("ima (after) ="), ima)
--
1.6.5
1
0
[PATCH 07/10] Help Mac OS X's Mach-O dynamic linker (dyld) find libdynmilena.
by Roland Levillain 03 Nov '09
by Roland Levillain 03 Nov '09
03 Nov '09
* swig/run.in: Remove symlink, and replace it by an actual copy of
../../swilena/run.in.
(modpath): Append @abs_top_builddir@/src/wrappers/.libs.
---
dynamic-use-of-static-c++/ChangeLog | 8 ++++
dynamic-use-of-static-c++/swig/run.in | 60 ++++++++++++++++++++++++++++++++-
2 files changed, 67 insertions(+), 1 deletions(-)
mode change 120000 => 100755 dynamic-use-of-static-c++/swig/run.in
diff --git a/dynamic-use-of-static-c++/ChangeLog b/dynamic-use-of-static-c++/ChangeLog
index 6921732..81c90c3 100644
--- a/dynamic-use-of-static-c++/ChangeLog
+++ b/dynamic-use-of-static-c++/ChangeLog
@@ -1,3 +1,11 @@
+2009-11-03 Roland Levillain <roland(a)lrde.epita.fr>
+
+ Help Mac OS X's Mach-O dynamic linker (dyld) find libdynmilena.
+
+ * swig/run.in: Remove symlink, and replace it by an actual copy of
+ ../../swilena/run.in.
+ (modpath): Append @abs_top_builddir@/src/wrappers/.libs.
+
2009-11-02 Roland Levillain <roland(a)lrde.epita.fr>
Expose the Milena wrappers to SWIG.
diff --git a/dynamic-use-of-static-c++/swig/run.in b/dynamic-use-of-static-c++/swig/run.in
deleted file mode 120000
index 585aed6..0000000
--- a/dynamic-use-of-static-c++/swig/run.in
+++ /dev/null
@@ -1 +0,0 @@
-../../swilena/run.in
\ No newline at end of file
diff --git a/dynamic-use-of-static-c++/swig/run.in b/dynamic-use-of-static-c++/swig/run.in
new file mode 100755
index 0000000..41ec0e8
--- /dev/null
+++ b/dynamic-use-of-static-c++/swig/run.in
@@ -0,0 +1,59 @@
+#!/bin/sh
+
+# Copyright (C) 2003, 2004, 2006, 2009 Laboratoire d'Informatique de Paris 6
+# (LIP6), département Systèmes Répartis Coopératifs (SRC), Université
+# Pierre et Marie Curie.
+#
+# This file is part of Spot, a model checking library.
+#
+# Spot 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; either version 2 of the License, or
+# (at your option) any later version.
+#
+# Spot 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 Spot; see the file COPYING. If not, write to the Free
+# Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+
+# If we are running from make check (srcdir is set) and VERBOSE is
+# unset, be quiet.
+test -n "$srcdir" && test -z "$VERBOSE" && exec >/dev/null 2>&1
+
+# Darwin needs some help in figuring out where non-installed libtool
+# libraries are (on this platform libtool encodes the expected final
+# path of dependent libraries in each library).
+## FIXME: This path should be configurable from outside the script.
+modpath='.libs:@abs_top_builddir@/src/.libs:@abs_top_builddir@/src/wrappers/.libs'
+
+case $1 in
+ '' | *.py)
+ PYTHONPATH='@abs_builddir@/python:@abs_srcdir@/python':"$PYTHONPATH" \
+ DYLD_LIBRARY_PATH=$modpath \
+ exec @PYTHON@ "$@"
+ ;;
+ # What's the point in adding `.libs' to SWILENA_RUBY_PATH?
+ #
+ # As some of our SWIG interfaces import other SWIG interfaces
+ # (with the `%import' keyword), we must add the `.libs' directory
+ # to SWILENA_RUBY_PATH so that the Ruby interpreter can load the
+ # corresponding dynamic module(s) (SWIG's `%import' statements
+ # generate code in dynamic modules that bypass Ruby's
+ # `Kernel.require' mechanism).
+ *.rb)
+ SWILENA_RUBY_PATH='@abs_builddir@/ruby:@abs_srcdir@/ruby:.libs' \
+ DYLD_LIBRARY_PATH=$modpath \
+ exec @RUBY@ "$@"
+ ;;
+ *.test)
+ exec sh -x "$@";;
+ *)
+ echo "Unknown extension" 2>&1
+ exit 2;;
+esac
--
1.6.5
1
0