Olena-patches
Threads by month
- ----- 2025 -----
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- 9625 discussions
* headers.mk: add new header to distribution.
* mln/make/h_mat.hh: create a h_mat from a C-style array.
* tests/unit_test/Makefile.am,
* tests/unit_test/mln_make_h_mat.cc: add unit test.
---
milena/ChangeLog | 38 +++++++++
milena/headers.mk | 1 +
milena/mln/make/h_mat.hh | 121 ++++++++++++++++++++++++++++++
milena/tests/unit_test/Makefile.am | 1 +
milena/tests/unit_test/mln_make_h_mat.cc | 11 +++
5 files changed, 172 insertions(+), 0 deletions(-)
create mode 100644 milena/mln/make/h_mat.hh
create mode 100644 milena/tests/unit_test/mln_make_h_mat.cc
diff --git a/milena/ChangeLog b/milena/ChangeLog
index eb424b1..58b16ad 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,5 +1,43 @@
2009-02-02 Guillaume Lazzara <z(a)lrde.epita.fr>
+ Add make::h_mat.
+
+ * headers.mk: add new header to distribution.
+
+ * mln/make/h_mat.hh: create a h_mat from a C-style array.
+
+ * tests/unit_test/Makefile.am,
+ * tests/unit_test/mln_make_h_mat.cc: add unit test.
+
+2009-02-02 Guillaume Lazzara <z(a)lrde.epita.fr>
+
+ Add core/alias/all.hh and alias/vec3d.hh.
+
+ * doc/tutorial/examples/examples.mk
+ * doc/tutorial/figures/figures.mk
+ * doc/tutorial/outputs/outputs.mk
+ * doc/tutorial/samples/samples.mk: Update generated files.
+
+ * headers.mk: add new header to distribution.
+
+ * mln/core/alias/all.hh: new header.
+
+ * mln/core/alias/vec3d.hh: new aliases for 3d algebra::vec.
+
+ * mln/core/alias/box2d.hh,
+ * mln/core/alias/box3d.hh: update comments.
+
+ * mln/core/all.hh: include alias/all.hh.
+
+ * mln/essential/3d.hh: add image3d.hh and vec3d.hh.
+
+ * tests/unit_test/Makefile.am,
+ * tests/unit_test/mln_core_alias_all.cc,
+ * tests/unit_test/mln_core_alias_vec3d.cc,
+ * tests/unit_test/mln_make_image3d.cc: add new unit test files.
+
+2009-02-02 Guillaume Lazzara <z(a)lrde.epita.fr>
+
Fix tutorial generation.
* doc/tutorial/generate_dist_files.sh: dot not include current
diff --git a/milena/headers.mk b/milena/headers.mk
index 037b5cc..04bef51 100644
--- a/milena/headers.mk
+++ b/milena/headers.mk
@@ -148,6 +148,7 @@ mln/make/w_window2d_int.hh \
mln/make/box1d.hh \
mln/make/voronoi.hh \
mln/make/box2d.hh \
+mln/make/h_mat.hh \
mln/make/w_window2d.hh \
mln/make/box3d.hh \
mln/make/relabelfun.hh \
diff --git a/milena/mln/make/h_mat.hh b/milena/mln/make/h_mat.hh
new file mode 100644
index 0000000..930c133
--- /dev/null
+++ b/milena/mln/make/h_mat.hh
@@ -0,0 +1,121 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library 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 this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library 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_MAKE_H_MAT_HH
+# define MLN_MAKE_H_MAT_HH
+
+/// \file mln/make/h_mat.hh
+///
+/// Routine to construct an mln::algebra::h_mat.
+
+# include <mln/algebra/h_mat.hh>
+# include <mln/metal/math/sqrt.hh>
+
+
+namespace mln
+{
+
+ namespace make
+ {
+
+ /// Create an mln::algebra::h_mat<d,T>.
+ /*
+ * \param[in] tab Array of values.
+ *
+ * \pre The array dimension has to be d * d.
+ */
+ template <typename T, unsigned d>
+ algebra::h_mat<d,T> h_mat(const T (&tab)[(d+1)*(d+1)]);
+
+
+ /// Create an mln::algebra::h_mat<d,T>.
+ /*
+ * \param[in] tab Array of values.
+ *
+ * \pre The array dimension has to be d * d.
+ */
+ template <typename T, unsigned d>
+ algebra::h_mat<d,T> h_mat(const T (&tab)[d+1][d+1]);
+
+
+ /// reate an mln::algebra::mat<n,n,T>.
+ /*
+ * \param[in] tab C-array of values.
+ *
+ * \pre The array dimension N has to be square (N = n * n).
+ */
+ template <typename T, unsigned N>
+ algebra::h_mat<mlc_sqrt_int(N), T> h_mat(const T (&tab)[N]);
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename T, unsigned d>
+ inline
+ algebra::h_mat<d,T>
+ h_mat(const T (&tab)[(d+1)*(d+1)])
+ {
+ algebra::h_mat<d,T> tmp;
+ for (unsigned i = 0; i <= d; ++i)
+ tmp(i / (d+1), i % (d+1)) = tab[i];
+ return tmp;
+ }
+
+
+ template <typename T, unsigned d>
+ algebra::h_mat<d,T>
+ h_mat(const T (&tab)[d+1][d+1])
+ {
+ algebra::h_mat<d,T> tmp;
+ for (unsigned i = 0; i <= d; ++i)
+ for (unsigned j = 0; j <= d; ++j)
+ tmp(i, j) = tab[i][j];
+ return tmp;
+ }
+
+
+ template <typename T, unsigned N>
+ inline
+ algebra::h_mat<mlc_sqrt_int(N), T>
+ h_mat(const T (&tab)[N])
+ {
+ enum { n = mlc_sqrt_int(N) };
+ mlc_bool(N == n * n)::check();
+ algebra::h_mat<n,T> tmp;
+ for (unsigned i = 0; i < N; ++i)
+ tmp(i / n, i % n) = tab[i];
+ return tmp;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::make
+
+} // end of namespace mln
+
+#endif // ! MLN_MAKE_H_MAT_HH
diff --git a/milena/tests/unit_test/Makefile.am b/milena/tests/unit_test/Makefile.am
index 2653f23..a6b6b26 100644
--- a/milena/tests/unit_test/Makefile.am
+++ b/milena/tests/unit_test/Makefile.am
@@ -145,6 +145,7 @@ mln_make_w_window2d_int \
mln_make_box1d \
mln_make_voronoi \
mln_make_box2d \
+mln_make_h_mat \
mln_make_w_window2d \
mln_make_box3d \
mln_make_relabelfun \
diff --git a/milena/tests/unit_test/mln_make_h_mat.cc b/milena/tests/unit_test/mln_make_h_mat.cc
new file mode 100644
index 0000000..b572cb4
--- /dev/null
+++ b/milena/tests/unit_test/mln_make_h_mat.cc
@@ -0,0 +1,11 @@
+// Unit test for mln/make/h_mat.hh.
+// Generated by ./build_unit_test.sh, do not modify.
+
+// Include the file twice, so we detect missing inclusion guards.
+#include <mln/make/h_mat.hh>
+#include <mln/make/h_mat.hh>
+
+int main()
+{
+ // Nothing.
+}
--
1.5.6.5
1
0
* doc/tutorial/examples/examples.mk
* doc/tutorial/figures/figures.mk
* doc/tutorial/outputs/outputs.mk
* doc/tutorial/samples/samples.mk: Update generated files.
* headers.mk: add new header to distribution.
* mln/core/alias/all.hh: new header.
* mln/core/alias/vec3d.hh: new aliases for 3d algebra::vec.
* mln/core/alias/box2d.hh,
* mln/core/alias/box3d.hh: update comments.
* mln/core/all.hh: include alias/all.hh.
* mln/essential/3d.hh: add image3d.hh and vec3d.hh.
* tests/unit_test/Makefile.am,
* tests/unit_test/mln_core_alias_all.cc,
* tests/unit_test/mln_core_alias_vec3d.cc,
* tests/unit_test/mln_make_image3d.cc: add new unit test files.
---
milena/doc/tutorial/examples/examples.mk | 1 -
milena/doc/tutorial/figures/figures.mk | 1 -
milena/doc/tutorial/outputs/outputs.mk | 1 -
milena/doc/tutorial/samples/samples.mk | 1 -
milena/headers.mk | 3 +
milena/mln/core/alias/{box2d.hh => all.hh} | 66 +++++++++++++----------
milena/mln/core/alias/box2d.hh | 27 +++++-----
milena/mln/core/alias/box3d.hh | 27 +++++-----
milena/mln/core/alias/{box3d.hh => vec3d.hh} | 30 +++++------
milena/mln/core/all.hh | 1 +
milena/mln/essential/3d.hh | 2 +
milena/tests/unit_test/Makefile.am | 3 +
milena/tests/unit_test/mln_core_alias_all.cc | 11 ++++
milena/tests/unit_test/mln_core_alias_vec3d.cc | 11 ++++
milena/tests/unit_test/mln_make_image3d.cc | 11 ++++
15 files changed, 118 insertions(+), 78 deletions(-)
copy milena/mln/core/alias/{box2d.hh => all.hh} (56%)
copy milena/mln/core/alias/{box3d.hh => vec3d.hh} (71%)
create mode 100644 milena/tests/unit_test/mln_core_alias_all.cc
create mode 100644 milena/tests/unit_test/mln_core_alias_vec3d.cc
create mode 100644 milena/tests/unit_test/mln_make_image3d.cc
diff --git a/milena/doc/tutorial/examples/examples.mk b/milena/doc/tutorial/examples/examples.mk
index 146f068..7458ead 100644
--- a/milena/doc/tutorial/examples/examples.mk
+++ b/milena/doc/tutorial/examples/examples.mk
@@ -1,6 +1,5 @@
## Generated by ../generate_dist_files, do not modify ##
EXTRA_DIST += \
-examples \
examples/cpp_issue.cc \
examples/sub_image.cc \
examples/sub_image_if.cc \
diff --git a/milena/doc/tutorial/figures/figures.mk b/milena/doc/tutorial/figures/figures.mk
index 3d11a2b..aba2682 100644
--- a/milena/doc/tutorial/figures/figures.mk
+++ b/milena/doc/tutorial/figures/figures.mk
@@ -1,6 +1,5 @@
## Generated by ../generate_dist_files, do not modify ##
EXTRA_DIST += \
-figures \
figures/ima2d-rot-2.ppm \
figures/tuto3_rw_image-1.ppm \
figures/logical-not-2.pbm \
diff --git a/milena/doc/tutorial/outputs/outputs.mk b/milena/doc/tutorial/outputs/outputs.mk
index 7d7596d..c6d318a 100644
--- a/milena/doc/tutorial/outputs/outputs.mk
+++ b/milena/doc/tutorial/outputs/outputs.mk
@@ -1,6 +1,5 @@
## Generated by ../generate_dist_files, do not modify ##
EXTRA_DIST += \
-outputs \
outputs/win-create-1-display.txt \
outputs/win-create-2.txt \
outputs/accu-right-instanciation.txt \
diff --git a/milena/doc/tutorial/samples/samples.mk b/milena/doc/tutorial/samples/samples.mk
index 7213ed1..40b410d 100644
--- a/milena/doc/tutorial/samples/samples.mk
+++ b/milena/doc/tutorial/samples/samples.mk
@@ -1,6 +1,5 @@
## Generated by ../generate_dist_files, do not modify ##
EXTRA_DIST += \
-samples \
samples/paste-call-1.cc \
samples/dpoint-1.cc \
samples/parray-append.cc \
diff --git a/milena/headers.mk b/milena/headers.mk
index 74a3002..037b5cc 100644
--- a/milena/headers.mk
+++ b/milena/headers.mk
@@ -134,6 +134,7 @@ mln/trace/stop.hh \
mln/trace/essential.hh \
mln/make/graph.hh \
mln/make/double_neighb2d.hh \
+mln/make/image3d.hh \
mln/make/dpoint2d_h.hh \
mln/make/w_window.hh \
mln/make/image.hh \
@@ -800,11 +801,13 @@ mln/core/alias/p_run2d.hh \
mln/core/alias/point3d.hh \
mln/core/alias/neighb3d.hh \
mln/core/alias/window3d.hh \
+mln/core/alias/all.hh \
mln/core/alias/neighb2d.hh \
mln/core/alias/complex_image.hh \
mln/core/alias/w_window1d_float.hh \
mln/core/alias/neighb1d.hh \
mln/core/alias/w_window2d_float.hh \
+mln/core/alias/vec3d.hh \
mln/core/alias/w_window2d_int.hh \
mln/core/alias/box1d.hh \
mln/core/alias/box2d.hh \
diff --git a/milena/mln/core/alias/box2d.hh b/milena/mln/core/alias/all.hh
similarity index 56%
copy from milena/mln/core/alias/box2d.hh
copy to milena/mln/core/alias/all.hh
index fb51e5d..ce509a6 100644
--- a/milena/mln/core/alias/box2d.hh
+++ b/milena/mln/core/alias/all.hh
@@ -1,4 +1,4 @@
-// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -25,34 +25,42 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-#ifndef MLN_CORE_SITE_SET_BOX2D_HH
-# define MLN_CORE_SITE_SET_BOX2D_HH
+#ifndef MLN_CORE_ALIAS_ALL_HH
+# define MLN_CORE_ALIAS_ALL_HH
-/*! \file mln/core/alias/box2d.hh
- *
- * \brief Definition of the mln::box2d alias and of construction
- * routines.
- */
+/// \file mln/core/alias/all.hh
+///
+/// File that includes all the aliases.
-# include <mln/core/site_set/box.hh>
-# include <mln/core/alias/point2d.hh>
+#include <box1d.hh>
+#include <box2d.hh>
+#include <box2d_h.hh>
+#include <box3d.hh>
+#include <complex_geometry.hh>
+#include <complex_image.hh>
+#include <dpoint1d.hh>
+#include <dpoint2d.hh>
+#include <dpoint2d_h.hh>
+#include <dpoint3d.hh>
+#include <neighb1d.hh>
+#include <neighb2d.hh>
+#include <neighb3d.hh>
+#include <p_run2d.hh>
+#include <p_runs2d.hh>
+#include <point1d.hh>
+#include <point2d.hh>
+#include <point2d_h.hh>
+#include <point3d.hh>
+#include <point3df.hh>
+#include <vec3d.hh>
+#include <w_window1d_float.hh>
+#include <w_window1d_int.hh>
+#include <w_window2d_float.hh>
+#include <w_window2d_int.hh>
+#include <w_window3d_float.hh>
+#include <w_window3d_int.hh>
+#include <window1d.hh>
+#include <window2d.hh>
+#include <window3d.hh>
-
-namespace mln
-{
-
- /*! \brief Type alias for a box defined on the 2D square grid with
- * integer coordinates.
- *
- * \see mln::win::rectangle2d.
- */
- typedef box<mln::point2d> box2d;
-
-
-} // end of namespace mln
-
-
-# include <mln/make/box2d.hh>
-
-
-#endif // ! MLN_CORE_SITE_SET_BOX2D_HH
+#endif // ! MLN_CORE_ALIAS_ALL_HH
diff --git a/milena/mln/core/alias/box2d.hh b/milena/mln/core/alias/box2d.hh
index fb51e5d..20cae3b 100644
--- a/milena/mln/core/alias/box2d.hh
+++ b/milena/mln/core/alias/box2d.hh
@@ -1,4 +1,5 @@
-// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2008, 2009 EPITA Research and Development
+// Laboratory (LRDE)
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -25,14 +26,13 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-#ifndef MLN_CORE_SITE_SET_BOX2D_HH
-# define MLN_CORE_SITE_SET_BOX2D_HH
+#ifndef MLN_CORE_ALIAS_BOX2D_HH
+# define MLN_CORE_ALIAS_BOX2D_HH
-/*! \file mln/core/alias/box2d.hh
- *
- * \brief Definition of the mln::box2d alias and of construction
- * routines.
- */
+/// \file mln/core/alias/box2d.hh
+///
+/// Definition of the mln::box2d alias and of construction
+/// routines.
# include <mln/core/site_set/box.hh>
# include <mln/core/alias/point2d.hh>
@@ -41,11 +41,10 @@
namespace mln
{
- /*! \brief Type alias for a box defined on the 2D square grid with
- * integer coordinates.
- *
- * \see mln::win::rectangle2d.
- */
+ /// Type alias for a box defined on the 2D square grid with
+ /// integer coordinates.
+ ///
+ /// \see mln::win::rectangle2d.
typedef box<mln::point2d> box2d;
@@ -55,4 +54,4 @@ namespace mln
# include <mln/make/box2d.hh>
-#endif // ! MLN_CORE_SITE_SET_BOX2D_HH
+#endif // ! MLN_CORE_ALIAS_BOX2D_HH
diff --git a/milena/mln/core/alias/box3d.hh b/milena/mln/core/alias/box3d.hh
index 54beaf6..4deafb7 100644
--- a/milena/mln/core/alias/box3d.hh
+++ b/milena/mln/core/alias/box3d.hh
@@ -1,4 +1,5 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2009 EPITA Research and Development Laboratory
+// (LRDE)
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -25,14 +26,13 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-#ifndef MLN_CORE_SITE_SET_BOX3D_HH
-# define MLN_CORE_SITE_SET_BOX3D_HH
+#ifndef MLN_CORE_ALIAS_BOX3D_HH
+# define MLN_CORE_ALIAS_BOX3D_HH
-/*! \file mln/core/alias/box3d.hh
- *
- * \brief Definition of the mln::box3d alias and of construction
- * routines.
- */
+/// \file mln/core/alias/box3d.hh
+///
+/// Definition of the mln::box3d alias and of construction
+/// routines.
# include <mln/core/site_set/box.hh>
# include <mln/core/alias/point3d.hh>
@@ -41,11 +41,10 @@
namespace mln
{
- /*! \brief Type alias for a box defined on the 3D square grid with
- * integer coordinates.
- *
- * \see mln::win::rectangle3d.
- */
+ /// Type alias for a box defined on the 3D square grid with
+ /// integer coordinates.
+ ///
+ /// \see mln::win::rectangle3d.
typedef box<point3d> box3d;
@@ -55,4 +54,4 @@ namespace mln
# include <mln/make/box3d.hh>
-#endif // ! MLN_CORE_SITE_SET_BOX3D_HH
+#endif // ! MLN_CORE_ALIAS_BOX3D_HH
diff --git a/milena/mln/core/alias/box3d.hh b/milena/mln/core/alias/vec3d.hh
similarity index 71%
copy from milena/mln/core/alias/box3d.hh
copy to milena/mln/core/alias/vec3d.hh
index 54beaf6..621b505 100644
--- a/milena/mln/core/alias/box3d.hh
+++ b/milena/mln/core/alias/vec3d.hh
@@ -1,4 +1,4 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -25,28 +25,24 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-#ifndef MLN_CORE_SITE_SET_BOX3D_HH
-# define MLN_CORE_SITE_SET_BOX3D_HH
+#ifndef MLN_CORE_ALIAS_VEC3D_HH
+# define MLN_CORE_ALIAS_VEC3D_HH
-/*! \file mln/core/alias/box3d.hh
- *
- * \brief Definition of the mln::box3d alias and of construction
- * routines.
- */
+/// \file mln/core/alias/vec3d.hh
+///
+/// Definition of the mln::vec3d* alias
-# include <mln/core/site_set/box.hh>
-# include <mln/core/alias/point3d.hh>
+# include <mln/algebra/vec.hh>
namespace mln
{
- /*! \brief Type alias for a box defined on the 3D square grid with
- * integer coordinates.
- *
- * \see mln::win::rectangle3d.
- */
- typedef box<point3d> box3d;
+ /// 3D vector with float coordinates.
+ typedef algebra::vec<3u,float> vec3d_f;
+
+ /// 3D vector with double coordinates.
+ typedef algebra::vec<3u,double> vec3d_d;
} // end of namespace mln
@@ -55,4 +51,4 @@ namespace mln
# include <mln/make/box3d.hh>
-#endif // ! MLN_CORE_SITE_SET_BOX3D_HH
+#endif // ! MLN_CORE_ALIAS_VEC3D_HH
diff --git a/milena/mln/core/all.hh b/milena/mln/core/all.hh
index f92dbd8..d0ab2c3 100644
--- a/milena/mln/core/all.hh
+++ b/milena/mln/core/all.hh
@@ -34,6 +34,7 @@
// Sub-directories.
+# include <mln/core/alias/all.hh>
# include <mln/core/concept/all.hh>
# include <mln/core/def/all.hh>
# include <mln/core/image/all.hh>
diff --git a/milena/mln/essential/3d.hh b/milena/mln/essential/3d.hh
index 8d782c6..ec1a602 100644
--- a/milena/mln/essential/3d.hh
+++ b/milena/mln/essential/3d.hh
@@ -34,11 +34,13 @@
# include <mln/core/alias/dpoint3d.hh>
# include <mln/core/alias/neighb3d.hh>
# include <mln/core/alias/point3d.hh>
+# include <mln/core/alias/vec3d.hh>
# include <mln/core/alias/w_window3d_float.hh>
# include <mln/core/alias/w_window3d_int.hh>
# include <mln/core/alias/window3d.hh>
# include <mln/geom/size3d.hh>
# include <mln/make/box3d.hh>
+# include <mln/make/image3d.hh>
# include <mln/make/w_window3d.hh>
# include <mln/make/w_window3d_int.hh>
# include <mln/metal/array3d.hh>
diff --git a/milena/tests/unit_test/Makefile.am b/milena/tests/unit_test/Makefile.am
index 0475cc4..2653f23 100644
--- a/milena/tests/unit_test/Makefile.am
+++ b/milena/tests/unit_test/Makefile.am
@@ -131,6 +131,7 @@ mln_trace_stop \
mln_trace_essential \
mln_make_graph \
mln_make_double_neighb2d \
+mln_make_image3d \
mln_make_dpoint2d_h \
mln_make_w_window \
mln_make_image \
@@ -791,11 +792,13 @@ mln_core_alias_p_run2d \
mln_core_alias_point3d \
mln_core_alias_neighb3d \
mln_core_alias_window3d \
+mln_core_alias_all \
mln_core_alias_neighb2d \
mln_core_alias_complex_image \
mln_core_alias_w_window1d_float \
mln_core_alias_neighb1d \
mln_core_alias_w_window2d_float \
+mln_core_alias_vec3d \
mln_core_alias_w_window2d_int \
mln_core_alias_box1d \
mln_core_alias_box2d \
diff --git a/milena/tests/unit_test/mln_core_alias_all.cc b/milena/tests/unit_test/mln_core_alias_all.cc
new file mode 100644
index 0000000..97f068e
--- /dev/null
+++ b/milena/tests/unit_test/mln_core_alias_all.cc
@@ -0,0 +1,11 @@
+// Unit test for mln/core/alias/all.hh.
+// Generated by ./build_unit_test.sh, do not modify.
+
+// Include the file twice, so we detect missing inclusion guards.
+#include <mln/core/alias/all.hh>
+#include <mln/core/alias/all.hh>
+
+int main()
+{
+ // Nothing.
+}
diff --git a/milena/tests/unit_test/mln_core_alias_vec3d.cc b/milena/tests/unit_test/mln_core_alias_vec3d.cc
new file mode 100644
index 0000000..476c522
--- /dev/null
+++ b/milena/tests/unit_test/mln_core_alias_vec3d.cc
@@ -0,0 +1,11 @@
+// Unit test for mln/core/alias/vec3d.hh.
+// Generated by ./build_unit_test.sh, do not modify.
+
+// Include the file twice, so we detect missing inclusion guards.
+#include <mln/core/alias/vec3d.hh>
+#include <mln/core/alias/vec3d.hh>
+
+int main()
+{
+ // Nothing.
+}
diff --git a/milena/tests/unit_test/mln_make_image3d.cc b/milena/tests/unit_test/mln_make_image3d.cc
new file mode 100644
index 0000000..85fbb01
--- /dev/null
+++ b/milena/tests/unit_test/mln_make_image3d.cc
@@ -0,0 +1,11 @@
+// Unit test for mln/make/image3d.hh.
+// Generated by ./build_unit_test.sh, do not modify.
+
+// Include the file twice, so we detect missing inclusion guards.
+#include <mln/make/image3d.hh>
+#include <mln/make/image3d.hh>
+
+int main()
+{
+ // Nothing.
+}
--
1.5.6.5
1
0
https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Update Laurent's cleanup code.
* theo/esiee/laurent/ismm09/trash.hh: New.
* theo/esiee/laurent/ismm09/util.hh: New.
* theo/esiee/laurent/ismm09/main.cc: Update.
main.cc | 251 +++++++++++++++++++++++++++++++++++++++------------------------
trash.hh | 62 +++++++++++++++
util.hh | 62 +++++++++++++++
3 files changed, 280 insertions(+), 95 deletions(-)
Index: theo/esiee/laurent/ismm09/trash.hh
--- theo/esiee/laurent/ismm09/trash.hh (revision 0)
+++ theo/esiee/laurent/ismm09/trash.hh (revision 0)
@@ -0,0 +1,62 @@
+
+namespace mln
+{
+
+
+ template <typename F, typename N, typename A, typename W>
+ void // util::array<unsigned>
+ compute_attribute_extincted(const F& f, const N& nbh, const A& a,
+ const W& w)
+ {
+ typedef value::label_16 L;
+ L n_basins;
+ mln_ch_value(F,L) regmins = labeling::regional_minima(f, nbh, n_basins);
+
+ typedef p_array<mln_psite(F)> S;
+ S s = level::sort_psites_decreasing(f);
+
+ typedef morpho::tree::data<F,S> tree_t;
+ tree_t t(f, s, nbh);
+ mln_VAR(a_ima, morpho::tree::compute_attribute_image(a, t));
+
+ std::cout << "BEFORE:" << std::endl;
+ debug::println("a_ima:", a_ima);
+ debug::println("a_ima | w_line:", a_ima | (pw::value(w) == 0));
+ debug::println("a_ima | basins:", a_ima | (pw::value(w) != 0));
+ // debug::println("a_ima | regmins:", a_ima | (pw::value(regmins) != 0));
+
+
+ extinct_attributes(t, a_ima);
+
+ std::cout << "AFTER:" << std::endl;
+ debug::println("a_ima:", a_ima);
+ debug::println("a_ima | w_line:", a_ima | (pw::value(w) == 0));
+ debug::println("a_ima | basins:", a_ima | (pw::value(w) != 0));
+ debug::println("a_ima | regmins:", a_ima | (pw::value(regmins) != 0));
+ }
+
+
+} // end of namespace mln
+
+
+
+
+// Trash code:
+
+
+// {
+// L n_regmins;
+// mln_VAR(regmins, labeling::regional_minima(g, cplx2d::e2e(), n_regmins));
+// mln_invariant(n_regmins == n_basins);
+// debug::println("regmins(g):", regmins);
+
+// debug::println("w:", w);
+// std::cout << "n basins = " << n_basins << std::endl
+// << std::endl;
+// }
+
+// // accu::count< util::pix<g_t> > a_;
+// accu::height<g_t> a_;
+
+// compute_attribute_extincted(g, cplx2d::e2e(), a_,
+// w);
Index: theo/esiee/laurent/ismm09/main.cc
--- theo/esiee/laurent/ismm09/main.cc (revision 3235)
+++ theo/esiee/laurent/ismm09/main.cc (working copy)
@@ -19,13 +19,15 @@
#include <mln/labeling/compute.hh>
#include <mln/level/sort_psites.hh>
+#include <mln/core/site_set/p_queue.hh>
+#include <mln/core/site_set/p_priority.hh>
+
#include <mln/morpho/gradient.hh>
#include <mln/morpho/meyer_wst.hh>
#include <mln/morpho/tree/data.hh>
#include <mln/morpho/tree/compute_attribute_image.hh>
#include <mln/accu/count.hh>
-#include <mln/accu/height.hh>
@@ -160,102 +162,70 @@
}
- } // end of namespace mln::cplx2d
-
-
- namespace internal
- {
-
- template <typename T>
- struct node_pred : Function_p2b< node_pred<T> >
- {
- typedef bool result;
-
- template <typename P>
- bool operator()(const P& p) const
+ inline
+ point2d p1_from_e(const point2d& e)
{
- return t->is_a_node(p);
+ return e + (is_row_odd(e) ? up : left);
}
- const T* t;
- };
-
- template <typename T, typename I, typename M>
- mln_value(I) rec(const T& t, // tree
- I& a, // attribute image
- M& mark,
- const mln_psite(I)& p)
+ inline
+ point2d p2_from_e(const point2d& e)
{
- mln_invariant(mark(p) == false);
- mark(p) = true;
- if (t.parent(p) == p || mark(t.parent(p)) == true) // Stop.
- return a(p);
- return a(p) = rec(t, a, mark, t.parent(p));
+ return e + (is_row_odd(e) ? down : right);
}
- } // internal
-
-
- template <typename T, typename A>
+ template <typename W, typename L>
+ inline
void
- extinct_attributes(const T& t, // Tree.
- A& a) // Attribute image.
+ e_to_labels(const W& w, const point2d& e, L& l1, L& l2)
{
- mln_ch_value(A, bool) mark;
- initialize(mark, a);
- data::fill(mark, false);
-
- internal::node_pred<T> node_only;
- node_only.t = &t;
-
- typedef p_array<mln_site(A)> S;
- S s = level::sort_psites_increasing(a | node_only);
-
- mln_fwd_piter(S) p(s);
- for_all(p)
- {
- if (mark(p) == true)
- continue;
- internal::rec(t, a, mark, p);
- }
+ mln_precondition(w(e) == 0);
+ l1 = 0;
+ l2 = 0;
+ mln_niter(dbl_neighb2d) n(e2e(), e);
+ for_all(n)
+ if (w.has(n) && w(n) != 0)
+ {
+ if (l1 == 0) // First label to be stored.
+ l1 = w(n);
+ else
+ if (w(n) != l1 && l2 == 0) // Second label to be stored.
+ l2 = w(n);
+ else
+ mln_invariant(w(n) == l1 || w(n) == l2);
+ }
+ mln_invariant(l1 != 0 && l2 != 0);
+ if (l1 > l2)
+ std::swap(l1, l2);
+ mln_postcondition(l2 >= l1);
}
- template <typename F, typename N, typename A, typename W>
- void // util::array<unsigned>
- compute_attribute_extincted(const F& f, const N& nbh, const A& a,
- const W& w)
- {
- typedef value::label_16 L;
- L n_basins;
- mln_ch_value(F,L) regmins = labeling::regional_minima(f, nbh, n_basins);
-
- typedef p_array<mln_psite(F)> S;
- S s = level::sort_psites_decreasing(f);
-
- typedef morpho::tree::data<F,S> tree_t;
- tree_t t(f, s, nbh);
- mln_VAR(a_ima, morpho::tree::compute_attribute_image(a, t));
+ } // end of namespace mln::cplx2d
- std::cout << "BEFORE:" << std::endl;
- debug::println("a_ima:", a_ima);
- debug::println("a_ima | w_line:", a_ima | (pw::value(w) == 0));
- debug::println("a_ima | basins:", a_ima | (pw::value(w) != 0));
- // debug::println("a_ima | regmins:", a_ima | (pw::value(regmins) != 0));
- extinct_attributes(t, a_ima);
+ template <typename A, typename L>
+ util::array<L>
+ sort_by_increasing_attributes(const util::array<A>& a, L n_basins)
+ {
+ typedef std::pair<A,L> pair_t;
+ std::vector<pair_t> v;
+ v.reserve(n_basins);
+ for (L l = 1; l <= n_basins; ++l)
+ v.push_back(pair_t(a[l], l));
+
+ std::sort(v.begin(), v.end());
+
+ util::array<L> l(n_basins);
+ for (unsigned i = 0; i < n_basins; ++i)
+ l[i] = v[i].second;
- std::cout << "AFTER:" << std::endl;
- debug::println("a_ima:", a_ima);
- debug::println("a_ima | w_line:", a_ima | (pw::value(w) == 0));
- debug::println("a_ima | basins:", a_ima | (pw::value(w) != 0));
- debug::println("a_ima | regmins:", a_ima | (pw::value(regmins) != 0));
+ return l;
}
-
} // end of namespace mln
@@ -291,34 +261,125 @@
mln_VAR(g, cplx2d::f_to_g(f) );
debug::println("g:", g);
+ typedef mln_value_(g_t) T; // <--- Type of edge values.
+ typedef mln_psite_(g_t) E; // <--- Type of edges.
+
+
+ mln_VAR(nbh_g, cplx2d::e2e()); // Neighborhood between edges.
+
// w: watershed labeling on edges.
- typedef label_16 L;
+ typedef label_16 L; // <--- Type of labels.
L n_basins;
- mln_VAR( w, morpho::meyer_wst(g, cplx2d::e2e(), n_basins) );
+ mln_VAR( w, morpho::meyer_wst(g, nbh_g, n_basins) );
+ debug::println("w:", w);
+
+
+ mln_VAR( w_line, pw::value(w) == pw::cst(0) );
+ mln_VAR( g_line, g | w_line );
+ debug::println("g | line:", g_line);
+
{
- L n_regmins;
- mln_VAR(regmins, labeling::regional_minima(g, cplx2d::e2e(), n_regmins));
- mln_invariant(n_regmins == n_basins);
- debug::println("regmins(g):", regmins);
+ /*
+ // debug::println("w | line:", w | w_line);
+ mln_VAR(w_ext, cplx2d::extend_w_edges_to_all_faces(w));
+ debug::println("w_ext:", w_ext);
+ // debug::println("w_ext | line:", w_ext | (pw::value(w_ext) == pw::cst(0)));
+ */
+ }
- debug::println("w:", w);
- std::cout << "n basins = " << n_basins << std::endl
- << std::endl;
-// mln_VAR(w_ext, cplx2d::extend_w_edges_to_all_faces(w));
-// debug::println("w_ext:", w_ext);
-// mln_VAR(is_line, pw::value(w_ext) == pw::cst(0));
-// debug::println("w line:", w_ext | is_line);
+ // a: array "label -> attribute".
+
+ typedef unsigned A; // <--- Type of attributes.
+
+ util::array<A> a = labeling::compute(accu::meta::count(),
+ g, // image of values
+ w, // image of labels
+ n_basins);
+
+ util::array<L> l = sort_by_increasing_attributes(a, n_basins);
+
+ {
+ /*
+ std::cout << "l:" << std::endl;
+ for (unsigned i = 0; i < l.nelements(); ++i)
+ std::cout << l[i] << "(" << a[l[i]] << ") ";
+ std::cout << std::endl;
+ */
+ }
+
+
+// {
+// // Test adjacency "e -> (l1, l2)".
+// L l1, l2;
+// mln_piter_(g_t) e(g.domain());
+// for_all(e)
+// if (w(e) == 0)
+// {
+// cplx2d::e_to_labels(w, e, l1, l2);
+// std::cout << e << ':' << l1 << ',' << l2 << std::endl;
+// }
+// }
+
+
+
+ // Edges -> Priority queue.
+
+ typedef p_priority< T, p_queue<E> > Q;
+ util::array<Q> q(n_basins.next());
+
+ {
+ L l1, l2;
+ mln_piter_(g_t) e(g.domain());
+ for_all(e)
+ if (w(e) == 0)
+ {
+ cplx2d::e_to_labels(w, e, // input
+ l1, l2); // output
+ q[l1].push(mln_max(T) - g(e), e);
+ q[l2].push(mln_max(T) - g(e), e);
+ }
+ }
+
+
+ // Information "label l -> edge e".
+
+ E null = E(0,0); // Impossible value.
+
+ util::array<E> edge(n_basins.next());
+ for (L l = 0; l <= n_basins; ++l)
+ edge[l] = null;
+
+
+ // Initialization.
+
+ util::array<L> lpar(n_basins.next());
+ for (L l = 0; l <= n_basins; ++l)
+ lpar[l] = l; // Make-Set.
+
+
+
+ mln_ch_value_(g_line_t, E)
+ epar, // Edge forest.
+ z_epar; // Auxiliary data: edge forest with compression and balancing.
+
+ {
+ initialize(epar, g_line);
+ initialize(z_epar, g_line);
+ mln_piter_(g_line_t) e(g_line.domain());
+ for_all(e)
+ {
+ // Make-Set.
+ epar(e) = e;
+ z_epar(e) = e;
+ }
+ debug::println("all edges:", epar); // epar(e) == e so we depict the edges!
}
- // accu::count< util::pix<g_t> > a_;
- accu::height<g_t> a_;
- compute_attribute_extincted(g, cplx2d::e2e(), a_,
- w);
}
Index: theo/esiee/laurent/ismm09/util.hh
--- theo/esiee/laurent/ismm09/util.hh (revision 0)
+++ theo/esiee/laurent/ismm09/util.hh (revision 0)
@@ -0,0 +1,62 @@
+
+namespace mln
+{
+
+ namespace internal
+ {
+
+ template <typename T>
+ struct node_pred : Function_p2b< node_pred<T> >
+ {
+ typedef bool result;
+
+ template <typename P>
+ bool operator()(const P& p) const
+ {
+ return t->is_a_node(p);
+ }
+
+ const T* t;
+ };
+
+ template <typename T, typename I, typename M>
+ mln_value(I) rec(const T& t, // tree
+ I& a, // attribute image
+ M& mark,
+ const mln_psite(I)& p)
+ {
+ mln_invariant(mark(p) == false);
+ mark(p) = true;
+ if (t.parent(p) == p || mark(t.parent(p)) == true) // Stop.
+ return a(p);
+ return a(p) = rec(t, a, mark, t.parent(p));
+ }
+
+ } // internal
+
+
+ template <typename T, typename A>
+ void
+ extinct_attributes(const T& t, // Tree.
+ A& a) // Attribute image.
+ {
+ mln_ch_value(A, bool) mark;
+ initialize(mark, a);
+ data::fill(mark, false);
+
+ internal::node_pred<T> node_only;
+ node_only.t = &t;
+
+ typedef p_array<mln_site(A)> S;
+ S s = level::sort_psites_increasing(a | node_only);
+
+ mln_fwd_piter(S) p(s);
+ for_all(p)
+ {
+ if (mark(p) == true)
+ continue;
+ internal::rec(t, a, mark, p);
+ }
+ }
+
+} // end of namespace mln
1
0
URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox
ChangeLog:
2009-02-02 Edwin Carlinet <carlinet(a)lrde.epita.fr>
Add dispatch functions for accumulator.
* .: New.
* fredwin.cc: New.
---
fredwin.cc | 220 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 220 insertions(+)
Index: trunk/milena/sandbox/edwin/fredwin.cc
===================================================================
--- trunk/milena/sandbox/edwin/fredwin.cc (revision 0)
+++ trunk/milena/sandbox/edwin/fredwin.cc (revision 3235)
@@ -0,0 +1,220 @@
+
+
+template <typename E>
+struct Accumulator
+{
+};
+
+
+template <typename E>
+struct Meta_Accumulator
+{
+};
+
+// Cf. mln/core/concept/*
+
+
+namespace accu
+{
+
+ template <typename T>
+ struct card : Accumulator<card>
+ {
+ void take(const T& elt) { ++c_; }
+ unsigned c_;
+ };
+
+ namespace meta
+ {
+ struct card : Meta_Accumulator<card>
+ {
+ template <typename T>
+ struct with
+ {
+ typedef accu::card<T> ret;
+ };
+ };
+
+ // FIXME: passez de accu::meta::card a accu::card<T> ?
+
+ // Cf. mln/accu/count.hh
+ // et mln/accu/compute.hh
+
+ } // meta
+
+} // accu
+
+
+
+namespace impl
+{
+
+ // Leveling
+ // --------
+
+ template <typename I, typename A>
+ void
+ leveling(const Image<I>& input, const Accumulator<A>& acc)
+ {
+ const I& ima = exact(input);
+ // algo en resume :
+ mln_piter(I) p(ima.domain());
+ for_all(p)
+ acc.take(make::pix(ima, p)); // util::pix<I>
+ }
+
+ template <typename I, typename A>
+ void
+ leveling_fastest(const Image<I>& input_, const Accumulator<A>& acc)
+ {
+ const I& input = exact(input_);
+
+ // algo en resume :
+ mln_pixter(const I) pxl(input);
+ for_all(pxl)
+ acc.take(pxl);
+ }
+
+
+ // FIXME: pb: on a 2 fois le même code, plusieurs fois car 1
+ // spécialisation pour les images fastest
+
+
+ // Algebraic
+ // ---------
+
+
+ template <typename I, typename A>
+ void
+ generic_algebraic(const Image<I>& input, const Accumulator<A>& acc)
+ {
+ // algo en resume :
+ mln_piter(I) p(ima.domain());
+ for_all(p)
+ acc.take(p); // psite
+ }
+
+ template <typename I, typename A>
+ void
+ algebraic_fastest(const Image<I>& input, const Accumulator<A>& acc)
+ {
+ // algo en resume :
+ mln_pixter(const I) pxl(input);
+ for_all(pxl)
+ acc.take(pxl);
+ }
+
+
+ // FIXME: pb: soit on passe du "site", soit du "pixel"...
+
+
+ // pour mémoire mais on s'en fout (!!!) :
+ /*
+ template <typename I, typename A>
+ void
+ algebraic_fastest_alt(const Image<I>& input, const Accumulator<A>& acc)
+ {
+ for (unsigned i = 0; i < n; ++i)
+ acc.take(input, i); // (image, offset) -> site
+ // Cf. methode image2d<T>::point_at_index(i)
+ }
+ */
+
+
+ // FIXME: On veut qqch qui ressemble à :
+
+ template <typename I, typename A>
+ void
+ generic_algebraic_or_leveling(const Image<I>& input, const Accumulator<A>& acc)
+ {
+ // algo en resume :
+ mln_piter(I) p(ima.domain());
+ for_all(p)
+ acc.take( FIXME );
+ }
+
+ template <typename I, typename A>
+ void
+ algebraic_or_leveling_fastest(const Image<I>& input, const Accumulator<A>& acc)
+ {
+ // algo en resume :
+ mln_pixter(const I) pxl(input);
+ for_all(pxl)
+ acc.take( FIXME );
+ }
+
+
+ // FIXME: Mais ce n'est peut-être pas possible avec des
+ // Accumulator...
+
+
+} // impl
+
+
+
+namespace internal
+{
+
+ // dispatch for geneneric implementation.
+ template <typename M, typename I>
+ void
+ algebraic_dispatch(metal::false_,
+ const Image<I>& input,
+ const Meta_Accumulator<M>& acc)
+ {
+ typedef mln_accu_with(M, mln_piter(I)) A;
+
+ mln_piter(I)* piter;
+ A accu = accu::unmeta(exact(acc), piter);
+
+ generic_algebraic(input, acc);
+ }
+
+
+ // dispatch for fastest implementation.
+ template <typename M, typename I>
+ void
+ algebraic_dispatch(metal::true_,
+ const Image<I>& input,
+ const Meta_Accumulator<M>& acc)
+ {
+ typedef mln_accu_with(M, util::pix<I>) A;
+
+ util::pix<I>* pix_;
+ A accu = accu::unmeta(exact(acc), pix_);
+
+ algebraic_fastest(input, acc);
+ }
+
+ template <typename M, typename I>
+ void
+ algebraic_dispatch(const Image<I>& input,
+ const Meta_Accumulator<M>& acc)
+ {
+
+
+ algebraic_dispatch(mlc_equal(mln_trait_image_speed(I),
+ trait::image::speed::fastest)::value,
+ input,
+ acc);
+ }
+
+}
+
+
+
+// Facade.
+
+template <typename M, typename I>
+void
+algebraic(const Image<I>& input, const Meta_Accumulator<M>& acc) // FIXME: on préfère Meta_Accumulator !
+{
+ internal::algebraic_dispatch(input, acc);
+}
+
+
+
+int main()
+{
+ algebraic(ima, accu::meta::card());
+}
1
0
* doc/tutorial/generate_dist_files.sh: dot not include current
directory...
* doc/tutorial/samples/borderthickness.cc: Fix a non initialized
border.
---
milena/ChangeLog | 10 ++++++++++
milena/doc/tutorial/generate_dist_files.sh | 2 +-
milena/doc/tutorial/samples/borderthickness.cc | 1 +
3 files changed, 12 insertions(+), 1 deletions(-)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index cdffe3f..eb424b1 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,3 +1,13 @@
+2009-02-02 Guillaume Lazzara <z(a)lrde.epita.fr>
+
+ Fix tutorial generation.
+
+ * doc/tutorial/generate_dist_files.sh: dot not include current
+ directory...
+
+ * doc/tutorial/samples/borderthickness.cc: Fix a non initialized
+ border.
+
2009-02-02 Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Activate fastest version of algebraic union-find.
diff --git a/milena/doc/tutorial/generate_dist_files.sh b/milena/doc/tutorial/generate_dist_files.sh
index 5864bff..91f75f1 100755
--- a/milena/doc/tutorial/generate_dist_files.sh
+++ b/milena/doc/tutorial/generate_dist_files.sh
@@ -4,7 +4,7 @@ for dir in samples figures outputs examples; do
OUT="$dir/$dir.mk"
echo "## Generated by ../generate_dist_files, do not modify ##" > $OUT
echo -n "EXTRA_DIST += " >> $OUT
- for file in `find $dir`; do
+ for file in `find $dir -mindepth 1`; do
echo " \\" >> $OUT
echo -n $file >> $OUT
done
diff --git a/milena/doc/tutorial/samples/borderthickness.cc b/milena/doc/tutorial/samples/borderthickness.cc
index 8c96bfb..ce02abe 100644
--- a/milena/doc/tutorial/samples/borderthickness.cc
+++ b/milena/doc/tutorial/samples/borderthickness.cc
@@ -9,6 +9,7 @@ int main()
{ 1, 1, 0 } };
image2d<bool> ima_def = make::image(vals);
+ border::fill(ima_def, false);
debug::println_with_border(ima_def);
std::cout << "===========" << std::endl << std::endl;
--
1.5.6.5
1
0
https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Activate fastest version of algebraic union-find.
* mln/morpho/closing_attribute.hh
(closing_attribute_dispatch): Activate for fastest images.
* mln/canvas/morpho/algebraic_union_find.hh: Likewise.
* mln/canvas/labeling.hh: Remove dead code.
canvas/labeling.hh | 155 ----------------------------------
canvas/morpho/algebraic_union_find.hh | 30 +++---
morpho/closing_attribute.hh | 28 +++---
3 files changed, 35 insertions(+), 178 deletions(-)
Index: mln/morpho/closing_attribute.hh
--- mln/morpho/closing_attribute.hh (revision 3231)
+++ mln/morpho/closing_attribute.hh (working copy)
@@ -209,22 +209,22 @@
template <typename A, typename I, typename N>
inline
mln_concrete(I)
- closing_attribute_dispatch(trait::image::speed::any,
+ closing_attribute_dispatch(metal::false_,
const Image<I>& input, const Neighborhood<N>& nbh,
mln_result(A) lambda)
{
return impl::generic::closing_attribute<A>(input, nbh, lambda);
}
-// template <typename A, typename I, typename N>
-// inline
-// mln_concrete(I)
-// closing_attribute_dispatch(trait::image::speed::fastest,
-// const Image<I>& input, const Neighborhood<N>& nbh,
-// mln_result(A) lambda)
-// {
-// return impl::closing_attribute_fastest<A>(input, nbh, lambda);
-// }
+ template <typename A, typename I, typename N>
+ inline
+ mln_concrete(I)
+ closing_attribute_dispatch(metal::true_,
+ const Image<I>& input, const Neighborhood<N>& nbh,
+ mln_result(A) lambda)
+ {
+ return impl::closing_attribute_fastest<A>(input, nbh, lambda);
+ }
template <typename A, typename I, typename N>
inline
@@ -232,7 +232,13 @@
closing_attribute_dispatch(const Image<I>& input, const Neighborhood<N>& nbh,
mln_result(A) lambda)
{
- return closing_attribute_dispatch<A>(mln_trait_image_speed(I)(),
+ enum {
+ test = mlc_equal(mln_trait_image_speed(I),
+ trait::image::speed::fastest)::value
+ &&
+ mln_is_simple_neighborhood(N)::value
+ };
+ return closing_attribute_dispatch<A>(metal::bool_<test>(),
input, nbh, lambda);
}
Index: mln/canvas/morpho/algebraic_union_find.hh
--- mln/canvas/morpho/algebraic_union_find.hh (revision 3231)
+++ mln/canvas/morpho/algebraic_union_find.hh (working copy)
@@ -336,7 +336,7 @@
template <typename I, typename N, typename F>
inline
mln_concrete(I)
- algebraic_union_find_dispatch(trait::image::speed::any,
+ algebraic_union_find_dispatch(metal::false_,
const Image<I>& input,
const Neighborhood<N>& nbh,
F& f)
@@ -344,16 +344,16 @@
return impl::generic::algebraic_union_find(input, nbh, f);
}
- // template <typename I, typename N, typename F>
- // inline
- // mln_concrete(I)
- // algebraic_union_find_dispatch(trait::image::speed::fastest,
- // const Image<I>& input,
- // const Neighborhood<N>& nbh,
- // F& f)
- // {
- // return impl::algebraic_union_find_fastest(input, nbh, f);
- // }
+ template <typename I, typename N, typename F>
+ inline
+ mln_concrete(I)
+ algebraic_union_find_dispatch(metal::true_,
+ const Image<I>& input,
+ const Neighborhood<N>& nbh,
+ F& f)
+ {
+ return impl::algebraic_union_find_fastest(input, nbh, f);
+ }
template <typename I, typename N, typename F>
inline
@@ -362,7 +362,13 @@
const Neighborhood<N>& nbh,
F& f)
{
- return algebraic_union_find_dispatch(mln_trait_image_speed(I)(),
+ enum {
+ test = mlc_equal(mln_trait_image_speed(I),
+ trait::image::speed::fastest)::value
+ &&
+ mln_is_simple_neighborhood(N)::value
+ };
+ return algebraic_union_find_dispatch(metal::bool_<test>(),
input, nbh, f);
}
Index: mln/canvas/labeling.hh
--- mln/canvas/labeling.hh (revision 3231)
+++ mln/canvas/labeling.hh (working copy)
@@ -203,161 +203,6 @@
-
-
-
-
- // -----------------------------------------------------------
- // Old code below.
-
-
- /*
-
- // Fastest version.
-
- template <typename F>
- struct labeling_fastest
- {
- // Functor.
- F& f;
-
- typedef typename F::I I;
- typedef typename F::N N;
- typedef typename F::L L;
-
- // Auxiliary data.
- mln_ch_value(I, unsigned) parent;
-
- // Output.
- mln_ch_value(I, L) output;
- L nlabels;
- bool status;
-
- // Ctor.
- labeling_fastest(F& f);
-
- void init();
-
- void pass_1();
-
- void pass_2();
-
- // Auxiliary methods.
-
- bool is_root(unsigned p) const;
-
- unsigned find_root(unsigned x);
-
- void do_union(unsigned n, unsigned p);
-
- };
-
- template <typename F>
- labeling_fastest<F>::labeling_fastest(F& f)
- : f(f)
- {
- trace::entering("canvas::labeling_fastest");
-
- init();
- f.init(); // Client initialization.
- pass_1();
- pass_2();
-
- trace::exiting("canvas::labeling_fastest");
- }
-
- template <typename F>
- void
- labeling_fastest<F>::init()
- {
- initialize(parent, f.input);
- for (unsigned p = 0; p < parent.nelements(); ++p)
- parent.element(p) = p; // make_set
- initialize(output, f.input);
- mln::data::fill(output, 0); // FIXME: Use literal::zero.
- nlabels = 0;
- }
-
- template <typename F>
- void
- labeling_fastest<F>::pass_1()
- {
- mln_bkd_pixter(const I) p(f.input);
-
- typedef window<mln_dpsite(I)> W;
- W win = mln::convert::to_upper_window(f.nbh);
- mln_qixter(const I, W) n(p, win);
-
- for_all(p) if (f.handles(p))
- {
- f.init_attr(p);
- for_all(n)
- if (f.equiv(n, p))
- do_union(n, p);
- else
- f.do_no_union(n, p);
- }
- }
-
- template <typename F>
- void
- labeling_fastest<F>::pass_2()
- {
- mln_fwd_pixter(const I) p(f.input);
-
- for_all(p) if (f.handles(p))
- {
- if (is_root(p))
- {
- if (f.labels(p))
- {
- if (nlabels == mln_max(L))
- {
- status = false;
- return;
- }
- output(p) = ++nlabels;
- }
- }
- else
- output(p) = output(parent.element(p));
- }
- status = true;
- }
-
- template <typename F>
- bool
- labeling_fastest<F>::is_root(unsigned p) const
- {
- return parent.element(p) == p;
- }
-
- template <typename F>
- unsigned
- labeling_fastest<F>::find_root(unsigned x)
- {
- if (parent.element(x) == x)
- return x;
- else
- return parent.element(x) = find_root(parent.element(x));
- }
-
- template <typename F>
- void
- labeling_fastest<F>::do_union(unsigned n, unsigned p)
- {
- unsigned r = find_root(n);
- if (r != p)
- {
- parent.element(r) = p;
- f.merge_attr(r, p);
- }
- }
-
- */
-
-
-
// Dispatch.
namespace internal
1
0
https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Update Laurent's cleanup code.
* theo/esiee/laurent/ismm09/main.cc: Update.
* theo/esiee/jean/pfg3d.cc: Update.
* igr/images/s7.ppm: Remove image.
jean/pfg3d.cc | 2
laurent/ismm09/main.cc | 169 ++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 167 insertions(+), 4 deletions(-)
Index: theo/esiee/laurent/ismm09/main.cc
--- theo/esiee/laurent/ismm09/main.cc (revision 3230)
+++ theo/esiee/laurent/ismm09/main.cc (working copy)
@@ -2,6 +2,7 @@
#include <mln/core/var.hh>
#include <mln/core/image/image2d.hh>
+#include <mln/core/alias/neighb2d.hh>
#include <mln/make/double_neighb2d.hh>
#include <mln/core/image/image_if.hh>
@@ -15,8 +16,17 @@
#include <mln/data/fill.hh>
#include <mln/data/paste.hh>
+#include <mln/labeling/compute.hh>
+#include <mln/level/sort_psites.hh>
#include <mln/morpho/gradient.hh>
+#include <mln/morpho/meyer_wst.hh>
+#include <mln/morpho/tree/data.hh>
+#include <mln/morpho/tree/compute_attribute_image.hh>
+
+#include <mln/accu/count.hh>
+#include <mln/accu/height.hh>
+
namespace mln
@@ -109,6 +119,7 @@
}
+
image_if< image2d<value::int_u8>, predicate_t >
f_to_g(const image2d<value::int_u8>& f)
{
@@ -117,23 +128,138 @@
data::fill(f_, 0); // Useless but for display!
data__paste_values(f, (f_ | is_pixel).rw());
- debug::println(f_ | is_pixel);
mln_VAR(g, f_ | is_edge);
data::paste(morpho::gradient(extend(g, f_),
e2p().win()),
g);
- debug::println(g);
return g;
}
- } // end of namespace mln::face2
+ template <typename W>
+ image2d<mln_value(W)>
+ extend_w_edges_to_all_faces(W& w)
+ {
+ mln_VAR(w_ext, w.unmorph_());
+
+ // edges (1D-faces) -> pixels (2D-faces)
+ data::paste(morpho::dilation(extend(w_ext | is_pixel,
+ pw::value(w_ext)),
+ c4().win()),
+ w_ext);
+
+ // edges (1D-faces) -> points (0D-faces)
+ data::paste(morpho::erosion(extend(w_ext | is_point,
+ pw::value(w_ext)),
+ c4().win()),
+ w_ext);
+
+ return w_ext;
+ }
+
+
+ } // end of namespace mln::cplx2d
+
+
+ namespace internal
+ {
+
+ template <typename T>
+ struct node_pred : Function_p2b< node_pred<T> >
+ {
+ typedef bool result;
+
+ template <typename P>
+ bool operator()(const P& p) const
+ {
+ return t->is_a_node(p);
+ }
+
+ const T* t;
+ };
+
+ template <typename T, typename I, typename M>
+ mln_value(I) rec(const T& t, // tree
+ I& a, // attribute image
+ M& mark,
+ const mln_psite(I)& p)
+ {
+ mln_invariant(mark(p) == false);
+ mark(p) = true;
+ if (t.parent(p) == p || mark(t.parent(p)) == true) // Stop.
+ return a(p);
+ return a(p) = rec(t, a, mark, t.parent(p));
+ }
+
+ } // internal
+
+
+ template <typename T, typename A>
+ void
+ extinct_attributes(const T& t, // Tree.
+ A& a) // Attribute image.
+ {
+ mln_ch_value(A, bool) mark;
+ initialize(mark, a);
+ data::fill(mark, false);
+
+ internal::node_pred<T> node_only;
+ node_only.t = &t;
+
+ typedef p_array<mln_site(A)> S;
+ S s = level::sort_psites_increasing(a | node_only);
+
+ mln_fwd_piter(S) p(s);
+ for_all(p)
+ {
+ if (mark(p) == true)
+ continue;
+ internal::rec(t, a, mark, p);
+ }
+ }
+
+
+ template <typename F, typename N, typename A, typename W>
+ void // util::array<unsigned>
+ compute_attribute_extincted(const F& f, const N& nbh, const A& a,
+ const W& w)
+ {
+ typedef value::label_16 L;
+ L n_basins;
+ mln_ch_value(F,L) regmins = labeling::regional_minima(f, nbh, n_basins);
+
+ typedef p_array<mln_psite(F)> S;
+ S s = level::sort_psites_decreasing(f);
+
+ typedef morpho::tree::data<F,S> tree_t;
+ tree_t t(f, s, nbh);
+ mln_VAR(a_ima, morpho::tree::compute_attribute_image(a, t));
+
+ std::cout << "BEFORE:" << std::endl;
+ debug::println("a_ima:", a_ima);
+ debug::println("a_ima | w_line:", a_ima | (pw::value(w) == 0));
+ debug::println("a_ima | basins:", a_ima | (pw::value(w) != 0));
+ // debug::println("a_ima | regmins:", a_ima | (pw::value(regmins) != 0));
+
+
+ extinct_attributes(t, a_ima);
+
+ std::cout << "AFTER:" << std::endl;
+ debug::println("a_ima:", a_ima);
+ debug::println("a_ima | w_line:", a_ima | (pw::value(w) == 0));
+ debug::println("a_ima | basins:", a_ima | (pw::value(w) != 0));
+ debug::println("a_ima | regmins:", a_ima | (pw::value(regmins) != 0));
+ }
+
+
+
} // end of namespace mln
+
void usage(char* argv[])
{
std::cerr << "usage: " << argv[0] << " input.pgm echo output.pgm" << std::endl;
@@ -154,8 +280,45 @@
if (argc != 4)
usage(argv);
+ // f: regular image.
+
image2d<int_u8> f;
io::pgm::load(f, argv[1]);
+
+ // g: weights on edges.
+
mln_VAR(g, cplx2d::f_to_g(f) );
+ debug::println("g:", g);
+
+
+ // w: watershed labeling on edges.
+
+ typedef label_16 L;
+ L n_basins;
+ mln_VAR( w, morpho::meyer_wst(g, cplx2d::e2e(), n_basins) );
+
+ {
+ L n_regmins;
+ mln_VAR(regmins, labeling::regional_minima(g, cplx2d::e2e(), n_regmins));
+ mln_invariant(n_regmins == n_basins);
+ debug::println("regmins(g):", regmins);
+
+ debug::println("w:", w);
+ std::cout << "n basins = " << n_basins << std::endl
+ << std::endl;
+
+// mln_VAR(w_ext, cplx2d::extend_w_edges_to_all_faces(w));
+// debug::println("w_ext:", w_ext);
+
+// mln_VAR(is_line, pw::value(w_ext) == pw::cst(0));
+// debug::println("w line:", w_ext | is_line);
+ }
+
+ // accu::count< util::pix<g_t> > a_;
+ accu::height<g_t> a_;
+
+ compute_attribute_extincted(g, cplx2d::e2e(), a_,
+ w);
+
}
Index: theo/esiee/jean/pfg3d.cc
--- theo/esiee/jean/pfg3d.cc (revision 3230)
+++ theo/esiee/jean/pfg3d.cc (working copy)
@@ -70,7 +70,7 @@
{
using namespace mln;
- box3d b = make::box3d(-1,1, -1,1, -1,1);
+ box3d b = make::box3d(-1,-1,-1, +1,+1,+1);
image3d<unsigned> ima(b);
debug::iota(ima);
debug::println(ima);
1
0
30 Jan '09
https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Make the fastest version for the algebraic morpho canvas work.
* mln/level/sort_offsets.hh: New.
* mln/level/all.hh: Update.
* mln/morpho/closing_attribute.hh
(closing_attribute_fastest_functor_t): Update.
* mln/canvas/morpho/algebraic_union_find.hh
(algebraic_union_find_fastest): Update.
canvas/morpho/algebraic_union_find.hh | 71 +++----
level/all.hh | 1
level/sort_offsets.hh | 337 ++++++++++++++++++++++++++++++++++
morpho/closing_attribute.hh | 5
4 files changed, 377 insertions(+), 37 deletions(-)
Index: mln/level/all.hh
--- mln/level/all.hh (revision 3229)
+++ mln/level/all.hh (working copy)
@@ -66,6 +66,7 @@
# include <mln/level/replace.hh>
# include <mln/level/saturate.hh>
# include <mln/level/sort_psites.hh>
+# include <mln/level/sort_offsets.hh>
# include <mln/level/stretch.hh>
# include <mln/level/to_enc.hh>
# include <mln/level/transform.hh>
Index: mln/level/sort_offsets.hh
--- mln/level/sort_offsets.hh (revision 0)
+++ mln/level/sort_offsets.hh (revision 0)
@@ -0,0 +1,337 @@
+// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
+// (LRDE)
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library 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 this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library 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_LEVEL_SORT_OFFSETS_HH
+# define MLN_LEVEL_SORT_OFFSETS_HH
+
+/// \file mln/level/sort_offsets.hh
+/// \brief Sort_Offsets the contents of an image into another one.
+///
+/// \todo Factor code + optimize.
+
+# include <algorithm>
+
+# include <mln/core/concept/image.hh>
+# include <mln/histo/compute.hh>
+# include <mln/util/array.hh>
+# include <mln/util/ord.hh>
+# include <mln/geom/nsites.hh>
+
+
+namespace mln
+{
+
+ namespace level
+ {
+
+ /// Sort pixel offsets of the image \p input wrt increasing pixel
+ /// values.
+ ///
+ template <typename I>
+ util::array<unsigned>
+ sort_offsets_increasing(const Image<I>& input);
+
+
+ // /// Sort pixel offsets of the image \p input wrt decreasing pixel
+ // /// values.
+ // ///
+ // template <typename I>
+ // util::array<unsigned>
+ // sort_offsets_decreasing(const Image<I>& input);
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace impl
+ {
+
+ namespace generic
+ {
+
+ // increasing
+
+ template <typename I>
+ struct value_offset_less_
+ {
+ const I& ima_;
+ inline value_offset_less_(const I& ima) : ima_(ima) {}
+ inline bool operator()(unsigned lhs, unsigned rhs) const
+ {
+ return util::ord_strict(ima_.element(lhs), ima_.element(rhs))
+ || (ima_.element(lhs) == ima_.element(rhs)
+ &&
+ lhs < rhs);
+ }
+ };
+
+ template <typename I>
+ inline
+ util::array<unsigned>
+ sort_offsets_increasing(const Image<I>& input_)
+ {
+ trace::entering("level::impl::generic::sort_offsets_increasing");
+
+ const I& input = exact(input_);
+
+ util::array<unsigned> v;
+ v.reserve(input.nelements());
+ mln_fwd_pixter(const I) pxl(input);
+ for_all(pxl)
+ v.append(pxl.offset());
+ std::sort(v.hook_std_vector_().begin(), v.hook_std_vector_().end(),
+ value_offset_less_<I>(input));
+
+ trace::exiting("level::impl::generic::sort_offsets_increasing");
+ return v;
+ }
+
+
+ // decreasing
+
+ template <typename I>
+ struct value_offset_greater_
+ {
+ const I& ima_;
+ inline value_offset_greater_(const I& ima) : ima_(ima) {}
+ inline bool operator()(unsigned lhs, unsigned rhs) const
+ {
+ return util::ord_strict(ima_.element(rhs), ima_.element(lhs))
+ || (ima_.element(lhs) == ima_.element(rhs)
+ &&
+ lhs > rhs);
+ }
+ };
+
+ template <typename I>
+ inline
+ util::array<unsigned>
+ sort_offsets_decreasing(const Image<I>& input_)
+ {
+ trace::entering("level::impl::generic::sort_offsets_decreasing");
+
+ const I& input = exact(input_);
+
+ util::array<unsigned> v;
+ v.reserve(input.nelements());
+ mln_fwd_pixter(const I) pxl(input);
+ for_all(pxl)
+ v.append(pxl.offset());
+ std::sort(v.hook_std_vector_().begin(), v.hook_std_vector_().end(),
+ value_offset_greater_<I>(input));
+
+ trace::exiting("level::impl::generic::sort_offsets_decreasing");
+ return v;
+ }
+
+
+ } // end of namespace mln::level::impl::generic
+
+
+
+ // increasing
+
+ template <typename I>
+ inline
+ util::array<unsigned>
+ sort_offsets_increasing_radix(const Image<I>& input_)
+ {
+ trace::entering("level::impl::sort_offsets_increasing_radix");
+
+ const I& input = exact(input_);
+
+ typedef mln_vset(I) S;
+ const S& vset = input.values_eligible();
+ const unsigned n = vset.nvalues();
+
+ // h
+ histo::array<mln_value(I)> h = histo::compute(input);
+
+ // preparing output data
+ std::vector<unsigned> loc(vset.nvalues());
+ loc[0] = 0;
+ for (unsigned i = 1; i != n; ++i)
+ loc[i] = loc[i-1] + h[i-1];
+
+ // computing output data
+ util::array<unsigned> vec(geom::nsites(input));
+ mln_fwd_pixter(const I) pxl(input);
+ for_all(pxl)
+ vec[loc[vset.index_of(pxl.val())]++] = pxl.offset();
+
+ trace::exiting("level::impl::sort_offsets_increasing_radix");
+ return vec;
+ }
+
+
+ // decreasing
+
+ template <typename I>
+ inline
+ util::array<unsigned>
+ sort_offsets_decreasing_radix(const Image<I>& input_)
+ {
+ trace::entering("level::impl::sort_offsets_decreasing_radix");
+
+ const I& input = exact(input_);
+
+ typedef mln_vset(I) S;
+ const S& vset = input.values_eligible();
+ const unsigned n = vset.nvalues();
+
+ // h
+ histo::array<mln_value(I)> h = histo::compute(input);
+
+ // preparing output data
+ std::vector<unsigned> loc(vset.nvalues());
+ loc[n-1] = 0;
+ for (int i = n - 2; i >= 0; --i)
+ loc[i] = loc[i+1] + h[i+1];
+
+ // computing output data
+ util::array<unsigned> vec(geom::nsites(input));
+ mln_fwd_pixter(const I) pxl(input);
+ for_all(pxl)
+ vec[loc[vset.index_of(pxl.val())]++] = pxl.offset();
+
+ trace::exiting("level::impl::sort_offsets_decreasing_radix");
+ return vec;
+ }
+
+
+ } // end of namespace mln::level::impl
+
+
+
+ namespace internal
+ {
+
+ // increasing
+
+ template <typename I>
+ inline
+ util::array<unsigned>
+ sort_offsets_increasing_dispatch(trait::image::quant::any,
+ const Image<I>& input)
+ {
+ return impl::generic::sort_offsets_increasing(input);
+ }
+
+ template <typename I>
+ inline
+ util::array<unsigned>
+ sort_offsets_increasing_dispatch(trait::image::quant::low,
+ const Image<I>& input)
+ {
+ return impl::sort_offsets_increasing_radix(input);
+ }
+
+ template <typename I>
+ inline
+ util::array<unsigned>
+ sort_offsets_increasing_dispatch(const Image<I>& input)
+ {
+ return sort_offsets_increasing_dispatch(mln_trait_image_quant(I)(),
+ input);
+ }
+
+ // decreasing
+
+ template <typename I>
+ inline
+ util::array<unsigned>
+ sort_offsets_decreasing_dispatch(trait::image::quant::any,
+ const Image<I>& input)
+ {
+ return impl::generic::sort_offsets_decreasing(input);
+ }
+
+ template <typename I>
+ inline
+ util::array<unsigned>
+ sort_offsets_decreasing_dispatch(trait::image::quant::low,
+ const Image<I>& input)
+ {
+ return impl::sort_offsets_decreasing_radix(input);
+ }
+
+ template <typename I>
+ inline
+ util::array<unsigned>
+ sort_offsets_decreasing_dispatch(const Image<I>& input)
+ {
+ return sort_offsets_decreasing_dispatch(mln_trait_image_quant(I)(),
+ input);
+ }
+
+ } // end of namespace mln::level::internal
+
+
+
+ // Facades.
+
+ template <typename I>
+ inline
+ util::array<unsigned>
+ sort_offsets_increasing(const Image<I>& input)
+ {
+ trace::entering("level::sort_offsets_increasing");
+ mlc_is(mln_trait_image_speed(I),
+ trait::image::speed::fastest)::check();
+
+ mln_precondition(exact(input).is_valid());
+ util::array<unsigned> output = internal::sort_offsets_increasing_dispatch(input);
+
+ trace::exiting("level::sort_offsets_increasing");
+ return output;
+ }
+
+ template <typename I>
+ inline
+ util::array<unsigned>
+ sort_offsets_decreasing(const Image<I>& input)
+ {
+ trace::entering("level::sort_offsets_decreasing");
+ mlc_is(mln_trait_image_speed(I),
+ trait::image::speed::fastest)::check();
+
+ mln_precondition(exact(input).is_valid());
+ util::array<unsigned> output = internal::sort_offsets_decreasing_dispatch(input);
+
+ trace::exiting("level::sort_offsets_decreasing");
+ return output;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::level
+
+} // end of namespace mln
+
+
+#endif // ! MLN_LEVEL_SORT_OFFSETS_HH
Index: mln/morpho/closing_attribute.hh
--- mln/morpho/closing_attribute.hh (revision 3229)
+++ mln/morpho/closing_attribute.hh (working copy)
@@ -40,6 +40,7 @@
# include <mln/morpho/includes.hh>
# include <mln/canvas/morpho/algebraic_union_find.hh>
# include <mln/level/sort_psites.hh>
+# include <mln/level/sort_offsets.hh>
# include <mln/util/pix.hh>
@@ -144,7 +145,7 @@
typedef A_ A;
typedef mln_psite(I) P;
- typedef p_array<P> S;
+ typedef util::array<unsigned> S;
mln_result(A) lambda;
const S s;
@@ -168,7 +169,7 @@
closing_attribute_fastest_functor_t(const Image<I>& input, mln_result(A) lambda)
: lambda(lambda),
- s(level::sort_psites_increasing(exact(input)))
+ s(level::sort_offsets_increasing(exact(input)))
{
}
Index: mln/canvas/morpho/algebraic_union_find.hh
--- mln/canvas/morpho/algebraic_union_find.hh (revision 3229)
+++ mln/canvas/morpho/algebraic_union_find.hh (working copy)
@@ -214,7 +214,7 @@
if (parent.element(x) == x)
return x;
else
- return parent.element(x) = find_root(parent, parent.element(x));
+ return parent.element(x) = find_root_fastest(parent, parent.element(x));
}
@@ -260,63 +260,64 @@
}
util::array<int> dp = offsets_wrt(input, nbh);
- for (unsigned i = 0; i < dp.nelements(); ++i)
- std::cout << dp[i] << ' ';
- std::cout << std::endl;
+ const unsigned n_nbhs = dp.nelements();
- /*
+ const util::array<unsigned>& s = f.s;
+ const unsigned n_points = s.nelements();
// First pass.
{
- for (unsigned p = 0; p < f.s.size(); ++p)
- mln_niter(N) n(nbh, p);
- for_all(p)
+
+ for (unsigned i = 0; i < n_points; ++i)
{
+ unsigned p = s[i]; // An offset.
+
// Make set.
- {
- parent(p) = p;
- data(p).take_as_init(make::pix(input, p)); // FIXME: algebraic so p!
- }
+ parent.element(p) = p;
+ data.element(p).take_as_init( input.element(p) ); // FIXME: Very bad!!!
- for_all(n)
- if (input.domain().has(n) && deja_vu(n))
+ for (unsigned j = 0; j < n_nbhs; ++j)
{
- P r = find_root(parent, n);
+ unsigned n = p + dp[j];
+ if (! deja_vu.element(n))
+ continue;
+
+ unsigned r = find_root_fastest(parent, n);
if (r != p)
{
- if (input(r) == input(p) || (activity(r) && f.is_active(data(r))))
- {
- data(p).take(data(r));
- parent(r) = p;
- if (activity(r) == false)
- activity(p) = false;
+ if (input.element(r) == input.element(p)
+ || (activity.element(r)
+ && f.is_active(data.element(r))))
+ {
+ data.element(p).take(data.element(r));
+ parent.element(r) = p;
+ if (activity.element(r) == false)
+ activity.element(p) = false;
}
else
{
- activity(p) = false;
- f.inactivate(data(p));
- }
+ activity.element(p) = false;
+ f.inactivate(data.element(p));
}
}
- deja_vu(p) = true;
- }
}
- */
+ deja_vu.element(p) = true;
+ }
- /*
+ }
// Second pass.
{
- mln_bkd_piter(S) p(f.s);
- for_all(p)
- if (parent(p) == p) // p is root.
- output(p) = input(p);
+ for (int i = n_points - 1; i >= 0 ; --i)
+ {
+ unsigned p = s[i];
+ if (parent.element(p) == p) // p is root.
+ output.element(p) = input.element(p);
else
- output(p) = output(parent(p));
+ output.element(p) = output.element(parent.element(p));
+ }
}
-
- */
trace::exiting("canvas::morpho::impl::algebraic_union_find_fastest");
return output;
1
0
https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Fix repeated loops with pixel iterators.
* mln/core/image/image2d.hh (todo): New.
* mln/core/pixter2d.hh (start_): New.
Upgrade file doc style.
Layout.
* mln/core/pixter3d.hh: Likewise.
* mln/core/dpoints_pixter.hh (todo): New.
* mln/core/internal/pixel_iterator_base.hh:
Upgrade file doc style.
(start_): New; default impl is no-op.
(start): Call start_.
* mln/core/internal/pixel_impl.hh (todo): New.
(pixel_impl_base_): New.
(image_, value_ptr_): Move from pixel_impl_ to
pixel_impl_base_.
* mln/core/pixel.hh: Upgrade file doc style.
(todo): New.
* mln/util/pix.hh (todo): New.
Misc.
* mln/core/concept/window.hh (offsets_wrt): New.
* mln/core/concept/neighborhood.hh: Likewise.
* mln/morpho/closing_attribute.hh: Update.
* mln/morpho/opening_attribute.hh: Update.
* mln/canvas/morpho/algebraic_union_find.hh: Update.
canvas/morpho/algebraic_union_find.hh | 159 ++++++++++++++++++++++++++++++++--
core/concept/neighborhood.hh | 32 ++++++
core/concept/window.hh | 32 ++++++
core/dpoints_pixter.hh | 2
core/image/image2d.hh | 3
core/internal/pixel_impl.hh | 115 +++++++++++++++++++++---
core/internal/pixel_iterator_base.hh | 24 ++++-
core/pixel.hh | 14 +-
core/pixter2d.hh | 40 +++++++-
core/pixter3d.hh | 73 ++++++++++++---
morpho/closing_attribute.hh | 149 ++++++++++++++++++++++++++++++-
morpho/opening_attribute.hh | 2
util/pix.hh | 7 +
13 files changed, 598 insertions(+), 54 deletions(-)
Index: mln/core/image/image2d.hh
--- mln/core/image/image2d.hh (revision 3228)
+++ mln/core/image/image2d.hh (working copy)
@@ -33,6 +33,9 @@
/// Definition of the basic mln::image2d class.
///
/// \todo Re-activate include at EOF when make::image2d is up again.
+///
+/// \todo Rename delta_index and point_at_index as offset and
+/// point_at_offset.
# include <mln/core/internal/image_primary.hh>
# include <mln/core/internal/fixme.hh>
Index: mln/core/pixter2d.hh
--- mln/core/pixter2d.hh (revision 3228)
+++ mln/core/pixter2d.hh (working copy)
@@ -30,7 +30,8 @@
# define MLN_CORE_PIXTER2D_HH
/// \file mln/core/pixter2d.hh
-/// \brief Pixel iterators on a 2-D image with border.
+///
+/// Pixel iterators on a 2D image with border.
# include <mln/core/internal/pixel_iterator_base.hh>
# include <mln/core/alias/point2d.hh>
@@ -62,13 +63,21 @@
/// Go to the next pixel.
void next_();
+ /// Extra code for start().
+ void start_();
+
private:
+
/// Twice the size of the image border.
unsigned border_x2_;
+
/// Row offset.
unsigned row_offset_;
+
/// End of the current row.
mln_qlf_value(I)* eor_;
+
+ using super_::image_;
};
@@ -94,14 +103,21 @@
/// Go to the next pixel.
void next_();
+ /// Extra code for start().
+ void start_();
+
private:
/// Twice the size of the image border.
unsigned border_x2_;
+
/// Row offset.
unsigned row_offset_;
+
/// Beginning of the current row.
mln_qlf_value(I)* bor_;
+
+ using super_::image_;
};
@@ -117,8 +133,7 @@
fwd_pixter2d<I>::fwd_pixter2d(I& image)
: super_(image),
border_x2_(2 * image.border()),
- row_offset_(image.bbox().ncols() + border_x2_),
- eor_(& opt::at(image, geom::min_row(image), geom::max_col(image)) + 1)
+ row_offset_(image.bbox().ncols() + border_x2_)
{
mln_precondition(image.is_valid());
}
@@ -136,6 +151,14 @@
}
}
+ template <typename I>
+ inline
+ void
+ fwd_pixter2d<I>::start_()
+ {
+ eor_ = & opt::at(image_, geom::min_row(image_), geom::max_col(image_)) + 1;
+ }
+
/*------------------.
| fwd_pixter2d<I>. |
@@ -146,8 +169,7 @@
bkd_pixter2d<I>::bkd_pixter2d(I& image)
: super_(image),
border_x2_(2 * image.border()),
- row_offset_(image.bbox().ncols() + border_x2_),
- bor_(& opt::at(image, geom::max_row(image), geom::min_col(image)) - 1)
+ row_offset_(image.bbox().ncols() + border_x2_)
{
mln_precondition(image.is_valid());
}
@@ -165,6 +187,14 @@
}
}
+ template <typename I>
+ inline
+ void
+ bkd_pixter2d<I>::start_()
+ {
+ bor_ = & opt::at(image_, geom::max_row(image_), geom::min_col(image_)) - 1;
+ }
+
#endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln
Index: mln/core/pixter3d.hh
--- mln/core/pixter3d.hh (revision 3228)
+++ mln/core/pixter3d.hh (working copy)
@@ -30,13 +30,15 @@
# define MLN_CORE_PIXTER3D_HH
/// \file mln/core/pixter3d.hh
-/// \brief Pixel iterators on a 3-D image with border.
+///
+/// Pixel iterators on a 3D image with border.
# include <mln/core/internal/pixel_iterator_base.hh>
# include <mln/core/alias/point3d.hh>
# include <mln/geom/size3d.hh>
# include <mln/opt/at.hh>
+
namespace mln
{
@@ -62,22 +64,33 @@
/// Go to the next pixel.
void next_();
+ /// Extra code for start().
+ void start_();
+
private:
+
/// Twice the size of the image border.
const unsigned border_x2_;
+
/// Row offset.
const unsigned row_offset_;
+
/// End of the current row.
mln_qlf_value(I)* eor_;
/// Next slice offset.
const unsigned next_sli_offset_;
+
/// Next slice offset for row.
const unsigned next_srow_offset_;
+
/// Slice offset.
const unsigned sli_offset_;
+
/// End of the current slice.
mln_qlf_value(I)* eos_;
+
+ using super_::image_;
};
@@ -103,22 +116,33 @@
/// Go to the next pixel.
void next_();
+ /// Extra code for start().
+ void start_();
+
private:
+
/// Twice the size of the image border.
const unsigned border_x2_;
+
/// Row offset.
const unsigned row_offset_;
+
/// Beginning of the current row.
mln_qlf_value(I)* bor_;
/// Next slice offset.
const unsigned next_sli_offset_;
+
/// Next slice offset for row.
const unsigned next_srow_offset_;
+
/// Slice offset.
const unsigned sli_offset_;
+
/// Beginning of the current slice.
mln_qlf_value(I)* bos_;
+
+ using super_::image_;
};
@@ -134,16 +158,10 @@
: super_(image),
border_x2_(2 * image.border()),
row_offset_(image.bbox().ncols() + border_x2_),
- eor_(& opt::at(image, geom::min_sli(image),
- geom::min_row(image),
- geom::max_col(image)) + 1),
next_sli_offset_(row_offset_ * border_x2_ + border_x2_),
next_srow_offset_(next_sli_offset_ + image.bbox().ncols()),
sli_offset_((image.bbox().ncols() + border_x2_) *
- (image.bbox().nrows() + border_x2_)),
- eos_(& opt::at(image, geom::min_sli(image),
- geom::max_row(image),
- geom::max_col(image)) + 1)
+ (image.bbox().nrows() + border_x2_))
{
mln_precondition(image.is_valid());
}
@@ -151,6 +169,21 @@
template <typename I>
inline
void
+ fwd_pixter3d<I>::start_()
+ {
+ eor_ = & opt::at(image_,
+ geom::min_sli(image_),
+ geom::min_row(image_),
+ geom::max_col(image_)) + 1;
+ eos_ = & opt::at(image_,
+ geom::min_sli(image_),
+ geom::max_row(image_),
+ geom::max_col(image_)) + 1;
+ }
+
+ template <typename I>
+ inline
+ void
fwd_pixter3d<I>::next_()
{
++this->value_ptr_;
@@ -178,16 +211,10 @@
: super_(image),
border_x2_(2 * image.border()),
row_offset_(image.bbox().ncols() + border_x2_),
- bor_(& opt::at(image, geom::max_sli(image),
- geom::max_row(image),
- geom::min_col(image)) - 1),
next_sli_offset_(row_offset_ * border_x2_ + border_x2_),
next_srow_offset_(next_sli_offset_ + image.bbox().ncols()),
sli_offset_((image.bbox().ncols() + border_x2_) *
- (image.bbox().nrows() + border_x2_)),
- bos_(& opt::at(image, geom::max_sli(image),
- geom::min_row(image),
- geom::min_col(image)) - 1)
+ (image.bbox().nrows() + border_x2_))
{
mln_precondition(image.is_valid());
}
@@ -195,6 +222,21 @@
template <typename I>
inline
void
+ bkd_pixter3d<I>::start_()
+ {
+ bor_ = & opt::at(image_,
+ geom::max_sli(image_),
+ geom::max_row(image_),
+ geom::min_col(image_)) - 1;
+ bos_ = & opt::at(image_,
+ geom::max_sli(image_),
+ geom::min_row(image_),
+ geom::min_col(image_)) - 1;
+ }
+
+ template <typename I>
+ inline
+ void
bkd_pixter3d<I>::next_()
{
--this->value_ptr_;
@@ -215,4 +257,5 @@
} // end of namespace mln
+
#endif // ! MLN_CORE_PIXTER3D_HH
Index: mln/core/dpoints_pixter.hh
--- mln/core/dpoints_pixter.hh (revision 3228)
+++ mln/core/dpoints_pixter.hh (working copy)
@@ -33,6 +33,8 @@
///
/// \brief Definition of forward and backward mln::dpoint-based
/// iterators for pixels iterations.
+///
+/// \todo In ::init_ use offsets_wrt (defined in concept/window.hh).
# include <cassert>
# include <vector>
Index: mln/core/internal/pixel_iterator_base.hh
--- mln/core/internal/pixel_iterator_base.hh (revision 3228)
+++ mln/core/internal/pixel_iterator_base.hh (working copy)
@@ -30,12 +30,14 @@
# define MLN_CORE_INTERNAL_PIXEL_ITERATOR_BASE_HH
/// \file mln/core/internal/pixel_iterator_base.hh
-/// \brief Base classes factoring code for pixel iterator classes.
+///
+/// Base classes factoring code for pixel iterator classes.
# include <mln/core/concept/pixel_iterator.hh>
# include <mln/core/internal/pixel_impl.hh>
# include <mln/core/trait/qlf_value.hh>
+
namespace mln
{
@@ -58,10 +60,15 @@
pixel_iterator_base_(I& image);
protected:
+
/// Beginning of the image.
mln_qlf_value(I)* boi_;
+
/// End of the image (past-the-end).
mln_qlf_value(I)* eoi_;
+
+ /// Default impl is no-op.
+ void start_();
};
@@ -76,6 +83,7 @@
typedef pixel_iterator_base_<I, E> super_;
public:
+
/// Manipulation
/// \{
/// Start an iteration.
@@ -87,6 +95,7 @@
/// \}
protected:
+
/// Constructor.
forward_pixel_iterator_base_(I& image);
};
@@ -114,13 +123,16 @@
/// \}
protected:
+
/// Constructor.
backward_pixel_iterator_base_(I& image);
};
+
#ifndef MLN_INCLUDE_ONLY
+
/*---------------------------------------.
| internal::pixel_iterator_base_<I, E>. |
`---------------------------------------*/
@@ -137,6 +149,14 @@
exact(*this).invalidate();
}
+ template <typename I, typename E>
+ inline
+ void
+ pixel_iterator_base_<I, E>::start_()
+ {
+ // Default impl is no-op.
+ }
+
/*-----------------------------------------------.
| internal::forward_pixel_iterator_base_<I, E>. |
@@ -155,6 +175,7 @@
forward_pixel_iterator_base_<I, E>::start()
{
this->value_ptr_ = this->boi_ + 1;
+ exact(this)->start_();
}
template <typename I, typename E>
@@ -191,6 +212,7 @@
backward_pixel_iterator_base_<I, E>::start()
{
this->value_ptr_ = this->eoi_ - 1;
+ exact(this)->start_();
}
template <typename I, typename E>
Index: mln/core/internal/pixel_impl.hh
--- mln/core/internal/pixel_impl.hh (revision 3228)
+++ mln/core/internal/pixel_impl.hh (working copy)
@@ -1,4 +1,5 @@
-// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
+// (LRDE)
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -32,9 +33,13 @@
///
/// Define a couple of implementation classes to provide methods
/// to classes of generalized pixels.
+///
+/// \todo Clean-up code.
# include <mln/core/concept/image.hh>
# include <mln/core/internal/force_exact.hh>
+# include <mln/util/pix.hh>
+
namespace mln
@@ -43,11 +48,83 @@
namespace internal
{
+ // We indeed have to handle the couple of cases when I is fastest
+ // or is not. Justification: mln::pixel derives from pixel_impl_
+ // and is a general purpose pixel class; it can be used on any
+ // image whatever it is a fastest one or not.
+
+ template <bool is_fastest, typename I, typename E>
+ class pixel_impl_base_;
+
+
+ template <typename I, typename E>
+ struct pixel_impl_base_< false, I, E > // I is not fastest.
+ {
+ typedef mlc_if(mlc_is_const(I), const mln_value(I), mln_value(I)) value_ptr_t;
+
+ pixel_impl_base_(I& image, value_ptr_t* value_ptr)
+ : image_(image),
+ value_ptr_(value_ptr)
+ {
+ }
+
+ protected:
+
+ /// Image associated to the iterator
+ I& image_;
+
+ /// Current pixel / value
+ value_ptr_t* value_ptr_;
+ };
+
+
+ template <typename I, typename E>
+ struct pixel_impl_base_< true, I, E > // I is fastest => extra interface.
+ {
+ typedef mlc_if(mlc_is_const(I), const mln_value(I), mln_value(I)) value_ptr_t;
+ typedef mlc_unconst(I) unconst_image_t;
+
+ pixel_impl_base_(I& image, value_ptr_t* value_ptr)
+ : image_(image),
+ value_ptr_(value_ptr)
+ {
+ }
+
+ unsigned offset() const
+ {
+ return value_ptr_ - image_.buffer();
+ }
+
+ operator util::pix<unconst_image_t>() const
+ {
+ util::pix<unconst_image_t> tmp(image_, image_.point_at_index(offset()));
+ return tmp;
+ }
+
+ protected:
+
+ /// Image associated to the iterator.
+ I& image_;
+
+ /// Current pixel / value.
+ value_ptr_t* value_ptr_;
+ };
+
+
/// Implementation class to equip generalized pixel
/// classes based on mutable images.
+ ///
template <typename I, typename E>
class pixel_impl_
- {
+
+ : public pixel_impl_base_< mlc_is(mln_trait_image_speed(I),
+ trait::image::speed::fastest)::value,
+ I, E >
+ {
+ typedef pixel_impl_base_< mlc_is(mln_trait_image_speed(I),
+ trait::image::speed::fastest)::value,
+ I, E > super_;
+
public:
/// Image type.
@@ -79,11 +156,11 @@
protected:
- /// Image associated to the iterator
- I& image_;
+ /// Image associated to the iterator.
+ using super_::image_;
- /// Current pixel / value
- value* value_ptr_;
+ /// Current pixel / value.
+ using super_::value_ptr_;
/// Constructor
pixel_impl_(I& image);
@@ -95,9 +172,18 @@
/// Implementation class to equip generalized pixel
/// classes based on constant images.
+ ///
template <typename I, typename E>
class pixel_impl_< const I, E >
- {
+
+ : public pixel_impl_base_< mlc_is(mln_trait_image_speed(I),
+ trait::image::speed::fastest)::value,
+ const I, E >
+ {
+ typedef pixel_impl_base_< mlc_is(mln_trait_image_speed(I),
+ trait::image::speed::fastest)::value,
+ const I, E > super_;
+
public:
/// Image type.
@@ -121,13 +207,14 @@
/// Address of the current iterator value/pixel.
const value** address_() const;
+
protected:
- /// Image associated to the iterator
- const I& image_;
+ /// Image associated to the iterator.
+ using super_::image_;
- /// Current pixel / value
- const value* value_ptr_;
+ /// Current pixel / value.
+ using super_::value_ptr_;
/// Constructor
pixel_impl_(const I& image);
@@ -152,8 +239,7 @@
template <typename I, typename E>
inline
pixel_impl_<I, E>::pixel_impl_(I& image) :
- image_(image),
- value_ptr_(0)
+ super_(image, 0)
{
}
@@ -206,8 +292,7 @@
template <typename I, typename E>
inline
pixel_impl_<const I, E>::pixel_impl_(const I& image) :
- image_(image),
- value_ptr_(0)
+ super_(image, 0)
{
}
Index: mln/core/pixel.hh
--- mln/core/pixel.hh (revision 3228)
+++ mln/core/pixel.hh (working copy)
@@ -1,4 +1,5 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
+// (LRDE)
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -28,10 +29,13 @@
#ifndef MLN_CORE_PIXEL_HH
# define MLN_CORE_PIXEL_HH
-/*! \file mln/core/pixel.hh
- *
- * \brief Definition of the generic pixel class mln::pixel.
- */
+/// \file mln/core/pixel.hh
+///
+/// Definition of the generic pixel class mln::pixel.
+///
+/// \todo Answer these questions:
+/// - why do we have 2 classes (mln::pixel and mln::util::pix)?
+/// - what about keeping only one of both?
# include <mln/core/concept/generalized_pixel.hh>
# include <mln/core/internal/pixel_impl.hh>
Index: mln/core/concept/window.hh
--- mln/core/concept/window.hh (revision 3228)
+++ mln/core/concept/window.hh (working copy)
@@ -46,6 +46,7 @@
# include <mln/core/site_set/p_array.hh>
# include <mln/core/internal/geom_bbox.hh> // For use in convert::from_to.
# include <mln/convert/from_to.hxx>
+# include <mln/util/array.hh>
@@ -70,8 +71,9 @@
namespace mln
{
- // Forward declaration.
+ // Forward declarations.
template <typename E> struct Window;
+ template <typename E> struct Image;
// Window category flag type.
@@ -114,6 +116,12 @@
std::ostream& operator<<(std::ostream& ostr, const Window<W>& win);
+ // FIXME: Move as a method of Image?
+ template <typename I, typename W>
+ util::array<int>
+ offsets_wrt(const Image<I>& ima, const Window<W>& win);
+
+
namespace convert
{
@@ -309,6 +317,28 @@
}
+ template <typename I, typename W>
+ inline
+ util::array<int>
+ offsets_wrt(const Image<I>& ima_, const Window<W>& win_)
+ {
+ mln_is_simple_window(W)::check();
+
+ const I& ima = exact(ima_);
+ const W& win = exact(win_);
+ mln_precondition(ima.is_valid());
+ // mln_precondition(win.is_valid());
+
+ util::array<int> arr;
+ unsigned n = win.size();
+
+ for (unsigned i = 0; i < n; ++i)
+ arr.append(ima.delta_index(win.dp(i)));
+
+ return arr;
+ }
+
+
namespace convert
{
Index: mln/core/concept/neighborhood.hh
--- mln/core/concept/neighborhood.hh (revision 3228)
+++ mln/core/concept/neighborhood.hh (working copy)
@@ -33,14 +33,21 @@
///
/// Definition of the concept of mln::Neighborhood.
-# include <mln/core/concept/object.hh>
+# include <mln/core/concept/window.hh>
# include <mln/trait/windows.hh>
+
+# define mln_is_simple_neighborhood(N) mln_is_simple_window(mln_window(N))
+
+
+
+
namespace mln
{
- // Fwd decl.
+
+ // Forward declaration.
template <typename E> struct Neighborhood;
@@ -90,6 +97,12 @@
operator<<(std::ostream&ostr, const Neighborhood<N>& nbh);
+ // FIXME: Move as a method of Image?
+ template <typename I, typename N>
+ util::array<int>
+ offsets_wrt(const Image<I>& ima, const Neighborhood<N>& nbh);
+
+
# ifndef MLN_INCLUDE_ONLY
@@ -129,6 +142,21 @@
return ostr << exact(nbh).win();
}
+ template <typename I, typename N>
+ inline
+ util::array<int>
+ offsets_wrt(const Image<I>& ima_, const Neighborhood<N>& nbh_)
+ {
+ mln_is_simple_neighborhood(N)::check();
+
+ const I& ima = exact(ima_);
+ const N& nbh = exact(nbh_);
+ mln_precondition(ima.is_valid());
+ // mln_precondition(nbh.is_valid());
+
+ return offsets_wrt(ima, nbh.win());
+ }
+
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln
Index: mln/morpho/closing_attribute.hh
--- mln/morpho/closing_attribute.hh (revision 3228)
+++ mln/morpho/closing_attribute.hh (working copy)
@@ -34,6 +34,8 @@
/// Morphological attribute closing.
///
/// \todo How to pass dynamic data (e.g., k of accu::rank) to the routine?
+///
+/// \todo Add extension::adjust_fill.
# include <mln/morpho/includes.hh>
# include <mln/canvas/morpho/algebraic_union_find.hh>
@@ -57,11 +59,20 @@
# ifndef MLN_INCLUDE_ONLY
+
+ // Implementations.
+
namespace impl
{
+
+ // Generic version.
+
+ namespace generic
+ {
+
template <typename I, typename A_>
- struct closing_attribute_t
+ struct closing_attribute_functor_t
{
// requirements from mln::canvas::morpho::algebraic_union_find
@@ -89,7 +100,7 @@
// end of requirements
- closing_attribute_t(const Image<I>& input, mln_result(A) lambda)
+ closing_attribute_functor_t(const Image<I>& input, mln_result(A) lambda)
: lambda(lambda),
s(level::sort_psites_increasing(exact(input)))
{
@@ -97,10 +108,137 @@
};
+
+ template <typename A, typename I, typename N>
+ inline
+ mln_concrete(I)
+ closing_attribute(const Image<I>& input, const Neighborhood<N>& nbh,
+ mln_result(A) lambda)
+ {
+ trace::entering("morpho::impl::generic::closing_attribute");
+
+ mln_precondition(exact(input).is_valid());
+
+ typedef closing_attribute_functor_t<I, A> F;
+ F f(input, lambda);
+ mln_concrete(I) output = canvas::morpho::impl::generic::algebraic_union_find(input, nbh, f);
+
+ mln_postcondition(output >= input);
+
+ trace::exiting("morpho::impl::generic::closing_attribute");
+ return output;
+ }
+
+
+ } // end of namespace mln::morpho::impl::generic
+
+
+
+ // "Fastest" version.
+
+
+ template <typename I, typename A_>
+ struct closing_attribute_fastest_functor_t
+ {
+ // requirements from mln::canvas::morpho::algebraic_union_find
+
+ typedef A_ A;
+ typedef mln_psite(I) P;
+ typedef p_array<P> S;
+
+ mln_result(A) lambda;
+ const S s;
+
+ void init()
+ {
+ // FIXME: border::fill(input, mln_max(mln_value(I)));
+ }
+
+ bool is_active(const A& attr) const
+ {
+ return attr.to_result() < lambda;
+ }
+
+ void inactivate(A& attr)
+ {
+ attr.set_value(lambda);
+ }
+
+ // end of requirements
+
+ closing_attribute_fastest_functor_t(const Image<I>& input, mln_result(A) lambda)
+ : lambda(lambda),
+ s(level::sort_psites_increasing(exact(input)))
+ {
+ }
+
+ };
+
+
+ template <typename A, typename I, typename N>
+ inline
+ mln_concrete(I)
+ closing_attribute_fastest(const Image<I>& input, const Neighborhood<N>& nbh,
+ mln_result(A) lambda)
+ {
+ trace::entering("morpho::impl::closing_attribute_fastest");
+
+ mln_precondition(exact(input).is_valid());
+
+ typedef impl::closing_attribute_fastest_functor_t<I, A> F;
+ F f(input, lambda);
+ mln_concrete(I) output = canvas::morpho::impl::algebraic_union_find_fastest(input, nbh, f);
+
+ mln_postcondition(output >= input);
+
+ trace::exiting("morpho::impl::closing_attribute_fastest");
+ return output;
+ }
+
+
} // end of namespace mln::morpho::impl
+ // Dispatch.
+
+ namespace internal
+ {
+
+ template <typename A, typename I, typename N>
+ inline
+ mln_concrete(I)
+ closing_attribute_dispatch(trait::image::speed::any,
+ const Image<I>& input, const Neighborhood<N>& nbh,
+ mln_result(A) lambda)
+ {
+ return impl::generic::closing_attribute<A>(input, nbh, lambda);
+ }
+
+// template <typename A, typename I, typename N>
+// inline
+// mln_concrete(I)
+// closing_attribute_dispatch(trait::image::speed::fastest,
+// const Image<I>& input, const Neighborhood<N>& nbh,
+// mln_result(A) lambda)
+// {
+// return impl::closing_attribute_fastest<A>(input, nbh, lambda);
+// }
+
+ template <typename A, typename I, typename N>
+ inline
+ mln_concrete(I)
+ closing_attribute_dispatch(const Image<I>& input, const Neighborhood<N>& nbh,
+ mln_result(A) lambda)
+ {
+ return closing_attribute_dispatch<A>(mln_trait_image_speed(I)(),
+ input, nbh, lambda);
+ }
+
+ } // end of namespace internal
+
+
+
// Facade.
template <typename A, typename I, typename N>
@@ -113,9 +251,7 @@
mln_precondition(exact(input).is_valid());
- typedef impl::closing_attribute_t<I, A> F;
- F f(input, lambda);
- mln_concrete(I) output = canvas::morpho::algebraic_union_find(input, nbh, f);
+ mln_concrete(I) output = internal::closing_attribute_dispatch<A>(input, nbh, lambda);
mln_postcondition(output >= input);
@@ -124,6 +260,9 @@
}
+ // Facade.
+
+
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln::morpho
Index: mln/morpho/opening_attribute.hh
--- mln/morpho/opening_attribute.hh (revision 3228)
+++ mln/morpho/opening_attribute.hh (working copy)
@@ -32,6 +32,8 @@
/// \file mln/morpho/opening_attribute.hh
///
/// Morphological attribute opening.
+///
+/// \todo Add extension::adjust_fill.
# include <mln/morpho/includes.hh>
# include <mln/canvas/morpho/algebraic_union_find.hh>
Index: mln/canvas/morpho/algebraic_union_find.hh
--- mln/canvas/morpho/algebraic_union_find.hh (revision 3228)
+++ mln/canvas/morpho/algebraic_union_find.hh (working copy)
@@ -51,6 +51,11 @@
namespace impl
{
+ // Generic version.
+
+ namespace generic
+ {
+
template <typename I>
inline
mln_psite(I)
@@ -69,7 +74,7 @@
const Neighborhood<N>& nbh_,
F& f)
{
- trace::entering("canvas::morpho::algebraic_union_find");
+ trace::entering("canvas::morpho::impl::generic::algebraic_union_find");
// FIXME: Tests?
@@ -190,11 +195,134 @@
and add in init:
mln::data::fill(output, input);
*/
- trace::exiting("canvas::morpho::algebraic_union_find");
+ trace::exiting("canvas::morpho::impl::generic::algebraic_union_find");
+
+ return output;
+ }
+
+ } // end of namespace mln::canvas::morpho::impl::generic
+
+
+
+ // Fastest version.
+
+ template <typename I>
+ inline
+ unsigned
+ find_root_fastest(I& parent, unsigned x)
+ {
+ if (parent.element(x) == x)
+ return x;
+ else
+ return parent.element(x) = find_root(parent, parent.element(x));
+ }
+
+
+ template <typename I, typename N, typename F>
+ inline
+ mln_concrete(I)
+ algebraic_union_find_fastest(const Image<I>& input_,
+ const Neighborhood<N>& nbh_,
+ F& f)
+ {
+ trace::entering("canvas::morpho::impl::algebraic_union_find_fastest");
+
+ // FIXME: Tests?
+
+ typedef typename F::S S;
+ typedef typename F::A A;
+
+ const I& input = exact(input_);
+ const N& nbh = exact(nbh_);
+
+ mln_concrete(I) output;
+ initialize(output, input);
+
+ // Local type.
+ typedef mln_psite(I) P;
+
+ // Auxiliary data.
+ mln_ch_value(I, bool) deja_vu;
+ mln_ch_value(I, bool) activity;
+ mln_ch_value(I, unsigned) parent;
+ mln_ch_value(I, A) data;
+
+ // Initialization.
+ {
+ initialize(deja_vu, input);
+ mln::data::fill(deja_vu, false);
+ initialize(activity, input);
+ mln::data::fill(activity, true);
+ initialize(parent, input);
+ mln::data::fill(parent, 0);
+ initialize(data, input);
+ f.init(); // init required.
+ }
+
+ util::array<int> dp = offsets_wrt(input, nbh);
+ for (unsigned i = 0; i < dp.nelements(); ++i)
+ std::cout << dp[i] << ' ';
+ std::cout << std::endl;
+
+ /*
+
+ // First pass.
+ {
+ for (unsigned p = 0; p < f.s.size(); ++p)
+ mln_niter(N) n(nbh, p);
+ for_all(p)
+ {
+ // Make set.
+ {
+ parent(p) = p;
+ data(p).take_as_init(make::pix(input, p)); // FIXME: algebraic so p!
+ }
+
+ for_all(n)
+ if (input.domain().has(n) && deja_vu(n))
+ {
+ P r = find_root(parent, n);
+ if (r != p)
+ {
+ if (input(r) == input(p) || (activity(r) && f.is_active(data(r))))
+ {
+ data(p).take(data(r));
+ parent(r) = p;
+ if (activity(r) == false)
+ activity(p) = false;
+ }
+ else
+ {
+ activity(p) = false;
+ f.inactivate(data(p));
+ }
+ }
+ }
+ deja_vu(p) = true;
+ }
+ }
+
+ */
+
+ /*
+
+ // Second pass.
+ {
+ mln_bkd_piter(S) p(f.s);
+ for_all(p)
+ if (parent(p) == p) // p is root.
+ output(p) = input(p);
+ else
+ output(p) = output(parent(p));
+ }
+
+ */
+ trace::exiting("canvas::morpho::impl::algebraic_union_find_fastest");
return output;
}
+
} // end of namespace mln::canvas::morpho::impl
@@ -212,7 +340,29 @@
const Neighborhood<N>& nbh,
F& f)
{
- return impl::algebraic_union_find(input, nbh, f);
+ return impl::generic::algebraic_union_find(input, nbh, f);
+ }
+
+// template <typename I, typename N, typename F>
+// inline
+// mln_concrete(I)
+// algebraic_union_find_dispatch(trait::image::speed::fastest,
+// const Image<I>& input,
+// const Neighborhood<N>& nbh,
+// F& f)
+// {
+// return impl::algebraic_union_find_fastest(input, nbh, f);
+// }
+
+ template <typename I, typename N, typename F>
+ inline
+ mln_concrete(I)
+ algebraic_union_find_dispatch(const Image<I>& input,
+ const Neighborhood<N>& nbh,
+ F& f)
+ {
+ return algebraic_union_find_dispatch(mln_trait_image_speed(I)(),
+ input, nbh, f);
}
} // end of namespace mln::canvas::morpho::internal
@@ -228,8 +378,7 @@
const Neighborhood<N>& nbh,
F& f)
{
- return internal::algebraic_union_find_dispatch(mln_trait_image_speed(I)(),
- input, nbh, f);
+ return internal::algebraic_union_find_dispatch(input, nbh, f);
}
Index: mln/util/pix.hh
--- mln/util/pix.hh (revision 3228)
+++ mln/util/pix.hh (working copy)
@@ -32,6 +32,13 @@
/// \file mln/util/pix.hh
///
/// Definition of an instant pix.
+///
+/// \todo Rename as util::pixel.
+///
+/// \todo Think about separating this class between
+/// util::pixel<"mutable" I> and util::pixel<const I>.
+///
+/// \todo Look at the todo entry of mln/core/pixel.hh.
# include <mln/core/concept/image.hh>
1
0
https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Fix delta_index in image3d.
* mln/core/image/image3d.hh (delta_index): Fix.
* mln/morpho/elementary/gradient.hh
(gradient_on_function): Handle extension.
(todo): Remove; done.
core/image/image3d.hh | 3 ++-
morpho/elementary/gradient.hh | 12 +++++++-----
2 files changed, 9 insertions(+), 6 deletions(-)
Index: mln/core/image/image3d.hh
--- mln/core/image/image3d.hh (revision 3227)
+++ mln/core/image/image3d.hh (working copy)
@@ -560,7 +560,8 @@
image3d<T>::delta_index(const dpoint3d& dp) const
{
mln_precondition(this->is_valid());
- int o = dp[0];
+ int o = (dp[0] * this->data_->vb_.len(1)
+ + dp[1]) * this->data_->vb_.len(2) + dp[2];
return o;
}
Index: mln/morpho/elementary/gradient.hh
--- mln/morpho/elementary/gradient.hh (revision 3227)
+++ mln/morpho/elementary/gradient.hh (working copy)
@@ -32,8 +32,6 @@
/// \file mln/morpho/elementary/gradient.hh
///
/// \todo Add fastest version for sets.
-///
-/// \todo Replace .domain().has() by .has()!
# include <mln/morpho/includes.hh>
# include <mln/accu/min_max.hh>
@@ -87,6 +85,8 @@
accu::min_max<mln_value(I)> a;
+ extension::adjust_duplicate(input, nbh);
+
mln_concrete(I) output;
initialize(output, input);
@@ -95,7 +95,7 @@
for_all(p)
{
a.take_as_init(input(p));
- for_all(n) if (input.domain().has(n))
+ for_all(n) if (input.has(n))
a.take(input(n));
output(p) = a.second() - a.first();
}
@@ -114,6 +114,8 @@
const N& nbh = exact(nbh_);
internal::gradient_tests(input, nbh);
+ extension::adjust_duplicate(input, nbh);
+
mln_concrete(I) output;
initialize(output, input);
data::fill(output, false);
@@ -123,7 +125,7 @@
for_all(p)
if (input(p) == true)
{
- for_all(n) if (input.domain().has(n))
+ for_all(n) if (input.has(n))
if (input(n) == false)
{
output(p) = true;
@@ -132,7 +134,7 @@
}
else // input(p) == false
{
- for_all(n) if (input.domain().has(n))
+ for_all(n) if (input.has(n))
if (input(n) == true)
{
output(p) = true;
1
0