Olena-patches
Threads by month
- ----- 2025 -----
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
October 2012
- 9 participants
- 221 discussions

26 Oct '12
* mln/world/kn/holes.hh,
* mln/world/kn/internal/get_background_label.hh,
* mln/world/kn/saturate.hh,
* tests/world/kn/holes.cc,
* tests/world/kn/saturate.cc: New.
* tests/world/kn/Makefile.am: New targets.
---
milena/ChangeLog | 12 ++
...{fill_0_1_faces_internal_border.hh => holes.hh} | 68 ++++++-----
.../mln/world/kn/internal/get_background_label.hh | 122 ++++++++++++++++++++
...ll_0_1_faces_internal_border.hh => saturate.hh} | 70 ++++++-----
milena/tests/world/kn/Makefile.am | 4 +
.../{k1/fill_1_from_2_faces.cc => kn/holes.cc} | 88 +++++++--------
.../{k1/fill_1_from_2_faces.cc => kn/saturate.cc} | 89 +++++++--------
7 files changed, 295 insertions(+), 158 deletions(-)
copy milena/mln/world/kn/{fill_0_1_faces_internal_border.hh => holes.hh} (58%)
create mode 100644 milena/mln/world/kn/internal/get_background_label.hh
copy milena/mln/world/kn/{fill_0_1_faces_internal_border.hh => saturate.hh} (57%)
copy milena/tests/world/{k1/fill_1_from_2_faces.cc => kn/holes.cc} (59%)
copy milena/tests/world/{k1/fill_1_from_2_faces.cc => kn/saturate.cc} (58%)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index cc55293..45480d5 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,3 +1,15 @@
+2012-10-26 Guillaume Lazzara <z(a)lrde.epita.fr>
+
+ Add kn::holes() and kn::saturate().
+
+ * mln/world/kn/holes.hh,
+ * mln/world/kn/internal/get_background_label.hh,
+ * mln/world/kn/saturate.hh,
+ * tests/world/kn/holes.cc,
+ * tests/world/kn/saturate.cc: New.
+
+ * tests/world/kn/Makefile.am: New targets.
+
2012-10-25 Guillaume Lazzara <z(a)lrde.epita.fr>
Fix preconditions.
diff --git a/milena/mln/world/kn/fill_0_1_faces_internal_border.hh b/milena/mln/world/kn/holes.hh
similarity index 58%
copy from milena/mln/world/kn/fill_0_1_faces_internal_border.hh
copy to milena/mln/world/kn/holes.hh
index 915a69a..dad04cd 100644
--- a/milena/mln/world/kn/fill_0_1_faces_internal_border.hh
+++ b/milena/mln/world/kn/holes.hh
@@ -25,12 +25,17 @@
/// \file
///
-/// \brief Fill 0 and 1 faces border with a value in a KN 2D image.
+/// \brief
-#ifndef MLN_WORLD_KN_FILL_0_1_FACES_INTERNAL_BORDER_HH
-# define MLN_WORLD_KN_FILL_0_1_FACES_INTERNAL_BORDER_HH
+#ifndef MLN_WORLD_KN_SATURATE_HH
+# define MLN_WORLD_KN_SATURATE_HH
-# include <mln/inner_border/fill.hh>
+# include <mln/core/image/image2d.hh>
+# include <mln/core/alias/neighb2d.hh>
+# include <mln/labeling/background.hh>
+# include <mln/data/fill.hh>
+# include <mln/pw/all.hh>
+# include <mln/world/kn/internal/get_background_label.hh>
namespace mln
@@ -42,44 +47,45 @@ namespace mln
namespace kn
{
- /*! \brief Fill 0 and 1 faces border with a value in a KN 2D image.
- \param[in,out] inout A 2D image immersed in KN.
- \param[in] v The border value.
-
- Example with \p v=1:
-
- . - . - . 1 1 1 1 1
- | o | o | 1 o | o 1
- . - . - . -> 1 - . - 1
- | o | o | 1 o | o 1
- . - . - . 1 1 1 1 1
-
- */
template <typename I>
- void fill_0_1_faces_internal_border(Image<I>& inout,
- const mln_value(I)& v);
-
+ mln_concrete(I)
+ holes(const Image<I>& input);
# ifndef MLN_INCLUDE_ONLY
+ template <typename I>
+ mln_concrete(I)
+ holes(const Image<I>& input_)
+ {
+ trace::entering("mln::world::kn::holes");
+ mlc_equal(mln_trait_image_kind(I),
+ mln::trait::image::kind::binary)::check();
+ mln_precondition(exact(input_).is_valid());
- // Facade
+ const I& input = exact(input_);
+ unsigned n_labels;
+ mln_ch_value(I,unsigned)
+ lab = labeling::background(input, c4(), n_labels);
- template <typename I>
- void fill_0_1_faces_internal_border(Image<I>& inout_,
- const mln_value(I)& v)
- {
- trace::entering("mln::world::kn::fill_0_1_faces_internal_border");
+ bool has_bg_label;
+ unsigned bg = internal::get_background_label(lab, has_bg_label);
+
+ mln_concrete(I) output(input.domain());
- mln_precondition(exact(inout_).is_valid());
- I& inout = exact(inout_);
+ if (! has_bg_label)
+ {
+ data::fill(output, false);
+ return output;
+ }
- inner_border::fill(inout, v);
+ data::fill(output, pw::value(lab) != pw::cst(bg)
+ && pw::value(lab) != pw::cst(literal::zero));
- trace::exiting("mln::world::kn::fill_0_1_faces_internal_border");
+ trace::exiting("mln::world::kn::holes");
+ return output;
}
# endif // ! MLN_INCLUDE_ONLY
@@ -90,4 +96,4 @@ namespace mln
} // end of namespace mln
-#endif // ! MLN_WORLD_KN_FILL_0_1_FACES_INTERNAL_BORDER_HH
+#endif // ! MLN_WORLD_KN_SATURATE_HH
diff --git a/milena/mln/world/kn/internal/get_background_label.hh b/milena/mln/world/kn/internal/get_background_label.hh
new file mode 100644
index 0000000..a993b5a
--- /dev/null
+++ b/milena/mln/world/kn/internal/get_background_label.hh
@@ -0,0 +1,122 @@
+// Copyright (C) 2012 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.
+
+/// \file
+///
+/// \brief Look for background label in the borders of a labeled
+/// image.
+
+#ifndef MLN_WORLD_KN_INTERNAL_GET_BACKGROUND_LABEL_HH
+# define MLN_WORLD_KN_INTERNAL_GET_BACKGROUND_LABEL_HH
+
+# include <mln/core/concept/image.hh>
+
+namespace mln
+{
+
+ namespace world
+ {
+
+ namespace kn
+ {
+
+ namespace internal
+ {
+
+ /// \brief Look for background label in the borders of a
+ /// labeled image.
+ template <typename I>
+ mln_value(I)
+ get_background_label(const Image<I>& lab, bool& has_bg_label);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename I>
+ mln_value(I)
+ get_background_label(const Image<I>& lab_, bool& has_bg_label)
+ {
+ trace::entering("mln::world::kn::internal::get_background_label");
+ mln_precondition(exact(lab_).is_valid());
+
+ const I& lab = exact(lab_);
+
+ mln_box(I) dom = lab.domain();
+ def::coord
+ min_row = dom.pmin().row(),
+ max_row = dom.pmax().row(),
+ min_col = dom.pmin().col(),
+ max_col = dom.pmax().col();
+
+ has_bg_label = false;
+ for (def::coord col = min_col; col <= max_col; ++col)
+ {
+ // first row
+ if (lab.at_(min_row, col) != 0)
+ {
+ has_bg_label = true;
+ return lab.at_(min_row, col);
+ }
+ // last row
+ if (lab.at_(max_row, col) != 0)
+ {
+ has_bg_label = true;
+ return lab.at_(max_row, col);
+ }
+ }
+ if (! has_bg_label)
+ {
+ for (def::coord row = min_row; row <= max_row; ++row)
+ {
+ // first col
+ if (lab.at_(row, min_col) != 0)
+ {
+ has_bg_label = true;
+ return lab.at_(row, min_col);
+ }
+ // last col
+ if (lab.at_(row, max_col) != 0)
+ {
+ has_bg_label = true;
+ return lab.at_(row, max_col);
+ }
+ }
+ }
+
+ trace::exiting("mln::world::kn::internal::get_background_label");
+ return 0;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::world::kn::internal
+
+ } // end of namespace mln::world::kn
+
+ } // end of namespace mln::world
+
+} // end of namespace mln
+
+#endif // ! MLN_WORLD_KN_INTERNAL_GET_BACKGROUND_LABEL_HH
diff --git a/milena/mln/world/kn/fill_0_1_faces_internal_border.hh b/milena/mln/world/kn/saturate.hh
similarity index 57%
copy from milena/mln/world/kn/fill_0_1_faces_internal_border.hh
copy to milena/mln/world/kn/saturate.hh
index 915a69a..3677333 100644
--- a/milena/mln/world/kn/fill_0_1_faces_internal_border.hh
+++ b/milena/mln/world/kn/saturate.hh
@@ -25,12 +25,17 @@
/// \file
///
-/// \brief Fill 0 and 1 faces border with a value in a KN 2D image.
+/// \brief Saturate a cut of an image.
-#ifndef MLN_WORLD_KN_FILL_0_1_FACES_INTERNAL_BORDER_HH
-# define MLN_WORLD_KN_FILL_0_1_FACES_INTERNAL_BORDER_HH
+#ifndef MLN_WORLD_KN_SATURATE_HH
+# define MLN_WORLD_KN_SATURATE_HH
-# include <mln/inner_border/fill.hh>
+# include <mln/core/image/image2d.hh>
+# include <mln/core/alias/neighb2d.hh>
+# include <mln/labeling/background.hh>
+# include <mln/data/fill.hh>
+# include <mln/pw/all.hh>
+# include <mln/world/kn/internal/get_background_label.hh>
namespace mln
@@ -42,44 +47,45 @@ namespace mln
namespace kn
{
- /*! \brief Fill 0 and 1 faces border with a value in a KN 2D image.
-
- \param[in,out] inout A 2D image immersed in KN.
- \param[in] v The border value.
-
- Example with \p v=1:
-
- . - . - . 1 1 1 1 1
- | o | o | 1 o | o 1
- . - . - . -> 1 - . - 1
- | o | o | 1 o | o 1
- . - . - . 1 1 1 1 1
-
- */
+ /// \brief Saturate a cut of an image.
template <typename I>
- void fill_0_1_faces_internal_border(Image<I>& inout,
- const mln_value(I)& v);
-
+ mln_concrete(I)
+ saturate(const Image<I>& input);
# ifndef MLN_INCLUDE_ONLY
+ template <typename I>
+ mln_concrete(I)
+ saturate(const Image<I>& input_)
+ {
+ trace::entering("mln::world::kn::saturate");
+ mlc_equal(mln_trait_image_kind(I),
+ mln::trait::image::kind::binary)::check();
+ mln_precondition(exact(input_).is_valid());
- // Facade
+ const I& input = exact(input_);
+ unsigned n_labels;
+ mln_ch_value(I,unsigned)
+ lab = labeling::background(input, c4(), n_labels);
- template <typename I>
- void fill_0_1_faces_internal_border(Image<I>& inout_,
- const mln_value(I)& v)
- {
- trace::entering("mln::world::kn::fill_0_1_faces_internal_border");
+ bool has_bg_label;
+ unsigned bg = internal::get_background_label(lab, has_bg_label);
+
+ mln_concrete(I) output;
+ initialize(output, input);
- mln_precondition(exact(inout_).is_valid());
- I& inout = exact(inout_);
+ if (! has_bg_label)
+ {
+ data::fill(output, true);
+ return output;
+ }
- inner_border::fill(inout, v);
+ data::fill(output, pw::value(lab) != pw::cst(bg));
- trace::exiting("mln::world::kn::fill_0_1_faces_internal_border");
+ trace::exiting("mln::world::kn::saturate");
+ return output;
}
# endif // ! MLN_INCLUDE_ONLY
@@ -90,4 +96,4 @@ namespace mln
} // end of namespace mln
-#endif // ! MLN_WORLD_KN_FILL_0_1_FACES_INTERNAL_BORDER_HH
+#endif // ! MLN_WORLD_KN_SATURATE_HH
diff --git a/milena/tests/world/kn/Makefile.am b/milena/tests/world/kn/Makefile.am
index 866ae00..2a89e48a 100644
--- a/milena/tests/world/kn/Makefile.am
+++ b/milena/tests/world/kn/Makefile.am
@@ -23,6 +23,7 @@ check_PROGRAMS = \
fill_1_from_2_faces \
fill_1_from_aux_2_faces \
fill_2_from_1_faces \
+ holes \
immerse \
immerse_with_inner_border \
is_0_face \
@@ -32,6 +33,7 @@ check_PROGRAMS = \
is_1_face_horizontal \
is_2_face \
level \
+ saturate \
un_immerse
fill_0_1_faces_internal_border_SOURCES = fill_0_1_faces_internal_border.cc
@@ -40,6 +42,7 @@ fill_0_from_2_faces_SOURCES = fill_0_from_2_faces.cc
fill_1_from_2_faces_SOURCES = fill_1_from_2_faces.cc
fill_1_from_aux_2_faces_SOURCES = fill_1_from_aux_2_faces.cc
fill_2_from_1_faces_SOURCES = fill_2_from_1_faces.cc
+holes_SOURCES = holes.cc
immerse_SOURCES = immerse.cc
immerse_with_inner_border_SOURCES = immerse_with_inner_border.cc
is_0_face_SOURCES = is_0_face.cc
@@ -49,6 +52,7 @@ is_1_face_vertical_SOURCES = is_1_face_vertical.cc
is_1_face_horizontal_SOURCES = is_1_face_horizontal.cc
is_2_face_SOURCES = is_2_face.cc
level_SOURCES = level.cc
+saturate_SOURCES = saturate.cc
un_immerse_SOURCES = un_immerse.cc
diff --git a/milena/tests/world/k1/fill_1_from_2_faces.cc b/milena/tests/world/kn/holes.cc
similarity index 59%
copy from milena/tests/world/k1/fill_1_from_2_faces.cc
copy to milena/tests/world/kn/holes.cc
index 4045674..9bba24f 100644
--- a/milena/tests/world/k1/fill_1_from_2_faces.cc
+++ b/milena/tests/world/kn/holes.cc
@@ -26,61 +26,55 @@
/// \file
#include <mln/core/image/image2d.hh>
-#include <mln/make/box2d.hh>
+#include <mln/world/kn/holes.hh>
#include <mln/data/compare.hh>
-#include <mln/accu/math/sum.hh>
-#include <mln/world/k1/fill_1_from_2_faces.hh>
-#include <mln/border/fill.hh>
-
-
-namespace mln
-{
-
- struct sum_t : Function_vv2v<sum_t>
- {
- typedef int result;
-
- int operator()(const int& v1, const int& v2) const
- {
- return v1 + v2;
- }
-
- };
-
-}
-
-
int main()
{
using namespace mln;
- int refvals[5][5] = {
- {1, 3, 1, 3, 1},
- {3, 3, 6, 3, 3},
- {1, 6, 1, 6, 1},
- {3, 3, 6, 3, 3},
- {1, 3, 1, 3, 1}
- };
- image2d<int> ref = make::image(refvals, point2d(-1, -1));
-
- int vals[5][5] = {
- {1, 0, 1, 0, 1 },
- {0, 3, 0, 3, 0 },
- {1, 0, 1, 0, 1 },
- {0, 3, 0, 3, 0 },
- {1, 0, 1, 0, 1 }
- };
- image2d<int> imakn = make::image(vals, point2d(-1, -1));
+ {
+ bool vals[][5] = {
+ {0, 0, 1, 1, 1},
+ {1, 0, 1, 0, 1},
+ {1, 1, 1, 1, 1},
+ {1, 1, 1, 1, 1},
+ {1, 1, 1, 1, 1}
+ };
+ image2d<bool> ima = make::image(vals);
+ bool refvals[][5] = {
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 1, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0}
+ };
+ image2d<bool> ref = make::image(refvals);
+
+ image2d<bool> out = world::kn::holes(ima);
+ mln_assertion(out == ref);
+ }
- /// Make sure the border is set to 0 to get deterministic results.
- border::fill(imakn, 0);
- // Overload with function
{
- sum_t f;
- world::k1::fill_1_from_2_faces(imakn, f);
- mln_assertion(ref == imakn);
+ bool vals[][5] = {
+ {1, 1, 1, 1, 1},
+ {1, 0, 1, 0, 1},
+ {1, 1, 1, 1, 1},
+ {1, 1, 1, 1, 1},
+ {1, 1, 1, 1, 1}
+ };
+ image2d<bool> ima = make::image(vals);
+ bool refvals[][5] = {
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0}
+ };
+ image2d<bool> ref = make::image(refvals);
+
+ image2d<bool> out = world::kn::holes(ima);
+ mln_assertion(out == ref);
}
-
}
diff --git a/milena/tests/world/k1/fill_1_from_2_faces.cc b/milena/tests/world/kn/saturate.cc
similarity index 58%
copy from milena/tests/world/k1/fill_1_from_2_faces.cc
copy to milena/tests/world/kn/saturate.cc
index 4045674..33b0f79 100644
--- a/milena/tests/world/k1/fill_1_from_2_faces.cc
+++ b/milena/tests/world/kn/saturate.cc
@@ -26,61 +26,54 @@
/// \file
#include <mln/core/image/image2d.hh>
-#include <mln/make/box2d.hh>
+#include <mln/world/kn/saturate.hh>
#include <mln/data/compare.hh>
-#include <mln/accu/math/sum.hh>
-#include <mln/world/k1/fill_1_from_2_faces.hh>
-#include <mln/border/fill.hh>
-
-
-namespace mln
-{
-
- struct sum_t : Function_vv2v<sum_t>
- {
- typedef int result;
-
- int operator()(const int& v1, const int& v2) const
- {
- return v1 + v2;
- }
-
- };
-
-}
-
-
int main()
{
using namespace mln;
- int refvals[5][5] = {
- {1, 3, 1, 3, 1},
- {3, 3, 6, 3, 3},
- {1, 6, 1, 6, 1},
- {3, 3, 6, 3, 3},
- {1, 3, 1, 3, 1}
- };
- image2d<int> ref = make::image(refvals, point2d(-1, -1));
-
- int vals[5][5] = {
- {1, 0, 1, 0, 1 },
- {0, 3, 0, 3, 0 },
- {1, 0, 1, 0, 1 },
- {0, 3, 0, 3, 0 },
- {1, 0, 1, 0, 1 }
- };
- image2d<int> imakn = make::image(vals, point2d(-1, -1));
-
- /// Make sure the border is set to 0 to get deterministic results.
- border::fill(imakn, 0);
-
- // Overload with function
{
- sum_t f;
- world::k1::fill_1_from_2_faces(imakn, f);
- mln_assertion(ref == imakn);
+ bool vals[][5] = {
+ {0, 0, 1, 1, 1},
+ {1, 0, 1, 0, 1},
+ {1, 1, 1, 1, 1},
+ {1, 1, 1, 1, 1},
+ {1, 1, 1, 1, 1}
+ };
+ image2d<bool> ima = make::image(vals);
+ bool refvals[][5] = {
+ {0, 0, 1, 1, 1},
+ {1, 0, 1, 1, 1},
+ {1, 1, 1, 1, 1},
+ {1, 1, 1, 1, 1},
+ {1, 1, 1, 1, 1}
+ };
+ image2d<bool> ref = make::image(refvals);
+
+ image2d<bool> out = world::kn::saturate(ima);
+ mln_assertion(out == ref);
}
+ {
+ bool vals[][5] = {
+ {1, 1, 1, 1, 1},
+ {1, 0, 1, 0, 1},
+ {1, 1, 1, 1, 1},
+ {1, 1, 1, 1, 1},
+ {1, 1, 1, 1, 1}
+ };
+ image2d<bool> ima = make::image(vals);
+ bool refvals[][5] = {
+ {1, 1, 1, 1, 1},
+ {1, 1, 1, 1, 1},
+ {1, 1, 1, 1, 1},
+ {1, 1, 1, 1, 1},
+ {1, 1, 1, 1, 1}
+ };
+ image2d<bool> ref = make::image(refvals);
+
+ image2d<bool> out = world::kn::saturate(ima);
+ mln_assertion(out == ref);
+ }
}
--
1.7.2.5
1
0
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Olena, a generic and efficient image processing platform".
The branch exp/khalimsky has been updated
via 104c7b7044973cc4da49295f06294ddc2aa552ea (commit)
via 8ea985cae75d44dec8136731773c9cfa1764724c (commit)
via 89de8a2b83bd6d56272cf272381d2dab8b27bb32 (commit)
from 81fe5b981e588b3dfe533d7763c3aa73372b3780 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
104c7b7 Fix preconditions.
8ea985c Add tests for inner_border routines.
89de8a2 configure.ac: Configure milena/tests/inner_border/Makefile.am.
-----------------------------------------------------------------------
Summary of changes:
ChangeLog | 4 +
configure.ac | 1 +
milena/ChangeLog | 19 +++++
milena/mln/inner_border/extend.hh | 2 +-
milena/mln/inner_border/fill.hh | 2 +-
milena/tests/Makefile.am | 3 +-
.../{core/routine => inner_border}/Makefile.am | 17 ++--
.../extend.cc} | 45 ++++++------
.../extend_and_fill.cc} | 51 +++++++------
.../extend_and_fill_with_inner_border.cc} | 79 ++++++++------------
.../k1/immerse_with.cc => inner_border/fill.cc} | 65 ++++++++++-------
11 files changed, 155 insertions(+), 133 deletions(-)
copy milena/tests/{core/routine => inner_border}/Makefile.am (71%)
copy milena/tests/{world/kn/fill_0_1_faces_internal_border.cc => inner_border/extend.cc} (67%)
copy milena/tests/{world/kn/fill_0_1_faces_internal_border.cc => inner_border/extend_and_fill.cc} (62%)
copy milena/tests/{world/kn/fill_1_from_2_faces.cc => inner_border/extend_and_fill_with_inner_border.cc} (60%)
copy milena/tests/{world/k1/immerse_with.cc => inner_border/fill.cc} (64%)
hooks/post-receive
--
Olena, a generic and efficient image processing platform
1
0
* mln/inner_border/extend.hh,
* mln/inner_border/fill.hh: Here.
---
milena/ChangeLog | 7 +++++++
milena/mln/inner_border/extend.hh | 2 +-
milena/mln/inner_border/fill.hh | 2 +-
3 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 8b0ef22..cc55293 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,5 +1,12 @@
2012-10-25 Guillaume Lazzara <z(a)lrde.epita.fr>
+ Fix preconditions.
+
+ * mln/inner_border/extend.hh,
+ * mln/inner_border/fill.hh: Here.
+
+2012-10-25 Guillaume Lazzara <z(a)lrde.epita.fr>
+
Add tests for inner_border routines.
* tests/Makefile.am: Add inner_border subdir.
diff --git a/milena/mln/inner_border/extend.hh b/milena/mln/inner_border/extend.hh
index d5172a2..08c1901 100644
--- a/milena/mln/inner_border/extend.hh
+++ b/milena/mln/inner_border/extend.hh
@@ -59,7 +59,7 @@ namespace mln
extend(const Image<I>& input_, unsigned inner_border_size)
{
trace::entering("mln::inner_border::extend");
- mln_precondition(exact(input).is_valid());
+ mln_precondition(exact(input_).is_valid());
const I& input = exact(input_);
box2d b = input.domain(), bb = b;
diff --git a/milena/mln/inner_border/fill.hh b/milena/mln/inner_border/fill.hh
index 8f669df..57c6ed6 100644
--- a/milena/mln/inner_border/fill.hh
+++ b/milena/mln/inner_border/fill.hh
@@ -62,7 +62,7 @@ namespace mln
const mln_value(I)& value)
{
trace::entering("mln::inner_border::fill");
- mln_precondition(exact(input).is_valid());
+ mln_precondition(exact(input_).is_valid());
I& input = exact(input_);
mln_piter(I) p(input.domain());
--
1.7.2.5
1
0

25 Oct '12
* tests/Makefile.am: Add inner_border subdir.
* tests/inner_border/Makefile.am,
* tests/inner_border/extend.cc,
* tests/inner_border/extend_and_fill.cc,
* tests/inner_border/extend_and_fill_with_inner_border.cc,
* tests/inner_border/fill.cc: New.
---
milena/ChangeLog | 12 +++
milena/tests/Makefile.am | 3 +-
.../{core/routine => inner_border}/Makefile.am | 17 ++--
.../extend.cc} | 45 ++++++------
.../extend_and_fill.cc} | 51 +++++++------
.../extend_and_fill_with_inner_border.cc} | 79 ++++++++------------
.../k1/immerse_with.cc => inner_border/fill.cc} | 65 ++++++++++-------
7 files changed, 141 insertions(+), 131 deletions(-)
copy milena/tests/{core/routine => inner_border}/Makefile.am (71%)
copy milena/tests/{world/kn/fill_0_1_faces_internal_border.cc => inner_border/extend.cc} (67%)
copy milena/tests/{world/kn/fill_0_1_faces_internal_border.cc => inner_border/extend_and_fill.cc} (62%)
copy milena/tests/{world/kn/fill_1_from_2_faces.cc => inner_border/extend_and_fill_with_inner_border.cc} (60%)
copy milena/tests/{world/k1/immerse_with.cc => inner_border/fill.cc} (64%)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 47a167d..8b0ef22 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,5 +1,17 @@
2012-10-25 Guillaume Lazzara <z(a)lrde.epita.fr>
+ Add tests for inner_border routines.
+
+ * tests/Makefile.am: Add inner_border subdir.
+
+ * tests/inner_border/Makefile.am,
+ * tests/inner_border/extend.cc,
+ * tests/inner_border/extend_and_fill.cc,
+ * tests/inner_border/extend_and_fill_with_inner_border.cc,
+ * tests/inner_border/fill.cc: New.
+
+2012-10-25 Guillaume Lazzara <z(a)lrde.epita.fr>
+
Add compute_tree_of_shapes algorithm.
* mln/util/hqueue.hh,
diff --git a/milena/tests/Makefile.am b/milena/tests/Makefile.am
index 3493250..bb6f3b9 100644
--- a/milena/tests/Makefile.am
+++ b/milena/tests/Makefile.am
@@ -1,4 +1,4 @@
-# Copyright (C) 2007, 2008, 2009 EPITA Research and Development
+# Copyright (C) 2007, 2008, 2009, 2012 EPITA Research and Development
# Laboratory (LRDE).
#
# This file is part of Olena.
@@ -36,6 +36,7 @@ SUBDIRS = \
geom \
graph \
histo \
+ inner_border \
io \
labeling \
linear \
diff --git a/milena/tests/core/routine/Makefile.am b/milena/tests/inner_border/Makefile.am
similarity index 71%
copy from milena/tests/core/routine/Makefile.am
copy to milena/tests/inner_border/Makefile.am
index 2640c47..a3443ad 100644
--- a/milena/tests/core/routine/Makefile.am
+++ b/milena/tests/inner_border/Makefile.am
@@ -1,4 +1,4 @@
-# Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE).
+# Copyright (C) 2012 EPITA Research and Development Laboratory (LRDE).
#
# This file is part of Olena.
#
@@ -17,16 +17,15 @@
include $(top_srcdir)/milena/tests/tests.mk
check_PROGRAMS = \
- duplicate \
- exact \
extend \
- initialize \
- primary
+ extend_and_fill \
+ extend_and_fill_with_inner_border \
+ fill
-duplicate_SOURCES = duplicate.cc
-exact_SOURCES = exact.cc
extend_SOURCES = extend.cc
-initialize_SOURCES = initialize.cc
-primary_SOURCES = primary.cc
+extend_and_fill_SOURCES = extend_and_fill.cc
+extend_and_fill_with_inner_border_SOURCES = extend_and_fill_with_inner_border.cc
+fill_SOURCES = fill.cc
+
TESTS = $(check_PROGRAMS)
diff --git a/milena/tests/world/kn/fill_0_1_faces_internal_border.cc b/milena/tests/inner_border/extend.cc
similarity index 67%
copy from milena/tests/world/kn/fill_0_1_faces_internal_border.cc
copy to milena/tests/inner_border/extend.cc
index 7bd186e..2380989 100644
--- a/milena/tests/world/kn/fill_0_1_faces_internal_border.cc
+++ b/milena/tests/inner_border/extend.cc
@@ -23,37 +23,36 @@
// exception does not however invalidate any other reasons why the
// executable file might be covered by the GNU General Public License.
-/// \file
-
+#include <mln/inner_border/extend.hh>
#include <mln/core/image/image2d.hh>
-#include <mln/make/box2d.hh>
+#include <mln/data/fill.hh>
#include <mln/data/compare.hh>
-#include <mln/world/kn/fill_0_1_faces_internal_border.hh>
int main()
{
using namespace mln;
- int refvals[5][5] = {
- {1, 1, 1, 1, 1 },
- {1, 2, 0, 2, 1 },
- {1, 0, 0, 0, 1 },
- {1, 2, 0, 2, 1 },
- {1, 1, 1, 1, 1 }
- };
- image2d<int> ref = make::image(refvals, point2d(-1, -1));
-
- int vals[5][5] = {
- {0, 0, 0, 0, 0 },
- {0, 2, 0, 2, 0 },
- {0, 0, 0, 0, 0 },
- {0, 2, 0, 2, 0 },
- {0, 0, 0, 0, 0 }
- };
- image2d<int> imak1 = make::image(vals, point2d(-1, -1));
+ // inner_border == 1
+ {
+ image2d<int> ima(5,5);
+ box2d b = ima.domain();
+ data::fill(ima, 1);
+ ima = inner_border::extend(ima, 1);
+ mln_assertion(ima.domain() == box2d(point2d(-1,-1),point2d(5,5)));
+ mln_piter(image2d<int>) p(b);
+ for_all(p)
+ mln_assertion(ima(p) == 1);
+ }
+ // inner_border == 2
{
- world::kn::fill_0_1_faces_internal_border(imak1, 1);
- mln_assertion(ref == imak1);
+ image2d<int> ima(5,5);
+ box2d b = ima.domain();
+ data::fill(ima, 1);
+ ima = inner_border::extend(ima, 2);
+ mln_assertion(ima.domain() == box2d(point2d(-2,-2),point2d(6,6)));
+ mln_piter(image2d<int>) p(b);
+ for_all(p)
+ mln_assertion(ima(p) == 1);
}
}
diff --git a/milena/tests/world/kn/fill_0_1_faces_internal_border.cc b/milena/tests/inner_border/extend_and_fill.cc
similarity index 62%
copy from milena/tests/world/kn/fill_0_1_faces_internal_border.cc
copy to milena/tests/inner_border/extend_and_fill.cc
index 7bd186e..c1ebb2e 100644
--- a/milena/tests/world/kn/fill_0_1_faces_internal_border.cc
+++ b/milena/tests/inner_border/extend_and_fill.cc
@@ -23,37 +23,42 @@
// exception does not however invalidate any other reasons why the
// executable file might be covered by the GNU General Public License.
-/// \file
-
+#include <mln/inner_border/extend_and_fill.hh>
#include <mln/core/image/image2d.hh>
-#include <mln/make/box2d.hh>
+#include <mln/data/fill.hh>
#include <mln/data/compare.hh>
-#include <mln/world/kn/fill_0_1_faces_internal_border.hh>
int main()
{
using namespace mln;
- int refvals[5][5] = {
- {1, 1, 1, 1, 1 },
- {1, 2, 0, 2, 1 },
- {1, 0, 0, 0, 1 },
- {1, 2, 0, 2, 1 },
- {1, 1, 1, 1, 1 }
- };
- image2d<int> ref = make::image(refvals, point2d(-1, -1));
-
- int vals[5][5] = {
- {0, 0, 0, 0, 0 },
- {0, 2, 0, 2, 0 },
- {0, 0, 0, 0, 0 },
- {0, 2, 0, 2, 0 },
- {0, 0, 0, 0, 0 }
- };
- image2d<int> imak1 = make::image(vals, point2d(-1, -1));
+ // inner_border == 1
+ {
+ image2d<int> ima(5,5);
+ box2d b = ima.domain();
+ data::fill(ima, 1);
+ ima = inner_border::extend_and_fill(ima, 1, 2);
+ mln_assertion(ima.domain() == box2d(point2d(-1,-1),point2d(5,5)));
+ mln_piter(image2d<int>) p(ima.domain());
+ for_all(p)
+ if (b.has(p))
+ mln_assertion(ima(p) == 1);
+ else
+ mln_assertion(ima(p) == 2);
+ }
+ // inner_border == 2
{
- world::kn::fill_0_1_faces_internal_border(imak1, 1);
- mln_assertion(ref == imak1);
+ image2d<int> ima(5,5);
+ box2d b = ima.domain();
+ data::fill(ima, 1);
+ ima = inner_border::extend_and_fill(ima, 2, 2);
+ mln_assertion(ima.domain() == box2d(point2d(-2,-2),point2d(6,6)));
+ mln_piter(image2d<int>) p(ima.domain());
+ for_all(p)
+ if (b.has(p))
+ mln_assertion(ima(p) == 1);
+ else
+ mln_assertion(ima(p) == 2);
}
}
diff --git a/milena/tests/world/kn/fill_1_from_2_faces.cc b/milena/tests/inner_border/extend_and_fill_with_inner_border.cc
similarity index 60%
copy from milena/tests/world/kn/fill_1_from_2_faces.cc
copy to milena/tests/inner_border/extend_and_fill_with_inner_border.cc
index bd14ace..b5fb3d0 100644
--- a/milena/tests/world/kn/fill_1_from_2_faces.cc
+++ b/milena/tests/inner_border/extend_and_fill_with_inner_border.cc
@@ -23,65 +23,48 @@
// exception does not however invalidate any other reasons why the
// executable file might be covered by the GNU General Public License.
-/// \file
-
+#include <mln/inner_border/extend_and_fill_with_inner_border.hh>
#include <mln/core/image/image2d.hh>
-#include <mln/make/box2d.hh>
+#include <mln/data/fill.hh>
#include <mln/data/compare.hh>
#include <mln/accu/math/sum.hh>
-#include <mln/world/kn/fill_1_from_2_faces.hh>
-#include <mln/border/fill.hh>
-
-
-namespace mln
-{
-
- struct sum_t : Function_vv2v<sum_t>
- {
- typedef int result;
-
- int operator()(const int& v1, const int& v2) const
- {
- return v1 + v2;
- }
-
- };
-
-}
-
int main()
{
using namespace mln;
- int refvals[5][5] = {
- {1, 3, 1, 3, 1},
- {3, 3, 6, 3, 3},
- {1, 6, 1, 6, 1},
- {3, 3, 6, 3, 3},
- {1, 3, 1, 3, 1}
- };
- image2d<int> ref = make::image(refvals, point2d(-1, -1));
-
- int vals[5][5] = {
- {1, 0, 1, 0, 1 },
- {0, 3, 0, 3, 0 },
- {1, 0, 1, 0, 1 },
- {0, 3, 0, 3, 0 },
- {1, 0, 1, 0, 1 }
- };
- image2d<int> imakn = make::image(vals, point2d(-1, -1));
-
- /// Make sure the border is set to 0 to get deterministic results.
- border::fill(imakn, 0);
-
-
- // Overload with accumulator
+ // inner_border == 1
{
+ image2d<int> ima(5,5);
+ box2d b = ima.domain();
+ data::fill(ima, 1);
accu::math::sum<int> accu;
- world::kn::fill_1_from_2_faces(imakn, accu);
- mln_assertion(ref == imakn);
+ ima = inner_border::extend_and_fill_with_inner_border(ima, 1, accu, 2);
+
+ mln_assertion(ima.domain() == box2d(point2d(-1,-1),point2d(5,5)));
+ mln_piter(image2d<int>) p(ima.domain());
+ for_all(p)
+ if (b.has(p))
+ mln_assertion(ima(p) == 1);
+ else
+ mln_assertion(ima(p) == 24);
}
+ // inner_border == 2
+ {
+ image2d<int> ima(5,5);
+ box2d b = ima.domain();
+ data::fill(ima, 1);
+ accu::math::sum<int> accu;
+ ima = inner_border::extend_and_fill_with_inner_border(ima, 2, accu, 2);
+
+ mln_assertion(ima.domain() == box2d(point2d(-2,-2),point2d(6,6)));
+ mln_piter(image2d<int>) p(ima.domain());
+ for_all(p)
+ if (b.has(p))
+ mln_assertion(ima(p) == 1);
+ else
+ mln_assertion(ima(p) == 24);
+ }
}
diff --git a/milena/tests/world/k1/immerse_with.cc b/milena/tests/inner_border/fill.cc
similarity index 64%
copy from milena/tests/world/k1/immerse_with.cc
copy to milena/tests/inner_border/fill.cc
index 3b7e8fc..3bc2443 100644
--- a/milena/tests/world/k1/immerse_with.cc
+++ b/milena/tests/inner_border/fill.cc
@@ -23,41 +23,52 @@
// exception does not however invalidate any other reasons why the
// executable file might be covered by the GNU General Public License.
-/// \file
-
+#include <mln/inner_border/fill.hh>
#include <mln/core/image/image2d.hh>
-#include <mln/world/k1/immerse_with.hh>
+#include <mln/data/fill.hh>
#include <mln/data/compare.hh>
-#include <mln/border/fill.hh>
-#include <mln/fun/vv2v/max.hh>
-#include <mln/fun/vvvv2v/max.hh>
-int main()
+int
+main (void)
{
using namespace mln;
- int ivals[][2] = {
- {1, 2},
- {3, 4}
- };
- image2d<int> ima = make::image(ivals);
- border::fill(ima, 0); // Make sure there is not border effect.
-
- int fvals[][5] = {
- {1, 1, 2, 2, 2},
- {1, 1, 2, 2, 2},
- {3, 3, 4, 4, 4},
- {3, 3, 4, 4, 4},
- {3, 3, 4, 4, 4}
- };
- image2d<int> ref = make::image(fvals, point2d(-1,-1));
+ // inner_border == 1
+ {
+ int refvals[5][5] = {
+ {2, 2, 2, 2, 2},
+ {2, 1, 1, 1, 2},
+ {2, 1, 1, 1, 2},
+ {2, 1, 1, 1, 2},
+ {2, 2, 2, 2, 2}
+ };
+ image2d<int> ref = make::image(refvals);
+
+ image2d<int> ima(5,5);
+ data::fill(ima, 1);
+ inner_border::fill(ima, 2);
+
+ mln_assertion(ima == ref);
+ }
+
+ // inner_border == 2
{
- image2d<long>
- immersed = world::k1::immerse_with(ima, long(),
- fun::vv2v::max<long>(),
- fun::vvvv2v::max<long>());
- mln_assertion(immersed == ref);
+ int refvals[5][5] = {
+ {2, 2, 2, 2, 2},
+ {2, 2, 2, 2, 2},
+ {2, 2, 1, 2, 2},
+ {2, 2, 2, 2, 2},
+ {2, 2, 2, 2, 2}
+ };
+ image2d<int> ref = make::image(refvals);
+
+ image2d<int> ima(5,5);
+ data::fill(ima, 1);
+
+ inner_border::fill(ima, 2, 2);
+
+ mln_assertion(ima == ref);
}
}
--
1.7.2.5
1
0

olena-2.0-133-g89de8a2 configure.ac: Configure milena/tests/inner_border/Makefile.am.
by Guillaume Lazzara 25 Oct '12
by Guillaume Lazzara 25 Oct '12
25 Oct '12
---
ChangeLog | 4 ++++
configure.ac | 1 +
2 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index e651497..6178343 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2012-10-25 Guillaume Lazzara <z(a)lrde.epita.fr>
+
+ * configure.ac: Configure milena/tests/inner_border/Makefile.am.
+
2012-09-27 Guillaume Lazzara <z(a)lrde.epita.fr>
* configure.ac: Configure milena/tests/world/k{2,n}/Makefile.am.
diff --git a/configure.ac b/configure.ac
index 84c0093..75d50cd 100644
--- a/configure.ac
+++ b/configure.ac
@@ -469,6 +469,7 @@ AC_CONFIG_FILES([
milena/tests/graph/Makefile
milena/tests/graph/attribute/Makefile
milena/tests/histo/Makefile
+ milena/tests/inner_border/Makefile
milena/tests/io/Makefile
milena/tests/io/dicom/Makefile
milena/tests/io/dump/Makefile
--
1.7.2.5
1
0
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Olena, a generic and efficient image processing platform".
The branch exp/khalimsky has been updated
via 81fe5b981e588b3dfe533d7763c3aa73372b3780 (commit)
via ab1d771840bf5feb550af4f83fdf17b68aad3cfd (commit)
from abeebe9d18431d7dfb2f0fb711b3ede92a17ab55 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
81fe5b9 Add compute_tree_of_shapes algorithm.
ab1d771 Various fixes.
-----------------------------------------------------------------------
Summary of changes:
milena/ChangeLog | 36 ++
milena/mln/accu/math/span.hh | 43 +-
milena/mln/data/compute_in_inner_border.hh | 6 +-
milena/mln/fun/vv2v/span.hh | 19 +-
milena/mln/fun/vvvv2v/span.hh | 27 +-
milena/mln/inner_border/fill.hh | 4 +-
.../{on_frontiere.hh => is_on_frontiere.hh} | 45 ++-
milena/mln/util/hqueue.hh | 162 +++++++
.../fill.hh => util/tree_of_shapes.hh} | 79 ++--
milena/mln/value/interval.hh | 20 +-
milena/mln/world/k2/is_primary_2_face.hh | 2 +-
milena/mln/world/kn/compute_tree_of_shapes.hh | 500 ++++++++++++++++++++
.../mln/world/kn/fill_0_1_faces_internal_border.hh | 22 +-
milena/mln/world/kn/internal/display.hh | 320 +++++++++++++
.../kn/internal/fill_primary_2_faces_from_input.hh | 3 +-
milena/mln/world/kn/safe_cast.hh | 87 ++--
milena/mln/world/kn/un_immerse.hh | 4 +-
17 files changed, 1207 insertions(+), 172 deletions(-)
rename milena/mln/inner_border/internal/{on_frontiere.hh => is_on_frontiere.hh} (68%)
create mode 100644 milena/mln/util/hqueue.hh
copy milena/mln/{inner_border/fill.hh => util/tree_of_shapes.hh} (56%)
create mode 100644 milena/mln/world/kn/compute_tree_of_shapes.hh
create mode 100644 milena/mln/world/kn/internal/display.hh
hooks/post-receive
--
Olena, a generic and efficient image processing platform
1
0

25 Oct '12
* mln/util/hqueue.hh,
* mln/util/tree_of_shapes.hh,
* mln/world/kn/compute_tree_of_shapes.hh,
* mln/world/kn/internal/display.hh: New.
---
milena/ChangeLog | 9 +
milena/mln/util/hqueue.hh | 162 +++++++
.../fill.hh => util/tree_of_shapes.hh} | 79 ++--
milena/mln/world/kn/compute_tree_of_shapes.hh | 500 ++++++++++++++++++++
milena/mln/world/kn/internal/display.hh | 320 +++++++++++++
5 files changed, 1036 insertions(+), 34 deletions(-)
create mode 100644 milena/mln/util/hqueue.hh
copy milena/mln/{inner_border/fill.hh => util/tree_of_shapes.hh} (56%)
create mode 100644 milena/mln/world/kn/compute_tree_of_shapes.hh
create mode 100644 milena/mln/world/kn/internal/display.hh
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 9c48f48..47a167d 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,5 +1,14 @@
2012-10-25 Guillaume Lazzara <z(a)lrde.epita.fr>
+ Add compute_tree_of_shapes algorithm.
+
+ * mln/util/hqueue.hh,
+ * mln/util/tree_of_shapes.hh,
+ * mln/world/kn/compute_tree_of_shapes.hh,
+ * mln/world/kn/internal/display.hh: New.
+
+2012-10-25 Guillaume Lazzara <z(a)lrde.epita.fr>
+
Various fixes.
* mln/accu/math/span.hh,
diff --git a/milena/mln/util/hqueue.hh b/milena/mln/util/hqueue.hh
new file mode 100644
index 0000000..3a68b5c
--- /dev/null
+++ b/milena/mln/util/hqueue.hh
@@ -0,0 +1,162 @@
+// Copyright (C) 2012 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef MLN_UTIL_HQUEUE_HH
+# define MLN_UTIL_HQUEUE_HH
+
+/// \file
+/// \brief Class for hierarchical queues.
+
+
+# include <cstdlib>
+# include <iostream>
+# include <vector>
+# include <queue>
+
+
+namespace mln
+{
+
+ namespace util
+ {
+
+ /// \brief Class for hierarchical queues.
+ template <typename T, typename P>
+ class hqueue
+ {
+ public:
+ hqueue();
+ hqueue(const value::interval<P>& inter);
+ hqueue(const P& first, const P& last);
+
+ unsigned size() const;
+
+ bool is_empty() const;
+ bool is_not_empty() const;
+
+ const std::queue<T>& operator[](const P& priority) const;
+
+ void push(const T& t, const P& priority);
+ T pop(const P& priority);
+
+ private:
+ std::vector<std::queue<T> > v_;
+ unsigned head_;
+ value::interval<P> inter_;
+ };
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ template <typename T, typename P>
+ hqueue<T,P>::hqueue()
+ {
+ head_ = 0;
+ }
+
+ template <typename T, typename P>
+ hqueue<T,P>::hqueue(const value::interval<P>& inter)
+ {
+ inter_ = inter;
+ v_.resize(inter.nelements());
+ head_ = 0;
+ }
+
+ template <typename T, typename P>
+ hqueue<T,P>::hqueue(const P& first, const P& last)
+ {
+ inter_ = value::interval<P>(first, last);
+ v_.resize(inter_.nelements());
+ head_ = 0;
+ }
+
+ template <typename T, typename P>
+ unsigned
+ hqueue<T,P>::size() const
+ {
+ mln_precondition(head_ <= v_.size());
+ return v_.size() - head_;
+ }
+
+ template <typename T, typename P>
+ bool
+ hqueue<T,P>::is_empty() const
+ {
+ return this->size() == 0;
+ }
+
+ template <typename T, typename P>
+ bool
+ hqueue<T,P>::is_not_empty() const
+ {
+ return ! this->is_empty();
+ }
+
+ template <typename T, typename P>
+ const std::queue<T>&
+ hqueue<T,P>::operator[](const P& i) const
+ {
+ mln_precondition(i < this->size());
+ return v_[head_ + i];
+ }
+
+ template <typename T, typename P>
+ void
+ hqueue<T,P>::push(const T& t, const P& priority)
+ {
+ v_[inter_.index_of(priority)].push(t);
+ }
+
+ template <typename T, typename P>
+ T
+ hqueue<T,P>::pop(const P& priority)
+ {
+ mln_precondition(!is_empty());
+ T front = v_[priority].front();
+ v_[priority].pop();
+ return front;
+ }
+
+
+ template <typename T, typename P>
+ std::ostream&
+ operator<<(std::ostream& ostr, const hqueue<T,P>& q)
+ {
+ unsigned n = q.size();
+ ostr << '(';
+ for (unsigned i = 0; i < n; ++i)
+ ostr << q.v_[i] << (i + 1 == n ? "" : ", ");
+ return ostr << ')';
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::util
+
+} // end of namespace mln
+
+#endif // ! MLN_UTIL_HQUEUE_HH
diff --git a/milena/mln/inner_border/fill.hh b/milena/mln/util/tree_of_shapes.hh
similarity index 56%
copy from milena/mln/inner_border/fill.hh
copy to milena/mln/util/tree_of_shapes.hh
index 8f669df..c3b00e5 100644
--- a/milena/mln/inner_border/fill.hh
+++ b/milena/mln/util/tree_of_shapes.hh
@@ -23,68 +23,79 @@
// exception does not however invalidate any other reasons why the
// executable file might be covered by the GNU General Public License.
-#ifndef MLN_INNER_BORDER_FILL_HH
-# define MLN_INNER_BORDER_FILL_HH
-
/// \file
///
-/// \brief Fill the inner border of an image.
+/// \brief Tree of shapes data structure.
+
+#ifndef MLN_UTIL_TREE_OF_SHAPES_HH
+# define MLN_UTIL_TREE_OF_SHAPES_HH
-# include <mln/core/image/image2d.hh>
-# include <mln/data/paste.hh>
-# include <mln/inner_border/internal/is_on_frontiere.hh>
namespace mln
{
- namespace inner_border
+ namespace util
{
- /// \brief Fill the inner border of an image.
template <typename I>
- void
- fill(Image<I>& input, unsigned border_size,
- const mln_value(I)& value);
+ struct tree_of_shapes
+ {
+ typedef mln_site(I) P;
+ typedef mln_value(I) V;
+ typedef mln_equiv(V) EV;
- /// \overload
- /// The border_size is set to 1.
- template <typename I>
- void
- fill(Image<I>& input, const mln_value(I)& value);
+ I Fb;
+ std::vector<P> R;
+ mln_ch_value(I,P) parent;
+ mln_ch_value(I,bool) show;
+
+ V level(const P& p) const;
+ bool level_changes_at(unsigned i) const;
+ bool is_root(const P& p) const;
+ bool is_representative(const P& p) const;
+
+ };
# ifndef MLN_INCLUDE_ONLY
template <typename I>
- void
- fill(Image<I>& input_, unsigned border_size,
- const mln_value(I)& value)
+ typename tree_of_shapes<I>::V
+ tree_of_shapes<I>::level(const P& p) const
{
- trace::entering("mln::inner_border::fill");
- mln_precondition(exact(input).is_valid());
- I& input = exact(input_);
+ return Fb(p);
+ }
- mln_piter(I) p(input.domain());
- for_all(p)
- if (internal::is_on_frontiere(p, input.domain(), border_size))
- input(p) = value;
+ template <typename I>
+ bool
+ tree_of_shapes<I>::level_changes_at(unsigned i) const
+ {
+ if (i == 0) // the end...
+ return true;
+ P p = R[i], p_next = R[i-1];
+ return Fb(p_next) != Fb(p); // ..or next level is different
+ }
- trace::exiting("mln::inner_border::fill");
+ template <typename I>
+ bool
+ tree_of_shapes<I>::is_root(const P& p) const
+ {
+ return parent(p) == p;
}
template <typename I>
- void
- fill(Image<I>& input, const mln_value(I)& value)
+ bool
+ tree_of_shapes<I>::is_representative(const P& p) const
{
- fill(input, 1, value);
+ return is_root(p) || Fb(parent(p)) != Fb(p);
}
+
# endif // ! MLN_INCLUDE_ONLY
- } // end of namespace mln::inner_border
+ } // end of namespace mln::util
} // end of namespace mln
-#endif // ! MLN_INNER_BORDER_FILL_HH
-
+#endif // ! MLN_UTIL_TREE_OF_SHAPES_HH
diff --git a/milena/mln/world/kn/compute_tree_of_shapes.hh b/milena/mln/world/kn/compute_tree_of_shapes.hh
new file mode 100644
index 0000000..63cf1a5
--- /dev/null
+++ b/milena/mln/world/kn/compute_tree_of_shapes.hh
@@ -0,0 +1,500 @@
+// Copyright (C) 2012 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.
+
+/// \file
+///
+/// \brief Compute the tree of shape from a Kn 2D image.
+
+#ifndef MLN_WORLD_KN_COMPUTE_TREE_OF_SHAPES_HH
+# define MLN_WORLD_KN_COMPUTE_TREE_OF_SHAPES_HH
+
+# include <cstdlib>
+# include <vector>
+# include <utility>
+
+# include <mln/core/alias/neighb2d.hh>
+
+# include <mln/data/compute.hh>
+
+# include <mln/accu/math/span.hh>
+
+# include <mln/value/dec.hh>
+# include <mln/value/inc.hh>
+
+# include <mln/util/hqueue.hh>
+# include <mln/util/tree_of_shapes.hh>
+# include <mln/world/kn/is_2_face.hh>
+
+
+// FIXME: to be removed or disabled.
+# include <mln/world/kn/internal/display.hh>
+
+
+namespace mln
+{
+
+ namespace world
+ {
+
+ namespace kn
+ {
+
+ /// \brief Compute the tree of shape from a Kn 2D image.
+ template <typename I>
+ util::tree_of_shapes<I>
+ compute_tree_of_shapes(const Image<I>& F);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace internal
+ {
+
+ template <typename I>
+ struct compute_tree_of_shapes_t
+ {
+ typedef mln_value(I) V;
+ typedef mln_equiv(V) EV;
+ typedef mln_site(I) P;
+ typedef mln_box(I) B;
+
+ typedef mln_ch_value(I,P) T;
+ typedef mln_ch_value(I,unsigned) U;
+ typedef std::vector<P> Array_P;
+ typedef util::hqueue<P,EV> q_type;
+
+ compute_tree_of_shapes_t();
+
+ util::tree_of_shapes<I> operator()(const I& F_);
+
+ void do_union(P p_, P r_, T& zpar, U& rank, U& last);
+
+ P find_root(T& zpar, P x);
+
+ T union_find(const Array_P& R, display& dsp);
+
+ void priority_push(q_type& q, const P& p, const I& F);
+ P priority_pop(q_type& q);
+
+ EV upper_level_next_to_lcur(q_type& q, bool& found);
+
+ EV lower_level_next_to_lcur(q_type& q, bool& found);
+
+ EV level_next_to_lcur(q_type& q);
+
+ void sort(const Image<I>& F_, util::tree_of_shapes<I>& t, display& dsp);
+ void canonicalize_tree(util::tree_of_shapes<I>& t);
+
+
+ protected:
+ // Attributes
+ mln_equiv(V) lcur;
+
+ P undef;
+ P p_0;
+
+ unsigned N;
+ box2d D;
+
+ V vspan_;
+ };
+
+
+ template <typename I>
+ void
+ compute_tree_of_shapes_t<I>::do_union(P p_, P r_,
+ T& zpar, U& rank, U& last)
+ // modify zpar, rank, and last
+ {
+ if (rank(p_) > rank(r_))
+ {
+ // new root is p_
+ zpar(r_) = p_;
+ if (last(r_) < last(p_))
+ last(p_) = last(r_);
+ }
+ else
+ {
+ // new root is r_
+ zpar(p_) = r_;
+ if (last(p_) < last(r_))
+ last(r_) = last(p_);
+ if (rank(p_) == rank(r_))
+ rank(r_) = rank(r_) + 1;
+ }
+ }
+
+
+ template <typename I>
+ typename compute_tree_of_shapes_t<I>::P
+ compute_tree_of_shapes_t<I>::find_root(T& zpar, P x)
+ // modify zpar
+ {
+ if (zpar(x) == x)
+ return x;
+ else {
+ zpar(x) = find_root(zpar, zpar(x));
+ return zpar(x);
+ }
+ }
+
+ template <typename I>
+ typename compute_tree_of_shapes_t<I>::T
+ compute_tree_of_shapes_t<I>::union_find(const Array_P& R,
+ display& dsp)
+ // with balancing
+ {
+ T zpar(D), parent(D);
+ U rank(D), last(D);
+ mln_ch_value(I,bool) done(D);
+ mln_piter(B) p(D);
+
+ for_all(p)
+ {
+ zpar(p) = undef;
+ rank(p) = 0;
+ done(p) = false;
+ }
+ for (int i = N - 1; i >= 0; --i)
+ {
+ P p = R[i]; // p goes from leaves to root
+ parent(p) = p;
+ zpar(p) = p;
+ last(p) = i;
+ mln_niter(neighb2d) n(c4(), p);
+ for_all(n) if (D.has(n) && zpar(n) != undef)
+ {
+ P p_ = find_root(zpar, p),
+ r_ = find_root(zpar, n);
+ if (r_ != p_)
+ {
+ P r = R[ last(r_) ];
+ parent(r) = p;
+ do_union(p_, r_, zpar, rank, last); // update zpar
+ }
+ }
+ done(p) = true;
+
+ if (dsp.level_changes_at(i))
+ {
+ std::cout << "union-find: done with level " << dsp.level(p) << std::endl;
+ dsp.show(done);
+ }
+ }
+ return parent;
+ }
+
+
+
+ // std::ostream&
+ // operator<<(std::ostream& ostr, const q_type& q)
+ // {
+ // ostr << "q = ";
+ // for (unsigned i = 0; i < q.size(); ++i)
+ // if (! q[i].empty())
+ // ostr << i << ':' << q[i].size() << " ";
+ // return ostr;
+ // }
+
+
+ template <typename I>
+ void
+ compute_tree_of_shapes_t<I>::priority_push(q_type& q, const P& p, const I& F)
+ // modify q
+ {
+ EV
+ lcur_,
+ lower = F(p).first(),
+ upper = F(p).last();
+ if (lower > lcur)
+ lcur_ = lower;
+ else if (upper < lcur)
+ lcur_ = upper;
+ else
+ lcur_ = lcur;
+ q.push(p, lcur_);
+ }
+
+
+ template <typename I>
+ typename compute_tree_of_shapes_t<I>::EV
+ compute_tree_of_shapes_t<I>::upper_level_next_to_lcur(q_type& q, bool& found)
+ {
+ for (EV l_ = lcur; l_ <= vspan_.last(); value::inc(l_))
+ if (! q[l_].empty())
+ {
+ found = true;
+ return l_;
+ }
+ found = false;
+ return EV();
+ }
+
+ template <typename I>
+ typename compute_tree_of_shapes_t<I>::EV
+ compute_tree_of_shapes_t<I>::lower_level_next_to_lcur(q_type& q, bool& found)
+ {
+ for (EV l_ = lcur; l_ >= vspan_.first(); value::dec(l_))
+ if (! q[l_].empty())
+ {
+ found = true;
+ return l_;
+ }
+ found = false;
+ return EV();
+ }
+
+
+ template <typename I>
+ typename compute_tree_of_shapes_t<I>::EV
+ compute_tree_of_shapes_t<I>::level_next_to_lcur(q_type& q)
+ {
+ EV l_;
+ bool found;
+
+ bool up = int(2. * std::rand() / (RAND_MAX + 1.));
+ if (up)
+ {
+ l_ = upper_level_next_to_lcur(q, found);
+ if (found)
+ return l_;
+ else
+ {
+ l_ = lower_level_next_to_lcur(q, found);
+ if (! found)
+ std::abort();
+ return l_;
+ }
+ }
+ else
+ {
+ l_ = lower_level_next_to_lcur(q, found);
+ if (found)
+ return l_;
+ else
+ {
+ l_ = upper_level_next_to_lcur(q, found);
+ if (! found)
+ std::abort();
+ return l_;
+ }
+ }
+ }
+
+
+ template <typename I>
+ typename compute_tree_of_shapes_t<I>::P
+ compute_tree_of_shapes_t<I>::priority_pop(q_type& q)
+ // modify q, and sometimes l
+ {
+ if (q[lcur].empty())
+ {
+ EV lcur_ = level_next_to_lcur(q); // such as q[lcur_] is not empty
+ if (q[lcur_].empty())
+ std::abort();
+ lcur = lcur_;
+ }
+ return q.pop(lcur);
+ }
+
+
+
+
+ template <typename I>
+ void
+ compute_tree_of_shapes_t<I>::sort(const Image<I>& F_,
+ util::tree_of_shapes<I>& t, display& dsp)
+ {
+ trace::entering("mln::world::kn::sort");
+ mln_precondition(exact(F_).is_valid());
+
+ const I& F = exact(F_);
+
+ typedef mln_site(I) P;
+
+ B D = F.domain();
+ mln_concrete(I) Fb(D);
+ Array_P R(F.nsites());
+
+ mln_ch_value(I,bool) deja_vu(D), done(D);
+ mln_piter(B) p(D);
+
+ q_type q(vspan_);
+
+ for_all(p)
+ {
+ deja_vu(p) = false;
+ done(p) = false;
+ // p is in queue if p is 'deja_vu' but not 'done'
+ }
+ unsigned i = 0;
+ lcur = safe_cast_to<EV>(F(p_0)); // the start level is the one of root
+ priority_push(q, p_0, F); // realize push(q[lcur], p_0)
+ deja_vu(p_0) = true;
+ do
+ {
+ P p = priority_pop(q);
+
+ Fb(p) = lcur;
+ R[i] = p;
+ mln_niter(neighb2d) n(c4(), p);
+ for_all(n) if (D.has(n) && deja_vu(n) == false)
+ {
+ priority_push(q, n, F);
+ deja_vu(n) = true;
+ }
+ i = i + 1;
+ done(p) = true;
+
+ if (q[lcur].empty())
+ {
+ std::cout << "sort: done with level " << lcur << std::endl;
+ dsp.show(done);
+ }
+ }
+ while (i != N);
+
+ t.Fb = Fb;
+ t.R = R;
+ }
+
+
+ template <typename I>
+ void
+ compute_tree_of_shapes_t<I>::canonicalize_tree(util::tree_of_shapes<I>& t)
+ // modify parent
+ {
+ const I& Fb = t.Fb;
+ const Array_P& R = t.R;
+ T& parent = t.parent;
+
+ for (unsigned i = 0; i <= N - 1; ++i)
+ {
+ P p = R[i]; // p goes from root to leaves
+ P q = parent(p);
+ if (Fb(parent(q)) == Fb(q))
+ parent(p) = parent(q);
+ }
+
+ mln_ch_value(I,bool) show(D);
+ for (unsigned i = 0; i <= N - 1; ++i)
+ {
+ P p = R[i];
+ show(p) = k2::is_primary_2_face(p) || t.is_representative(p);
+ }
+
+ for (unsigned i = 0; i <= N - 1; ++i)
+ {
+ P p = R[i]; // p goes from root to leaves
+ if (! show(p))
+ continue;
+ P q = parent(p);
+
+ if (show(q) == false) // skip node q
+ {
+ if (parent(q) == q) // q cannot be root
+ std::abort();
+
+ P r = parent(q); // new representative
+ if (p != r) // if p is a repr node, do nothing
+ parent(p) = r;
+ }
+ else
+ if (Fb(q) == Fb(p) && k2::is_primary_2_face(p) && ! k2::is_primary_2_face(q))
+ {
+ show(q) = false;
+
+ if (parent(q) == q) // q is root
+ parent(p) = p; // p is the new root
+ else
+ parent(p) = parent(q); // new parent of the representative
+ parent(q) = p; // the new representative is p, stored as q's parent
+ }
+ }
+ t.show = show;
+ }
+
+
+ template <typename I>
+ compute_tree_of_shapes_t<I>::compute_tree_of_shapes_t()
+ : undef(-1, -1), p_0(-1, -1)
+ {
+ }
+
+ template <typename I>
+ util::tree_of_shapes<I>
+ compute_tree_of_shapes_t<I>::operator()(const I& F)
+ {
+ trace::entering("mln::world::kn::compute_tree_of_shapes");
+ mln_precondition(F.is_valid());
+
+ /// FIXME: Really ?
+ /// Useful while sorting sites and constructing the hqueue.
+ accu::math::span<V> accu;
+ vspan_ = data::compute(accu, F | kn::is_2_face);
+ /// End of FIXME
+
+ N = F.nsites();
+ D = F.domain();
+
+ util::tree_of_shapes<I> t;
+
+ display_in_K2<util::tree_of_shapes<I> > dsp(t, std::cout);
+ sort(F, t, dsp);
+
+ t.parent = union_find(t.R, dsp);
+ canonicalize_tree(t);
+
+ return t;
+ }
+
+ } // end of namespace mln::world::kn::internal
+
+
+
+ template <typename I>
+ util::tree_of_shapes<I>
+ compute_tree_of_shapes(const Image<I>& F)
+ {
+ trace::entering("mln::world::kn::compute_tree_of_shapes");
+ mln_precondition(exact(F).is_valid());
+
+ util::tree_of_shapes<I>
+ t = internal::compute_tree_of_shapes_t<I>()(exact(F));
+
+ trace::exiting("mln::world::kn::compute_tree_of_shapes");
+ return t;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::world::kn
+
+ } // end of namespace mln::world
+
+ } // end of namespace mln
+
+
+#endif // ! MLN_WORLD_KN_COMPUTE_TREE_OF_SHAPES_HH
diff --git a/milena/mln/world/kn/internal/display.hh b/milena/mln/world/kn/internal/display.hh
new file mode 100644
index 0000000..7eb1261
--- /dev/null
+++ b/milena/mln/world/kn/internal/display.hh
@@ -0,0 +1,320 @@
+// Copyright (C) 2012 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.
+
+/// \file
+///
+/// \brief Helpers to display tree of shapes.
+
+#ifndef MLN_WORLD_KN_INTERNAL_DISPLAY_HH
+# define MLN_WORLD_KN_INTERNAL_DISPLAY_HH
+
+# include <sstream>
+# include <mln/world/kn/internal/face_dim.hh>
+# include <mln/world/k2/is_primary_2_face.hh>
+# include <mln/world/kn/is_1_face_horizontal.hh>
+# include <mln/world/kn/is_1_face_vertical.hh>
+
+
+namespace mln
+{
+
+ namespace world
+ {
+
+ namespace kn
+ {
+
+ namespace internal
+ {
+
+
+ struct display
+ {
+ virtual bool is_on() const = 0;
+ virtual std::string level(const point2d& p) = 0;
+ virtual bool level_changes_at(unsigned i) const = 0;
+ virtual void show(const image2d<bool>& input) = 0;
+ virtual ~display();
+ };
+
+
+ struct display_off : public display
+ {
+ virtual bool is_on() const;
+ virtual std::string level(const point2d&);
+ virtual bool level_changes_at(unsigned) const;
+ virtual void show(const image2d<bool>&);
+ };
+
+
+ template <typename Tree>
+ struct display_on : public display
+ {
+ const Tree& t;
+ std::ostream& ostr;
+
+ display_on(const Tree& t, std::ostream& ostr);
+ virtual bool is_on() const;
+ virtual std::string level(const point2d& p);
+ virtual bool level_changes_at(unsigned i) const;
+ virtual void print_p(const point2d& p) = 0;
+ virtual void show(const image2d<bool>& input);
+ };
+
+
+
+ template <typename Tree>
+ struct display_in_D : public display_on<Tree>
+ {
+ typedef display_on<Tree> super;
+ using super::ostr;
+ using super::t;
+
+ display_in_D(const Tree& t, std::ostream& ostr = std::cout);
+ virtual void print_p(const point2d& p);
+ };
+
+
+
+ template <typename Tree>
+ struct display_in_K1 : public display_on<Tree>
+ {
+ typedef display_on<Tree> super;
+ using super::ostr;
+ using super::t;
+
+ display_in_K1(const Tree& t, std::ostream& ostr = std::cout);
+ virtual void print_p(const point2d& p);
+ };
+
+
+
+ template <typename Tree>
+ struct display_in_K2 : public display_on<Tree>
+ {
+ typedef display_on<Tree> super;
+ using super::ostr;
+ using super::t;
+
+ display_in_K2(const Tree& t, std::ostream& ostr = std::cout);
+ virtual void print_p(const point2d& p);
+ };
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ // display
+
+ inline
+ display::~display()
+ {
+ }
+
+
+ // display_off
+
+ inline
+ bool
+ display_off::is_on() const
+ {
+ return false;
+ }
+
+ inline
+ std::string
+ display_off::level(const point2d&)
+ {
+ return "";
+ }
+
+ inline
+ bool
+ display_off::level_changes_at(unsigned) const
+ {
+ return false;
+ }
+
+ inline
+ void
+ display_off:: show(const image2d<bool>&)
+ {
+ }
+
+
+ // display_on
+
+ template <typename Tree>
+ display_on<Tree>::display_on(const Tree& t,
+ std::ostream& ostr)
+ : t(t), ostr(ostr)
+ {
+ }
+
+ template <typename Tree>
+ bool
+ display_on<Tree>::is_on() const
+ {
+ return true;
+ }
+
+ template <typename Tree>
+ std::string
+ display_on<Tree>::level(const point2d& p)
+ {
+ std::ostringstream s;
+ s << t.level(p);
+ return s.str();
+ }
+
+ template <typename Tree>
+ bool
+ display_on<Tree>::level_changes_at(unsigned i) const
+ {
+ return t.level_changes_at(i);
+ }
+
+ template <typename Tree>
+ void
+ display_on<Tree>::show(const image2d<bool>& input)
+ {
+ box2d dom = input.domain();
+ const short
+ min_row = dom.pmin().row(),
+ max_row = dom.pmax().row(),
+ min_col = dom.pmin().col(),
+ max_col = dom.pmax().col();
+
+ point2d p;
+ short& row = p.row();
+ short& col = p.col();
+
+ char bdr = '#';
+
+ for (col = min_col; col <= max_col + 2; ++col)
+ ostr << bdr << ' ';
+ ostr << std::endl;
+
+ for (row = min_row; row <= max_row; ++row)
+ {
+ ostr << bdr;
+ for (col = min_col; col <= max_col; ++col)
+ if (input(p))
+ print_p(p);
+ else
+ ostr << " ";
+ ostr << ' ' << bdr << std::endl;
+ }
+
+ for (col = min_col; col <= max_col + 2; ++col)
+ ostr << bdr << ' ';
+ ostr << std::endl
+ << std::endl;
+ }
+
+
+ // display_in_D
+
+ template <typename Tree>
+ display_in_D<Tree>::display_in_D(const Tree& t,
+ std::ostream& ostr)
+ : super(t, ostr)
+ {
+ }
+
+ template <typename Tree>
+ void
+ display_in_D<Tree>::print_p(const point2d& p)
+ {
+ ostr << " O";
+ }
+
+
+ // display_in_K1
+
+ template <typename Tree>
+ display_in_K1<Tree>::display_in_K1(const Tree& t,
+ std::ostream& ostr)
+ : super(t, ostr)
+ {
+ }
+
+ template <typename Tree>
+ void
+ display_in_K1<Tree>::print_p(const point2d& p)
+ {
+ switch (internal::face_dim(p))
+ {
+ case 0:
+ ostr << " +";
+ break;
+ case 1:
+ ostr << (kn::is_1_face_horizontal(p) ? " -" : " |");
+ break;
+ case 2:
+ ostr << " O";
+ break;
+ }
+ }
+
+
+ // display_in_K2
+
+ template <typename Tree>
+ display_in_K2<Tree>::display_in_K2(const Tree& t,
+ std::ostream& ostr)
+ : super(t, ostr)
+ {
+ }
+
+ template <typename Tree>
+ void
+ display_in_K2<Tree>::print_p(const point2d& p)
+ {
+ switch (internal::face_dim(p))
+ {
+ case 0:
+ ostr << " +";
+ break;
+ case 1:
+ ostr << (kn::is_1_face_horizontal(p) ? " -" : " |");
+ break;
+ case 2:
+ ostr << (k2::is_primary_2_face(p) ? " O" : " x");
+ break;
+ }
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::world::kn::internal
+
+ } // end of namespace mln::world::kn
+
+ } // end of namespace mln::world
+
+} // end of namespace mln
+
+
+#endif // ! MLN_WORLD_KN_INTERNAL_DISPLAY_HH
--
1.7.2.5
1
0
* mln/accu/math/span.hh,
* mln/fun/vv2v/span.hh,
* mln/fun/vvvv2v/span.hh: Do not force the use of value::interval.
* mln/world/kn/fill_0_1_faces_internal_border.hh: Rely on
mln::inner_border::fill.
* mln/inner_border/internal/on_frontiere.hh: Rename as...
* mln/inner_border/internal/is_on_frontiere.hh: ... this.
* mln/data/compute_in_inner_border.hh,
* mln/inner_border/fill.hh: Rename on_frontiere as
is_on_frontiere.
* mln/value/interval.hh: Relax type of constructor arguments.
* mln/world/k2/is_primary_2_face.hh: Fix invalid test.
* mln/world/kn/internal/fill_primary_2_faces_from_input.hh,
* mln/world/kn/un_immerse.hh: Make use of safe_cast_to.
* mln/world/kn/safe_cast.hh: Remove safe_cast() function.
---
milena/ChangeLog | 27 ++++++
milena/mln/accu/math/span.hh | 43 +++++-----
milena/mln/data/compute_in_inner_border.hh | 6 +-
milena/mln/fun/vv2v/span.hh | 19 ++---
milena/mln/fun/vvvv2v/span.hh | 27 +++----
milena/mln/inner_border/fill.hh | 4 +-
.../{on_frontiere.hh => is_on_frontiere.hh} | 45 +++++++----
milena/mln/value/interval.hh | 20 +++--
milena/mln/world/k2/is_primary_2_face.hh | 2 +-
.../mln/world/kn/fill_0_1_faces_internal_border.hh | 22 ++----
.../kn/internal/fill_primary_2_faces_from_input.hh | 3 +-
milena/mln/world/kn/safe_cast.hh | 87 ++++++++++----------
milena/mln/world/kn/un_immerse.hh | 4 +-
13 files changed, 171 insertions(+), 138 deletions(-)
rename milena/mln/inner_border/internal/{on_frontiere.hh => is_on_frontiere.hh} (68%)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 2a3885d..9c48f48 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,3 +1,30 @@
+2012-10-25 Guillaume Lazzara <z(a)lrde.epita.fr>
+
+ Various fixes.
+
+ * mln/accu/math/span.hh,
+ * mln/fun/vv2v/span.hh,
+ * mln/fun/vvvv2v/span.hh: Do not force the use of value::interval.
+
+ * mln/world/kn/fill_0_1_faces_internal_border.hh: Rely on
+ mln::inner_border::fill.
+
+ * mln/inner_border/internal/on_frontiere.hh: Rename as...
+ * mln/inner_border/internal/is_on_frontiere.hh: ... this.
+
+ * mln/data/compute_in_inner_border.hh,
+ * mln/inner_border/fill.hh: Rename on_frontiere as
+ is_on_frontiere.
+
+ * mln/value/interval.hh: Relax type of constructor arguments.
+
+ * mln/world/k2/is_primary_2_face.hh: Fix invalid test.
+
+ * mln/world/kn/internal/fill_primary_2_faces_from_input.hh,
+ * mln/world/kn/un_immerse.hh: Make use of safe_cast_to.
+
+ * mln/world/kn/safe_cast.hh: Remove safe_cast() function.
+
2012-10-24 Guillaume Lazzara <z(a)lrde.epita.fr>
Some fixes.
diff --git a/milena/mln/accu/math/span.hh b/milena/mln/accu/math/span.hh
index eda4e85..839dbcc 100644
--- a/milena/mln/accu/math/span.hh
+++ b/milena/mln/accu/math/span.hh
@@ -31,7 +31,6 @@
/// Define an accumulator that computes a span.
# include <mln/accu/internal/base.hh>
-# include <mln/value/interval.hh>
namespace mln
{
@@ -50,10 +49,10 @@ namespace mln
///
/// \ingroup modaccuvalues
//
- template <typename T>
- struct span : public mln::accu::internal::base< const value::interval<T>&, span<T> >
+ template <typename T, typename R = T>
+ struct span : public mln::accu::internal::base< const R&, span<T,R> >
{
- typedef value::interval<T> argument;
+ typedef T argument;
span();
@@ -62,11 +61,11 @@ namespace mln
void init();
void take_as_init_(const argument& t);
void take(const argument& t);
- void take(const span<T>& other);
+ void take(const span<T,R>& other);
/// \}
/// Get the value of the accumulator.
- const value::interval<T>& to_result() const;
+ const R& to_result() const;
/// Check whether this accu is able to return a result.
/// Always true here.
@@ -74,7 +73,7 @@ namespace mln
protected:
- value::interval<T> t_;
+ R t_;
bool is_valid_;
};
@@ -88,32 +87,32 @@ namespace mln
namespace math
{
- template <typename T>
+ template <typename T, typename R>
inline
- span<T>::span()
+ span<T,R>::span()
{
init();
}
- template <typename T>
+ template <typename T, typename R>
inline
void
- span<T>::init()
+ span<T,R>::init()
{
is_valid_ = false;
}
- template <typename T>
+ template <typename T, typename R>
inline
- void span<T>::take_as_init_(const argument& t)
+ void span<T,R>::take_as_init_(const argument& t)
{
t_ = t;
is_valid_ = true;
}
- template <typename T>
+ template <typename T, typename R>
inline
- void span<T>::take(const argument& t)
+ void span<T,R>::take(const argument& t)
{
if (is_valid_)
this->t_ = value::span(this->t_, t);
@@ -125,10 +124,10 @@ namespace mln
}
}
- template <typename T>
+ template <typename T, typename R>
inline
void
- span<T>::take(const span<T>& other)
+ span<T,R>::take(const span<T,R>& other)
{
mln_precondition(other.is_valid());
@@ -141,18 +140,18 @@ namespace mln
}
}
- template <typename T>
+ template <typename T, typename R>
inline
- const value::interval<T>&
- span<T>::to_result() const
+ const R&
+ span<T,R>::to_result() const
{
return t_;
}
- template <typename T>
+ template <typename T, typename R>
inline
bool
- span<T>::is_valid() const
+ span<T,R>::is_valid() const
{
return is_valid_;
}
diff --git a/milena/mln/data/compute_in_inner_border.hh b/milena/mln/data/compute_in_inner_border.hh
index 917373e..780aa63 100644
--- a/milena/mln/data/compute_in_inner_border.hh
+++ b/milena/mln/data/compute_in_inner_border.hh
@@ -32,7 +32,7 @@
# include <mln/core/concept/image.hh>
# include <mln/core/concept/accumulator.hh>
-# include <mln/inner_border/internal/on_frontiere.hh>
+# include <mln/inner_border/internal/is_on_frontiere.hh>
# include <mln/geom/nrows.hh>
# include <mln/geom/ncols.hh>
@@ -126,8 +126,8 @@ namespace mln
mln_piter(I) p(input.domain());
for_all(p)
- if (inner_border::internal::on_frontiere(p, input.domain(),
- inner_border_thickness))
+ if (inner_border::internal::is_on_frontiere(p, input.domain(),
+ inner_border_thickness))
a.take(input(p));
trace::exiting("mln::data::compute_in_inner_border");
diff --git a/milena/mln/fun/vv2v/span.hh b/milena/mln/fun/vv2v/span.hh
index e9cd002..3e5a367 100644
--- a/milena/mln/fun/vv2v/span.hh
+++ b/milena/mln/fun/vv2v/span.hh
@@ -31,7 +31,6 @@
/// Functor that computes the spanimum of two values.
# include <mln/core/concept/function.hh>
-# include <mln/value/interval.hh>
namespace mln
@@ -46,24 +45,22 @@ namespace mln
// FIXME: Doc.
/// \brief A functor computing the span of two interval values.
- template <typename T>
- struct span : public Function_vv2v< span<T> >
+ template <typename T, typename R = T>
+ struct span : public Function_vv2v< span<T,R> >
{
- typedef value::interval<T> result;
+ typedef R result;
- value::interval<T> operator()(const value::interval<T>& v1,
- const value::interval<T>& v2) const;
+ R operator()(const T& v1, const T& v2) const;
};
# ifndef MLN_INCLUDE_ONLY
- template <typename T>
- value::interval<T>
- span<T>::operator()(const value::interval<T>& v1,
- const value::interval<T>& v2) const
+ template <typename T, typename R>
+ R
+ span<T,R>::operator()(const T& v1, const T& v2) const
{
- return value::span(v1, v2);
+ return R(value::span(v1, v2));
}
# endif // ! MLN_INCLUDE_ONLY
diff --git a/milena/mln/fun/vvvv2v/span.hh b/milena/mln/fun/vvvv2v/span.hh
index 8c99bd1..3ce0987 100644
--- a/milena/mln/fun/vvvv2v/span.hh
+++ b/milena/mln/fun/vvvv2v/span.hh
@@ -31,7 +31,6 @@
/// Functor that computes the spanimum of two values.
# include <mln/core/concept/function.hh>
-# include <mln/value/interval.hh>
namespace mln
@@ -46,28 +45,26 @@ namespace mln
// FIXME: Doc.
/// \brief A functor computing the span of two interval values.
- template <typename T>
- struct span : public Function_vvvv2v< span<T> >
+ template <typename T, typename R = T>
+ struct span : public Function_vvvv2v< span<T,R> >
{
- typedef value::interval<T> result;
+ typedef R result;
- value::interval<T> operator()(const value::interval<T>& v1,
- const value::interval<T>& v2,
- const value::interval<T>& v3,
- const value::interval<T>& v4) const;
+ R operator()(const T& v1,
+ const T& v2,
+ const T& v3,
+ const T& v4) const;
};
# ifndef MLN_INCLUDE_ONLY
- template <typename T>
- value::interval<T>
- span<T>::operator()(const value::interval<T>& v1,
- const value::interval<T>& v2,
- const value::interval<T>& v3,
- const value::interval<T>& v4) const
+ template <typename T, typename R>
+ R
+ span<T,R>::operator()(const T& v1, const T& v2,
+ const T& v3, const T& v4) const
{
- return value::span(v1, v2, v3, v4);
+ return R(value::span(v1, v2, v3, v4));
}
# endif // ! MLN_INCLUDE_ONLY
diff --git a/milena/mln/inner_border/fill.hh b/milena/mln/inner_border/fill.hh
index ccee289..8f669df 100644
--- a/milena/mln/inner_border/fill.hh
+++ b/milena/mln/inner_border/fill.hh
@@ -32,7 +32,7 @@
# include <mln/core/image/image2d.hh>
# include <mln/data/paste.hh>
-# include <mln/inner_border/internal/on_frontiere.hh>
+# include <mln/inner_border/internal/is_on_frontiere.hh>
namespace mln
{
@@ -67,7 +67,7 @@ namespace mln
mln_piter(I) p(input.domain());
for_all(p)
- if (internal::on_frontiere(p, input.domain(), border_size))
+ if (internal::is_on_frontiere(p, input.domain(), border_size))
input(p) = value;
trace::exiting("mln::inner_border::fill");
diff --git a/milena/mln/inner_border/internal/on_frontiere.hh b/milena/mln/inner_border/internal/is_on_frontiere.hh
similarity index 68%
rename from milena/mln/inner_border/internal/on_frontiere.hh
rename to milena/mln/inner_border/internal/is_on_frontiere.hh
index 49430a8..33d8cb9 100644
--- a/milena/mln/inner_border/internal/on_frontiere.hh
+++ b/milena/mln/inner_border/internal/is_on_frontiere.hh
@@ -23,8 +23,8 @@
// exception does not however invalidate any other reasons why the
// executable file might be covered by the GNU General Public License.
-#ifndef MLN_INNER_BORDER_ON_FRONTIERE_HH
-# define MLN_INNER_BORDER_ON_FRONTIERE_HH
+#ifndef MLN_INNER_BORDER_IS_ON_FRONTIERE_HH
+# define MLN_INNER_BORDER_IS_ON_FRONTIERE_HH
/// \file
///
@@ -48,8 +48,14 @@ namespace mln
/// border of the image.
template <typename P>
bool
- on_frontiere(const mln_site(box<P>)& p, const box<P>& b,
- def::coord inner_border_size);
+ is_on_frontiere(const mln_site(box<P>)& p, const box<P>& b,
+ def::coord inner_border_size);
+
+ /// \overload
+ /// inner_border_size is set to 1.
+ template <typename P>
+ bool
+ is_on_frontiere(const mln_site(box<P>)& p, const box<P>& b);
# ifndef MLN_INCLUDE_ONLY
@@ -58,8 +64,8 @@ namespace mln
inline
bool
- on_frontiere_2d(const point2d& p, const box2d& b,
- def::coord inner_border_size)
+ is_on_frontiere_2d(const point2d& p, const box2d& b,
+ def::coord inner_border_size)
{
for (int d = 0; d < 2; ++d)
if ((p[d] >= b.pmin()[d]
@@ -75,30 +81,37 @@ namespace mln
inline
bool
- on_frontiere_dispatch(const point2d& p, const box2d& b,
- def::coord inner_border_size)
+ is_on_frontiere_dispatch(const point2d& p, const box2d& b,
+ def::coord inner_border_size)
{
- return on_frontiere_2d(p, b, inner_border_size);
+ return is_on_frontiere_2d(p, b, inner_border_size);
}
template <typename P>
bool
- on_frontiere_dispatch(const mln_site(box<P>)& p, const box<P>& b,
- def::coord inner_border_size)
+ is_on_frontiere_dispatch(const mln_site(box<P>)& p, const box<P>& b,
+ def::coord inner_border_size)
{
mlc_abort(P)::check(); // Not implemented.
return false;
}
- // Facade
+ // Facades
+
+ template <typename P>
+ bool
+ is_on_frontiere(const mln_site(box<P>)& p, const box<P>& b,
+ def::coord inner_border_size)
+ {
+ return is_on_frontiere_dispatch(p, b, inner_border_size);
+ }
template <typename P>
bool
- on_frontiere(const mln_site(box<P>)& p, const box<P>& b,
- def::coord inner_border_size)
+ is_on_frontiere(const mln_site(box<P>)& p, const box<P>& b)
{
- return on_frontiere_dispatch(p, b, inner_border_size);
+ return is_on_frontiere(p, b, 1);
}
# endif // ! MLN_INCLUDE_ONLY
@@ -109,5 +122,5 @@ namespace mln
} // end of namespace mln
-#endif // ! MLN_INNER_BORDER_ON_FRONTIERE_HH
+#endif // ! MLN_INNER_BORDER_IS_ON_FRONTIERE_HH
diff --git a/milena/mln/value/interval.hh b/milena/mln/value/interval.hh
index bdae72f..b40f989 100644
--- a/milena/mln/value/interval.hh
+++ b/milena/mln/value/interval.hh
@@ -53,8 +53,12 @@ namespace mln
typedef T equiv;
interval();
- interval(T single);
- interval(T first, T last);
+
+ template <typename U>
+ interval(U single);
+
+ template <typename U>
+ interval(U first, U last);
interval& operator=(const interval& rhs);
@@ -223,8 +227,10 @@ namespace mln
}
template <typename T>
- interval<T>::interval(T single)
+ template <typename U>
+ interval<T>::interval(U single)
{
+ mlc_converts_to(U,T)::check();
first_ = single;
last_ = single;
@@ -233,8 +239,10 @@ namespace mln
template <typename T>
- interval<T>::interval(T first, T last)
+ template <typename U>
+ interval<T>::interval(U first, U last)
{
+ mlc_converts_to(U,T)::check();
mln_precondition(last >= first);
first_ = first;
last_ = last;
@@ -245,7 +253,7 @@ namespace mln
if (first != last)
{
for (T v = value::succ(first_); v <= last_ && v > first_; value::inc(v))
- ++nelements_; // FIXME: overflow with unsigned char + [0,255]
+ ++nelements_;
}
}
@@ -321,7 +329,7 @@ namespace mln
interval<T>::self_open()
{
if (is_degenerated())
- abort();
+ std::abort();
mln_precondition(nelements_ > 2);
first += iota<T>::value();
diff --git a/milena/mln/world/k2/is_primary_2_face.hh b/milena/mln/world/k2/is_primary_2_face.hh
index cd90bac..442a8f5 100644
--- a/milena/mln/world/k2/is_primary_2_face.hh
+++ b/milena/mln/world/k2/is_primary_2_face.hh
@@ -66,7 +66,7 @@ namespace mln
bool is_primary_2_face(const mln::def::coord& row,
const mln::def::coord& col)
{
- return !((row % 4) + (col % 4));
+ return row % 4 == 0 && col % 4 == 0;
}
diff --git a/milena/mln/world/kn/fill_0_1_faces_internal_border.hh b/milena/mln/world/kn/fill_0_1_faces_internal_border.hh
index 7324a34..915a69a 100644
--- a/milena/mln/world/kn/fill_0_1_faces_internal_border.hh
+++ b/milena/mln/world/kn/fill_0_1_faces_internal_border.hh
@@ -30,7 +30,7 @@
#ifndef MLN_WORLD_KN_FILL_0_1_FACES_INTERNAL_BORDER_HH
# define MLN_WORLD_KN_FILL_0_1_FACES_INTERNAL_BORDER_HH
-# include <mln/core/alias/point2d.hh>
+# include <mln/inner_border/fill.hh>
namespace mln
@@ -57,7 +57,8 @@ namespace mln
*/
template <typename I>
- void fill_0_1_faces_internal_border(Image<I>& inout, const mln_value(I)& v);
+ void fill_0_1_faces_internal_border(Image<I>& inout,
+ const mln_value(I)& v);
@@ -68,26 +69,15 @@ namespace mln
template <typename I>
- void fill_0_1_faces_internal_border(Image<I>& inout_, const mln_value(I)& v)
+ void fill_0_1_faces_internal_border(Image<I>& inout_,
+ const mln_value(I)& v)
{
trace::entering("mln::world::kn::fill_0_1_faces_internal_border");
mln_precondition(exact(inout_).is_valid());
I& inout = exact(inout_);
- // Horizontal borders
- for (mln::def::coord col = geom::min_col(inout); col <= geom::max_col(inout); ++col)
- {
- inout.at_(geom::min_row(inout), col) = v;
- inout.at_(geom::max_row(inout), col) = v;
- }
-
- // Vertical borders
- for (mln::def::coord row = geom::min_row(inout); row <= geom::max_row(inout); ++row)
- {
- inout.at_(row, geom::min_col(inout)) = v;
- inout.at_(row, geom::max_col(inout)) = v;
- }
+ inner_border::fill(inout, v);
trace::exiting("mln::world::kn::fill_0_1_faces_internal_border");
}
diff --git a/milena/mln/world/kn/internal/fill_primary_2_faces_from_input.hh b/milena/mln/world/kn/internal/fill_primary_2_faces_from_input.hh
index 5884771..04baddc 100644
--- a/milena/mln/world/kn/internal/fill_primary_2_faces_from_input.hh
+++ b/milena/mln/world/kn/internal/fill_primary_2_faces_from_input.hh
@@ -83,11 +83,12 @@ namespace mln
const J& ima = exact(ima_);
// Filling Primary 2-Faces
+ typedef mln_value(I) V;
mln_piter(J) p(ima.domain());
for_all(p)
{
mln_site(I) pout = internal::immerse_point(p, n, inner_border_thickness);
- ima_kn(pout) = safe_cast(ima(p));
+ ima_kn(pout) = safe_cast_to<V>(ima(p));
}
trace::exiting("mln::world::kn::internal::fill_primary_2_faces_from_input");
diff --git a/milena/mln/world/kn/safe_cast.hh b/milena/mln/world/kn/safe_cast.hh
index 31fe3cd..d4e4f5c 100644
--- a/milena/mln/world/kn/safe_cast.hh
+++ b/milena/mln/world/kn/safe_cast.hh
@@ -46,17 +46,6 @@ namespace mln
using namespace mln::value;
- // Forward declaration.
- namespace internal {
- template <typename Tsrc> struct to_be_casted_t;
- }
-
-
- /// \brief Safe convertion function for manipulating Kn-immersed
- /// images.
- template <typename Tsrc>
- internal::to_be_casted_t<Tsrc> safe_cast(const Tsrc& src);
-
/// \brief Safe convertion function for manipulating Kn-immersed
/// images.
template <typename Tdest, typename Tsrc>
@@ -85,19 +74,47 @@ namespace mln
to = intsub<n>(from.to_interop());
}
+ inline
+ void safe_cast_(const int_u8& from, interval<int_u8>& to)
+ {
+ to = from;
+ }
+
+ inline
+ void safe_cast_(const int_u8& from, int& to)
+ {
+ to = from.to_interop();
+ }
+
template <unsigned n>
- void safe_cast_(const interval<intsub<n> >& from, value::int_u8& to)
+ void safe_cast_(const interval<intsub<n> >& from, int_u8& to)
{
if (!from.is_degenerated())
- abort();
+ std::abort();
to = intsub<n>(from.first());
}
+ inline
+ void safe_cast_(const interval<int_u8>& from, int_u8& to)
+ {
+ if (!from.is_degenerated())
+ std::abort();
+ to = from.first();
+ }
+
+ template <unsigned n>
+ void safe_cast_(const interval<int_u8>& from, intsub<n>& to)
+ {
+ if (!from.is_degenerated())
+ std::abort();
+ to = from.first().to_interop();
+ }
+
template <unsigned n>
void safe_cast_(const interval<intsub<n> >& from, int& to)
{
if (!from.is_degenerated())
- abort();
+ std::abort();
to = from.first();
}
@@ -105,7 +122,7 @@ namespace mln
void safe_cast_(const interval<intsub<n> >& from, intsub<n>& to)
{
if (!from.is_degenerated())
- abort();
+ std::abort();
to = from.first();
}
@@ -115,6 +132,12 @@ namespace mln
to = interval<intsub<n> >(from);
}
+ inline
+ void safe_cast_(const int& from, int_u8& to)
+ {
+ to = from;
+ }
+
template <unsigned n>
void safe_cast_(const intsub<n>& from, intsub<2*n>& to)
{
@@ -122,6 +145,12 @@ namespace mln
}
template <unsigned n>
+ void safe_cast_(const intsub<n>& from, intsub<n/2>& to)
+ {
+ to = static_cast<intsub<n/2> >(from.to_int());
+ }
+
+ template <unsigned n>
void safe_cast_(const intsub<n>& from, int_u8& to)
{
to = from.to_interop();
@@ -152,34 +181,6 @@ namespace mln
namespace kn
{
- namespace internal
- {
-
- template <typename Tsrc>
- struct to_be_casted_t
- {
- to_be_casted_t(const Tsrc& src) : src(src) {}
- Tsrc src;
-
- template <typename Tdest>
- operator Tdest const()
- {
- Tdest dest;
- safe_cast_(src, dest);
- return dest;
- }
- };
-
- } // end of namespace mln::world::kn::internal
-
-
- template <typename Tsrc>
- internal::to_be_casted_t<Tsrc> safe_cast(const Tsrc& src)
- {
- internal::to_be_casted_t<Tsrc> tmp(src);
- return tmp;
- }
-
template <typename Tdest, typename Tsrc>
Tdest safe_cast_to(const Tsrc& src)
{
diff --git a/milena/mln/world/kn/un_immerse.hh b/milena/mln/world/kn/un_immerse.hh
index 5159d86..ead7132 100644
--- a/milena/mln/world/kn/un_immerse.hh
+++ b/milena/mln/world/kn/un_immerse.hh
@@ -113,11 +113,11 @@ namespace mln
const I& ima = exact(ima_);
(void) new_value_type;
- mln_concrete(I) output(internal::domain_K0_from_Kn(ima.domain(), n));
+ mln_ch_value(I,V) output(internal::domain_K0_from_Kn(ima.domain(), n));
mln_piter(I) p(output.domain());
for_all(p)
- output(p) = safe_cast(ima(internal::immerse_point(p, n)));
+ output(p) = safe_cast_to<V>(ima(internal::immerse_point(p, n)));
trace::exiting("mln::world::kn::un_immerse");
return output;
--
1.7.2.5
1
0
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Olena, a generic and efficient image processing platform".
The branch exp/khalimsky has been updated
via abeebe9d18431d7dfb2f0fb711b3ede92a17ab55 (commit)
via 35287d9cbad815ebbcb5021e697fbe8385cf2b87 (commit)
from fd94360102b88b25a7f6bbed8046fc329871c6b3 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
abeebe9 Some fixes.
35287d9 Add inner_border routines.
-----------------------------------------------------------------------
Summary of changes:
milena/ChangeLog | 26 +++++
milena/mln/core/site_set/box.hh | 33 ++++++-
milena/mln/data/compute_in_inner_border.hh | 95 ++++++-----------
.../mln/{make/pixel.hh => inner_border/extend.hh} | 55 ++++++----
.../extend_and_fill.hh} | 68 ++++++------
.../extend_and_fill_with_inner_border.hh | 99 +++++++++++++++++
milena/mln/{debug/iota.hh => inner_border/fill.hh} | 86 ++++++---------
milena/mln/inner_border/internal/on_frontiere.hh | 113 ++++++++++++++++++++
milena/mln/trait/routine/mean.hh | 12 ++
milena/mln/value/interval.hh | 12 ++-
milena/mln/value/intsub.hh | 9 ++
milena/mln/value/iota.hh | 27 +++++
12 files changed, 459 insertions(+), 176 deletions(-)
copy milena/mln/{make/pixel.hh => inner_border/extend.hh} (55%)
copy milena/mln/{subsampling/gaussian_subsampling.hh => inner_border/extend_and_fill.hh} (52%)
create mode 100644 milena/mln/inner_border/extend_and_fill_with_inner_border.hh
copy milena/mln/{debug/iota.hh => inner_border/fill.hh} (56%)
create mode 100644 milena/mln/inner_border/internal/on_frontiere.hh
hooks/post-receive
--
Olena, a generic and efficient image processing platform
1
0
* mln/core/site_set/box.hh: Add shrink() method.
* mln/data/compute_in_inner_border.hh: Rewrite and add overloads.
* mln/trait/routine/mean.hh: New trait for builtins.
* mln/value/interval.hh: Fix overflow while counting elements.
* mln/value/intsub.hh: Add a constructor based on int_u8.
* mln/value/iota.hh: Add new specializations for builtins.
---
milena/ChangeLog | 16 +++++
milena/mln/core/site_set/box.hh | 33 +++++++++-
milena/mln/data/compute_in_inner_border.hh | 95 +++++++++-------------------
milena/mln/trait/routine/mean.hh | 12 ++++
milena/mln/value/interval.hh | 12 +++-
milena/mln/value/intsub.hh | 9 +++
milena/mln/value/iota.hh | 27 ++++++++
7 files changed, 136 insertions(+), 68 deletions(-)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 1bfdd14..2a3885d 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,5 +1,21 @@
2012-10-24 Guillaume Lazzara <z(a)lrde.epita.fr>
+ Some fixes.
+
+ * mln/core/site_set/box.hh: Add shrink() method.
+
+ * mln/data/compute_in_inner_border.hh: Rewrite and add overloads.
+
+ * mln/trait/routine/mean.hh: New trait for builtins.
+
+ * mln/value/interval.hh: Fix overflow while counting elements.
+
+ * mln/value/intsub.hh: Add a constructor based on int_u8.
+
+ * mln/value/iota.hh: Add new specializations for builtins.
+
+2012-10-24 Guillaume Lazzara <z(a)lrde.epita.fr>
+
Add inner_border routines.
* mln/inner_border/extend.hh,
diff --git a/milena/mln/core/site_set/box.hh b/milena/mln/core/site_set/box.hh
index 4256dc4..ed1ce91 100644
--- a/milena/mln/core/site_set/box.hh
+++ b/milena/mln/core/site_set/box.hh
@@ -1,4 +1,4 @@
-// Copyright (C) 2007, 2008, 2009, 2010, 2011 EPITA Research and
+// Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012 EPITA Research and
// Development Laboratory (LRDE)
//
// This file is part of Olena.
@@ -141,6 +141,12 @@ namespace mln
/// Enlarge the box with a border \p b for dimension \p dim.
void enlarge(unsigned dim, unsigned b);
+ /// Shrink the box with a border \p b.
+ void shrink(unsigned b);
+
+ /// Shrink the box with a border \p b for dimension \p dim.
+ void shrink(unsigned dim, unsigned b);
+
/// Give a larger box.
box<P> to_larger(unsigned b) const;
@@ -358,6 +364,31 @@ namespace mln
template <typename P>
inline
+ void
+ box<P>::shrink(unsigned b)
+ {
+ mln_precondition(is_valid());
+ for (unsigned i = 0; i < P::dim; ++i)
+ {
+ pmin_[i] = static_cast<mln_coord(P)>(pmin_[i] + b);
+ pmax_[i] = static_cast<mln_coord(P)>(pmax_[i] - b);
+ }
+ mln_postcondition(is_valid());
+ }
+
+ template <typename P>
+ inline
+ void
+ box<P>::shrink(unsigned dim, unsigned b)
+ {
+ mln_precondition(is_valid());
+ pmin_[dim] = static_cast<mln_coord(P)>(pmin_[dim] + b);
+ pmax_[dim] = static_cast<mln_coord(P)>(pmax_[dim] - b);
+ mln_postcondition(is_valid());
+ }
+
+ template <typename P>
+ inline
box<P>
larger_than(const box<P> a, const box<P> b)
{
diff --git a/milena/mln/data/compute_in_inner_border.hh b/milena/mln/data/compute_in_inner_border.hh
index 20e8a37..917373e 100644
--- a/milena/mln/data/compute_in_inner_border.hh
+++ b/milena/mln/data/compute_in_inner_border.hh
@@ -32,6 +32,7 @@
# include <mln/core/concept/image.hh>
# include <mln/core/concept/accumulator.hh>
+# include <mln/inner_border/internal/on_frontiere.hh>
# include <mln/geom/nrows.hh>
# include <mln/geom/ncols.hh>
@@ -58,6 +59,11 @@ namespace mln
compute_in_inner_border(const Accumulator<A>& a, const Image<I>& input,
unsigned inner_border_thickness);
+ /// \overload
+ /// inner_border_thickness is set to 1.
+ template <typename A, typename I>
+ mln_result(A)
+ compute_in_inner_border(const Accumulator<A>& a, const Image<I>& input);
/// Compute an accumulator onto the inner border pixel values of
/// the image \p input.
@@ -75,6 +81,12 @@ namespace mln
compute_in_inner_border(Accumulator<A>& a, const Image<I>& input,
unsigned inner_border_thickness);
+ /// \overload
+ /// inner_border_thickness is set to 1.
+ template <typename A, typename I>
+ mln_result(A)
+ compute_in_inner_border(Accumulator<A>& a, const Image<I>& input);
+
# ifndef MLN_INCLUDE_ONLY
@@ -85,10 +97,16 @@ namespace mln
unsigned inner_border_thickness)
{
(void) a_;
- A a;
+ A a(exact(a_));
return compute_in_inner_border(a, input, inner_border_thickness);
}
+ template <typename A, typename I>
+ mln_result(A)
+ compute_in_inner_border(const Accumulator<A>& a, const Image<I>& input)
+ {
+ return compute_in_inner_border(a, input, 1);
+ }
template <typename A, typename I>
mln_result(A)
@@ -106,74 +124,23 @@ namespace mln
a.init();
- unsigned inner_border_thickness_1 = inner_border_thickness - 1;
- unsigned nrows_1 = geom::nrows(input) - 1;
- unsigned ncols_1 = geom::ncols(input) - 1;
-
- typedef mln_box(I) B;
-
- /*
- .--------------------.
- | b_top |<------ Image domain
- |--------------------|
- | | | |
- |b| |b|
- | | | |
- |l| |r|
- |e| |i|
- |f| |g|
- |t| |h|
- | | |t|
- |--------------------|
- | b_bot |
- .--------------------.
-
- */
- B b_top = B(input.domain().pmin(),
- input.domain().pmin()
- + inner_border_thickness_1 * down
- + ncols_1 * right);
- mln_piter(I) p_top(b_top);
-
- B b_bot = B(input.domain().pmax()
- + inner_border_thickness_1 * up
- + ncols_1 * left,
- input.domain().pmax());
- mln_piter(I) p_bot(b_bot);
-
- B b_left = B(input.domain().pmin()
- + inner_border_thickness * down,
- input.domain().pmin()
- + inner_border_thickness_1 * right
- + (nrows_1 - inner_border_thickness) * down);
- mln_piter(I) p_left(b_left);
-
- B b_right = B(input.domain().pmax()
- + inner_border_thickness_1 * left
- + (nrows_1 - inner_border_thickness) * up,
- input.domain().pmax()
- + inner_border_thickness * up);
- mln_piter(I) p_right(b_right);
-
- mln_assertion(b_right.nsites() == b_left.nsites());
- mln_assertion(b_top.nsites() == b_bot.nsites());
-
- for_all_2(p_top, p_bot)
- {
- a.take(input(p_top));
- a.take(input(p_bot));
- }
-
- for_all_2(p_left, p_right)
- {
- a.take(input(p_left));
- a.take(input(p_right));
- }
+ mln_piter(I) p(input.domain());
+ for_all(p)
+ if (inner_border::internal::on_frontiere(p, input.domain(),
+ inner_border_thickness))
+ a.take(input(p));
trace::exiting("mln::data::compute_in_inner_border");
return a;
}
+ template <typename A, typename I>
+ mln_result(A)
+ compute_in_inner_border(Accumulator<A>& a, const Image<I>& input)
+ {
+ return compute_in_inner_border(a, input, 1);
+ }
+
# endif // ! MLN_INCLUDE_ONLY
diff --git a/milena/mln/trait/routine/mean.hh b/milena/mln/trait/routine/mean.hh
index 8cdbcc2..16bbfea 100644
--- a/milena/mln/trait/routine/mean.hh
+++ b/milena/mln/trait/routine/mean.hh
@@ -59,6 +59,18 @@ namespace mln
};
template <unsigned nvalues>
+ struct mean< nvalues, unsigned >
+ {
+ typedef float ret; // FIXME: really ?
+ };
+
+ template <unsigned nvalues>
+ struct mean< nvalues, unsigned char >
+ {
+ typedef mln::value::intsub<nvalues> ret;
+ };
+
+ template <unsigned nvalues>
struct mean< nvalues, float >
{
typedef float ret;
diff --git a/milena/mln/value/interval.hh b/milena/mln/value/interval.hh
index e2e9855..bdae72f 100644
--- a/milena/mln/value/interval.hh
+++ b/milena/mln/value/interval.hh
@@ -33,6 +33,7 @@
# include <cstdlib>
# include <iostream>
# include <mln/value/inc.hh>
+# include <mln/value/succ.hh>
# include <mln/value/concept/interval.hh>
@@ -238,9 +239,14 @@ namespace mln
first_ = first;
last_ = last;
- nelements_ = 0;
- for (T v = first_; v <= last_; value::inc(v))
- ++nelements_;
+ nelements_ = 1;
+ // The second condition in the for-loop is required in case of
+ // overflow...
+ if (first != last)
+ {
+ for (T v = value::succ(first_); v <= last_ && v > first_; value::inc(v))
+ ++nelements_; // FIXME: overflow with unsigned char + [0,255]
+ }
}
template <typename T>
diff --git a/milena/mln/value/intsub.hh b/milena/mln/value/intsub.hh
index ae71803..9fc7007 100644
--- a/milena/mln/value/intsub.hh
+++ b/milena/mln/value/intsub.hh
@@ -138,6 +138,10 @@ namespace mln
intsub(const intsub<n>& rhs);
template <unsigned m>
intsub(const intsub<m>& rhs);
+
+ // FIXME: Really ?
+ intsub(const value::int_u<8>& rhs);
+
/// Construct an intsub with value : \p int_part + 1 / \p denominator.
intsub(int int_part, unsigned denominator);
intsub(const literal::zero_t&);
@@ -299,6 +303,11 @@ namespace mln
this->v_ = rhs.to_enc() * (n / m);
}
+ template <unsigned n>
+ intsub<n>::intsub(const value::int_u<8>& rhs)
+ {
+ this->v_ = n * rhs.to_equiv();
+ }
template <unsigned n>
intsub<n>::intsub(const literal::zero_t&)
diff --git a/milena/mln/value/iota.hh b/milena/mln/value/iota.hh
index bdad60c..6fcd71a 100644
--- a/milena/mln/value/iota.hh
+++ b/milena/mln/value/iota.hh
@@ -56,6 +56,21 @@ namespace mln
static int value();
};
+ /// Specialization of \ref mln::value::internal::iota for unsigned
+ /// char.
+ template <>
+ struct iota<unsigned char>
+ {
+ static unsigned char value();
+ };
+
+ /// Specialization of \ref mln::value::internal::iota for char.
+ template <>
+ struct iota<char>
+ {
+ static char value();
+ };
+
# ifndef MLN_INCLUDE_ONLY
@@ -71,6 +86,18 @@ namespace mln
return 1;
}
+ unsigned char
+ iota<unsigned char>::value()
+ {
+ return 1u;
+ }
+
+ char
+ iota<char>::value()
+ {
+ return 1;
+ }
+
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln::value
--
1.7.2.5
1
0