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
March 2010
- 4 participants
- 277 discussions
last-svn-commit-44-g27b5f71 configure.ac: Configure scribo/demo/review.
by Guillaume Lazzara 11 Mar '10
by Guillaume Lazzara 11 Mar '10
11 Mar '10
---
ChangeLog | 4 ++++
configure.ac | 2 +-
2 files changed, 5 insertions(+), 1 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 961ff85..4f21dd6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2010-02-16 Guillaume Lazzara <z(a)lrde.epita.fr>
+
+ * configure.ac: Configure scribo/demo/review.
+
2009-12-15 Guillaume Lazzara <z(a)lrde.epita.fr>
* configure.ac: Configure scribo/tests/core.
diff --git a/configure.ac b/configure.ac
index 0f66fa3..0edfcb6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -210,7 +210,7 @@ AM_CONDITIONAL([ENABLE_SCRIBO], [test x$enable_scribo = xyes])
AC_CONFIG_FILES([
scribo/Makefile
- scribo/demo/Makefile
+ scribo/demo/review/Makefile
scribo/src/Makefile
scribo/src/binarization/Makefile
scribo/src/debug/Makefile
--
1.5.6.5
1
0
* demo/Makefile.am,
* demo/demo.pro,
* demo/demo.qrc,
* demo/icons/document-open.png,
* demo/icons/edit-find.png,
* demo/icons/format-indent-more.png,
* demo/icons/go-next.png,
* demo/icons/image-x-generic.png,
* demo/icons/list-add.png,
* demo/icons/ocr.png,
* demo/icons/text-x-generic.png,
* demo/icons/view-refresh.png,
* demo/icons/x-office-spreadsheet.png,
* demo/src/main.cc,
* demo/src/mainwindow.cc,
* demo/src/mainwindow.hh,
* demo/ui/mainwindow.ui: Move...
* demo/review/Makefile.am,
* demo/review/icons/document-open.png,
* demo/review/icons/edit-find.png,
* demo/review/icons/format-indent-more.png,
* demo/review/icons/go-next.png,
* demo/review/icons/image-x-generic.png,
* demo/review/icons/list-add.png,
* demo/review/icons/ocr.png,
* demo/review/icons/text-x-generic.png,
* demo/review/icons/view-refresh.png,
* demo/review/icons/x-office-spreadsheet.png,
* demo/review/review.pro,
* demo/review/review.qrc,
* demo/review/src/main.cc,
* demo/review/src/mainwindow.cc,
* demo/review/src/mainwindow.hh,
* demo/review/ui/mainwindow.ui: ... here.
---
scribo/ChangeLog | 40 ++++++++++++++++++++
scribo/demo/{ => review}/Makefile.am | 0
scribo/demo/{ => review}/icons/document-open.png | Bin 1550 -> 1550 bytes
scribo/demo/{ => review}/icons/edit-find.png | Bin 1636 -> 1636 bytes
.../demo/{ => review}/icons/format-indent-more.png | Bin 766 -> 766 bytes
scribo/demo/{ => review}/icons/go-next.png | Bin 1219 -> 1219 bytes
scribo/demo/{ => review}/icons/image-x-generic.png | Bin 1163 -> 1163 bytes
scribo/demo/{ => review}/icons/list-add.png | Bin 601 -> 601 bytes
scribo/demo/{ => review}/icons/ocr.png | Bin 14929 -> 14929 bytes
scribo/demo/{ => review}/icons/text-x-generic.png | Bin 744 -> 744 bytes
scribo/demo/{ => review}/icons/view-refresh.png | Bin 2024 -> 2024 bytes
.../{ => review}/icons/x-office-spreadsheet.png | Bin 1518 -> 1518 bytes
scribo/demo/{demo.pro => review/review.pro} | 4 +-
scribo/demo/{demo.qrc => review/review.qrc} | 0
scribo/demo/{ => review}/src/main.cc | 0
scribo/demo/{ => review}/src/mainwindow.cc | 0
scribo/demo/{ => review}/src/mainwindow.hh | 0
scribo/demo/{ => review}/ui/mainwindow.ui | 0
18 files changed, 42 insertions(+), 2 deletions(-)
rename scribo/demo/{ => review}/Makefile.am (100%)
rename scribo/demo/{ => review}/icons/document-open.png (100%)
rename scribo/demo/{ => review}/icons/edit-find.png (100%)
rename scribo/demo/{ => review}/icons/format-indent-more.png (100%)
rename scribo/demo/{ => review}/icons/go-next.png (100%)
rename scribo/demo/{ => review}/icons/image-x-generic.png (100%)
rename scribo/demo/{ => review}/icons/list-add.png (100%)
rename scribo/demo/{ => review}/icons/ocr.png (100%)
rename scribo/demo/{ => review}/icons/text-x-generic.png (100%)
rename scribo/demo/{ => review}/icons/view-refresh.png (100%)
rename scribo/demo/{ => review}/icons/x-office-spreadsheet.png (100%)
rename scribo/demo/{demo.pro => review/review.pro} (84%)
rename scribo/demo/{demo.qrc => review/review.qrc} (100%)
rename scribo/demo/{ => review}/src/main.cc (100%)
rename scribo/demo/{ => review}/src/mainwindow.cc (100%)
rename scribo/demo/{ => review}/src/mainwindow.hh (100%)
rename scribo/demo/{ => review}/ui/mainwindow.ui (100%)
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index f3c022a..26f6201 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,3 +1,43 @@
+2010-02-09 Guillaume Lazzara <z(a)lrde.epita.fr>
+
+ Move Scribo demo.
+
+ * demo/Makefile.am,
+ * demo/demo.pro,
+ * demo/demo.qrc,
+ * demo/icons/document-open.png,
+ * demo/icons/edit-find.png,
+ * demo/icons/format-indent-more.png,
+ * demo/icons/go-next.png,
+ * demo/icons/image-x-generic.png,
+ * demo/icons/list-add.png,
+ * demo/icons/ocr.png,
+ * demo/icons/text-x-generic.png,
+ * demo/icons/view-refresh.png,
+ * demo/icons/x-office-spreadsheet.png,
+ * demo/src/main.cc,
+ * demo/src/mainwindow.cc,
+ * demo/src/mainwindow.hh,
+ * demo/ui/mainwindow.ui: Move...
+
+ * demo/review/Makefile.am,
+ * demo/review/icons/document-open.png,
+ * demo/review/icons/edit-find.png,
+ * demo/review/icons/format-indent-more.png,
+ * demo/review/icons/go-next.png,
+ * demo/review/icons/image-x-generic.png,
+ * demo/review/icons/list-add.png,
+ * demo/review/icons/ocr.png,
+ * demo/review/icons/text-x-generic.png,
+ * demo/review/icons/view-refresh.png,
+ * demo/review/icons/x-office-spreadsheet.png,
+ * demo/review/review.pro,
+ * demo/review/review.qrc,
+ * demo/review/src/main.cc,
+ * demo/review/src/mainwindow.cc,
+ * demo/review/src/mainwindow.hh,
+ * demo/review/ui/mainwindow.ui: ... here.
+
2010-02-19 Guillaume Lazzara <z(a)lrde.epita.fr>
* io/xml/save_text_lines.hh: New. Add partial support for
diff --git a/scribo/demo/Makefile.am b/scribo/demo/review/Makefile.am
similarity index 100%
rename from scribo/demo/Makefile.am
rename to scribo/demo/review/Makefile.am
diff --git a/scribo/demo/icons/document-open.png b/scribo/demo/review/icons/document-open.png
similarity index 100%
rename from scribo/demo/icons/document-open.png
rename to scribo/demo/review/icons/document-open.png
diff --git a/scribo/demo/icons/edit-find.png b/scribo/demo/review/icons/edit-find.png
similarity index 100%
rename from scribo/demo/icons/edit-find.png
rename to scribo/demo/review/icons/edit-find.png
diff --git a/scribo/demo/icons/format-indent-more.png b/scribo/demo/review/icons/format-indent-more.png
similarity index 100%
rename from scribo/demo/icons/format-indent-more.png
rename to scribo/demo/review/icons/format-indent-more.png
diff --git a/scribo/demo/icons/go-next.png b/scribo/demo/review/icons/go-next.png
similarity index 100%
rename from scribo/demo/icons/go-next.png
rename to scribo/demo/review/icons/go-next.png
diff --git a/scribo/demo/icons/image-x-generic.png b/scribo/demo/review/icons/image-x-generic.png
similarity index 100%
rename from scribo/demo/icons/image-x-generic.png
rename to scribo/demo/review/icons/image-x-generic.png
diff --git a/scribo/demo/icons/list-add.png b/scribo/demo/review/icons/list-add.png
similarity index 100%
rename from scribo/demo/icons/list-add.png
rename to scribo/demo/review/icons/list-add.png
diff --git a/scribo/demo/icons/ocr.png b/scribo/demo/review/icons/ocr.png
similarity index 100%
rename from scribo/demo/icons/ocr.png
rename to scribo/demo/review/icons/ocr.png
diff --git a/scribo/demo/icons/text-x-generic.png b/scribo/demo/review/icons/text-x-generic.png
similarity index 100%
rename from scribo/demo/icons/text-x-generic.png
rename to scribo/demo/review/icons/text-x-generic.png
diff --git a/scribo/demo/icons/view-refresh.png b/scribo/demo/review/icons/view-refresh.png
similarity index 100%
rename from scribo/demo/icons/view-refresh.png
rename to scribo/demo/review/icons/view-refresh.png
diff --git a/scribo/demo/icons/x-office-spreadsheet.png b/scribo/demo/review/icons/x-office-spreadsheet.png
similarity index 100%
rename from scribo/demo/icons/x-office-spreadsheet.png
rename to scribo/demo/review/icons/x-office-spreadsheet.png
diff --git a/scribo/demo/demo.pro b/scribo/demo/review/review.pro
similarity index 84%
rename from scribo/demo/demo.pro
rename to scribo/demo/review/review.pro
index 01e36ee..3ee66e9 100644
--- a/scribo/demo/demo.pro
+++ b/scribo/demo/review/review.pro
@@ -5,7 +5,7 @@
TEMPLATE = app
TARGET =
DEPENDPATH += . src ui
-INCLUDEPATH += . src ../../ ../../milena
+INCLUDEPATH += . src ../../../ ../../../milena
DEFINES += NDEBUG
# Input
@@ -13,4 +13,4 @@ HEADERS += src/mainwindow.hh
FORMS += ui/mainwindow.ui
SOURCES += src/main.cc src/mainwindow.cc
-RESOURCES = demo.qrc
+RESOURCES = review.qrc
diff --git a/scribo/demo/demo.qrc b/scribo/demo/review/review.qrc
similarity index 100%
rename from scribo/demo/demo.qrc
rename to scribo/demo/review/review.qrc
diff --git a/scribo/demo/src/main.cc b/scribo/demo/review/src/main.cc
similarity index 100%
rename from scribo/demo/src/main.cc
rename to scribo/demo/review/src/main.cc
diff --git a/scribo/demo/src/mainwindow.cc b/scribo/demo/review/src/mainwindow.cc
similarity index 100%
rename from scribo/demo/src/mainwindow.cc
rename to scribo/demo/review/src/mainwindow.cc
diff --git a/scribo/demo/src/mainwindow.hh b/scribo/demo/review/src/mainwindow.hh
similarity index 100%
rename from scribo/demo/src/mainwindow.hh
rename to scribo/demo/review/src/mainwindow.hh
diff --git a/scribo/demo/ui/mainwindow.ui b/scribo/demo/review/ui/mainwindow.ui
similarity index 100%
rename from scribo/demo/ui/mainwindow.ui
rename to scribo/demo/review/ui/mainwindow.ui
--
1.5.6.5
1
0
* milena/mln/accu/center.hh: Add nsites() member.
* milena/mln/accu/pair.hh: Provide access to the underlying accus.
* milena/mln/accu/stat/variance.hh: Use literal::zero.
* milena/mln/core/internal/labeled_image_base.hh: Indent.
* milena/mln/core/site_set/box.hh: Rename center() as pcenter().
* milena/mln/labeling/blobs_and_compute.hh: Return the array of
accumulators.
* milena/mln/labeling/colorize.hh: Make sure a color is not used
twice in the same image.
* milena/mln/labeling/compute.hh: Add a new overload.
* milena/mln/transform/influence_zone_geodesic.hh: Fix a
segmentation fault when an image had a border.
---
milena/ChangeLog | 25 +++++
milena/mln/accu/center.hh | 14 +++-
milena/mln/accu/pair.hh | 26 ++++++
milena/mln/accu/stat/variance.hh | 4 +-
milena/mln/core/internal/labeled_image_base.hh | 2 +-
milena/mln/core/site_set/box.hh | 4 +-
milena/mln/labeling/blobs_and_compute.hh | 14 ++-
milena/mln/labeling/colorize.hh | 51 ++++++++---
milena/mln/labeling/compute.hh | 111 +++++++++++++++++++----
milena/mln/transform/influence_zone_geodesic.hh | 13 +--
10 files changed, 214 insertions(+), 50 deletions(-)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 73b9647..ec2ef35 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,3 +1,28 @@
+2010-02-19 Guillaume Lazzara <z(a)lrde.epita.fr>
+
+ Small fixes in Milena.
+
+ * milena/mln/accu/center.hh: Add nsites() member.
+
+ * milena/mln/accu/pair.hh: Provide access to the underlying accus.
+
+ * milena/mln/accu/stat/variance.hh: Use literal::zero.
+
+ * milena/mln/core/internal/labeled_image_base.hh: Indent.
+
+ * milena/mln/core/site_set/box.hh: Rename center() as pcenter().
+
+ * milena/mln/labeling/blobs_and_compute.hh: Return the array of
+ accumulators.
+
+ * milena/mln/labeling/colorize.hh: Make sure a color is not used
+ twice in the same image.
+
+ * milena/mln/labeling/compute.hh: Add a new overload.
+
+ * milena/mln/transform/influence_zone_geodesic.hh: Fix a
+ segmentation fault when an image had a border.
+
2009-12-14 Guillaume Lazzara <z(a)lrde.epita.fr>
Add rbg_to_int_u function.
diff --git a/milena/mln/accu/center.hh b/milena/mln/accu/center.hh
index 7cfbe78..a3622b3 100644
--- a/milena/mln/accu/center.hh
+++ b/milena/mln/accu/center.hh
@@ -1,4 +1,5 @@
-// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2008, 2009, 2010 EPITA Research and Development
+// Laboratory (LRDE)
//
// This file is part of Olena.
//
@@ -73,6 +74,9 @@ namespace mln
/// Check whether this accu is able to return a result.
bool is_valid() const;
+ /// Return the number of sites taken in consideration.
+ unsigned nsites() const;
+
protected:
algebra::vec<P::dim, mln_sum(mln_coord(P))> center_;
unsigned nsites_;
@@ -158,6 +162,14 @@ namespace mln
return nsites_ > 0;
}
+ template <typename P, typename V>
+ inline
+ unsigned
+ center<P,V>::nsites() const
+ {
+ return nsites_;
+ }
+
# endif // ! MLN_INCLUDE_ONLY
diff --git a/milena/mln/accu/pair.hh b/milena/mln/accu/pair.hh
index bb0b691..11f4dc6 100644
--- a/milena/mln/accu/pair.hh
+++ b/milena/mln/accu/pair.hh
@@ -81,9 +81,16 @@ namespace mln
void get_result(result_1& r1, result_2& r2) const;
/// \}
+ /// Return the result of the first accumulator.
mln_result(A1) first() const;
+ /// Return the result of the second accumulator.
mln_result(A2) second() const;
+ /// Return the first accumulator.
+ A1 first_accu() const;
+ /// Return the second accumulator.
+ A2 second_accu() const;
+
/// Check whether this accu is able to return a result.
/// Always true here.
bool is_valid() const;
@@ -194,6 +201,25 @@ namespace mln
return a2_.to_result();
}
+
+
+ template <typename A1, typename A2, typename T>
+ inline
+ A1
+ pair<A1,A2,T>::first_accu() const
+ {
+ return a1_;
+ }
+
+ template <typename A1, typename A2, typename T>
+ inline
+ A2
+ pair<A1,A2,T>::second_accu() const
+ {
+ return a2_;
+ }
+
+
template <typename A1, typename A2, typename T>
inline
bool
diff --git a/milena/mln/accu/stat/variance.hh b/milena/mln/accu/stat/variance.hh
index 23e7731..c19761e 100644
--- a/milena/mln/accu/stat/variance.hh
+++ b/milena/mln/accu/stat/variance.hh
@@ -125,7 +125,7 @@ namespace mln
variance<T,S,R>::init()
{
n_ = 0;
- sum_ = sum2_ = 0;
+ sum_ = sum2_ = literal::zero;
}
template <typename T, typename S, typename R>
@@ -187,7 +187,7 @@ namespace mln
variance<T,S,R>::mean() const
{
if (n_ == 0u)
- return 0; // Safety.
+ return literal::zero; // Safety.
return sum_ / n_;
}
diff --git a/milena/mln/core/internal/labeled_image_base.hh b/milena/mln/core/internal/labeled_image_base.hh
index 9e2d314..86bb077 100644
--- a/milena/mln/core/internal/labeled_image_base.hh
+++ b/milena/mln/core/internal/labeled_image_base.hh
@@ -310,7 +310,7 @@ namespace mln
const util::array<typename labeled_image_base<I,E>::bbox_t>&
labeled_image_base<I,E>::bboxes() const
{
- return this->data_->bboxes_;
+ return this->data_->bboxes_;
}
diff --git a/milena/mln/core/site_set/box.hh b/milena/mln/core/site_set/box.hh
index 75fb91c..077ac3d 100644
--- a/milena/mln/core/site_set/box.hh
+++ b/milena/mln/core/site_set/box.hh
@@ -143,7 +143,7 @@ namespace mln
box<P> to_larger(unsigned b) const;
/// Return the approximated central site of this box.
- P center() const;
+ P pcenter() const;
/// Test that the box owns valid data, i.e., is initialized and
/// with pmin being 'less-than' pmax.
@@ -390,7 +390,7 @@ namespace mln
template <typename P>
inline
P
- box<P>::center() const
+ box<P>::pcenter() const
{
mln_precondition(is_valid());
P center;
diff --git a/milena/mln/labeling/blobs_and_compute.hh b/milena/mln/labeling/blobs_and_compute.hh
index 4d5d5d8..b76b62a 100644
--- a/milena/mln/labeling/blobs_and_compute.hh
+++ b/milena/mln/labeling/blobs_and_compute.hh
@@ -53,7 +53,9 @@ namespace mln
*/
template <typename I, typename N, typename L, typename A>
- util::couple<mln_ch_value(I, L), util::array<mln_result(A)> >
+ util::couple<mln_ch_value(I,L),
+ util::couple<util::array<mln_result(A)>,
+ util::array<A> > >
blobs_and_compute(const Image<I>& input, const Neighborhood<N>& nbh,
L& nlabels, const Accumulator<A>& accu);
@@ -72,7 +74,8 @@ namespace mln
{
typedef mln_result(A) accu_result;
typedef mln_argument(A) accu_argument;
- typedef util::array<accu_result> result;
+ typedef util::couple<util::array<accu_result>,
+ util::array<A> > result;
void init()
{
@@ -133,7 +136,9 @@ namespace mln
template <typename I, typename N, typename L, typename A>
- util::couple<mln_ch_value(I,L), util::array<mln_result(A)> >
+ util::couple<mln_ch_value(I,L),
+ util::couple<util::array<mln_result(A)>,
+ util::array<A> > >
blobs_and_compute(const Image<I>& input, const Neighborhood<N>& nbh,
L& nlabels, const Accumulator<A>& accu)
{
@@ -151,7 +156,8 @@ namespace mln
output = canvas::labeling::blobs(input, nbh, nlabels, functor);
util::couple<out_t, typename func_t::result>
- result = make::couple(output, functor.result_);
+ result = make::couple(output,
+ make::couple(functor.result_, functor.accus_));
trace::exiting("labeling::blobs_and_compute");
return result;
diff --git a/milena/mln/labeling/colorize.hh b/milena/mln/labeling/colorize.hh
index 26a78df..69493d5 100644
--- a/milena/mln/labeling/colorize.hh
+++ b/milena/mln/labeling/colorize.hh
@@ -103,11 +103,9 @@ namespace mln
unsigned random_number()
{
- static unsigned last = 1;
+ unsigned last = colorize_::min_value + (colorize_::max_value - colorize_::min_value + 1) * rand();
- last = (323 * last + 6603) % 1025;
-
- return colorize_::min_value + last % colorize_::max_value;
+ return math::min(colorize_::min_value + last % colorize_::max_value, colorize_::max_value);
}
@@ -120,17 +118,42 @@ namespace mln
mln::value::rgb<n>
random_color(const mln::value::rgb<n>&)
{
- // Make sure the numbers are generated in the same order
- // whatever the compiler used.
- // For instance, ICC does not compute function arguments in
- // the same order as GCC does.
- unsigned
- red = random_number(),
- green = random_number(),
+ static unsigned
+ nelements = colorize_::max_value - colorize_::min_value + 1;
+ static util::array<util::set<unsigned> >
+ red_(nelements),
+ green_(nelements);
+
+ unsigned red, green, blue;
+
+ unsigned ntries = 0;
+ do
+ {
+ red = random_number();
+ ++ntries;
+ }
+ while (red_[red - colorize_::min_value].nelements() == nelements
+ && ntries < nelements);
+
+ if (ntries == nelements)
+ {
+ trace::warning("labeling::colorize - Can't find a new unique color. Returning black.");
+ return literal::black;
+ }
+
+
+ do
+ green = random_number();
+ while (red_[red - colorize_::min_value].has(green)
+ || green_[green - colorize_::min_value].nelements() == nelements);
+ red_[red - colorize_::min_value].insert(green);
+
+ do
blue = random_number();
- return mln::value::rgb<n>(red,
- green,
- blue);
+ while (green_[green - colorize_::min_value].has(blue));
+ green_[green - colorize_::min_value].insert(blue);
+
+ return mln::value::rgb<n>(red, green, blue);
}
}
diff --git a/milena/mln/labeling/compute.hh b/milena/mln/labeling/compute.hh
index d29242f..4f0d97d 100644
--- a/milena/mln/labeling/compute.hh
+++ b/milena/mln/labeling/compute.hh
@@ -1,4 +1,5 @@
-// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory
+// (LRDE)
//
// This file is part of Olena.
//
@@ -60,23 +61,6 @@ namespace mln
/// Compute an accumulator onto the pixel values of the image \p input.
/// for each component of the image \p label.
///
- /// \param[in] a An array of accumulator.
- /// \param[in] input The input image.
- /// \param[in] label The labeled image.
- /// \param[in] nlabels The number of labels in \p label.
- /// \return A mln::p_array of accumulator result (one result per label).
- //
- template <typename A, typename I, typename L>
- util::array<mln_result(A)>
- compute(util::array<A>& a,
- const Image<I>& input,
- const Image<L>& label,
- const mln_value(L)& nlabels);
-
-
- /// Compute an accumulator onto the pixel values of the image \p input.
- /// for each component of the image \p label.
- ///
/// \param[in] a An accumulator.
/// \param[in] input The input image.
/// \param[in] label The labeled image.
@@ -138,6 +122,23 @@ namespace mln
const mln_value(L)& nlabels);
+ /// Compute an accumulator onto the pixel values of the image \p input.
+ /// for each component of the image \p label.
+ ///
+ /// \param[in] a An array of accumulator.
+ /// \param[in] input The input image.
+ /// \param[in] label The labeled image.
+ /// \param[in] nlabels The number of labels in \p label.
+ /// \return A mln::p_array of accumulator result (one result per label).
+ //
+ template <typename A, typename I, typename L>
+ util::array<mln_result(A)>
+ compute(util::array<A>& a,
+ const Image<I>& input,
+ const Image<L>& label,
+ const mln_value(L)& nlabels);
+
+
# ifndef MLN_INCLUDE_ONLY
@@ -221,6 +222,49 @@ namespace mln
return res;
}
+ /// Generic implementation of labeling::compute.
+ ///
+ /// \param[in] accus_ An array of accumulators. If the size is
+ /// set to nlabels + 1, the accumulators are
+ /// considered as initialized. Otherwise,
+ /// the size is adjusted.
+ /// \param[in] label_ The labeled image.
+ /// \param[in] nlabels The number of labels in \p label.
+ ///
+ /// \return A mln::p_array of accumulator result (one result per label).
+ //
+ template <typename A, typename L>
+ inline
+ util::array<mln_result(A)>
+ compute(util::array<A>& accus,
+ const Image<L>& label_,
+ const mln_value(L)& nlabels)
+ {
+ trace::entering("labeling::impl::generic::compute");
+ internal::compute_tests(A(), label_, nlabels);
+
+ if (static_cast<unsigned>(nlabels) + 1 != accus.size())
+ {
+ accus.resize(0); // Make sure all the accumulators are
+ // re-initialized when resizing on next
+ // line.
+ accus.resize(static_cast<unsigned>(nlabels) + 1);
+ }
+
+ const L& label = exact(label_);
+
+ mln_piter(L) p(label.domain());
+ for_all(p)
+ accus[label(p)].take(p);
+
+ util::array<mln_result(A)> res;
+ convert::from_to(accus, res);
+
+ trace::exiting("labeling::impl::generic::compute");
+ return res;
+ }
+
+
/// Generic implementation of labeling::compute.
///
@@ -343,6 +387,15 @@ namespace mln
return impl::generic::compute(a, input, label, nlabels);
}
+ template <typename A, typename L>
+ inline
+ util::array<mln_result(A)>
+ compute_dispatch(util::array<A>& accus,
+ const Image<L>& label,
+ const mln_value(L)& nlabels)
+ {
+ return impl::generic::compute(accus, label, nlabels);
+ }
} // end of namespace mln::labeling::internal
@@ -406,6 +459,28 @@ namespace mln
template <typename A, typename L>
inline
util::array<mln_result(A)>
+ compute(util::array<A>& accus,
+ const Image<L>& label,
+ const mln_value(L)& nlabels)
+ {
+ trace::entering("labeling::compute");
+
+ internal::compute_tests(A(), label, nlabels);
+
+ typedef util::array<mln_result(A)> R;
+ R res = internal::compute_dispatch(accus, label, nlabels);
+
+ mln_postcondition(res.nelements() == static_cast<unsigned>(nlabels) + 1);
+
+ trace::exiting("labeling::compute");
+ return res;
+ }
+
+
+
+ template <typename A, typename L>
+ inline
+ util::array<mln_result(A)>
compute(const Accumulator<A>& a,
const Image<L>& label,
const mln_value(L)& nlabels)
diff --git a/milena/mln/transform/influence_zone_geodesic.hh b/milena/mln/transform/influence_zone_geodesic.hh
index 4d7255a..b9a763f 100644
--- a/milena/mln/transform/influence_zone_geodesic.hh
+++ b/milena/mln/transform/influence_zone_geodesic.hh
@@ -1,4 +1,5 @@
-// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory
+// (LRDE)
//
// This file is part of Olena.
//
@@ -104,16 +105,12 @@ namespace mln
const N& nbh = exact(nbh_);
internal::influence_zone_geodesic_tests(input, nbh);
- mln_precondition(input.domain().pmin() == literal::origin);
std::queue<mln_value(I)*> q;
mln_concrete(I) output;
util::array<int> dp = offsets_wrt(input, nbh);
const unsigned n_nbhs = dp.nelements();
- const unsigned
- ncols = input.ncols(),
- first_offset = input.border() * (ncols + 2 * input.border() + 1);
// Initialization.
{
@@ -124,9 +121,9 @@ namespace mln
extension::fill(output, 1); // in propagation
const unsigned nelts = input.nelements();
- const mln_value(I)* p_i = & input.at_(0, 0);
- mln_value(I)* p_o = & output.at_(0, 0);
- for (unsigned i = first_offset; i < nelts; ++i, ++p_i, ++p_o)
+ const mln_value(I)* p_i = input.buffer();
+ mln_value(I)* p_o = output.buffer();
+ for (unsigned i = 0; i < nelts; ++i, ++p_i, ++p_o)
{
if (*p_i == 0)
continue;
--
1.5.6.5
1
0
last-svn-commit-41-g41b6112 io/xml/save_text_lines.hh: New. Add partial support for PageContent XML format.
by Guillaume Lazzara 11 Mar '10
by Guillaume Lazzara 11 Mar '10
11 Mar '10
---
scribo/ChangeLog | 59 +++++++++-------
scribo/io/xml/save_text_lines.hh | 144 ++++++++++++++++++++++++++++++++++++++
2 files changed, 176 insertions(+), 27 deletions(-)
create mode 100644 scribo/io/xml/save_text_lines.hh
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index dfac25a..f3c022a 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,3 +1,8 @@
+2010-02-19 Guillaume Lazzara <z(a)lrde.epita.fr>
+
+ * io/xml/save_text_lines.hh: New. Add partial support for
+ PageContent XML format.
+
2010-03-11 Guillaume Lazzara <z(a)lrde.epita.fr>
Introduce new Scribo core classes and start using them.
@@ -48,58 +53,58 @@
Add anchor support in debug routines.
- * scribo/debug/alignment_decision_image.hh,
- * scribo/debug/links_decision_image.hh,
- * scribo/debug/save_linked_bboxes_image.hh,
- * scribo/draw/bounding_box_links.hh: Make use of anchor points to
+ * debug/alignment_decision_image.hh,
+ * debug/links_decision_image.hh,
+ * debug/save_linked_bboxes_image.hh,
+ * draw/bounding_box_links.hh: Make use of anchor points to
draw debug outputs.
2010-02-19 Guillaume Lazzara <z(a)lrde.epita.fr>
Add new link filters.
- * scribo/filter/object_links_non_aligned_simple.hh: Handle new
+ * filter/object_links_non_aligned_simple.hh: Handle new
cases.
- * scribo/filter/object_links_left_aligned.hh,
- * scribo/filter/object_links_right_aligned.hh: New filters.
+ * filter/object_links_left_aligned.hh,
+ * filter/object_links_right_aligned.hh: New filters.
2010-02-19 Guillaume Lazzara <z(a)lrde.epita.fr>
Improve object linking backend.
- * scribo/primitive/internal/find_left_link.hh,
- * scribo/primitive/internal/find_right_link.hh,
- * scribo/primitive/internal/is_invalid_link.hh: Remove.
+ * primitive/internal/find_left_link.hh,
+ * primitive/internal/find_right_link.hh,
+ * primitive/internal/is_invalid_link.hh: Remove.
- * scribo/primitive/link/internal/compute_anchor.hh,
- * scribo/primitive/link/internal/link_ms_dmax_base.hh,
- * scribo/primitive/link/internal/link_ms_dmax_ratio_base.hh,
- * scribo/primitive/link/internal/link_single_dmax_base.hh,
- * scribo/primitive/link/internal/link_single_dmax_ratio_base.hh,
- * scribo/primitive/link/with_single_down_link.hh,
- * scribo/primitive/link/with_single_left_link.hh,
- * scribo/primitive/link/with_single_left_link_dmax_ratio.hh,
- * scribo/primitive/link/with_single_right_link.hh,
- * scribo/primitive/link/with_single_right_link_dmax_ratio.hh,
- * scribo/primitive/link/with_single_up_link.hh: Introduce the
+ * primitive/link/internal/compute_anchor.hh,
+ * primitive/link/internal/link_ms_dmax_base.hh,
+ * primitive/link/internal/link_ms_dmax_ratio_base.hh,
+ * primitive/link/internal/link_single_dmax_base.hh,
+ * primitive/link/internal/link_single_dmax_ratio_base.hh,
+ * primitive/link/with_single_down_link.hh,
+ * primitive/link/with_single_left_link.hh,
+ * primitive/link/with_single_left_link_dmax_ratio.hh,
+ * primitive/link/with_single_right_link.hh,
+ * primitive/link/with_single_right_link_dmax_ratio.hh,
+ * primitive/link/with_single_up_link.hh: Introduce the
anchor concept and make use of it.
2010-02-19 Guillaume Lazzara <z(a)lrde.epita.fr>
- * scribo/filter/objects_with_holes.hh: New component filter.
+ * filter/objects_with_holes.hh: New component filter.
2010-02-19 Guillaume Lazzara <z(a)lrde.epita.fr>
- * scribo/draw/bounding_boxes.hh: Do not draw box centers anymore.
+ * draw/bounding_boxes.hh: Do not draw box centers anymore.
2010-02-19 Guillaume Lazzara <z(a)lrde.epita.fr>
Add dedicated routines for AFP's use case.
- * scribo/src/afp/components.hh,
- * scribo/src/afp/link.hh,
- * scribo/src/afp/regroup.hh: New.
+ * src/afp/components.hh,
+ * src/afp/link.hh,
+ * src/afp/regroup.hh: New.
2010-02-19 Guillaume Lazzara <z(a)lrde.epita.fr>
diff --git a/scribo/io/xml/save_text_lines.hh b/scribo/io/xml/save_text_lines.hh
new file mode 100644
index 0000000..c86f121
--- /dev/null
+++ b/scribo/io/xml/save_text_lines.hh
@@ -0,0 +1,144 @@
+// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_IO_XML_SAVE_TEXT_LINES_HH
+# define SCRIBO_IO_XML_SAVE_TEXT_LINES_HH
+
+/// \file
+///
+/// \brief Save text line information as XML.
+
+#include <fstream>
+#include <sstream>
+
+
+namespace scribo
+{
+
+ namespace io
+ {
+
+ namespace xml
+ {
+
+ /*! \brief Save text line information as XML.
+
+ We use a XML Schema part of the PAGE (Page Analysis and Ground
+ truth Elements) image representation framework.
+
+ This schema was used in the Page Segmentation COMPetition
+ (PSCOMP) for ICDAR 2009.
+
+ Its XSD file is located here:
+ http://schema.primaresearch.org/PAGE/gts/pagecontent/2009-03-16/pagecontent…
+
+ */
+ template <typename L>
+ void
+ save_text_lines(const std::string& input_name,
+ const line_set<L>& lines,
+ const std::string& output_name);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ template <typename L>
+ void
+ save_text_lines(const std::string& input_name,
+ const line_set<L>& lines,
+ const std::string& output_name)
+ {
+ trace::entering("scribo::io::xml:save_text_lines");
+
+ std::ofstream file(output_name.c_str());
+ if (! file)
+ {
+ std::cerr << "error: cannot open file '" << input_name << "'!";
+ abort();
+ }
+
+ file << "<?xml version=\"1.0\"?>" << std::endl;
+ file << "<pcGts xmlns=\"http://schema.primaresearch.org/PAGE/gts/pagecontent/2009-03-16\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://schema.primaresearch.org/PAGE/gts/pagecontent/2009-03-16 http://schema.primaresearch.org/PAGE/gts/pagecontent/2009-03-16/pagecontent…" pcGtsId=\"" << input_name << "\">" << std::endl;
+
+
+ file << " <pcMetadata>" << std::endl;
+ file << " <pcCreator>LRDE</pcCreator>" << std::endl;
+ file << " <pcCreated/>" << std::endl;
+ file << " <pcLastChange/>" << std::endl;
+ file << " <pcComments/>" << std::endl;
+ file << " </pcMetadata>" << std::endl;
+
+ file << " <page image_filename=\"" << input_name
+ << "\" image_width=\"" << lines.component_set_().labeled_image().ncols()
+ << "\" image_height=\"" << lines.component_set_().labeled_image().nrows()
+ << "\">" << std::endl;
+
+ for_all_lines(l, lines)
+ {
+ file << " <text_region id=\"" << lines(l).id()
+ << "\" txt_orientation=\"0.000\" "
+ << "txt_reading_orientation=\"0.000\" "
+ << "txt_reading_direction=\"Left_To_Right\" "
+ << "txt_reverse_video=\"No\" "
+ << "txt_indented=\"No\">"
+ << std::endl;
+
+ file << " <coords>" << std::endl
+ << " <point x=\"" << lines(l).bbox().pmin().row()
+ << "\" y=\"" << lines(l).bbox().pmin().col() << "\"/>"
+ << std::endl
+ << " <point x=\"" << lines(l).bbox().pmin().row()
+ << "\" y=\"" << lines(l).bbox().pmax().col() << "\"/>"
+ << std::endl
+ << " <point x=\"" << lines(l).bbox().pmax().row()
+ << "\" y=\"" << lines(l).bbox().pmin().col() << "\"/>"
+ << std::endl
+ << " <point x=\"" << lines(l).bbox().pmax().row()
+ << "\" y=\"" << lines(l).bbox().pmax().col() << "\"/>"
+ << std::endl
+ << " </coords>" << std::endl;
+ }
+
+ file << " </text_region>" << std::endl;
+ file << " </page>" << std::endl;
+ file << "</pcGts>" << std::endl;
+
+
+
+ trace::exiting("scribo::io::xml::save_text_lines");
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace scribo::io::xml
+
+ } // end of namespace scribo::io
+
+} // end of namespace scribo
+
+
+#endif // ! SCRIBO_IO_XML_SAVE_TEXT_LINES_HH
--
1.5.6.5
1
0
11 Mar '10
* scribo/debug/alignment_decision_image.hh,
* scribo/debug/links_decision_image.hh,
* scribo/debug/save_linked_bboxes_image.hh,
* scribo/draw/bounding_box_links.hh: Make use of anchor points to
draw debug outputs.
---
scribo/ChangeLog | 10 +++++
scribo/debug/alignment_decision_image.hh | 26 ++++++++++--
scribo/debug/links_decision_image.hh | 34 ++++++++++++++---
scribo/debug/save_linked_bboxes_image.hh | 48 +++++++++++++++++------
scribo/draw/bounding_box_links.hh | 61 ++++++++++++------------------
5 files changed, 118 insertions(+), 61 deletions(-)
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index 01ab3a1..52a13dd 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,5 +1,15 @@
2010-02-19 Guillaume Lazzara <z(a)lrde.epita.fr>
+ Add anchor support in debug routines.
+
+ * scribo/debug/alignment_decision_image.hh,
+ * scribo/debug/links_decision_image.hh,
+ * scribo/debug/save_linked_bboxes_image.hh,
+ * scribo/draw/bounding_box_links.hh: Make use of anchor points to
+ draw debug outputs.
+
+2010-02-19 Guillaume Lazzara <z(a)lrde.epita.fr>
+
Add new link filters.
* scribo/filter/object_links_non_aligned_simple.hh: Handle new
diff --git a/scribo/debug/alignment_decision_image.hh b/scribo/debug/alignment_decision_image.hh
index 9a4fa50..e3b6163 100644
--- a/scribo/debug/alignment_decision_image.hh
+++ b/scribo/debug/alignment_decision_image.hh
@@ -114,7 +114,8 @@ namespace scribo
alignment_decision_image(const Image<I>& input_,
const object_links<L>& links,
const object_links<L>& filtered_links,
- const Alignment& alignment)
+ const Alignment& alignment,
+ unsigned max_link_length)
{
trace::entering("scribo::debug::alignment_decision_image");
const I& input = exact(input_);
@@ -147,10 +148,11 @@ namespace scribo
mln::util::couple<P,P>
anchors = internal::find_anchors(objects, i, links[i], alignment);
- mln::draw::line(decision_image,
- anchors.first(),
- anchors.second(),
- value);
+ if (norm::l1_distance(anchors.first(), anchors.second()) < max_link_length)
+ mln::draw::line(decision_image,
+ anchors.first(),
+ anchors.second(),
+ value);
}
}
@@ -159,6 +161,20 @@ namespace scribo
}
+ template <typename I, typename L>
+ mln_ch_value(I,value::rgb8)
+ alignment_decision_image(const Image<I>& input_,
+ const object_links<L>& links,
+ const object_links<L>& filtered_links,
+ const Alignment& alignment)
+ {
+ return alignment_decision_image(input_,
+ links,
+ filtered_links,
+ alignment,
+ mln_max(unsigned));
+ }
+
# endif // ! MLN_INCLUDE_ONLY
diff --git a/scribo/debug/links_decision_image.hh b/scribo/debug/links_decision_image.hh
index 368d9b7..e1cf766 100644
--- a/scribo/debug/links_decision_image.hh
+++ b/scribo/debug/links_decision_image.hh
@@ -36,6 +36,7 @@
# include <mln/value/rgb8.hh>
# include <mln/literal/colors.hh>
# include <mln/util/array.hh>
+# include <mln/norm/l1.hh>
# include <scribo/core/object_groups.hh>
# include <scribo/draw/bounding_boxes.hh>
@@ -54,8 +55,15 @@ namespace scribo
mln_ch_value(I,value::rgb8)
links_decision_image(const Image<I>& input_,
const object_links<L>& links,
- const object_links<L>& filtered_links);
+ const object_links<L>& filtered_links,
+ unsigned max_link_length);
+ /// \overload
+ template <typename I, typename L>
+ mln_ch_value(I,value::rgb8)
+ links_decision_image(const Image<I>& input_,
+ const object_links<L>& links,
+ const object_links<L>& filtered_links);
# ifndef MLN_INCLUDE_ONLY
@@ -63,7 +71,8 @@ namespace scribo
mln_ch_value(I,value::rgb8)
links_decision_image(const Image<I>& input_,
const object_links<L>& links,
- const object_links<L>& filtered_links)
+ const object_links<L>& filtered_links,
+ unsigned max_link_length)
{
trace::entering("scribo::debug::links_decision_image");
const I& input = exact(input_);
@@ -105,10 +114,11 @@ namespace scribo
while (objects(p2) != links[i] && objects.domain().has(p2))
++p2.col();
- mln::draw::line(links_decision_image,
- p1,
- p2,
- value);
+ if (norm::l1_distance(p2.to_vec(), p1.to_vec()) < max_link_length)
+ mln::draw::line(links_decision_image,
+ p1,
+ p2,
+ value);
}
}
@@ -117,6 +127,18 @@ namespace scribo
}
+ template <typename I, typename L>
+ mln_ch_value(I,value::rgb8)
+ links_decision_image(const Image<I>& input_,
+ const object_links<L>& links,
+ const object_links<L>& filtered_links)
+ {
+ return links_decision_image(input_,
+ links,
+ filtered_links,
+ mln_max(unsigned));
+ }
+
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace scribo::debug
diff --git a/scribo/debug/save_linked_bboxes_image.hh b/scribo/debug/save_linked_bboxes_image.hh
index 364f06e..c4e3cd1 100644
--- a/scribo/debug/save_linked_bboxes_image.hh
+++ b/scribo/debug/save_linked_bboxes_image.hh
@@ -62,6 +62,21 @@ namespace scribo
/// \param[in] box_value Value used to draw line bounding boxes.
/// \param[in] link_value Value used to draw line links.
/// \param[in] filename The target file name.
+ /// \param[in] anchor Anchor from where the links are drawn.
+ //
+ template <typename I, typename L>
+ void
+ save_linked_bboxes_image(const Image<I>& input,
+ const object_image(L)& objects,
+ const object_links<L>& array,
+ const value::rgb8& box_value,
+ const value::rgb8& link_value,
+ const std::string& filename,
+ anchor::Type anchor);
+
+ /// \overload
+ /// The default anchor type is set to anchor::Center.
+ //
template <typename I, typename L>
void
save_linked_bboxes_image(const Image<I>& input,
@@ -145,20 +160,16 @@ namespace scribo
const object_links<L>& array,
const value::rgb8& box_value,
const value::rgb8& link_value,
- const std::string& filename)
+ const std::string& filename,
+ anchor::Type anchor)
{
trace::entering("scribo::debug::save_linked_bboxes_image");
mln_precondition(exact(input).is_valid());
mln_ch_value(I,value::rgb8) tmp = data::convert(value::rgb8(), input);
- mln::util::array<mln_result(accu::center<mln_psite(L)>)>
- mass_center = labeling::compute(accu::meta::center(),
- objects,
- objects.nlabels());
-
draw::bounding_boxes(tmp, objects.bboxes(), box_value);
- draw::bounding_box_links(tmp, mass_center, array, link_value);
+ draw::bounding_box_links(tmp, array, link_value, anchor);
io::ppm::save(tmp, filename);
@@ -171,6 +182,22 @@ namespace scribo
void
save_linked_bboxes_image(const Image<I>& input,
const object_image(L)& objects,
+ const object_links<L>& array,
+ const value::rgb8& box_value,
+ const value::rgb8& link_value,
+ const std::string& filename)
+ {
+ save_linked_bboxes_image(input, objects, array, box_value,
+ link_value, filename, anchor::Center);
+ }
+
+
+
+ template <typename I, typename L>
+ inline
+ void
+ save_linked_bboxes_image(const Image<I>& input,
+ const object_image(L)& objects,
const object_links<L>& left_link,
const object_links<L>& right_link,
const value::rgb8& box_value,
@@ -182,13 +209,8 @@ namespace scribo
mln_ch_value(I,value::rgb8) tmp = data::convert(value::rgb8(), input);
- mln::util::array<mln_result(accu::center<mln_psite(L)>)>
- mass_center = labeling::compute(accu::meta::center(),
- objects,
- objects.nlabels());
-
draw::bounding_boxes(tmp, objects.bboxes(), box_value);
- draw::bounding_box_links(tmp, mass_center,
+ draw::bounding_box_links(tmp, objects.mass_centers(),
left_link, right_link,
value);
diff --git a/scribo/draw/bounding_box_links.hh b/scribo/draw/bounding_box_links.hh
index 47a4f0a..ed6337d 100644
--- a/scribo/draw/bounding_box_links.hh
+++ b/scribo/draw/bounding_box_links.hh
@@ -35,9 +35,11 @@
# include <mln/util/array.hh>
# include <mln/canvas/browsing/depth_first_search.hh>
+# include <scribo/core/tag/anchor.hh>
# include <scribo/core/macros.hh>
# include <scribo/core/object_links.hh>
# include <scribo/primitive/internal/is_link_valid.hh>
+# include <scribo/primitive/link/internal/compute_anchor.hh>
namespace scribo
{
@@ -54,25 +56,22 @@ namespace scribo
/// \param[in] bboxes Bounding boxes.
/// \param[in] links Bounding box links.
/// \param[in] value Value used to draw links.
+ /// \param[in] anchor Anchor from where the links are drawn.
+ //
template <typename I, typename L>
void
bounding_box_links(Image<I>& input_,
- const mln::util::array< box<mln_site(I)> >& bboxes,
const object_links<L>& link,
- const mln_value(I)& value);
+ const mln_value(I)& value,
+ anchor::Type anchor);
- /// Draw a list of bounding box links from their mass centers.
- ///
- /// \param[in,out] input_ An image where to draw.
- /// \param[in] mass_centers Bounding boxes mass centers.
- /// \param[in] links Bounding box links.
- /// \param[in] value Value used to draw links.
+ /// \overload
+ /// The default anchor type is set to anchor::Center.
+ //
template <typename I, typename L>
- inline
void
bounding_box_links(Image<I>& input_,
- const mln::util::array<mln_site(I)::vec>& mass_centers,
const object_links<L>& link,
const mln_value(I)& value);
@@ -236,9 +235,9 @@ namespace scribo
inline
void
bounding_box_links(Image<I>& input_,
- const mln::util::array< box<mln_site(I)> >& bboxes,
const object_links<L>& links,
- const mln_value(I)& value)
+ const mln_value(I)& value,
+ anchor::Type anchor)
{
trace::entering("scribo::draw::bounding_box_links");
@@ -246,41 +245,29 @@ namespace scribo
mln_precondition(input.is_valid());
+ const object_image(L)& objects = links.object_image_();
for_all_components(i, links)
- if (links[i] != i)
- mln::draw::line(input,
- bboxes[i].center(),
- bboxes[links[i]].center(),
- value);
+ if (links[i] != i && links[i] != 0)
+ {
+ mln_site(L)
+ p1 = primitive::link::internal::compute_anchor(objects, i, anchor),
+ p2 = primitive::link::internal::compute_anchor(objects, links[i], anchor);
+
+ mln::draw::line(input, p1, p2, value);
+ }
trace::exiting("scribo::draw::bounding_box_links");
}
+
template <typename I, typename L>
inline
void
- bounding_box_links(Image<I>& input_,
- const mln::util::array<mln_site(I)::vec>& mass_centers,
+ bounding_box_links(Image<I>& input,
const object_links<L>& links,
const mln_value(I)& value)
{
- trace::entering("scribo::draw::bounding_box_links");
-
- I& input = exact(input_);
-
- mln_precondition(input.is_valid());
-
- for_all_components(i, links)
- {
- if (links[i] != i)
- mln::draw::line(input,
- mass_centers[i],
- mass_centers[links[i]],
- value);
- input(mass_centers[i]) = value;
- }
-
- trace::exiting("scribo::draw::bounding_box_links");
+ return bounding_box_links(input, links, value, anchor::Center);
}
@@ -401,7 +388,7 @@ namespace scribo
mln_precondition(exact(g).v_nmax() == bboxes.nelements());
internal::draw_graph_edges_functor<I> f(exact(input), bboxes, link_value);
- canvas::browsing::depth_first_search(g, f);
+ mln::canvas::browsing::depth_first_search(g, f);
trace::exiting("scribo::draw::bounding_box_links");
}
--
1.5.6.5
1
0
* scribo/filter/object_links_non_aligned_simple.hh: Handle new
cases.
* scribo/filter/object_links_left_aligned.hh,
* scribo/filter/object_links_right_aligned.hh: New filters.
---
scribo/ChangeLog | 10 +++++
...top_aligned.hh => object_links_left_aligned.hh} | 33 +++++++++---------
scribo/filter/object_links_non_aligned_simple.hh | 36 ++++++++++++++++++++
...op_aligned.hh => object_links_right_aligned.hh} | 30 ++++++++--------
4 files changed, 78 insertions(+), 31 deletions(-)
copy scribo/filter/{object_links_top_aligned.hh => object_links_left_aligned.hh} (76%)
copy scribo/filter/{object_links_top_aligned.hh => object_links_right_aligned.hh} (77%)
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index 45faa9f..01ab3a1 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,5 +1,15 @@
2010-02-19 Guillaume Lazzara <z(a)lrde.epita.fr>
+ Add new link filters.
+
+ * scribo/filter/object_links_non_aligned_simple.hh: Handle new
+ cases.
+
+ * scribo/filter/object_links_left_aligned.hh,
+ * scribo/filter/object_links_right_aligned.hh: New filters.
+
+2010-02-19 Guillaume Lazzara <z(a)lrde.epita.fr>
+
Improve object linking backend.
* scribo/primitive/internal/find_left_link.hh,
diff --git a/scribo/filter/object_links_top_aligned.hh b/scribo/filter/object_links_left_aligned.hh
similarity index 76%
copy from scribo/filter/object_links_top_aligned.hh
copy to scribo/filter/object_links_left_aligned.hh
index 4a92c96..e69b110 100644
--- a/scribo/filter/object_links_top_aligned.hh
+++ b/scribo/filter/object_links_left_aligned.hh
@@ -23,14 +23,15 @@
// 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
+#ifndef SCRIBO_FILTER_OBJECT_LINKS_LEFT_ALIGNED_HH
+# define SCRIBO_FILTER_OBJECT_LINKS_LEFT_ALIGNED_HH
/// \file
///
-/// Invalidate links between two objects if their top are not
+/// Invalidate links between two objects if their left are not
/// aligned.
-
+///
+/// \fixme UPDATE DOC!
# include <mln/util/array.hh>
@@ -48,7 +49,7 @@ namespace scribo
using namespace mln;
- /*! \brief Invalidate links between two objects if their top are not
+ /*! \brief Invalidate links between two objects if their left are not
aligned.
\param[in] objects An object image.
@@ -77,13 +78,13 @@ namespace scribo
\endverbatim
- The angle between the two tops must be lower than \p max_alpha.
+ The angle between the two lefts 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);
+ object_links_left_aligned(const object_image(L)& objects,
+ const object_links<L>& links,
+ float max_alpha);
# ifndef MLN_INCLUDE_ONLY
@@ -91,21 +92,21 @@ namespace scribo
template <typename L>
object_links<L>
- object_links_top_aligned(const object_image(L)& objects,
- const object_links<L>& links,
- float max_alpha)
+ object_links_left_aligned(const object_image(L)& objects,
+ const object_links<L>& links,
+ float max_alpha)
{
- trace::entering("scribo::filter::object_links_top_aligned");
+ trace::entering("scribo::filter::object_links_left_aligned");
mln_precondition(objects.is_valid());
mln_precondition(links.is_valid());
object_links<L>
output = object_links_non_aligned_simple(objects, links,
- 1,
+ 3,
max_alpha);
- trace::exiting("scribo::filter::object_links_top_aligned");
+ trace::exiting("scribo::filter::object_links_left_aligned");
return output;
}
@@ -118,4 +119,4 @@ namespace scribo
} // end of namespace scribo
-#endif // ! SCRIBO_FILTER_OBJECT_LINKS_TOP_ALIGNED_HH
+#endif // ! SCRIBO_FILTER_OBJECT_LINKS_LEFT_ALIGNED_HH
diff --git a/scribo/filter/object_links_non_aligned_simple.hh b/scribo/filter/object_links_non_aligned_simple.hh
index 706497d..15be8e9 100644
--- a/scribo/filter/object_links_non_aligned_simple.hh
+++ b/scribo/filter/object_links_non_aligned_simple.hh
@@ -84,6 +84,8 @@ namespace scribo
0 = center
1 = top
2 = bottom
+ 3 = left
+ 4 = right
*/
template <typename L>
@@ -166,6 +168,40 @@ namespace scribo
}
}
}
+ // Left
+ else if (edge == 3)
+ {
+ 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].pmin().col()
+ - bboxes[links[i]].pmin().col());
+
+ if (std::atan(dc / dr) > max_alpha_rad)
+ output[i] = i;
+ }
+ }
+ }
+ // Right
+ else if (edge == 4)
+ {
+ 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].pmax().col()
+ - bboxes[links[i]].pmax().col());
+
+ if (std::atan(dc / dr) > max_alpha_rad)
+ output[i] = i;
+ }
+ }
+ }
else
{
trace::warning("Invalid edge value... Aborting computation.");
diff --git a/scribo/filter/object_links_top_aligned.hh b/scribo/filter/object_links_right_aligned.hh
similarity index 77%
copy from scribo/filter/object_links_top_aligned.hh
copy to scribo/filter/object_links_right_aligned.hh
index 4a92c96..2ee0280 100644
--- a/scribo/filter/object_links_top_aligned.hh
+++ b/scribo/filter/object_links_right_aligned.hh
@@ -23,12 +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_FILTER_OBJECT_LINKS_TOP_ALIGNED_HH
-# define SCRIBO_FILTER_OBJECT_LINKS_TOP_ALIGNED_HH
+#ifndef SCRIBO_FILTER_OBJECT_LINKS_RIGHT_ALIGNED_HH
+# define SCRIBO_FILTER_OBJECT_LINKS_RIGHT_ALIGNED_HH
/// \file
///
-/// Invalidate links between two objects if their top are not
+/// Invalidate links between two objects if their right are not
/// aligned.
@@ -48,7 +48,7 @@ namespace scribo
using namespace mln;
- /*! \brief Invalidate links between two objects if their top are not
+ /*! \brief Invalidate links between two objects if their right are not
aligned.
\param[in] objects An object image.
@@ -77,13 +77,13 @@ namespace scribo
\endverbatim
- The angle between the two tops must be lower than \p max_alpha.
+ The angle between the two rights 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);
+ object_links_right_aligned(const object_image(L)& objects,
+ const object_links<L>& links,
+ float max_alpha);
# ifndef MLN_INCLUDE_ONLY
@@ -91,21 +91,21 @@ namespace scribo
template <typename L>
object_links<L>
- object_links_top_aligned(const object_image(L)& objects,
- const object_links<L>& links,
- float max_alpha)
+ object_links_right_aligned(const object_image(L)& objects,
+ const object_links<L>& links,
+ float max_alpha)
{
- trace::entering("scribo::filter::object_links_top_aligned");
+ trace::entering("scribo::filter::object_links_right_aligned");
mln_precondition(objects.is_valid());
mln_precondition(links.is_valid());
object_links<L>
output = object_links_non_aligned_simple(objects, links,
- 1,
+ 4,
max_alpha);
- trace::exiting("scribo::filter::object_links_top_aligned");
+ trace::exiting("scribo::filter::object_links_right_aligned");
return output;
}
@@ -118,4 +118,4 @@ namespace scribo
} // end of namespace scribo
-#endif // ! SCRIBO_FILTER_OBJECT_LINKS_TOP_ALIGNED_HH
+#endif // ! SCRIBO_FILTER_OBJECT_LINKS_RIGHT_ALIGNED_HH
--
1.5.6.5
1
0
11 Mar '10
* scribo/primitive/internal/find_left_link.hh,
* scribo/primitive/internal/find_right_link.hh,
* scribo/primitive/internal/is_invalid_link.hh: Remove.
* scribo/primitive/link/internal/compute_anchor.hh,
* scribo/primitive/link/internal/link_ms_dmax_base.hh,
* scribo/primitive/link/internal/link_ms_dmax_ratio_base.hh,
* scribo/primitive/link/internal/link_single_dmax_base.hh,
* scribo/primitive/link/internal/link_single_dmax_ratio_base.hh,
* scribo/primitive/link/with_single_down_link.hh,
* scribo/primitive/link/with_single_left_link.hh,
* scribo/primitive/link/with_single_left_link_dmax_ratio.hh,
* scribo/primitive/link/with_single_right_link.hh,
* scribo/primitive/link/with_single_right_link_dmax_ratio.hh,
* scribo/primitive/link/with_single_up_link.hh: Introduce the
anchor concept and make use of it.
---
scribo/ChangeLog | 21 +++
scribo/primitive/internal/find_left_link.hh | 108 ---------------
scribo/primitive/internal/find_right_link.hh | 108 ---------------
scribo/primitive/internal/is_invalid_link.hh | 100 --------------
scribo/primitive/link/internal/compute_anchor.hh | 143 +++++++++++++++++---
.../primitive/link/internal/link_ms_dmax_base.hh | 27 ++--
.../link/internal/link_ms_dmax_ratio_base.hh | 18 ++-
.../link/internal/link_single_dmax_base.hh | 21 ++--
.../link/internal/link_single_dmax_ratio_base.hh | 20 ++--
...ingle_left_link.hh => with_single_down_link.hh} | 68 +++++++---
scribo/primitive/link/with_single_left_link.hh | 2 +-
.../link/with_single_left_link_dmax_ratio.hh | 10 +-
scribo/primitive/link/with_single_right_link.hh | 4 +-
.../link/with_single_right_link_dmax_ratio.hh | 8 +-
...le_right_link_top.hh => with_single_up_link.hh} | 81 +++++++----
15 files changed, 296 insertions(+), 443 deletions(-)
delete mode 100644 scribo/primitive/internal/find_left_link.hh
delete mode 100644 scribo/primitive/internal/find_right_link.hh
delete mode 100644 scribo/primitive/internal/is_invalid_link.hh
copy scribo/primitive/link/{with_single_left_link.hh => with_single_down_link.hh} (60%)
copy scribo/primitive/link/{with_single_right_link_top.hh => with_single_up_link.hh} (60%)
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index 891cd30..45faa9f 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,5 +1,26 @@
2010-02-19 Guillaume Lazzara <z(a)lrde.epita.fr>
+ Improve object linking backend.
+
+ * scribo/primitive/internal/find_left_link.hh,
+ * scribo/primitive/internal/find_right_link.hh,
+ * scribo/primitive/internal/is_invalid_link.hh: Remove.
+
+ * scribo/primitive/link/internal/compute_anchor.hh,
+ * scribo/primitive/link/internal/link_ms_dmax_base.hh,
+ * scribo/primitive/link/internal/link_ms_dmax_ratio_base.hh,
+ * scribo/primitive/link/internal/link_single_dmax_base.hh,
+ * scribo/primitive/link/internal/link_single_dmax_ratio_base.hh,
+ * scribo/primitive/link/with_single_down_link.hh,
+ * scribo/primitive/link/with_single_left_link.hh,
+ * scribo/primitive/link/with_single_left_link_dmax_ratio.hh,
+ * scribo/primitive/link/with_single_right_link.hh,
+ * scribo/primitive/link/with_single_right_link_dmax_ratio.hh,
+ * scribo/primitive/link/with_single_up_link.hh: Introduce the
+ anchor concept and make use of it.
+
+2010-02-19 Guillaume Lazzara <z(a)lrde.epita.fr>
+
* scribo/filter/objects_with_holes.hh: New component filter.
2010-02-19 Guillaume Lazzara <z(a)lrde.epita.fr>
diff --git a/scribo/primitive/internal/find_left_link.hh b/scribo/primitive/internal/find_left_link.hh
deleted file mode 100644
index 4f30e36..0000000
--- a/scribo/primitive/internal/find_left_link.hh
+++ /dev/null
@@ -1,108 +0,0 @@
-// 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_LEFT_LINK_HH
-# define SCRIBO_PRIMITIVE_INTERNAL_FIND_LEFT_LINK_HH
-
-/// \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>
-# include <scribo/primitive/internal/is_invalid_link.hh>
-
-//FIXME: not generic.
-# include <mln/core/alias/dpoint2d.hh>
-
-namespace scribo
-{
-
- namespace primitive
- {
-
- namespace internal
- {
-
- /// Find the left neighbor of a line of text if exists.
- ///
- /// \param objects An image of objects.
- /// \param left_link The left neighbors.
- /// \param current_comp A text line id.
- /// \param dmax The maximum lookup distance.
- /// \param c The lookup start point.
- //
- template <typename L>
- mln::util::couple<bool, mln_site(L)>
- find_left_link(const object_image(L)& objects,
- mln::util::array<unsigned>& left_link,
- unsigned current_comp,
- float dmax,
- const mln_site(L)& c);
-
-
-# ifndef MLN_INCLUDE_ONLY
-
- template <typename L>
- mln::util::couple<bool, mln_site(L)>
- find_left_link(const object_image(L)& objects,
- mln::util::array<unsigned>& left_link,
- unsigned current_comp,
- float dmax,
- const mln_site(L)& c)
- {
- ///FIXME: the following code is not generic...
- /// First site on the right of the central site
- mln_site(L) p = c + mln::left;
-
- while (is_invalid_link(objects, left_link, p,
- current_comp, c, dmax))
- --p.col();
-
- bool
- b = update_link_array(objects, left_link, p, c, current_comp, dmax);
-
- 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_LEFT_LINK_HH
diff --git a/scribo/primitive/internal/find_right_link.hh b/scribo/primitive/internal/find_right_link.hh
deleted file mode 100644
index 09e60f9..0000000
--- a/scribo/primitive/internal/find_right_link.hh
+++ /dev/null
@@ -1,108 +0,0 @@
-// 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_RIGHT_LINK_HH
-# define SCRIBO_PRIMITIVE_INTERNAL_FIND_RIGHT_LINK_HH
-
-/// \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>
-# include <scribo/primitive/internal/is_invalid_link.hh>
-
-//FIXME: not generic.
-# include <mln/core/alias/dpoint2d.hh>
-
-namespace scribo
-{
-
- namespace primitive
- {
-
- namespace internal
- {
-
- /// Find the right neighbor of a line of text if exists.
- ///
- /// \param objects An image of objects.
- /// \param right_link The right neighbors.
- /// \param current_comp A text line id.
- /// \param dmax The maximum lookup distance.
- /// \param c The lookup start point.
- //
- template <typename L>
- mln::util::couple<bool, mln_site(L)>
- find_right_link(const object_image(L)& objects,
- mln::util::array<unsigned>& right_link,
- unsigned current_comp,
- float dmax,
- const mln_site(L)& c);
-
-
-# ifndef MLN_INCLUDE_ONLY
-
- template <typename L>
- mln::util::couple<bool, mln_site(L)>
- find_right_link(const object_image(L)& objects,
- mln::util::array<unsigned>& right_link,
- unsigned current_comp,
- float dmax,
- const mln_site(L)& c)
- {
- /// FIXME: the following code is not generic...
- /// First site on the right of the central site
- mln_site(L) p = c + mln::right;
-
- while (is_invalid_link(objects, right_link, p,
- current_comp, c, dmax))
- ++p.col();
-
- bool
- b = update_link_array(objects, right_link, p, c, current_comp, dmax);
-
- 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_RIGHT_LINK_HH
diff --git a/scribo/primitive/internal/is_invalid_link.hh b/scribo/primitive/internal/is_invalid_link.hh
deleted file mode 100644
index e6343fd..0000000
--- a/scribo/primitive/internal/is_invalid_link.hh
+++ /dev/null
@@ -1,100 +0,0 @@
-// 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_IS_INVALID_LINK_HH
-# define SCRIBO_PRIMITIVE_INTERNAL_IS_INVALID_LINK_HH
-
-/// \file
-///
-/// Check whether an objects link is invalid or not.
-///
-/// \todo To be deleted.
-
-# include <mln/math/abs.hh>
-# include <mln/literal/zero.hh>
-
-# include <scribo/core/object_image.hh>
-
-namespace scribo
-{
-
- namespace primitive
- {
-
- namespace internal
- {
-
- using namespace mln;
-
-
- /// Check whether an objects link is invalid or not.
- ///
- /// \param objects An image of objects.
- /// \param left_link The left neighbors.
- /// \param p The current site.
- /// \param current_comp The current object id.
- /// \param c The left link start point.
- /// \param dmax The maximum lookup distance.
- //
- template <typename L>
- bool
- is_invalid_link(const object_image(L)& objects_,
- mln::util::array<unsigned>& link_array,
- const mln_site(L)& p,
- unsigned current_comp,
- const mln_site(L)& c,
- float dmax);
-
-# ifndef MLN_INCLUDE_ONLY
-
- template <typename L>
- inline
- bool
- is_invalid_link(const object_image(L)& objects,
- mln::util::array<unsigned>& link_array,
- const mln_site(L)& p,
- unsigned current_comp,
- const mln_site(L)& c,
- 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
- && static_cast<float>(math::abs(p.col() - c.col())) < dmax); // Not too far
- }
-
-# endif // ! MLN_INCLUDE_ONLY
-
- } // end of namespace scribo::primitive::internal
-
- } // end of namespace scribo::primitive
-
-} // end of namespace scribo
-
-
-#endif // ! SCRIBO_PRIMITIVE_INTERNAL_IS_INVALID_LINK_HH
-
-
diff --git a/scribo/primitive/link/internal/compute_anchor.hh b/scribo/primitive/link/internal/compute_anchor.hh
index c7bae11..0d3b6f2 100644
--- a/scribo/primitive/link/internal/compute_anchor.hh
+++ b/scribo/primitive/link/internal/compute_anchor.hh
@@ -52,15 +52,11 @@ namespace scribo
/*! \brief Return the proper anchor used to find a neighbor.
\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:
- - anchor::MassCenter, mass center anchor.
- - anchor::Top, top anchor.
- - anchor::Bottom, bottom anchor.
- - anchor::Center, center anchor.
+ Anchor can take one of the values defined in the
+ scribo::anchor::Type enum.
Top and bottom anchors are respectively computed from the
@@ -76,64 +72,169 @@ namespace scribo
out.row = P.row - min(10, h /10)
*/
- template <typename L, typename P>
+ template <typename L>
mln_site(L)
compute_anchor(const object_image(L)& objects,
- const mln::util::array<P>& mass_centers,
unsigned current_object, anchor::Type anchor);
# ifndef MLN_INCLUDE_ONLY
- template <typename L, typename P>
+ template <typename L>
mln_site(L)
compute_anchor(const object_image(L)& objects,
- const mln::util::array<P>& mass_centers,
unsigned current_object, anchor::Type anchor)
{
+ typedef mln_site(L) P;
+
unsigned h = objects.bbox(current_object).pmax().row()
- objects.bbox(current_object).pmin().row();
+ unsigned w = objects.bbox(current_object).pmax().col()
+ - objects.bbox(current_object).pmin().col();
mln_site(L) sp = objects.bbox(current_object).center();
- def::coord r = 0;
switch (anchor)
{
- // Masss Center
+ // Component masss center
case anchor::MassCenter:
- return mass_centers(current_object);
+ return objects.mass_center(current_object);
- // Top
+ // Bounding box top center
case anchor::Top:
if (h < 30)
- r = objects.bbox(current_object).pmin().row()
+ sp.row() = objects.bbox(current_object).pmin().row()
+ math::min(2u, (h + 1) / 2 - 1);
else
- r = objects.bbox(current_object).pmin().row()
+ sp.row() = objects.bbox(current_object).pmin().row()
+ math::min(10u, h /10);
break;
- // Bottom
+ // Bounding box bottom center
case anchor::Bottom:
if (h < 30)
- r = objects.bbox(current_object).pmax().row()
+ sp.row() = objects.bbox(current_object).pmax().row()
- math::min(2u, (h + 1) / 2 - 1);
else
- r = objects.bbox(current_object).pmax().row()
+ sp.row() = objects.bbox(current_object).pmax().row()
- math::min(10u, h /10);
break;
+
+ // Bounding box center
case anchor::Center:
return objects.bbox(current_object).center();
+
+ // Bounding box actual left center
+ case anchor::ActualLeft:
+ return P(objects.bbox(current_object).center().row(),
+ objects.bbox(current_object).pmin().col());
+
+
+ // Bounding box left center
+ case anchor::Left:
+ if (w < 30)
+ sp.col() = objects.bbox(current_object).pmin().col()
+ + math::min(2u, (w + 1) / 2 - 1);
+ else
+ sp.col() = objects.bbox(current_object).pmin().col()
+ + math::min(10u, w /10);
+ break;
+
+
+ // Bounding box actual right center
+ case anchor::ActualRight:
+ return P(objects.bbox(current_object).center().row(),
+ objects.bbox(current_object).pmax().col());
+
+
+ // Bounding box right center
+ case anchor::Right:
+ if (w < 30)
+ sp.col() = objects.bbox(current_object).pmax().col()
+ - math::min(2u, (w + 1) / 2 - 1);
+ else
+ sp.col() = objects.bbox(current_object).pmax().col()
+ - math::min(10u, w /10);
+ break;
+
+
+ // Bounding box top left
+ case anchor::TopLeft:
+ if (h < 30)
+ sp.row() = objects.bbox(current_object).pmin().row()
+ + math::min(2u, (h + 1) / 2 - 1);
+ else
+ sp.row() = objects.bbox(current_object).pmin().row()
+ + math::min(10u, h /10);
+ if (w < 30)
+ sp.col() = objects.bbox(current_object).pmin().col()
+ + math::min(2u, (w + 1) / 2 - 1);
+ else
+ sp.col() = objects.bbox(current_object).pmin().col()
+ + math::min(10u, w /10);
+ break;
+
+
+ // Bounding box top right
+ case anchor::TopRight:
+ if (h < 30)
+ sp.row() = objects.bbox(current_object).pmin().row()
+ + math::min(2u, (h + 1) / 2 - 1);
+ else
+ sp.row() = objects.bbox(current_object).pmin().row()
+ + math::min(10u, h /10);
+ if (w < 30)
+ sp.col() = objects.bbox(current_object).pmax().col()
+ - math::min(2u, (w + 1) / 2 - 1);
+ else
+ sp.col() = objects.bbox(current_object).pmax().col()
+ - math::min(10u, w /10);
+ break;
+
+
+ // Bounding box bottom left
+ case anchor::BottomLeft:
+ if (h < 30)
+ sp.row() = objects.bbox(current_object).pmax().row()
+ - math::min(2u, (h + 1) / 2 - 1);
+ else
+ sp.row() = objects.bbox(current_object).pmax().row()
+ - math::min(10u, h /10);
+ if (w < 30)
+ sp.col() = objects.bbox(current_object).pmin().col()
+ + math::min(2u, (w + 1) / 2 - 1);
+ else
+ sp.col() = objects.bbox(current_object).pmin().col()
+ + math::min(10u, w /10);
+ break;
+
+ // Bounding box bottom right
+ case anchor::BottomRight:
+ if (h < 30)
+ sp.row() = objects.bbox(current_object).pmax().row()
+ - math::min(2u, (h + 1) / 2 - 1);
+ else
+ sp.row() = objects.bbox(current_object).pmax().row()
+ - math::min(10u, h /10);
+ if (w < 30)
+ sp.col() = objects.bbox(current_object).pmax().col()
+ - math::min(2u, (w + 1) / 2 - 1);
+ else
+ sp.col() = objects.bbox(current_object).pmax().col()
+ - math::min(10u, w /10);
+ break;
+
+
+
default:
trace::warning("Non handled anchor");
- mln_assertion(anchor > 2);
+ mln_assertion(anchor < anchor::Invalid);
}
- sp.row() = r;
return sp;
}
diff --git a/scribo/primitive/link/internal/link_ms_dmax_base.hh b/scribo/primitive/link/internal/link_ms_dmax_base.hh
index 80a9a13..edb0941 100644
--- a/scribo/primitive/link/internal/link_ms_dmax_base.hh
+++ b/scribo/primitive/link/internal/link_ms_dmax_base.hh
@@ -75,12 +75,11 @@ namespace scribo
link_ms_dmax_base(const object_image(L)& objects,
- unsigned neighb_max_distance);
-
-
+ unsigned neighb_max_distance,
+ anchor::Direction direction);
bool verify_link_criterion_(unsigned current_object,
- const P& start_point, const P& p) const;
+ const P& start_point, const P& p) const;
mln_site(L) start_point_(unsigned current_object,
unsigned anchor);
@@ -88,9 +87,9 @@ namespace scribo
void start_processing_object_(unsigned current_object);
private:
- mln::util::array<ms_t> mass_centers_;
float dmax_;
float neighb_max_distance_;
+ anchor::Direction direction_;
};
@@ -101,17 +100,17 @@ namespace scribo
inline
link_ms_dmax_base<L, E>::link_ms_dmax_base(
const object_image(L)& objects,
- unsigned neighb_max_distance)
+ unsigned neighb_max_distance,
+ anchor::Direction direction)
: super_(objects),
dmax_(0),
- neighb_max_distance_(neighb_max_distance)
+ neighb_max_distance_(neighb_max_distance),
+ direction_(direction)
{
-
- mass_centers_ = labeling::compute(accu::meta::center(),
- objects, objects.nlabels());
}
+
template <typename L, typename E>
inline
bool
@@ -121,7 +120,7 @@ namespace scribo
{
(void) current_object;
- float dist = math::abs(p.col() - start_point.col());
+ float dist = math::abs(p[direction_] - start_point[direction_]);
return dist <= dmax_; // Not too far
}
@@ -133,7 +132,7 @@ namespace scribo
unsigned anchor)
{
(void) anchor;
- return mass_centers_(current_object);
+ return this->objects_.mass_center(current_object);
}
@@ -144,8 +143,8 @@ namespace scribo
unsigned current_object)
{
float
- midcol = (this->objects_.bbox(current_object).pmax().col()
- - this->objects_.bbox(current_object).pmin().col()) / 2;
+ midcol = (this->objects_.bbox(current_object).pmax()[direction_]
+ - this->objects_.bbox(current_object).pmin()[direction_]) / 2;
dmax_ = midcol + neighb_max_distance_;
}
diff --git a/scribo/primitive/link/internal/link_ms_dmax_ratio_base.hh b/scribo/primitive/link/internal/link_ms_dmax_ratio_base.hh
index 414e0b2..8eca53d 100644
--- a/scribo/primitive/link/internal/link_ms_dmax_ratio_base.hh
+++ b/scribo/primitive/link/internal/link_ms_dmax_ratio_base.hh
@@ -76,7 +76,8 @@ namespace scribo
link_ms_dmax_ratio_base(const object_image(L)& objects,
- float dmax_ratio);
+ float dmax_ratio,
+ anchor::Direction direction);
@@ -89,9 +90,9 @@ namespace scribo
void start_processing_object_(unsigned current_object);
private:
- mln::util::array<ms_t> mass_centers_;
float dmax_ratio_;
float dmax_;
+ anchor::Direction direction_;
};
@@ -102,14 +103,14 @@ namespace scribo
inline
link_ms_dmax_ratio_base<L, E>::link_ms_dmax_ratio_base(
const object_image(L)& objects,
- float dmax_ratio)
+ float dmax_ratio,
+ anchor::Direction direction)
: super_(objects),
dmax_ratio_(dmax_ratio),
- dmax_(0)
+ dmax_(0),
+ direction_(direction)
{
- mass_centers_ = labeling::compute(accu::meta::center(),
- objects, objects.nlabels());
}
template <typename L, typename E>
@@ -120,9 +121,10 @@ namespace scribo
const P& start_point,
const P& p) const
{
+ mln_assertion(dmax_ != 0);
(void) current_object;
- float dist = math::abs(p.col() - start_point.col());
+ float dist = math::abs(p[direction_] - start_point[direction_]);
return dist <= dmax_; // Not too far
}
@@ -134,7 +136,7 @@ namespace scribo
unsigned anchor)
{
(void) anchor;
- return mass_centers_(current_object);
+ return this->objects_.mass_center(current_object);
}
diff --git a/scribo/primitive/link/internal/link_single_dmax_base.hh b/scribo/primitive/link/internal/link_single_dmax_base.hh
index 4f571af..8d594f5 100644
--- a/scribo/primitive/link/internal/link_single_dmax_base.hh
+++ b/scribo/primitive/link/internal/link_single_dmax_base.hh
@@ -76,7 +76,8 @@ namespace scribo
typedef mln_site(L) P;
link_single_dmax_base(const object_image(L)& objects,
- unsigned neighb_max_distance);
+ unsigned neighb_max_distance,
+ anchor::Direction direction);
bool verify_link_criterion_(unsigned current_object,
@@ -90,7 +91,7 @@ namespace scribo
private:
float dmax_;
float neighb_max_distance_;
-// mln::util::array<ms_t> mass_centers_;
+ anchor::Direction direction_;
};
@@ -101,14 +102,14 @@ namespace scribo
inline
link_single_dmax_base<L, E>::link_single_dmax_base(
const object_image(L)& objects,
- unsigned neighb_max_distance)
+ unsigned neighb_max_distance,
+ anchor::Direction direction)
: super_(objects),
dmax_(0),
- neighb_max_distance_(neighb_max_distance)
+ neighb_max_distance_(neighb_max_distance),
+ direction_(direction)
{
-// mass_centers_ = labeling::compute(accu::meta::center(),
-// objects, objects.nlabels());
}
@@ -122,7 +123,7 @@ namespace scribo
{
(void) current_object;
- float dist = math::abs(p.col() - start_point.col());
+ float dist = math::abs(p[direction_] - start_point[direction_]);
return dist <= dmax_; // Not too far
}
@@ -133,7 +134,7 @@ namespace scribo
link_single_dmax_base<L, E>::start_point_(unsigned current_object,
anchor::Type anchor)
{
- return internal::compute_anchor(this->objects_, this->objects_.mass_centers(),//mass_centers_,
+ return internal::compute_anchor(this->objects_,
current_object, anchor);
}
@@ -145,8 +146,8 @@ namespace scribo
unsigned current_object)
{
float
- midcol = (this->objects_.bbox(current_object).pmax().col()
- - this->objects_.bbox(current_object).pmin().col()) / 2;
+ midcol = (this->objects_.bbox(current_object).pmax()[direction_]
+ - this->objects_.bbox(current_object).pmin()[direction_]) / 2;
dmax_ = midcol + neighb_max_distance_;
}
diff --git a/scribo/primitive/link/internal/link_single_dmax_ratio_base.hh b/scribo/primitive/link/internal/link_single_dmax_ratio_base.hh
index 9eadba7..ebe0b6a 100644
--- a/scribo/primitive/link/internal/link_single_dmax_ratio_base.hh
+++ b/scribo/primitive/link/internal/link_single_dmax_ratio_base.hh
@@ -78,8 +78,8 @@ namespace scribo
link_single_dmax_ratio_base(const object_image(L)& objects,
- float dmax_ratio,
- unsigned center_type_);
+ float dmax_ratio,
+ anchor::Direction direction);
@@ -94,7 +94,7 @@ namespace scribo
private:
float dmax_ratio_;
float dmax_;
- mln::util::array<ms_t> mass_centers_;
+ anchor::Direction direction_;
};
@@ -105,14 +105,14 @@ namespace scribo
inline
link_single_dmax_ratio_base<L, E>::link_single_dmax_ratio_base(
const object_image(L)& objects,
- float dmax_ratio)
+ float dmax_ratio,
+ anchor::Direction direction)
: super_(objects),
dmax_ratio_(dmax_ratio),
- dmax_(0)
+ dmax_(0),
+ direction_(direction)
{
- mass_centers_ = labeling::compute(accu::meta::center(),
- objects, objects.nlabels());
}
template <typename L, typename E>
@@ -125,7 +125,7 @@ namespace scribo
{
(void) current_object;
- float dist = math::abs(p.col() - start_point.col());
+ float dist = math::abs(p[direction_] - start_point[direction_]);
return dist <= dmax_; // Not too far
}
@@ -137,8 +137,8 @@ namespace scribo
anchor::Type anchor)
{
(void) anchor;
- return internal::compute_anchors(this->objects_, mass_centers_,
- current_object, anchor);
+ return internal::compute_anchor(this->objects_,
+ current_object, anchor);
}
diff --git a/scribo/primitive/link/with_single_left_link.hh b/scribo/primitive/link/with_single_down_link.hh
similarity index 60%
copy from scribo/primitive/link/with_single_left_link.hh
copy to scribo/primitive/link/with_single_down_link.hh
index 2cf0c5a..7e4e82c 100644
--- a/scribo/primitive/link/with_single_left_link.hh
+++ b/scribo/primitive/link/with_single_down_link.hh
@@ -23,12 +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_SINGLE_LEFT_LINK_HH
-# define SCRIBO_PRIMITIVE_LINK_WITH_SINGLE_LEFT_LINK_HH
+#ifndef SCRIBO_PRIMITIVE_LINK_WITH_SINGLE_DOWN_LINK_HH
+# define SCRIBO_PRIMITIVE_LINK_WITH_SINGLE_DOWN_LINK_HH
/// \file
///
-/// Link text objects with their left neighbor.
+/// Link text objects with their down neighbor.
# include <mln/core/concept/image.hh>
# include <mln/core/concept/neighborhood.hh>
@@ -61,17 +61,29 @@ namespace scribo
namespace link
{
- /// \brief Link objects with their left neighbor if exists.
+ /// \brief Link objects with their down neighbor if exists.
///
/// \param[in] objects An object image.
- /// \param[in] The maximum distance allowed to seach a neighbor object.
+ /// \param[in] neighb_max_distance The maximum distance allowed
+ /// to seach a neighbor object.
+ /// \param[in] anchor The neighborhod lookup start point.
///
/// \return Object links data.
//
template <typename L>
inline
object_links<L>
- with_single_left_link(const object_image(L)& objects,
+ with_single_down_link(const object_image(L)& objects,
+ unsigned neighb_max_distance,
+ anchor::Type anchor);
+
+ /// \overload
+ /// Anchor type is set to anchor::MassCenter
+ //
+ template <typename L>
+ inline
+ object_links<L>
+ with_single_down_link(const object_image(L)& objects,
unsigned neighb_max_distance);
@@ -80,7 +92,7 @@ namespace scribo
template <typename L>
inline
object_links<L>
- with_single_left_link(const object_image(L)& objects);
+ with_single_down_link(const object_image(L)& objects);
# ifndef MLN_INCLUDE_ONLY
@@ -92,23 +104,23 @@ namespace scribo
// Functor
template <typename L>
- class single_left_functor
- : public internal::link_single_dmax_base<L, single_left_functor<L> >
+ class single_down_functor
+ : public internal::link_single_dmax_base<L, single_down_functor<L> >
{
typedef
- internal::link_single_dmax_base<L, single_left_functor<L> > super_;
+ internal::link_single_dmax_base<L, single_down_functor<L> > sdowner_;
public:
typedef mln_site(L) P;
- single_left_functor(const object_image(L)& objects, unsigned dmax)
- : super_(objects, dmax)
+ single_down_functor(const object_image(L)& objects, unsigned dmax)
+ : sdowner_(objects, dmax, anchor::Vertical)
{
}
void compute_next_site_(P& p)
{
- --p.col();
+ ++p.row();
}
};
@@ -122,19 +134,20 @@ namespace scribo
template <typename L>
inline
object_links<L>
- with_single_left_link(const object_image(L)& objects,
- unsigned neighb_max_distance)
+ with_single_down_link(const object_image(L)& objects,
+ unsigned neighb_max_distance,
+ anchor::Type anchor)
{
- trace::entering("scribo::primitive::link::with_single_left_link");
+ trace::entering("scribo::primitive::link::with_single_down_link");
mln_precondition(objects.is_valid());
- internal::single_left_functor<L>
+ internal::single_down_functor<L>
functor(objects, neighb_max_distance);
- object_links<L> output = compute(functor);
+ object_links<L> output = compute(functor, anchor);
- trace::exiting("scribo::primitive::link::with_single_left_link");
+ trace::exiting("scribo::primitive::link::with_single_down_link");
return output;
}
@@ -142,9 +155,20 @@ namespace scribo
template <typename L>
inline
object_links<L>
- with_single_left_link(const object_image(L)& objects)
+ with_single_down_link(const object_image(L)& objects,
+ unsigned neighb_max_distance)
+ {
+ return with_single_down_link(objects, neighb_max_distance,
+ anchor::MassCenter);
+ }
+
+
+ template <typename L>
+ inline
+ object_links<L>
+ with_single_down_link(const object_image(L)& objects)
{
- return with_single_left_link(objects, mln_max(unsigned));
+ return with_single_down_link(objects, mln_max(unsigned));
}
@@ -156,4 +180,4 @@ namespace scribo
} // end of namespace scribo
-#endif // ! SCRIBO_PRIMITIVE_LINK_WITH_SINGLE_LEFT_LINK_HH
+#endif // ! SCRIBO_PRIMITIVE_LINK_WITH_SINGLE_DOWN_LINK_HH
diff --git a/scribo/primitive/link/with_single_left_link.hh b/scribo/primitive/link/with_single_left_link.hh
index 2cf0c5a..651f1f6 100644
--- a/scribo/primitive/link/with_single_left_link.hh
+++ b/scribo/primitive/link/with_single_left_link.hh
@@ -102,7 +102,7 @@ namespace scribo
typedef mln_site(L) P;
single_left_functor(const object_image(L)& objects, unsigned dmax)
- : super_(objects, dmax)
+ : super_(objects, dmax, anchor::Horizontal)
{
}
diff --git a/scribo/primitive/link/with_single_left_link_dmax_ratio.hh b/scribo/primitive/link/with_single_left_link_dmax_ratio.hh
index 587fb6c..d59bbc1 100644
--- a/scribo/primitive/link/with_single_left_link_dmax_ratio.hh
+++ b/scribo/primitive/link/with_single_left_link_dmax_ratio.hh
@@ -44,7 +44,7 @@
# 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/internal/link_single_dmax_ratio_base.hh>
# include <scribo/primitive/link/compute.hh>
@@ -99,18 +99,18 @@ namespace scribo
template <typename L>
class single_left_dmax_ratio_functor
- : public internal::link_ms_dmax_ratio_base<L,
- single_left_dmax_ratio_functor<L> >
+ : public internal::link_single_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_;
+ typedef internal::link_single_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)
+ : super_(objects, dmax, anchor::Horizontal)
{
}
diff --git a/scribo/primitive/link/with_single_right_link.hh b/scribo/primitive/link/with_single_right_link.hh
index f7272ee..22380ab 100644
--- a/scribo/primitive/link/with_single_right_link.hh
+++ b/scribo/primitive/link/with_single_right_link.hh
@@ -40,7 +40,7 @@
# include <mln/util/array.hh>
# include <scribo/core/macros.hh>
-# include <scribo/core/anchors.hh>
+# include <scribo/core/tag/anchor.hh>
# include <scribo/core/object_image.hh>
# include <scribo/core/object_links.hh>
@@ -102,7 +102,7 @@ namespace scribo
typedef mln_site(L) P;
single_right_functor(const object_image(L)& objects, unsigned dmax)
- : super_(objects, dmax)
+ : super_(objects, dmax, anchor::Horizontal)
{
}
diff --git a/scribo/primitive/link/with_single_right_link_dmax_ratio.hh b/scribo/primitive/link/with_single_right_link_dmax_ratio.hh
index ac6ef31..cd8360f 100644
--- a/scribo/primitive/link/with_single_right_link_dmax_ratio.hh
+++ b/scribo/primitive/link/with_single_right_link_dmax_ratio.hh
@@ -99,18 +99,18 @@ namespace scribo
template <typename L>
class single_right_dmax_ratio_functor
- : public link_ms_dmax_ratio_base<L,
- single_right_dmax_ratio_functor<L> >
+ : public link_single_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_;
+ typedef link_single_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)
+ : super_(objects, dmax, anchor::Horizontal)
{
}
diff --git a/scribo/primitive/link/with_single_right_link_top.hh b/scribo/primitive/link/with_single_up_link.hh
similarity index 60%
copy from scribo/primitive/link/with_single_right_link_top.hh
copy to scribo/primitive/link/with_single_up_link.hh
index 1e3e0df..8781128 100644
--- a/scribo/primitive/link/with_single_right_link_top.hh
+++ b/scribo/primitive/link/with_single_up_link.hh
@@ -23,24 +23,26 @@
// exception does not however invalidate any other reasons why the
// executable file might be covered by the GNU General Public License.
-#ifndef SCRIBO_PRIMITIVE_LINK_WITH_SINGLE_RIGHT_LINK_TOP_HH
-# define SCRIBO_PRIMITIVE_LINK_WITH_SINGLE_RIGHT_LINK_TOP_HH
+#ifndef SCRIBO_PRIMITIVE_LINK_WITH_SINGLE_UP_LINK_HH
+# define SCRIBO_PRIMITIVE_LINK_WITH_SINGLE_UP_LINK_HH
/// \file
///
-/// Link text objects with their right neighbor.
-
+/// Link text objects with their up neighbor.
# 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/anchors.hh>
# include <scribo/core/object_image.hh>
# include <scribo/core/object_links.hh>
@@ -59,28 +61,39 @@ namespace scribo
namespace link
{
- /// \brief Link objects with their right neighbor if exists.
- /// Lookup startup point is the object top center.
+ /// \brief Link objects with their up neighbor if exists.
///
/// \param[in] objects An object image.
- /// \param[in] The maximum distance allowed to seach a neighbor object.
+ /// \param[in] neighb_max_distance The maximum distance allowed
+ /// to seach a neighbor object.
+ /// \param[in] anchor The neighborhod lookup start point.
///
/// \return Object links data.
//
template <typename L>
inline
object_links<L>
- with_single_right_link_top(const object_image(L)& objects,
- unsigned neighb_max_distance);
+ with_single_up_link(const object_image(L)& objects,
+ unsigned neighb_max_distance,
+ anchor::Type anchor);
+
+ /// \overload
+ /// Anchor type is set to anchor::Center
+ //
+ template <typename L>
+ inline
+ object_links<L>
+ with_single_up_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_top(const object_image(L)& objects);
-
+ with_single_up_link(const object_image(L)& objects);
# ifndef MLN_INCLUDE_ONLY
@@ -92,26 +105,23 @@ namespace scribo
// Functor
template <typename L>
- class single_right_top_functor
- : public link_single_dmax_base<L,
- single_right_top_functor<L> >
+ class single_up_functor
+ : public internal::link_single_dmax_base<L, single_up_functor<L> >
{
typedef
- link_single_dmax_base<L, single_right_top_functor<L> >
- super_;
+ internal::link_single_dmax_base<L, single_up_functor<L> > super_;
public:
typedef mln_site(L) P;
- single_right_top_functor(const object_image(L)& objects,
- unsigned dmax)
- : super_(objects, dmax)
+ single_up_functor(const object_image(L)& objects, unsigned dmax)
+ : super_(objects, dmax, anchor::Vertical)
{
}
void compute_next_site_(P& p)
{
- ++p.col();
+ --p.row();
}
};
@@ -125,29 +135,40 @@ namespace scribo
template <typename L>
inline
object_links<L>
- with_single_right_link_top(const object_image(L)& objects,
- unsigned neighb_max_distance)
+ with_single_up_link(const object_image(L)& objects,
+ unsigned neighb_max_distance,
+ anchor::Type anchor)
{
- trace::entering("scribo::primitive::link::with_single_right_link_top");
+ trace::entering("scribo::primitive::link::with_single_up_link");
mln_precondition(objects.is_valid());
- internal::single_right_top_functor<L>
+ internal::single_up_functor<L>
functor(objects, neighb_max_distance);
- object_links<L> output = compute(functor, anchor::Top);
+ object_links<L> output = compute(functor, anchor);
- trace::exiting("scribo::primitive::link::with_single_right_link_top");
+ trace::exiting("scribo::primitive::link::with_single_up_link");
return output;
}
+ template <typename L>
+ inline
+ object_links<L>
+ with_single_up_link(const object_image(L)& objects,
+ unsigned neighb_max_distance)
+ {
+ return with_single_up_link(objects, neighb_max_distance,
+ anchor::MassCenter);
+ }
+
template <typename L>
inline
object_links<L>
- with_single_right_link_top(const object_image(L)& objects)
+ with_single_up_link(const object_image(L)& objects)
{
- return with_single_right_link_top(objects, mln_max(unsigned));
+ return with_single_up_link(objects, mln_max(unsigned));
}
@@ -159,4 +180,4 @@ namespace scribo
} // end of namespace scribo
-#endif // ! SCRIBO_PRIMITIVE_LINK_WITH_SINGLE_RIGHT_LINK_TOP_HH
+#endif // ! SCRIBO_PRIMITIVE_LINK_WITH_SINGLE_UP_LINK_HH
--
1.5.6.5
1
0
last-svn-commit-36-g55f2abf scribo/filter/objects_with_holes.hh: New component filter.
by Guillaume Lazzara 11 Mar '10
by Guillaume Lazzara 11 Mar '10
11 Mar '10
---
scribo/ChangeLog | 4 +
scribo/filter/objects_with_holes.hh | 575 +++++++++++++++++++++++++++++++++++
2 files changed, 579 insertions(+), 0 deletions(-)
create mode 100644 scribo/filter/objects_with_holes.hh
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index bfde10a..891cd30 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,5 +1,9 @@
2010-02-19 Guillaume Lazzara <z(a)lrde.epita.fr>
+ * scribo/filter/objects_with_holes.hh: New component filter.
+
+2010-02-19 Guillaume Lazzara <z(a)lrde.epita.fr>
+
* scribo/draw/bounding_boxes.hh: Do not draw box centers anymore.
2010-02-19 Guillaume Lazzara <z(a)lrde.epita.fr>
diff --git a/scribo/filter/objects_with_holes.hh b/scribo/filter/objects_with_holes.hh
new file mode 100644
index 0000000..c448e58
--- /dev/null
+++ b/scribo/filter/objects_with_holes.hh
@@ -0,0 +1,575 @@
+// 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_WITH_HOLES_HH
+# define SCRIBO_FILTER_OBJECTS_WITH_HOLES_HH
+
+/// \file
+///
+/// \brief Remove objects having a minimum number of holes.
+
+# include <sstream>
+
+# include <mln/core/concept/image.hh>
+# include <mln/core/alias/neighb2d.hh>
+# include <mln/core/routine/extend.hh>
+# include <mln/core/image/dmorph/extended.hh>
+
+# include <mln/extension/duplicate.hh>
+
+# include <mln/draw/box_plain.hh>
+# include <mln/util/array.hh>
+
+# include <mln/labeling/blobs_and_compute.hh>
+
+# include <mln/accu/math/count.hh>
+
+# include <mln/fun/i2v/array.hh>
+
+# include <mln/io/pbm/save.hh>
+# include <mln/io/pgm/save.hh>
+
+# include <mln/data/convert.hh>
+
+# include <mln/labeling/background.hh>
+
+# include <scribo/core/macros.hh>
+# include <scribo/core/object_image.hh>
+# include <scribo/filter/internal/compute.hh>
+
+# include <mln/data/fill.hh>
+# include <mln/data/paste.hh>
+
+# include <mln/util/timer.hh>
+
+# include <mln/value/label_16.hh>
+# include <mln/core/var.hh>
+
+
+#include <mln/debug/filename.hh>
+
+namespace scribo
+{
+
+ namespace filter
+ {
+
+ using namespace mln;
+
+ /*! \brief Remove objects having a minimum number of holes.
+
+
+
+ */
+ template <typename L>
+ object_image(L)
+ objects_with_holes(const object_image(L)& objects,
+ unsigned min_holes_count,
+ unsigned min_size);
+
+
+ template <typename L>
+ inline
+ object_image(L)
+ objects_with_two_holes(const object_image(L)& objects,
+ unsigned min_size);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace internal
+ {
+
+ unsigned my_find_root(image2d<unsigned>& parent, unsigned x)
+ {
+ if (parent.element(x) == x)
+ return x;
+ return parent.element(x) = my_find_root(parent,
+ parent.element(x));
+ }
+
+
+ template <typename L>
+ mln_concrete(L)
+ compute_bboxes_image(const object_image(L)& objects)
+ {
+ typedef mln_psite(L) P;
+ typedef mln_dpsite(P) D;
+
+ extension::adjust_fill(objects, 1, 0);
+
+ mln_concrete(L) output;
+ initialize(output, objects);
+ data::fill(output, 0);
+
+ for_all_components(i, objects.bboxes())
+ {
+ mln_box(L) b = objects.bbox(i);
+ b.enlarge(1);
+
+ unsigned
+ nrows = b.pmax().row() - b.pmin().row() + 1,
+ ncols = b.pmax().col() - b.pmin().col() + 1,
+ row_offset = objects.labeled_image_().delta_index(D(+1, -ncols));
+
+ mln_value(L) *ptr = &output(b.pmin());
+ for (unsigned row = 0; row < nrows; ++row, ptr += row_offset)
+ for (unsigned col = 0; col < ncols; ++col)
+ *ptr++ = i;
+ }
+
+ extension::duplicate(output);
+
+ return output;
+ }
+
+
+ } // end of namespace scribo::filter::internal
+
+
+
+ /*!
+ Label the background and count the number of background
+ components in an object bounding box.
+ */
+ template <typename L>
+ inline
+ object_image(L)
+ objects_with_holes(const object_image(L)& objects,
+ unsigned min_holes_count,
+ unsigned min_size)
+ {
+ trace::entering("scribo::filter::objects_with_holes");
+
+ typedef object_image(L) O;
+ neighb2d nbh = c4();
+
+ image2d<unsigned> parent, card;
+ L bboxes_ima;
+
+ util::array<util::set<unsigned> > bg_comps(
+ static_cast<unsigned>(objects.nlabels()) + 1);
+
+ fun::i2v::array<bool>
+ to_keep(static_cast<unsigned>(objects.nlabels()) + 1,
+ false);
+
+ const L& lbl = objects.labeled_image_();
+
+ std::cout << "objects.nlabels = " << objects.nlabels() << std::endl;
+
+ util::timer timer_;
+ timer_.start();
+
+ // init
+ {
+ extension::adjust_fill(objects, nbh, mln_max(mln_value(L)));
+ initialize(parent, objects);
+ data::fill(parent, 0u);
+
+ initialize(card, objects);
+ data::fill(card, 1);
+
+
+ // FIXME: Improve.
+ util::timer t2;
+ t2.start();
+ bboxes_ima = internal::compute_bboxes_image(objects);
+ float t2_ = t2;
+ std::cout << "compute bboxes image " << t2_ << std::endl;
+
+ to_keep(0) = true;
+ }
+ float t_ = timer_;
+ std::cout << "init = " << t_ << std::endl;
+
+ // 1st pass
+ timer_.restart();
+ {
+ util::array<int> dp = positive_offsets_wrt(lbl, nbh);
+ const unsigned n_nbhs = dp.nelements();
+
+ mln_bkd_pixter(const L) pxl(lbl); // Backward.
+ for_all(pxl)
+ {
+ unsigned p = pxl.offset();
+ if (bboxes_ima.element(p) == 0 || lbl.element(p) != literal::zero)
+ continue;
+
+ parent.element(p) = p;
+ for (unsigned i = 0; i < n_nbhs; ++i)
+ {
+ unsigned n = p + dp[i];
+ if (bboxes_ima.element(n) == 0 || lbl.element(n) != literal::zero)
+ continue;
+
+ unsigned r = internal::my_find_root(parent, n);
+ if (r != p)
+ {
+ parent.element(r) = p;
+ card.element(p) += card.element(r);
+ }
+ } // for_all(n)
+
+ } // for_all(pxl)
+
+ }
+ t_ = timer_;
+ std::cout << "1st pass = " << t_ << std::endl;
+
+ // FIXME: Iterate over another label when a label is marked as
+ // "to be kept".
+
+ // 2nd pass
+ timer_.restart();
+ {
+ unsigned kept = 0;
+ mln_fwd_pixter(const L) pxl(bboxes_ima); // Forward.
+ for_all(pxl)
+ {
+ unsigned p = pxl.offset();
+
+ // Foreground, ignored.
+ if (parent.element(p) == 0 || bboxes_ima.element(p) == literal::zero)
+ continue;
+
+ unsigned& parent_p = parent.element(p);
+
+ if (parent_p != p) // Not root => propagation
+ parent_p = parent.element(parent_p);
+ else // Root
+ if (card.element(p) < min_size)
+ {
+ parent_p = 0;
+ continue;
+ }
+
+// if (bboxes_ima.element(p) != literal::zero)
+// {
+ mln_value(L) object_id = bboxes_ima.element(p);
+ if (parent_p != 0 // Check parent again since
+ // parent's may have been set to
+ // 0.
+ && bg_comps(object_id).nelements() < min_holes_count)
+ {
+ if (! bg_comps(object_id).has(parent_p))
+ {
+ bg_comps(object_id).insert(parent_p);
+
+ if (bg_comps(object_id).nelements() == min_holes_count)
+ {
+ to_keep(object_id) = true;
+ ++kept;
+ }
+ }
+ }
+// }
+ }
+
+ float t_ = timer_;
+ std::cout << "2nd pass = " << t_ << std::endl;
+
+ std::cout << "kept = " << kept << std::endl;
+// debug::println(parent);
+// std::cout << bg_comps << std::endl;
+// std::cout << to_keep << std::endl;
+
+ timer_.restart();
+ object_image(L) output;
+
+ if (kept == objects.nlabels())
+ {
+ trace::exiting("scribo::filter::objects_with_holes");
+ return objects;
+ }
+
+ output.init_from_(objects);
+ output.relabel(to_keep);
+ t_ = timer_;
+ std::cout << "init output = " << t_ << std::endl;
+
+ trace::exiting("scribo::filter::objects_with_holes");
+ return output;
+ }
+
+
+ }
+
+
+ template <typename L>
+ inline
+ object_image(L)
+ objects_with_two_holes(const object_image(L)& objects,
+ unsigned min_size)
+ {
+ trace::entering("scribo::filter::objects_with_holes");
+
+ std::cout << objects.nlabels() << std::endl;
+
+ typedef object_image(L) O;
+ neighb2d nbh = c8();
+
+ image2d<unsigned> parent, card;
+ L bboxes_ima;
+
+ util::array<unsigned> bg_comps(
+ static_cast<unsigned>(objects.nlabels()) + 1, 0);
+ util::array<bool> bg_comps_done(
+ static_cast<unsigned>(objects.nlabels()) + 1, false);
+
+ fun::i2v::array<bool>
+ to_keep(static_cast<unsigned>(objects.nlabels()) + 1,
+ false);
+
+ const L& lbl = objects.labeled_image_();
+
+ // init
+ {
+ extension::fill(objects, mln_max(mln_value(L)));
+// extension::adjust_fill(objects, nbh, mln_max(mln_value(L)));
+ initialize(parent, objects);
+ data::fill(parent, 0u);
+
+ initialize(card, objects);
+ data::fill(card, 1);
+ border::fill(card, 1);
+
+ bboxes_ima = internal::compute_bboxes_image(objects);
+
+ to_keep(0) = true;
+ }
+
+ // 1st pass
+ std::cout << "1st pass" << std::endl;
+ {
+ util::array<int> dp = positive_offsets_wrt(lbl, nbh);
+ const unsigned n_nbhs = dp.nelements();
+
+ mln_bkd_pixter(const L) pxl(lbl); // Backward.
+ for_all(pxl)
+ {
+ unsigned p = pxl.offset();
+ if (bboxes_ima.element(p) == 0 || lbl.element(p) != literal::zero)
+ continue;
+
+ parent.element(p) = p;
+ for (unsigned i = 0; i < n_nbhs; ++i)
+ {
+ unsigned n = p + dp[i];
+ if (bboxes_ima.element(n) == 0 || lbl.element(n) != literal::zero)
+ continue;
+
+ unsigned r = internal::my_find_root(parent, n);
+ if (r != p)
+ {
+ parent.element(r) = p;
+ card.element(p) += card.element(r);
+ }
+ } // for_all(n)
+
+ } // for_all(pxl)
+
+ }
+
+ // 2nd pass
+ std::cout << "2nd pass" << std::endl;
+ {
+ unsigned kept = 0;
+ mln_fwd_pixter(const L) pxl(bboxes_ima); // Forward.
+ for_all(pxl)
+ {
+ unsigned p = pxl.offset();
+ if (parent.element(p) == 0) // Foreground, ignored.
+ continue;
+
+ unsigned& parent_p = parent.element(p);
+
+ if (parent_p != p) // Not root => propagation
+ parent_p = parent.element(parent_p);
+ else // Root
+ if (card.element(p) < min_size)
+ {
+ parent_p = 0;
+ continue;
+ }
+
+ if (parent_p != 0 // Check parent again since
+ // parent's may have been set to
+ // 0.
+ && bboxes_ima.element(p) != literal::zero)
+ {
+ mln_value(L) object_id = bboxes_ima.element(p);
+ if (!bg_comps_done(object_id))
+ {
+ if (bg_comps(object_id) == 0)
+ {
+ bg_comps(object_id) = parent_p;
+ }
+ else if (bg_comps(object_id) != parent_p)
+ {
+ bg_comps_done(object_id) = true;
+ to_keep(object_id) = true;
+ ++kept;
+ }
+ }
+ }
+ }
+
+ object_image(L) output;
+ if (kept == objects.nlabels())
+ {
+ trace::exiting("scribo::filter::objects_with_holes");
+ return objects;
+ }
+
+ output.init_from_(objects);
+ output.relabel(to_keep);
+
+ trace::exiting("scribo::filter::objects_with_holes");
+ return output;
+ }
+
+ }
+
+
+
+// template <typename L>
+// inline
+// object_image(L)
+// objects_with_holes(const object_image(L)& objects,
+// unsigned min_holes_count)
+// {
+// trace::entering("scribo::filter::objects_with_holes");
+
+// mln_precondition(objects.is_valid());
+
+
+// L bboxes_ima;
+// initialize(bboxes_ima, objects);
+// data::fill(bboxes_ima, literal::zero);
+
+// for_all_components(i, objects.bboxes())
+// mln::draw::box(bboxes_ima, objects.bbox(i), i);
+
+// util::array<util::set<mln_value(L)> > first_bg_comp(
+// static_cast<unsigned>(objects.nlabels()) + 1);
+
+// fun::i2v::array<bool>
+// to_keep(static_cast<unsigned>(objects.nlabels()) + 1,
+// false);
+// to_keep(0) = true;
+
+// mln_value(L) nbglabels;
+// L bg_lbl = labeling::background(objects, c8(), nbglabels);
+
+// unsigned kept;
+// mln_piter(L) p(bboxes_ima.domain());
+// for_all(p)
+// {
+// if (bboxes_ima(p) == literal::zero)
+// continue;
+
+// if (bg_lbl(p) != 0)
+// if (! first_bg_comp(bboxes_ima(p)).has(bg_lbl(p)))
+// if (first_bg_comp(bboxes_ima(p)).nelements() < min_holes_count - 1)
+// first_bg_comp(bboxes_ima(p)).insert(bg_lbl(p));
+// else
+// {
+// to_keep(bboxes_ima(p)) == true;
+// ++kept;
+// }
+// }
+
+// object_image(L) output;
+// if (kept == objects.nlabels())
+// output = objects;
+// else
+// output = internal::compute(objects, to_keep);
+
+// trace::exiting("scribo::filter::objects_with_holes");
+// return output;
+// }
+
+
+ template <typename L>
+ inline
+ object_image(L)
+ objects_with_holes_slow(const object_image(L)& objects,
+ unsigned min_holes_count)
+ {
+ trace::entering("scribo::filter::objects_with_holes");
+
+ mln_precondition(objects.is_valid());
+
+ fun::i2v::array<bool>
+ to_keep(static_cast<unsigned>(objects.nlabels()) + 1,
+ true);
+
+ bool to_remove = false;
+ for_all_components(i, objects.bboxes())
+ {
+ mln_domain(L) b = objects.bbox(i);
+ b.enlarge(1);
+
+ mln_ch_value(L, bool) tmp(b);
+ data::fill(tmp, true);
+ data::fill((tmp | ((objects | objects.bbox(i)) | (pw::value(objects) == pw::cst(i))).domain()).rw(), false);
+
+ typedef accu::math::count<mln_value(L)> accu_t;
+ mln_value(L) nlabels;
+ util::array<unsigned> counts
+ = labeling::blobs_and_compute(tmp,
+ c8(), nlabels,
+ accu_t()).second();
+ unsigned nholes = 0;
+ for_all_components(j, counts)
+ if (counts(j) > 4u)
+ ++nholes;
+
+ if (nholes < min_holes_count)
+ {
+ to_keep(i) = false;
+ to_remove = true;
+ }
+ }
+
+ object_image(L) output;
+ if (! to_remove)
+ output = objects;
+ else
+ output = internal::compute(objects, to_keep);
+
+ trace::exiting("scribo::filter::objects_with_holes");
+ return output;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace scribo::filter
+
+} // end of namespace scribo
+
+
+#endif // ! SCRIBO_FILTER_OBJECTS_WITH_HOLES_HH
--
1.5.6.5
1
0
last-svn-commit-35-gdb3dc85 scribo/draw/bounding_boxes.hh: Do not draw box centers anymore.
by Guillaume Lazzara 11 Mar '10
by Guillaume Lazzara 11 Mar '10
11 Mar '10
---
scribo/ChangeLog | 4 ++++
scribo/draw/bounding_boxes.hh | 9 +++------
2 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index d35119e..bfde10a 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,5 +1,9 @@
2010-02-19 Guillaume Lazzara <z(a)lrde.epita.fr>
+ * scribo/draw/bounding_boxes.hh: Do not draw box centers anymore.
+
+2010-02-19 Guillaume Lazzara <z(a)lrde.epita.fr>
+
Add dedicated routines for AFP's use case.
* scribo/src/afp/components.hh,
diff --git a/scribo/draw/bounding_boxes.hh b/scribo/draw/bounding_boxes.hh
index 2fe2cd3..0d4ab9b 100644
--- a/scribo/draw/bounding_boxes.hh
+++ b/scribo/draw/bounding_boxes.hh
@@ -28,7 +28,7 @@
/// \file
///
-/// Draw a list of bounding boxes and their associated mass center.
+/// Draw a list of bounding boxes
# include <mln/core/concept/image.hh>
# include <mln/draw/box.hh>
@@ -45,7 +45,7 @@ namespace scribo
using namespace mln;
- /// Draw a list of bounding boxes and their associated mass center.
+ /// Draw a list of bounding boxes.
template <typename I>
void
bounding_boxes(Image<I>& input_,
@@ -53,7 +53,7 @@ namespace scribo
const mln_value(I)& value);
- /// Draw object bounding boxes and their associated mass center.
+ /// Draw object bounding boxes.
template <typename I, typename L>
void
bounding_boxes(Image<I>& input_,
@@ -79,10 +79,7 @@ namespace scribo
for_all_components(i, boxes)
if (boxes[i].is_valid())
- {
- input(boxes[i].center()) = value;
mln::draw::box(input, boxes[i], value);
- }
trace::exiting("scribo::draw::bounding_boxes");
}
--
1.5.6.5
1
0
last-svn-commit-34-g7681799 Add dedicated routines for AFP's use case.
by Guillaume Lazzara 11 Mar '10
by Guillaume Lazzara 11 Mar '10
11 Mar '10
* scribo/src/afp/components.hh,
* scribo/src/afp/link.hh,
* scribo/src/afp/regroup.hh: New.
---
scribo/ChangeLog | 8 ++
scribo/src/afp/components.hh | 255 ++++++++++++++++++++++++++++++++++++++++++
scribo/src/afp/link.hh | 138 +++++++++++++++++++++++
scribo/src/afp/regroup.hh | 84 ++++++++++++++
4 files changed, 485 insertions(+), 0 deletions(-)
create mode 100644 scribo/src/afp/components.hh
create mode 100644 scribo/src/afp/link.hh
create mode 100644 scribo/src/afp/regroup.hh
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index f7a0e58..d35119e 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,5 +1,13 @@
2010-02-19 Guillaume Lazzara <z(a)lrde.epita.fr>
+ Add dedicated routines for AFP's use case.
+
+ * scribo/src/afp/components.hh,
+ * scribo/src/afp/link.hh,
+ * scribo/src/afp/regroup.hh: New.
+
+2010-02-19 Guillaume Lazzara <z(a)lrde.epita.fr>
+
Add new tools in Scribo.
* src/preprocessing/Makefile.am,
diff --git a/scribo/src/afp/components.hh b/scribo/src/afp/components.hh
new file mode 100644
index 0000000..7db8572
--- /dev/null
+++ b/scribo/src/afp/components.hh
@@ -0,0 +1,255 @@
+#include <mln/io/pbm/load.hh>
+#include <mln/io/pgm/save.hh>
+
+#include <mln/extension/adjust.hh>
+#include <mln/extension/fill.hh>
+#include <mln/data/fill.hh>
+#include <mln/accu/shape/bbox.hh>
+
+#include <mln/core/alias/neighb2d.hh>
+#include <mln/core/image/dmorph/image_if.hh>
+#include <mln/pw/value.hh>
+#include <mln/debug/println.hh>
+
+#include <mln/util/timer.hh>
+#include <mln/labeling/foreground.hh>
+#include <mln/labeling/wrap.hh>
+#include <mln/extension/fill.hh>
+#include <mln/data/compare.hh>
+
+
+namespace mln
+{
+
+ template <typename I>
+ unsigned my_find_root(image2d<I>& data, unsigned x)
+ {
+ if (data.element(x).parent == x)
+ return x;
+ else
+ return data.element(x).parent = my_find_root(data,
+ data.element(x).parent);
+ }
+
+
+
+ struct info
+ {
+ unsigned parent;
+ unsigned card;
+ float row_sum, col_sum;
+ point2d p_min, p_max;
+
+ int width() const
+ {
+ return p_max.col() - p_min.col();
+ }
+
+ int height() const
+ {
+ return p_max.row() - p_min.row();
+ }
+
+ void init(unsigned p, int row, int col)
+ {
+ parent = p;
+ card = 1;
+ row_sum = row;
+ col_sum = col;
+ p_min.row() = row;
+ p_max.row() = row;
+ p_min.col() = col;
+ p_max.col() = col;
+ }
+
+ void update(info& r)
+ {
+ r.parent = this->parent;
+ card += r.card;
+ row_sum += r.row_sum;
+ col_sum += r.col_sum;
+
+ // bkd browsing => p is always higher (lower row) than r
+ mln_invariant(p_min.row() <= r.p_min.row());
+
+ if (r.p_min.col() < p_min.col())
+ p_min.col() = r.p_min.col();
+ if (r.p_max.row() > p_max.row())
+ p_max.row() = r.p_max.row();
+ if (r.p_max.col() > p_max.col())
+ p_max.col() = r.p_max.col();
+ }
+ };
+
+
+
+ template <typename V>
+ image2d<V>
+ extract_components(const image2d<bool>& input,
+ V& nlabels,
+ util::array<box2d>& bboxes,
+ util::array<point2d>& mass_centers)
+ {
+ typedef image2d<bool> I;
+
+ neighb2d nbh = c8();
+ const int
+ nrows = input.nrows(),
+ ncols = input.ncols();
+
+ bboxes.resize(1);
+ mass_centers.resize(1);
+
+ image2d<info> data;
+ image2d<V> label;
+ V current_label = 0;
+ int N, dp_border;
+
+// util::timer time;
+// time.start();
+
+ // init
+ {
+ extension::adjust(input, nbh);
+ N = input.nelements();
+ dp_border = 2 * input.border();
+ extension::fill(input, false);
+ initialize(data, input);
+ }
+
+// float t = time;
+// std::cout << "init = " << t << std::endl;
+// time.restart();
+
+ // 1st pass
+ {
+ util::array<int> dp = positive_offsets_wrt(input, nbh);
+ const unsigned n_nbhs = dp.nelements();
+
+ // Backward.
+ unsigned p = input.index_of_point(point2d(nrows - 1, ncols - 1));
+ for (int row = nrows - 1; row >= 0; --row, p -= dp_border)
+ for (int col = ncols - 1; col >= 0; --col, --p)
+ {
+ if (! input.element(p))
+ continue;
+
+ data.element(p).init(p, row, col); // init
+
+ for (unsigned i = 0; i < n_nbhs; ++i)
+ {
+ unsigned n = p + dp[i];
+ if (! input.element(n))
+ continue;
+ unsigned r = my_find_root(data, n);
+ if (r != p)
+ {
+ data.element(p).update( data.element(r) ); // update
+ }
+ }
+ }
+ }
+
+// t = time;
+// std::cout << "1st pass = " << t << std::endl;
+// time.restart();
+
+ // 2nd pass
+ {
+ initialize(label, input);
+ data::fill(label, 0);
+
+ // Forward.
+ unsigned p = input.index_of_point(point2d(0, 0));
+ for (int row = 0; row < nrows; ++row, p += dp_border)
+ for (int col = 0; col < ncols; ++col, ++p)
+ {
+ if (! input.element(p))
+ continue;
+ const info& dta = data.element(p);
+ if (dta.parent == p)
+ {
+ if (dta.card > 5
+ && (dta.width() >= 1
+ && dta.height() >= 1))
+ {
+ label.element(p) = ++current_label;
+
+ bboxes.append(box2d(dta.p_min, dta.p_max));
+ mass_centers.append(point2d(dta.row_sum / dta.card,
+ dta.col_sum / dta.card));
+ }
+ }
+ else
+ label.element(p) = label.element(dta.parent);
+ }
+ }
+// t = time;
+// std::cout << "2nd pass = " << t << std::endl;
+
+ nlabels = current_label;
+ return label;
+ }
+
+
+} // mln
+
+
+
+// void usage(char* argv[])
+// {
+// std::cerr << argv[0] << " input.pbm output.pgm" << std::endl;
+// std::abort();
+// }
+
+
+// int main(int argc, char* argv[])
+// {
+// if (argc != 3)
+// usage(argv);
+
+// using namespace mln;
+
+// image2d<bool> input;
+// io::pbm::load(input, argv[1]);
+
+
+// image2d<unsigned> ref;
+
+// // {
+// // util::timer t;
+// // t.start();
+
+// // unsigned nlabels;
+// // ref = labeling::foreground(input, c4(), nlabels);
+
+// // float ts = t.stop();
+// // std::cout << "tufa: " << ts << " " << nlabels << std::endl;
+// // }
+
+// {
+// util::timer t;
+// t.start();
+
+
+// util::array<box2d> bboxes(1, box2d(1,1));
+// util::array<point2d> mass_centers(1, point2d(0,0));
+
+// // util::array<std::pair<box2d, point2d> > data_out(1);
+// unsigned nlabels;
+// image2d<unsigned> comps = extract_components(input, nlabels, bboxes, mass_centers);
+
+// float ts = t.stop();
+// std::cout << ts << " " << nlabels << std::endl;
+
+// // std::cout << bboxes << std::endl;
+// // std::cout << mass_centers << std::endl;
+
+// // if (comps != ref)
+// // std::cout << "diff" << std::endl;
+
+// io::pgm::save(labeling::wrap(value::int_u8(), comps),
+// argv[2]);
+// }
+
+// }
diff --git a/scribo/src/afp/link.hh b/scribo/src/afp/link.hh
new file mode 100644
index 0000000..b899957
--- /dev/null
+++ b/scribo/src/afp/link.hh
@@ -0,0 +1,138 @@
+#include <mln/geom/ncols.hh>
+#include <mln/geom/nrows.hh>
+#include <mln/util/couple.hh>
+#include <scribo/core/object_image.hh>
+#include <scribo/core/macros.hh>
+#include <scribo/primitive/internal/init_link_array.hh>
+
+namespace scribo
+{
+
+ namespace primitive
+ {
+
+ namespace link
+ {
+
+
+ template <typename L>
+ util::couple<object_links<L>, object_links<L> >
+ left_right(const object_image(L)& objects)
+ {
+ object_links<L>
+ right(objects, static_cast<unsigned>(objects.nlabels()) + 1);
+ primitive::internal::init_link_array(right);
+
+ object_links<L>
+ left(objects, static_cast<unsigned>(objects.nlabels()) + 1);
+ primitive::internal::init_link_array(left);
+
+ for_all_components(i, objects.bboxes())
+ {
+ float
+ w = (objects.bbox(i).pmax().col()
+ - objects.bbox(i).pmin().col()),
+ h = (objects.bbox(i).pmax().row()
+ - objects.bbox(i).pmin().row());
+ unsigned dmax = (w / 2.0f) + (3 * math::max(w, h));
+
+
+ const mln_site(L) c = objects.mass_center(i);
+
+ int
+ midcol = (objects.bbox(i).pmax().col()
+ - objects.bbox(i).pmin().col()) / 2;
+ int
+ nrightima = geom::ncols(objects) - c.col(),
+ nleftima = c.col(),
+ nright = std::min(static_cast<unsigned>(nrightima), midcol + dmax),
+ nleft = std::min(static_cast<unsigned>(nleftima), midcol + dmax);
+
+ // Right
+ {
+ const mln_value(L)
+ *p = &objects(c),
+ *pstop = p + nright + 1;
+
+ for (; p != pstop; ++p)
+ {
+ if (*p != literal::zero // Not the background
+ && *p != i // Not the current component
+ && right[*p] != i) // No loops
+ {
+ right[i] = *p;
+ break;
+ }
+ }
+ }
+
+
+ // Left
+ {
+ const mln_value(L)
+ *p = &objects(c),
+ *pstop = p - nleft - 1;
+
+ for (; p != pstop; --p)
+ {
+ if (*p != literal::zero // Not the background
+ && *p != i // Not the current component
+ && left[*p] != i) // No loops
+ {
+ left[i] = *p;
+ break;
+ }
+ }
+ }
+ }
+
+ return mln::make::couple(left, right);
+ }
+
+
+ template <typename L>
+ object_links<L>
+ left(const object_image(L)& objects, unsigned dmax)
+ {
+ object_links<L>
+ left(objects, static_cast<unsigned>(objects.nlabels()) + 1);
+ primitive::internal::init_link_array(left);
+
+ for_all_components(i, objects.bboxes())
+ {
+ const mln_site(L) c = objects.mass_center(i);
+
+ int
+ midcol = (objects.bbox(i).pmax().col()
+ - objects.bbox(i).pmin().col()) / 2;
+ int
+ nleftima = c.col(),
+ nleft = std::min(static_cast<unsigned>(nleftima), midcol + dmax);
+
+ // Left
+ {
+ const mln_value(L)
+ *p = &objects(c),
+ *pstop = p - nleft - 1;
+
+ for (; p != pstop; --p)
+ {
+ if (*p != literal::zero // Not the background
+ && *p != i // Not the current component
+ && left[*p] != i) // No loops
+ {
+ left[i] = *p;
+ break;
+ }
+ }
+ }
+ }
+
+ return left;
+ }
+
+ } // end of namespace scribo::primitive::link
+
+ } // end of namespace scribo::primitive
+
+} // end of namespace scribo
diff --git a/scribo/src/afp/regroup.hh b/scribo/src/afp/regroup.hh
new file mode 100644
index 0000000..c24880b
--- /dev/null
+++ b/scribo/src/afp/regroup.hh
@@ -0,0 +1,84 @@
+#include <mln/geom/ncols.hh>
+#include <mln/geom/nrows.hh>
+#include <mln/util/couple.hh>
+#include <scribo/core/object_image.hh>
+#include <scribo/core/macros.hh>
+#include <scribo/primitive/internal/init_link_array.hh>
+
+namespace scribo
+{
+
+ namespace primitive
+ {
+
+ namespace group
+ {
+
+ template <typename L>
+ object_groups<L>
+ regroup_left(const object_image(L)& objects,
+ const object_groups<L>& groups,
+ unsigned dmax)
+ {
+ trace::entering("scribo::primitive::group::regroup_left");
+
+ mln_precondition(groups.is_valid());
+
+ object_groups<L>
+ new_groups(objects, static_cast<unsigned>(objects.nlabels()) + 1, 0);
+
+ unsigned ngroups = 0;
+ for_all_components(i, objects.bboxes())
+ {
+ if (groups[i] == 0)
+ continue;
+
+ // We MUST set a group id here since the most left group
+ // component won't have any id otherwise.
+ if (new_groups[i] == 0)
+ new_groups[i] = ++ngroups;
+
+ const mln_site(L) c = objects.mass_center(i);
+
+ int
+ midcol = (objects.bbox(i).pmax().col()
+ - objects.bbox(i).pmin().col()) / 2;
+ int
+ nleftima = geom::ncols(objects),
+ nleft = std::min(static_cast<unsigned>(nleftima), midcol + dmax);
+
+ // Left
+ {
+ const mln_value(L)
+ *p = &objects(c),
+ *pstop = p - nleft - 1;
+
+ for (; p != pstop; --p)
+ {
+ if (*p != literal::zero // Not the background
+ && *p != i // Not the current component
+// && new_groups[*p] != ngroups
+ && groups[*p] != 0)
+ {
+ if (new_groups[*p] == 0)
+ new_groups[*p] = ngroups;
+ else
+ {
+ new_groups[i] = new_groups[*p];
+ --ngroups;
+ }
+
+ break;
+ }
+ }
+ }
+ }
+
+ return new_groups;
+ }
+
+ } // end of namespace scribo::primitive::group
+
+ } // end of namespace scribo::primitive
+
+} // end of namespace scribo
--
1.5.6.5
1
0