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
https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Roland Levillain <roland(a)lrde.epita.fr>
* mln/math/sqr.hh: New file.
sqr.hh | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 64 insertions(+)
Index: mln/math/sqr.hh
--- mln/math/sqr.hh (revision 0)
+++ mln/math/sqr.hh (revision 0)
@@ -0,0 +1,64 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// 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_MATH_SQR_HH
+# define MLN_MATH_SQR_HH
+
+/*! \file mln/math/sqr.hh
+ *
+ * \brief Define the square (sqr) routine.
+ */
+
+# include <cmath>
+
+
+namespace mln
+{
+
+ namespace math
+ {
+
+ template <typename T>
+ T sqr(const T& v);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename T>
+ T sqr(const T& v)
+ {
+ return v * v;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::math
+
+} // end of namespace mln
+
+
+#endif // ! MLN_MATH_SQR_HH
1
0
https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Roland Levillain <roland(a)lrde.epita.fr>
Refactor the L1-norm, and test it.
* mln/norm/l1.hh: Use type `mln_value_sum(C)' instead of `float'
to handle L1-norm values.
(mln::norm::impl::l1_, mln::norm::impl::l1_distance_): New.
Use to factor the implementations of...
(mln::norm::l1, mln::norm::l1_distance): ...these functions.
* tests/l1.cc: New test.
* tests/Makefile.am (check_PROGRAMS): Add l1.
(l1_SOURCES): New.
mln/norm/l1.hh | 82 +++++++++++++++++++++++++++++++-----------------------
tests/Makefile.am | 2 +
tests/l1.cc | 71 ++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 121 insertions(+), 34 deletions(-)
Index: mln/norm/l1.hh
--- mln/norm/l1.hh (revision 1411)
+++ mln/norm/l1.hh (working copy)
@@ -31,11 +31,11 @@
/*! \file mln/norm/l1.hh
*
* \brief Define some l1-norm related routines.
+ * \see http://mathworld.wolfram.com/L1-Norm.html for more information.
*/
-# include <cmath>
-
# include <mln/metal/vec.hh>
+# include <mln/math/abs.hh>
namespace mln
{
@@ -43,71 +43,85 @@
namespace norm
{
- /// Infinity-norm of a vector \p vec.
+ /// L1-norm of a vector \a vec.
+ /// \{
template <unsigned n, typename C>
- float l1(const C (&vec)[n]);
+ mln_value_sum(C) l1(const C (&vec)[n]);
- /// Infinity-norm distance between vectors \p v1 and \p v2.
template <unsigned n, typename C>
- float l1_distance(const C (&v1)[n], const C (&v2)[n]);
+ mln_value_sum(C) l1(const metal::vec<n,C>& vec);
+ /// \}
+ /// L1-norm distance between vectors \a v1 and \a v2.
+ /// \{
template <unsigned n, typename C>
- float l1(const metal::vec<n,C>& vec);
+ mln_value_sum(C) l1_distance(const C (&vec1)[n], const C (&vec2)[n]);
template <unsigned n, typename C>
- float l1_distance(const metal::vec<n,C>& vec1, const metal::vec<n,C>& vec2);
-
- // FIXME: Replace float by mln_value_sum(C)...
+ mln_value_sum(C) l1_distance(const metal::vec<n,C>& vec1,
+ const metal::vec<n,C>& vec2);
+ /// \}
# ifndef MLN_INCLUDE_ONLY
- template <unsigned n, typename C>
- float l1(const C (&vec)[n])
+ namespace impl
{
- float c = 0;
+ template <unsigned n, typename C, typename V>
+ mln_value_sum(C) l1_(const V& vec)
+ {
+ mln_value_sum(C) c = 0;
for (unsigned i = 0; i < n; ++i)
{
- float v = vec[i];
- c += fabs (v);
+ mln_value_sum(C) v = vec[i];
+ c += mln::math::abs (v);
}
return c;
}
- template <unsigned n, typename C>
- float l1_distance(const C (&v1)[n], const C (&v2)[n])
+ template <unsigned n, typename C, typename V>
+ mln_value_sum(C) l1_distance_(const V& vec1, const V& vec2)
{
- float d = 0;
+ mln_value_sum(C) d = 0;
for (unsigned i = 0; i < n; ++i)
{
- float v = v1[i] - v2[i];
- d += fabs (v);
+ mln_value_sum(C) v = vec1[i] - vec2[i];
+ d += mln::math::abs (v);
}
return d;
}
+ } // end of namespace mln::norm::impl
+
+
+ // Facades.
+
template <unsigned n, typename C>
- float l1(const metal::vec<n,C>& vec)
+ mln_value_sum(C)
+ l1(const C (&vec)[n])
{
- float c = 0;
- for (unsigned i = 0; i < n; ++i)
- if (vec[i] > 0)
- c += vec[i];
- else
- c -= vec[i];
- return c;
+ return impl::l1_<n, C>(vec);
}
template <unsigned n, typename C>
- float l1(const metal::vec<n,C>& vec1, const metal::vec<n,C>& vec2)
+ mln_value_sum(C)
+ l1(const metal::vec<n,C>& vec)
{
- float d = 0;
- for (unsigned i = 0; i < n; ++i)
+ return impl::l1_<n, C>(vec);
+ }
+
+ template <unsigned n, typename C>
+ mln_value_sum(C)
+ l1_distance(const C (&vec1)[n], const C (&vec2)[n])
{
- float v = vec1[i] - vec2[i];
- d += fabs (v);
+ return impl::l1_distance_<n, C>(vec1, vec2);
}
- return d;
+
+ template <unsigned n, typename C>
+ mln_value_sum(C)
+ l1_distance(const metal::vec<n,C>& vec1, const metal::vec<n,C>& vec2)
+ {
+ return impl::l1_distance_<n, C>(vec1, vec2);
}
# endif // ! MLN_INCLUDE_ONLY
Index: tests/l1.cc
--- tests/l1.cc (revision 0)
+++ tests/l1.cc (revision 0)
@@ -0,0 +1,71 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// 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.
+
+/// \file tests/l1.hh
+/// \brief Test the L1-norm.
+
+#include <cassert>
+
+#include <mln/metal/vec.hh>
+#include <mln/math/abs.hh>
+#include <mln/norm/l1.hh>
+
+// FIXME: We should have a almost_equal function somewhere in Milena.
+static const float epsilon = 0.0001;
+
+using mln::metal::vec;
+using mln::norm::l1;
+
+template <typename V>
+void check_l1 (const V& vec1, const V& vec2)
+{
+ assert (mln::math::abs(mln::norm::l1(vec1) - mln::norm::l1(vec2))
+ < epsilon);
+}
+
+template <typename V, typename S>
+void check_l1_distance (const V& vec1, const V& vec2, const S& ref_val)
+{
+ assert (mln::math::abs(mln::norm::l1_distance(vec1, vec2) - ref_val)
+ < epsilon);
+}
+
+int main ()
+{
+ vec<3, int> t; t.set (1, -2, 3);
+ vec<3, int> u; u.set (5, 1, 0);
+ int d = (5 - 1) + (1 + 2) + 3;
+
+ check_l1(t, u);
+ check_l1_distance (t, u, d);
+
+ int v[] = {1, -2, 3};
+ int w[] = {5, 1, 0};
+
+ check_l1(v, w);
+ check_l1_distance (v, w, d);
+}
Index: tests/Makefile.am
--- tests/Makefile.am (revision 1411)
+++ tests/Makefile.am (working copy)
@@ -84,6 +84,7 @@
io_ppm23 \
io_ppm \
\
+ l1 \
labeling_algo \
labeling_estimate \
labeling_foreground \
@@ -270,6 +271,7 @@
io_ppm23_SOURCES = io_ppm23.cc
io_ppm_SOURCES = io_ppm.cc
+l1_SOURCES = l1.cc
labeling_algo_SOURCES = labeling_algo.cc
labeling_estimate_SOURCES = labeling_estimate.cc
labeling_foreground_SOURCES = labeling_foreground.cc
1
0
URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena
ChangeLog:
2007-10-30 Guillaume Duhamel <guillaume.duhamel(a)lrde.epita.fr>
Add debug display tools for fllt.
* mln/util/tree_to_image.hh: Add functions :
(display_set(const Image<J>& ima_, set_p<P>& s)) :
display set_p with ima_ domain into a binary image.
(display_tree_rec(const Image<J>& ima_, node<T>* node, int level))
Recursive function of ...
(display_tree(const Image<J>& ima_, tree<I>& tree))
... function which displays all nodes of tree with display_set,
it shows the actual state of tree (of kind fllt) in pritting
each set_p of node with a number which gives the level of the node.
It isn't generic at all, it's just viewing tools for debugging,
to fix later when fllt will be generic too.
Use it ...
* sandbox/garrigues/fllt.hh: ... here for a better view of the
situation and so for the debbuging.
* sandbox/garrigues/test_fllt.cc: Fix the beggining of loop (1 -> 0).
---
mln/util/tree_to_image.hh | 59 +++++++++++++++++++++++++++++++++++++++--
sandbox/garrigues/fllt.hh | 18 +++++++++++-
sandbox/garrigues/test_fllt.cc | 4 +-
3 files changed, 76 insertions(+), 5 deletions(-)
Index: trunk/milena/mln/util/tree_to_image.hh
===================================================================
--- trunk/milena/mln/util/tree_to_image.hh (revision 1410)
+++ trunk/milena/mln/util/tree_to_image.hh (revision 1411)
@@ -53,6 +53,18 @@
void
tree_to_image (tree<T>& tree, Image<I>& output_);
+ template <typename P, typename J>
+ void
+ display_set(const Image<J>& ima_, set_p<P>& s);
+
+ template <typename T, typename J>
+ void
+ display_tree_rec(const Image<J>& ima_, node<T>* node, int level);
+
+ template <typename I, typename J>
+ void
+ display_tree(const Image<J>& ima_, tree<I>& tree);
+
# ifndef MLN_INCLUDE_ONLY
template <typename T, typename I>
@@ -61,7 +73,6 @@
{
I& output = exact(output_);
-
mln_piter(set_p<point2d>) p(node->elt().points);
for_all(p)
@@ -78,7 +89,6 @@
}
}
-
template <typename T, typename I>
void
tree_to_image (tree<T>& tree, Image<I>& output_)
@@ -87,6 +97,51 @@
tree_to_image_rec(tree.root(), output);
}
+
+ template <typename P, typename J>
+ void
+ display_set(const Image<J>& ima_, set_p<P>& s)
+ {
+ const J& ima = exact(ima_);
+ image2d<bool> out (ima.bbox ());
+
+ level::fill(out, false);
+ mln_piter(set_p<P>) p (s);
+ for_all (p)
+ out(p) = true;
+ debug::println(out);
+ }
+
+
+ template <typename T, typename J>
+ void
+ display_tree_rec(const Image<J>& ima_, node<T>* node, int level)
+ {
+ const J& ima = exact(ima_);
+ std::cout << level << std::endl;
+ std::cout << std::endl;
+ display_set(ima, node->elt().points);
+ typename mln::util::node<T>::children_t::iterator it = node->children().begin();
+ for (;
+ it != node->children().end(); ++it)
+ display_tree_rec(ima, (*it), level + 1);
+ std::cout << std::endl;
+ std::cout << std::endl;
+ std::cout << std::endl;
+ std::cout << std::endl;
+ }
+
+ template <typename I, typename J>
+ void
+ display_tree(const Image<J>& ima_, tree<I>& tree)
+ {
+ const J& ima = exact(ima_);
+ int level = 0;
+
+ mln_assertion(tree.root());
+ display_tree_rec(ima, tree.root(), level);
+ }
+
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln::util
Index: trunk/milena/sandbox/garrigues/fllt.hh
===================================================================
--- trunk/milena/sandbox/garrigues/fllt.hh (revision 1410)
+++ trunk/milena/sandbox/garrigues/fllt.hh (revision 1411)
@@ -269,7 +269,16 @@
static image2d<int> tmp(u.domain().to_larger(1));
static image2d<bool> border_ima(tmp.domain());
level::fill(border_ima, false);
- level::fill(inplace(border_ima | N), true);
+
+// level::fill(inplace(border_ima | N), true);
+// std::cout << "tmp border = " << tmp.border () << std::endl;
+// std::cout << "ima border = " << border_ima.border () << std::endl;
+ mln_piter(set_p<P>) z(N);
+ for_all(z)
+ {
+ mln_assertion(border_ima.owns_(z));
+ border_ima(z) = true;
+ }
unsigned n;
labeling::level(border_ima, true, F::bdr_nbh(), tmp, n);
@@ -459,6 +468,7 @@
fllt_tree(P, V)& tree = *new fllt_tree(P, V)(current_region);
util::tree_to_image (tree, output);
+ util::display_tree(ima, tree);
// debug::println(output);
// std::cout << std::endl;
@@ -576,6 +586,7 @@
mln_piter(set_p<P>) p(node.elt().holes);
for_all(p)
{
+ std::cout << "OK start loop" << std::endl;
bool h = true;
fllt_node(P, V)* hole = find_the_hole(node, point2d(p), other_reg);
typename fllt_node(P, V)::children_t::iterator it;
@@ -591,7 +602,10 @@
}
}
if (h)
+ {
move_shape(node, *hole, tree, other_reg);
+ std::cout << "OK" << std::endl;
+ }
}
}
@@ -615,6 +629,7 @@
{
fllt_node(P, V)& n(p);
fill_a_shape(n, lower, upp_reg);
+ mln_assertion(n.check_consistency());
}
// fllt_branch_iter(P, V) q(upper.main_branch());
// for_all(q)
@@ -704,6 +719,7 @@
abort();
}
+
// io::pgm::save(output, "out_final.pgm");
// std::cout << "out_final.pgm generate"
// << std::endl;
Index: trunk/milena/sandbox/garrigues/test_fllt.cc
===================================================================
--- trunk/milena/sandbox/garrigues/test_fllt.cc (revision 1410)
+++ trunk/milena/sandbox/garrigues/test_fllt.cc (revision 1411)
@@ -32,8 +32,8 @@
// fllt::fllt(ima);
- for (int i = 1; i < 16; ++i)
- for (int j = 1; j < 16; ++j)
+ for (int i = 0; i < 16; ++i)
+ for (int j = 0; j < 16; ++j)
{
std::stringstream path;
path << "/lrde/tegucigalpa/theo/pub/mln_docs/lena_tiles/lena_" << i << "_" << j << ".pgm";
Index: trunk/milena/sandbox/garrigues/test_fllt2.cc
===================================================================
1
0
30 Oct '07
https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Roland Levillain <roland(a)lrde.epita.fr>
Catch up with Olena's new way to handle FreeImagePlus.
* tests/Makefile.am: Add some white space to improve the
readability.
Adjust conditional; rename FREE_IMAGE_PLUS as FREEIMAGEPLUS.
(fi_adaptor_LDADD): Remove.
(fi_adaptor_CPPFLAGS, fi_adaptor_LDFLAGS): New.
* tests/fi_adaptor.cc (main): More comments/FIXMEs on the use of
FreeImagePlus.
Makefile.am | 39 +++++++++++++++++++++++++++++++++++++--
fi_adaptor.cc | 11 +++++++++--
2 files changed, 46 insertions(+), 4 deletions(-)
Index: tests/Makefile.am
--- tests/Makefile.am (revision 1409)
+++ tests/Makefile.am (working copy)
@@ -18,6 +18,7 @@
accu_all \
accu_min \
accu_nil \
+ \
border_get \
border_resize_image1d_1 \
border_resize_image1d_2 \
@@ -33,6 +34,7 @@
box1d \
box2d \
box3d \
+ \
canvas_browsing_fwd \
cast_image \
chamfer \
@@ -44,6 +46,7 @@
core_clone \
core_exact \
core_initialize \
+ \
debug_println \
debug_println_with_border \
decorated_image \
@@ -51,15 +54,19 @@
dpoint2d \
dpoint3d \
dpoints_pixter \
+ \
estim_mean \
+ \
fi_adaptor \
fun_x2x_composed \
fun_x2x_rotation \
fun_x2x_translation \
+ \
hexa \
histo_compute \
histo_to_image1d \
h_vec \
+ \
image1d \
image2d \
image2d_h \
@@ -76,6 +83,7 @@
io_ppm16 \
io_ppm23 \
io_ppm \
+ \
labeling_algo \
labeling_estimate \
labeling_foreground \
@@ -104,6 +112,7 @@
literal_medium_gray \
literal_zero \
local_convolve \
+ \
main \
mat \
mesh_image \
@@ -123,8 +132,10 @@
morpho_laplacian \
morpho_opening_area \
morpho_thinning \
+ \
new_io_pgm \
norm_l2 \
+ \
pixel \
pixter1d \
pixter2d \
@@ -136,12 +147,15 @@
pset_if \
pw_image \
pw_value \
+ \
queue_p \
queue_p_fast \
queue_p_fast_priority \
queue_p_priority \
+ \
rle_image \
run_pset \
+ \
safe_image \
seed2tiling \
set_p \
@@ -149,6 +163,7 @@
sparse_image \
stack \
sub_image \
+ \
test_positive \
trait_ch_value \
trait_images \
@@ -158,6 +173,7 @@
trait_value \
translate_image \
tr_image \
+ \
value_float01_bis \
value_float01 \
value_float01_f \
@@ -172,6 +188,7 @@
value_scalar \
value_set \
vec \
+ \
win_backdiag2d \
win_diag2d \
win_disk2d \
@@ -188,6 +205,7 @@
accu_all_SOURCES = accu_all.cc
accu_min_SOURCES = accu_min.cc
accu_nil_SOURCES = accu_nil.cc
+
border_get_SOURCES = border_get.cc
border_resize_image1d_1_SOURCES = border_resize_image1d_1.cc
border_resize_image1d_2_SOURCES = border_resize_image1d_2.cc
@@ -203,6 +221,7 @@
box1d_SOURCES = box1d.cc
box2d_SOURCES = box2d.cc
box3d_SOURCES = box3d.cc
+
canvas_browsing_fwd_SOURCES = canvas_browsing_fwd.cc
cast_image_SOURCES = cast_image.cc
chamfer_SOURCES = chamfer.cc
@@ -214,6 +233,7 @@
core_clone_SOURCES = core_clone.cc
core_exact_SOURCES = core_exact.cc
core_initialize_SOURCES = core_initialize.cc
+
debug_println_SOURCES = debug_println.cc
debug_println_with_border_SOURCES = debug_println_with_border.cc
decorated_image_SOURCES = decorated_image.cc
@@ -221,14 +241,18 @@
dpoint2d_SOURCES = dpoint2d.cc
dpoint3d_SOURCES = dpoint3d.cc
dpoints_pixter_SOURCES = dpoints_pixter.cc
+
estim_mean_SOURCES = estim_mean.cc
+
fun_x2x_composed_SOURCES = fun_x2x_composed.cc
fun_x2x_rotation_SOURCES = fun_x2x_rotation.cc
fun_x2x_translation_SOURCES = fun_x2x_translation.cc
+
hexa_SOURCES = hexa.cc
histo_compute_SOURCES = histo_compute.cc
histo_to_image1d_SOURCES = histo_to_image1d.cc
h_vec_SOURCES = h_vec.cc
+
image1d_SOURCES = image1d.cc
image2d_SOURCES = image2d.cc
image2d_h_SOURCES = image2d_h.cc
@@ -245,6 +269,7 @@
io_ppm16_SOURCES = io_ppm16.cc
io_ppm23_SOURCES = io_ppm23.cc
io_ppm_SOURCES = io_ppm.cc
+
labeling_algo_SOURCES = labeling_algo.cc
labeling_estimate_SOURCES = labeling_estimate.cc
labeling_foreground_SOURCES = labeling_foreground.cc
@@ -273,6 +298,7 @@
literal_medium_gray_SOURCES = literal_medium_gray.cc
literal_zero_SOURCES = literal_zero.cc
local_convolve_SOURCES = local_convolve.cc
+
main_SOURCES = main.cc
mat_SOURCES = mat.cc
mesh_image_SOURCES = mesh_image.cc
@@ -292,8 +318,10 @@
morpho_laplacian_SOURCES = morpho_laplacian.cc
morpho_opening_area_SOURCES = morpho_opening_area.cc
morpho_thinning_SOURCES = morpho_thinning.cc
+
new_io_pgm_SOURCES = new_io_pgm.cc
norm_l2_SOURCES = norm_l2.cc
+
pixel_SOURCES = pixel.cc
pixter1d_SOURCES = pixter1d.cc
pixter2d_SOURCES = pixter2d.cc
@@ -305,12 +333,15 @@
pset_if_SOURCES = pset_if.cc
pw_image_SOURCES = pw_image.cc
pw_value_SOURCES = pw_value.cc
+
queue_p_SOURCES = queue_p.cc
queue_p_fast_SOURCES = queue_p_fast.cc
queue_p_fast_priority_SOURCES = queue_p_fast_priority.cc
queue_p_priority_SOURCES = queue_p_priority.cc
+
rle_image_SOURCES = rle_image.cc
run_pset_SOURCES = run_pset.cc
+
safe_image_SOURCES = safe_image.cc
seed2tiling_SOURCES = seed2tiling.cc
set_p_SOURCES = set_p.cc
@@ -318,6 +349,7 @@
sparse_image_SOURCES = sparse_image.cc
stack_SOURCES = stack.cc
sub_image_SOURCES = sub_image.cc
+
test_positive_SOURCES = test_positive.cc
trait_ch_value_SOURCES = trait_ch_value.cc
trait_images_SOURCES = trait_images.cc
@@ -327,6 +359,7 @@
trait_value_SOURCES = trait_value.cc
translate_image_SOURCES = translate_image.cc
tr_image_SOURCES = tr_image.cc
+
value_float01_bis_SOURCES = value_float01_bis.cc
value_float01_SOURCES = value_float01.cc
value_float01_f_SOURCES = value_float01_f.cc
@@ -341,6 +374,7 @@
value_scalar_SOURCES = value_scalar.cc
value_set_SOURCES = value_set.cc
vec_SOURCES = vec.cc
+
win_backdiag2d_SOURCES = win_backdiag2d.cc
win_diag2d_SOURCES = win_diag2d.cc
win_disk2d_SOURCES = win_disk2d.cc
@@ -355,10 +389,11 @@
w_window3d_int_SOURCES = w_window3d_int.cc
# Tests depending on the FreeImage library.
-if FREE_IMAGE_PLUS
+if FREEIMAGEPLUS
check_PROGRAMS += fi_adaptor
fi_adaptor_SOURCES = fi_adaptor.cc
- fi_adaptor_LDADD = $(FREEIMAGELIB)
+ fi_adaptor_CPPFLAGS = $(AM_CPPFLAGS) $(FREEIMAGEPLUS_CPPFLAGS)
+ fi_adaptor_LDFLAGS = $(AM_LDFLAGS) $(FREEIMAGEPLUS_LDFLAGS)
endif
TESTS = $(check_PROGRAMS)
Index: tests/fi_adaptor.cc
--- tests/fi_adaptor.cc (revision 1409)
+++ tests/fi_adaptor.cc (working copy)
@@ -53,7 +53,7 @@
using typename value::int_u8;
using typename value::rgb8;
- //FIXME : is it necessary??
+ // FIXME: Is this necessary? See FreeImagePlus' documentation.
FreeImage_Initialise();
win::rectangle2d rect(51, 51);
@@ -71,6 +71,13 @@
display::save (adaptor);
display::show (adaptor, "xv");
- // call this ONLY when linking with FreeImage as a static library
+ // FIXME: Likewise.
+ /* A comment here (probably coming from an example of FreeImagePlus'
+ documentation) used to say:
+
+ call this ONLY when linking with FreeImage as a static library
+
+ Check if this statement holds in our case. Maybe we need to
+ involve Libtool in to handle FreeImagePlus properly. */
FreeImage_DeInitialise();
}
1
0
https://svn.lrde.epita.fr/svn/oln/trunk
The updates to Milena follow.
Index: ChangeLog
from Roland Levillain <roland(a)lrde.epita.fr>
Improve support for the FreeImagePlus library.
* build-aux/freeimageplus.m4: New.
Provide the Autoconf macro OLN_WITH_FREEIMAGEPLUS.
Inspired by Olena 0.11's macros AC_WITH_CXX_ZLIB and
AC_WITH_CXX_FFTW.
Use this macro...
* configure.ac: ...here, instead of the previous ad hoc solution.
Rename the Automake conditional FREE_IMAGE_PLUS as FREEIMAGEPLUS,
and adjust it.
* Makefile.am (ACLOCAL_AMFLAGS): New.
Set it to `-I build-aux' to have aclocal visit
build-aux/freeimageplus.m4.
Makefile.am | 2 +
build-aux/freeimageplus.m4 | 48 +++++++++++++++++++++++++++++++++++++++++++++
configure.ac | 5 +---
3 files changed, 52 insertions(+), 3 deletions(-)
Index: build-aux/freeimageplus.m4
--- build-aux/freeimageplus.m4 (revision 0)
+++ build-aux/freeimageplus.m4 (revision 0)
@@ -0,0 +1,48 @@
+# -*- Autoconf -*-
+
+# OLN_WITH_FREEIMAGEPLUS
+# ----------------------
+# Checks whether the FreeImagePlus library is available from C++
+# programs.
+#
+# This macro sets FREEIMAGEPLUS_CXXFLAGS and FREEIMAGEPLUS_LDFLAGS if
+# the library is found and its functions available from C++.
+AC_DEFUN([OLN_WITH_FREEIMAGEPLUS],
+[dnl
+ AC_REQUIRE([AC_PROG_CXX])
+ AC_LANG_PUSH([C++])
+
+ AC_ARG_WITH([freeimageplus],
+ [AC_HELP_STRING([--with-freeimageplus@<:@=DIR@:>@],
+ [using FreeImage (DIR = prefix for FreeImage installation)])])
+ FREEIMAGEPLUS_CXXFLAGS=''
+ FREEIMAGEPLUS_LDFLAGS=''
+ if test "x$with_freeimageplus" != xno; then
+ if test -n "$with_freeimageplus"; then
+ FREEIMAGEPLUS_CXXFLAGS="-I${with_freeimageplus}/include"
+ FREEIMAGEPLUS_LDFLAGS="-L${with_freeimageplus}/lib"
+ fi
+ oln_save_CXXFLAGS=$CXXFLAGS
+ oln_save_LDFLAGS=$LDFLAGS
+ CXXFLAGS="$CXXFLAGS $FREEIMAGEPLUS_CXXFLAGS"
+ LDFLAGS="$LDFLAGS $FREEIMAGEPLUS_LDFLAGS"
+ oln_have_freeimageplus=no
+ AC_CHECK_HEADER([FreeImagePlus.h],
+ [AC_CHECK_LIB([freeimageplus],
+ [main],
+ [oln_have_freeimageplus=yes
+ FREEIMAGEPLUS_LDFLAGS="$FREEIMAGEPLUS_LDFLAGS -lfreeimageplus"
+ AC_DEFINE([HAVE_FREEIMAGEPLUS], 1,
+ [Define to 1 if we can use FreeImage])
+ ]
+ )]
+ )
+ CXXFLAGS=$oln_save_CXXFLAGS
+ LDFLAGS=$oln_save_LDFLAGS
+ TOOLS_LDFLAGS="$TOOLS_LDFLAGS $FREEIMAGEPLUS_LDFLAGS"
+ fi
+ AC_SUBST([FREEIMAGEPLUS_CXXFLAGS])
+ AC_SUBST([FREEIMAGEPLUS_LDFLAGS])
+
+ AC_LANG_POP([C++])
+])
Index: configure.ac
--- configure.ac (revision 1408)
+++ configure.ac (working copy)
@@ -59,9 +59,8 @@
## -------------- ##
# FreeImage library.
-AC_CHECK_HEADERS([FreeImagePlus.h],
- [AM_CONDITIONAL([FREE_IMAGE_PLUS], [true])])
-AC_CHECK_LIB([freeimageplus], [main])
+OLN_WITH_FREEIMAGEPLUS
+AM_CONDITIONAL([FREEIMAGEPLUS], [test x$oln_have_freeimageplus = xyes])
## ------- ##
Index: Makefile.am
--- Makefile.am (revision 1408)
+++ Makefile.am (working copy)
@@ -1,3 +1,5 @@
## Process this file through Automake to produce Makefile.in -*- Makefile -*-
+ACLOCAL_AMFLAGS = -I build-aux
+
SUBDIRS = build-aux metalic extended static milena olena dynamic
1
0
URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena
ChangeLog:
2007-10-30 Matthieu Garrigues <garrigues(a)lrde.epita.fr>
Add make::image2d.
* mln/core/image2d.hh: Include make/image2d.hh at the end of the file.
* mln/make/image2d.hh: New, Add routine to make a image2d with a 2d
array
* tests/make_image2d.cc: New, tests on make::image2d.
---
mln/core/image2d.hh | 1
mln/make/image2d.hh | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++
tests/make_image2d.cc | 50 +++++++++++++++++++++++++++++++++
3 files changed, 126 insertions(+)
Index: trunk/milena/tests/make_image2d.cc
===================================================================
--- trunk/milena/tests/make_image2d.cc (revision 0)
+++ trunk/milena/tests/make_image2d.cc (revision 1408)
@@ -0,0 +1,50 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// 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.
+
+/*! \file tests/make_image2d.cc
+ *
+ * \brief Tests on mln::make::image2d.
+ */
+
+
+# include <mln/core/image2d.hh>
+# include <mln/debug/println.hh>
+
+int main()
+{
+ using namespace mln;
+
+ int vs[3][3] = { {-1, 0, 1},
+ {-2, 0, 2},
+ {-1, 0, 1} };
+
+ debug::println(make::image2d(vs));
+
+ int vs2[1][1] = { {-1} };
+
+ debug::println(make::image2d(vs2));
+}
Index: trunk/milena/mln/core/image2d.hh
===================================================================
--- trunk/milena/mln/core/image2d.hh (revision 1407)
+++ trunk/milena/mln/core/image2d.hh (revision 1408)
@@ -580,5 +580,6 @@
} // end of namespace mln
+# include <mln/make/image2d.hh>
#endif // ! MLN_CORE_IMAGE2D_B_HH
Index: trunk/milena/mln/make/image2d.hh
===================================================================
--- trunk/milena/mln/make/image2d.hh (revision 0)
+++ trunk/milena/mln/make/image2d.hh (revision 1408)
@@ -0,0 +1,75 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// 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_IMAGE2D_HH
+# define MLN_MAKE_IMAGE2D_HH
+
+/*! \file mln/make/image2d.hh
+ *
+ * \brief Routine to create an mln::image2d in the 2D case.
+ */
+
+# include <mln/core/image2d.hh>
+
+
+namespace mln
+{
+
+ namespace make
+ {
+
+ /*! \brief Create an image2d from an 2d array of values.
+ *
+ * \param[in] 2d array.
+ *
+ * \return A 2D image.
+ */
+ template <typename V, unsigned R, unsigned C>
+ mln::image2d<V> image2d(V (&values)[R][C]);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename V, unsigned R, unsigned C>
+ mln::image2d<V>
+ image2d(V (&values)[R][C])
+ {
+ mln::image2d<V> tmp(R, C);
+ for (unsigned row = 0; row <= R; ++row)
+ for (unsigned col = 0; col <= C; ++col)
+ tmp(make::point2d(row, col)) = values[row][col];
+ return tmp;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::make
+
+} // end of namespace mln
+
+
+#endif // ! MLN_MAKE_IMAGE2D_HH
1
0
https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Fix fast level labeling.
* mln/border/resize.hh: Change the behavior so that
resizing is always effective.
* mln/canvas/labeling.hh (labeling_fast): Initialize
parent properly.
* mln/labeling/level.hh (level_): Resize border in the fast
version.
border/resize.hh | 9 +++++----
canvas/labeling.hh | 5 +++--
labeling/level.hh | 6 ++++++
3 files changed, 14 insertions(+), 6 deletions(-)
Index: mln/border/resize.hh
--- mln/border/resize.hh (revision 1406)
+++ mln/border/resize.hh (working copy)
@@ -99,11 +99,12 @@
mlc_is(mln_trait_image_border(I), trait::image::border::some)::check();
const I& ima = exact(ima_);
mln_precondition(ima.has_data());
- if (border::get(ima) >= thickness)
- return;
+
+ if (border::get(ima) = thickness)
+ return; // No-op.
+
impl::resize_(ima, mln_trait_image_category(I)(), thickness);
- mln_postcondition(border::get(ima) >= thickness);
- return;
+ mln_postcondition(border::get(ima) = thickness);
}
# endif // ! MLN_INCLUDE_ONLY
Index: mln/canvas/labeling.hh
--- mln/canvas/labeling.hh (revision 1406)
+++ mln/canvas/labeling.hh (working copy)
@@ -38,6 +38,7 @@
# include <mln/level/sort_points.hh>
# include <mln/convert/to_window.hh>
+
namespace mln
{
@@ -167,8 +168,7 @@
mln_ch_value(O, unsigned) parent;
labeling_fast(F& f)
- : f(f),
- parent(f.output.domain(), f.input.border())
+ : f(f)
{
run();
}
@@ -178,6 +178,7 @@
// init
{
+ initialize(parent, f.input);
f.nlabels = 0;
f.init();
}
Index: mln/labeling/level.hh
--- mln/labeling/level.hh (revision 1406)
+++ mln/labeling/level.hh (working copy)
@@ -37,6 +37,7 @@
# include <mln/core/concept/image.hh>
# include <mln/labeling/base.hh>
# include <mln/level/fill.hh>
+# include <mln/border/resize.hh>
@@ -137,7 +138,12 @@
trait::image::speed::fastest, O& output, unsigned& nlabels)
{
typedef level_fast_t<I,N,O> F;
+
+ border::resize(input, exact(nbh).delta());
+ border::resize(output, exact(nbh).delta());
+
F f(input, val, exact(nbh), output);
+
canvas::labeling_fast<F> run(f);
nlabels = f.nlabels;
return f.status;
1
0
URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena
ChangeLog:
2007-10-29 Guillaume Duhamel <guillaume.duhamel(a)lrde.epita.fr>
New method to check consistency of tree.
* mln/util/tree.hh: Add new method which checks the
consistency of a tree.
* tests/tree.cc: Add this test at the end of file.
---
mln/util/tree.hh | 35 +++++++++++++++++++++++++++--------
tests/tree.cc | 1 +
2 files changed, 28 insertions(+), 8 deletions(-)
Index: trunk/milena/tests/tree.cc
===================================================================
--- trunk/milena/tests/tree.cc (revision 1403)
+++ trunk/milena/tests/tree.cc (revision 1404)
@@ -60,4 +60,5 @@
util::tree<unsigned>* tre = new util::tree<unsigned>(&node);
mln_assertion(tre);
tre->add_tree_up(elt6);
+ mln_assertion (tre->check_consistency());
}
Index: trunk/milena/mln/util/tree.hh
===================================================================
--- trunk/milena/mln/util/tree.hh (revision 1403)
+++ trunk/milena/mln/util/tree.hh (revision 1404)
@@ -29,7 +29,7 @@
# define MLN_UTIL_TREE_HH
# include <vector>
-
+# include <iostream>
# include <mln/core/contract.hh>
/*!
@@ -82,6 +82,7 @@
void set_parent(node<T>* parent);
void print_rec(int n) const;
void print() const;
+ bool check_consistency();
int search_rec(node<T>** res, T& elt);
node<T>* search(T& elt);
@@ -102,6 +103,7 @@
node<T>* root();
branch<T> main_branch();
+ bool check_consistency();
void add_tree_up (T& elt);
void add_tree_down (T& elt);
@@ -174,6 +176,13 @@
template <typename T>
+ bool
+ tree<T>::check_consistency()
+ {
+ return root()->check_consistency ();
+ }
+
+ template <typename T>
node<T>::node()
: parent_ (0)
{
@@ -252,13 +261,6 @@
return parent_;
}
-// template <typename T>
-// node<T>*&
-// node<T>::parent()
-// {
-// return parent_;
-// }
-
template <typename T>
int
node<T>::search_rec(node<T>** res, T& elt)
@@ -291,6 +293,23 @@
return 0;
}
+ template <typename T>
+ bool
+ node<T>::check_consistency()
+ {
+ for (typename std::vector<node<T>* >::iterator it = this->child_.begin();
+ it != this->child_.end(); ++it)
+ {
+ if ((**it).parent() != this)
+ return false;
+
+ if (!((**it).check_consistency()))
+ return false;
+ }
+ return true;
+ }
+
+
// Branch methods
template <typename T>
branch<T>::branch(util::tree<T>& tree,
2
1
29 Oct '07
https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Update the form of routines so that images are returned.
* mln/fun/ops.hh: Add traits.
(mln_decl_binary_expr_): Replace <opname> by <opname>_ when
it is a language keyword.
(mln_decl_unary_expr_): Likewise.
* mln/core/image_if_interval.hh: Update.
Use the "image foo(..)" form instead of "foo(.., output)";
Insert tracing calls to routines.
* tests/morpho_hit_or_miss.cc: .
* tests/labeling_level_fast.cc: .
* tests/arith_plus.cc: .
* tests/morpho_gradient.cc: .
* tests/window2d.cc: .
* tests/value_int_s.cc: .
* tests/morpho_thinning.cc: .
* tests/morpho_laplacian.cc: .
* tests/value_int_u8.cc: .
* tests/morpho_contrast.cc: .
* tests/pw_value.cc: .
* mln/core/concept/image.hh: .
* mln/core/clone.hh: .
* mln/arith/plus.hh: .
* mln/arith/min.hh: .
* mln/arith/revert.hh: .
* mln/arith/minus.hh: .
* mln/convert/to_image.hh: .
* mln/morpho/thickening.hh: .
* mln/morpho/plus.hh: .
* mln/morpho/min.hh: .
* mln/morpho/laplacian.hh: .
* mln/morpho/minus.hh: .
* mln/morpho/gradient.hh: .
* mln/morpho/contrast.hh: .
* mln/morpho/thick_miss.hh: .
* mln/morpho/closing.hh: .
* mln/morpho/top_hat.hh: .
* mln/morpho/complementation.hh: .
* mln/morpho/opening.hh: .
* mln/morpho/dilation.hh: .
* mln/morpho/thin_fit.hh: .
* mln/morpho/includes.hh: .
* mln/morpho/thinning.hh: .
* mln/morpho/hit_or_miss.hh: .
* mln/logical/and.hh: .
* mln/logical/and_not.hh: .
* mln/logical/or.hh: .
* mln/logical/not.hh: .
Misc.
* mln/value/builtin/ops.hh: Add versions for builtin OP= object.
* mln/value/cast.hh (cast_): Update using value::equiv.
* mln/trait/op/minus.hh (mln_trait_op_minus_twice): New.
* mln/fun/cast.hh: New.
* mln/fun/v2v/cast.hh: New.
* mln/fun/v2v/all.hh: Update.
* mln/arith/includes.hh: Update.
* img/picasso.pbm: New.
img/picasso.pbm | 0
mln/arith/includes.hh | 1
mln/arith/min.hh | 47 +++--
mln/arith/minus.hh | 344 ++++++++++++++++++++++++++++++++++++++----
mln/arith/plus.hh | 285 +++++++++++++++++++++++++++++-----
mln/arith/revert.hh | 43 +++--
mln/convert/to_image.hh | 2
mln/core/clone.hh | 4
mln/core/concept/image.hh | 2
mln/core/image_if_interval.hh | 2
mln/fun/cast.hh | 84 ++++++++++
mln/fun/ops.hh | 48 ++++-
mln/fun/v2v/all.hh | 1
mln/fun/v2v/cast.hh | 80 +++++++++
mln/fun/v2v/saturate.hh | 17 +-
mln/logical/and.hh | 44 +++--
mln/logical/and_not.hh | 44 +++--
mln/logical/not.hh | 35 ++--
mln/logical/or.hh | 46 +++--
mln/morpho/closing.hh | 25 +--
mln/morpho/complementation.hh | 66 +++++---
mln/morpho/contrast.hh | 31 +--
mln/morpho/dilation.hh | 18 ++
mln/morpho/gradient.hh | 83 ++++------
mln/morpho/hit_or_miss.hh | 270 +++++++++++++++++---------------
mln/morpho/includes.hh | 3
mln/morpho/laplacian.hh | 34 +++-
mln/morpho/min.hh | 58 ++++---
mln/morpho/minus.hh | 66 ++++----
mln/morpho/opening.hh | 25 +--
mln/morpho/plus.hh | 65 ++++---
mln/morpho/thick_miss.hh | 27 +--
mln/morpho/thickening.hh | 28 +--
mln/morpho/thin_fit.hh | 29 ++-
mln/morpho/thinning.hh | 43 ++---
mln/morpho/top_hat.hh | 82 ++++------
mln/trait/op/minus.hh | 1
mln/value/builtin/ops.hh | 84 ++++++++--
mln/value/cast.hh | 23 ++
tests/arith_plus.cc | 17 +-
tests/labeling_level_fast.cc | 10 -
tests/morpho_contrast.cc | 26 ---
tests/morpho_gradient.cc | 8
tests/morpho_hit_or_miss.cc | 16 +
tests/morpho_laplacian.cc | 5
tests/morpho_thinning.cc | 19 +-
tests/pw_value.cc | 6
tests/value_int_s.cc | 2
tests/value_int_u8.cc | 5
tests/window2d.cc | 2
50 files changed, 1609 insertions(+), 697 deletions(-)
Index: tests/morpho_hit_or_miss.cc
--- tests/morpho_hit_or_miss.cc (revision 1405)
+++ tests/morpho_hit_or_miss.cc (working copy)
@@ -38,8 +38,8 @@
#include <mln/geom/shift.hh>
#include <mln/set/diff.hh>
-#include <mln/io/pgm/load.hh>
-#include <mln/io/pgm/save.hh>
+#include <mln/io/pbm/load.hh>
+#include <mln/io/pbm/save.hh>
#include <mln/level/fill.hh>
#include <mln/level/stretch.hh>
@@ -75,11 +75,13 @@
border::thickness = 2;
- image2d<int_u8>
- pic = io::pgm::load("../img/picasso.pgm"),
- out(pic.domain());
+ image2d<bool>
+ pic = io::pbm::load("../img/picasso.pbm"),
+ out = morpho::hit_or_miss(pic, win_hit, win_miss);
+ io::pbm::save(out, "out.pbm");
- morpho::hit_or_miss(pic, win_hit, win_miss, out);
+ mln_postcondition(morpho::hit_or_miss(morpho::complementation(pic),
+ win_miss, win_hit) = out);
- io::pgm::save(out, "out.pgm");
+ // FIXME: Do not work if the input image is pgm!
}
Index: tests/labeling_level_fast.cc
--- tests/labeling_level_fast.cc (revision 1405)
+++ tests/labeling_level_fast.cc (working copy)
@@ -42,20 +42,20 @@
#include <mln/debug/iota.hh>
#include <mln/debug/println.hh>
+
int main()
{
using namespace mln;
using value::int_u8;
- unsigned border = 1;
-
- image2d<value::int_u8> i1(5, 5, border);
+ image2d<value::int_u8> i1(5, 5);
debug::iota(i1);
- i1[10] = i1[17] = i1[18] = i1[25] = i1[26] = i1[22] = i1[29] = 2;
+ i1(point2d(0, 2)) = i1(point2d(1, 2)) = i1(point2d(1, 3)) = i1(point2d(2, 3)) = i1(point2d(2, 4)) = 2;
+ i1(point2d(2, 0)) = i1(point2d(3, 0)) = 2;
debug::println(i1);
unsigned n;
- image2d<value::int_u8> out(i1.domain(), border);
+ image2d<value::int_u8> out(i1.domain());
labeling::level(i1, 2, c4(), out, n);
std::cout << "n = " << n << std::endl;
Index: tests/arith_plus.cc
--- tests/arith_plus.cc (revision 1405)
+++ tests/arith_plus.cc (working copy)
@@ -37,6 +37,7 @@
#include <mln/arith/plus.hh>
#include <mln/arith/times.hh>
#include <mln/level/compare.hh>
+#include <mln/fun/v2v/cast.hh>
#include <mln/debug/iota.hh>
#include <mln/debug/println.hh>
@@ -47,6 +48,8 @@
{
using namespace mln;
+ // trace::quiet = false;
+
{
image2d<int> ref(3,3);
debug::iota(ref);
@@ -55,12 +58,16 @@
ima_i += ima_i;
mln_assertion(ima_i = 2 * ref);
-// debug::println(ima_i);
-// ima_i += 1;
-// debug::println(ima_i);
+ debug::println(ima_i);
+ ima_i += 1;
+ debug::println(ima_i);
+
+ image2d<float> ima_f(3,3);
+ debug::iota(ima_f);
+ debug::println(ima_i + ima_f);
-// debug::iota(ima_f);
-// debug::println(ima_i + ima_f);
+ point2d p(0, 0);
+ std::cout << arith::plus<float>(ima_i, ima_i)(p) / 5 << std::endl;
}
}
Index: tests/morpho_gradient.cc
--- tests/morpho_gradient.cc (revision 1405)
+++ tests/morpho_gradient.cc (working copy)
@@ -49,10 +49,8 @@
win::rectangle2d rect(5, 5);
border::thickness = 2;
- image2d<int_u8>
- lena = io::pgm::load("../img/tiny.pgm"),
- out(lena.domain());
+ image2d<int_u8> lena = io::pgm::load("../img/tiny.pgm");
- morpho::gradient(lena, rect, out);
- io::pgm::save(out, "out.pgm");
+ io::pgm::save( morpho::gradient(lena, rect),
+ "out.pgm" );
}
Index: tests/window2d.cc
--- tests/window2d.cc (revision 1405)
+++ tests/window2d.cc (working copy)
@@ -34,6 +34,7 @@
#include <mln/core/image2d.hh>
#include <mln/convert/to_image.hh>
#include <mln/debug/println.hh>
+#include <mln/logical/not.hh>
@@ -51,6 +52,7 @@
image2d<bool> ima = convert::to_image(w);
debug::println(ima);
+ debug::println(logical::not_(ima));
mln_assertion(w.delta() = 1);
}
Index: tests/value_int_s.cc
--- tests/value_int_s.cc (revision 1405)
+++ tests/value_int_s.cc (working copy)
@@ -31,6 +31,7 @@
*/
#include <mln/value/int_s.hh>
+#include <mln/value/int_u.hh>
int main()
@@ -47,5 +48,4 @@
mln_assertion(-i = -2);
mln_assertion(-3 * i = -6);
}
-
}
Index: tests/morpho_thinning.cc
--- tests/morpho_thinning.cc (revision 1405)
+++ tests/morpho_thinning.cc (working copy)
@@ -36,7 +36,9 @@
#include <mln/win/rectangle2d.hh>
#include <mln/core/window2d.hh>
+#include <mln/io/pbm/load.hh>
#include <mln/io/pgm/load.hh>
+#include <mln/io/pbm/save.hh>
#include <mln/io/pgm/save.hh>
#include <mln/morpho/thinning.hh>
@@ -59,11 +61,14 @@
border::thickness = 2;
- image2d<int_u8>
- pic = io::pgm::load("../img/picasso.pgm"),
- out(pic.domain());
-
- morpho::thinning(pic, win_fg, win_bg, out);
-
- io::pgm::save(out, "out.pgm");
+ {
+ image2d<bool> pic = io::pbm::load("../img/picasso.pbm");
+ io::pbm::save( morpho::thinning(pic, win_fg, win_bg),
+ "out.pbm" );
+ }
+// {
+// image2d<int_u8> pic = io::pgm::load("../img/picasso.pgm");
+// io::pgm::save( morpho::thinning(pic, win_fg, win_bg),
+// "out.pgm" );
+// }
}
Index: tests/morpho_laplacian.cc
--- tests/morpho_laplacian.cc (revision 1405)
+++ tests/morpho_laplacian.cc (working copy)
@@ -57,7 +57,6 @@
image2d<int> lap(lena.domain());
morpho::laplacian(lena, rect, lap);
- image2d< value::int_u_sat<8> > out(lena.domain());
- arith::plus_cst(lap, 128, out);
- io::pgm::save(out, "out.pgm");
+ io::pgm::save( arith::plus_cst< value::int_u_sat<8> >(lap, 128),
+ "out.pgm" );
}
Index: tests/value_int_u8.cc
--- tests/value_int_u8.cc (revision 1405)
+++ tests/value_int_u8.cc (working copy)
@@ -41,6 +41,11 @@
int_u8 i = 3, j;
+ {
+ int k = 0;
+ k += value::scalar(k);
+ }
+
// Assignment.
{
i = 51;
Index: tests/morpho_contrast.cc
--- tests/morpho_contrast.cc (revision 1405)
+++ tests/morpho_contrast.cc (working copy)
@@ -41,9 +41,6 @@
#include <mln/morpho/contrast.hh>
-#include <mln/level/fill.hh>
-#include <mln/level/saturate.hh>
-
int main()
{
@@ -53,27 +50,16 @@
win::rectangle2d rect(5, 5);
border::thickness = 2;
- image2d<int_u8>
- lena = io::pgm::load("../img/tiny.pgm"),
- out(lena.domain());
-
- image2d< value::int_s<10> >
- in(lena.domain()),
- tmp(lena.domain());
-
- level::fill(in, lena);
- morpho::contrast(in, rect, tmp);
-
- level::saturate(tmp, out);
+ image2d<int_u8> lena = io::pgm::load("../img/tiny.pgm");
+ image2d<int_u8> out = morpho::contrast(lena, rect);
io::pgm::save(out, "out.pgm");
{
// self-duality test:
- morpho::complementation_inplace(in);
- image2d< value::int_s<10> > tmp_(lena.domain());
- morpho::contrast(in, rect, tmp_);
- morpho::complementation_inplace(tmp_);
- mln_assertion(tmp_ = tmp);
+ image2d<int_u8> out_ = morpho::complementation( morpho::contrast( morpho::complementation(lena),
+ rect )
+ );
+ mln_assertion(out_ = out);
}
}
Index: tests/pw_value.cc
--- tests/pw_value.cc (revision 1405)
+++ tests/pw_value.cc (working copy)
@@ -44,4 +44,10 @@
point2d p = make::point2d(1, 1);
ima(p) = 51;
mln_assertion( (pw::value(ima) = pw::cst(51))(p) = true );
+
+ {
+ image2d<float> imaf(3,3);
+ imaf(p) = 51;
+ mln_assertion(((pw::value(ima) + pw::value(imaf))(p) / 20) - 5.1 < 0.00001);
+ }
}
Index: mln/trait/op/minus.hh
--- mln/trait/op/minus.hh (revision 1405)
+++ mln/trait/op/minus.hh (working copy)
@@ -39,6 +39,7 @@
# define mln_trait_op_minus(L, R) typename mln::trait::op::minus< L , R >::ret
# define mln_trait_op_minus_(L, R) mln::trait::op::minus< L , R >::ret
+# define mln_trait_op_minus_twice(T) mln_trait_op_minus(T, T)
namespace mln
Index: mln/core/image_if_interval.hh
--- mln/core/image_if_interval.hh (revision 1405)
+++ mln/core/image_if_interval.hh (working copy)
@@ -39,7 +39,7 @@
# include <mln/value/interval.hh>
-# define F fun::and_p2b_expr_< \
+# define F fun::and__p2b_expr_< \
fun::geq_p2b_expr_< \
pw::value_<I>, \
pw::cst_<mln_value(I)> >, \
Index: mln/core/concept/image.hh
--- mln/core/concept/image.hh (revision 1405)
+++ mln/core/concept/image.hh (working copy)
@@ -183,12 +183,14 @@
template <typename I, typename J>
void initialize(Image<I>& target, const Image<J>& model)
{
+ trace::entering("core::initialize");
mln_precondition(! exact(target).has_data());
mln_precondition(exact(model).has_data());
init_(tag::image, exact(target), exact(model));
mln_postcondition(exact(target).has_data());
+ trace::exiting("core::initialize");
}
Index: mln/core/clone.hh
--- mln/core/clone.hh (revision 1405)
+++ mln/core/clone.hh (working copy)
@@ -58,9 +58,13 @@
mln_concrete(I) clone(const Image<I>& model)
{
// FIXME: Add a static check that mln_concrete(I) actually *is* concrete...
+ trace::entering("core::clone");
+
mln_concrete(I) tmp;
initialize(tmp, model);
level::fill(tmp, model);
+
+ trace::exiting("core::clone");
return tmp;
}
Index: mln/arith/plus.hh
--- mln/arith/plus.hh (revision 1405)
+++ mln/arith/plus.hh (working copy)
@@ -67,6 +67,7 @@
mln_trait_op_plus(L,R)
operator+(const Image<L>& lhs, const Image<R>& rhs);
+
template <typename L, typename R>
L&
operator+=(Image<L>& lhs, const Image<R>& rhs);
@@ -76,6 +77,7 @@
mln_trait_op_plus(I,S)
operator+(const Image<I>& ima, const value::Scalar<S>& s);
+
template <typename I, typename S>
I&
operator+=(Image<I>& ima, const value::Scalar<S>& s);
@@ -89,39 +91,111 @@
*
* \param[in] lhs First operand image.
* \param[in] rhs Second operand image.
- * \param[out] output The result image.
+ * \result The result image.
*
- * \pre \p output.domain = \p lhs.domain = \p rhs.domain
+ * \pre \p lhs.domain = \p rhs.domain
*/
- template <typename L, typename R, typename O>
- void plus(const Image<L>& lhs, const Image<R>& rhs, Image<O>& output);
+ template <typename L, typename R>
+ mln_trait_op_plus(L, R)
+ plus(const Image<L>& lhs, const Image<R>& rhs);
- /*! Point-wise addition of the value \p val to image \p input.
+ /*! Point-wise addition of images \p lhs and \p rhs.
*
- * \param[in] input The image.
- * \param[in] val The value.
- * \param[out] output The result image.
+ * \param[in] lhs First operand image.
+ * \param[in] rhs Second operand image.
+ * \param[in] f Function.
+ * \result The result image.
+ *
+ * \pre \p lhs.domain = \p rhs.domain
+ */
+ template <typename L, typename R, typename F>
+ mln_ch_value(L, mln_result(F))
+ plus(const Image<L>& lhs, const Image<R>& rhs, const Function_v2v<F>& f);
+
+
+ /*! Point-wise addition of images \p lhs and \p rhs.
*
- * \pre \p output.domain = \p input.domain
+ * \param[in] lhs First operand image.
+ * \param[in] rhs Second operand image.
+ * \result The result image.
+ *
+ * The free parameter \c V sets the destination value type.
+ *
+ * \pre \p lhs.domain = \p rhs.domain
*/
- template <typename I, typename V, typename O>
- void plus_cst(const Image<I>& input, const V& val, Image<O>& output);
+ template <typename V, typename L, typename R>
+ mln_ch_value(L, V)
+ plus(const Image<L>& lhs, const Image<R>& rhs);
/*! Point-wise addition of image \p rhs in image \p lhs.
*
- * \param[in] lhs First operand image (subject to addition).
- * \param[in,out] rhs Second operand image (to be added to \p lhs).
+ * \param[in,out] lhs First operand image (subject to addition).
+ * \param[in] rhs Second operand image (to be added to \p lhs).
*
* This addition performs: \n
* for all p of rhs.domain \n
* lhs(p) += rhs(p)
*
- * \pre \p rhs.domain <= \p lhs.domain
+ * \pre \p rhs.domain = \p lhs.domain
*/
template <typename L, typename R>
- void plus_inplace(Image<L>& lhs, const Image<R>& rhs);
+ void
+ plus_inplace(Image<L>& lhs, const Image<R>& rhs);
+
+
+ /*! Point-wise addition of the value \p val to image \p input.
+ *
+ * \param[in] input The image.
+ * \param[in] val The value.
+ * \result The result image.
+ *
+ * \pre \p input.has_data
+ */
+ template <typename I, typename V>
+ mln_trait_op_plus(I, V)
+ plus_cst(const Image<I>& input, const V& val);
+
+
+ /*! Point-wise addition of the value \p val to image \p input.
+ *
+ * \param[in] input The image.
+ * \param[in] val The value.
+ * \param[in] f Function.
+ * \result The result image.
+ *
+ * \pre \p input.has_data
+ */
+ template <typename I, typename V, typename F>
+ mln_ch_value(I, mln_result(F))
+ plus_cst(const Image<I>& input, const V& val, const Function_v2v<F>& f);
+
+
+ /*! Point-wise addition of the value \p val to image \p input.
+ *
+ * \param[in] input The image.
+ * \param[in] val The value.
+ * \param[in] f Function.
+ * \result The result image.
+ *
+ * \pre \p input.has_data
+ */
+ template <typename W, typename I, typename V>
+ mln_ch_value(I, W)
+ plus_cst(const Image<I>& input, const V& val);
+
+
+ /*! Point-wise addition of the value \p val to image \p input.
+ *
+ * \param[in,out] input The image.
+ * \param[in] val The value.
+ *
+ * \pre \p input.has_data
+ */
+ template <typename I, typename V>
+ I&
+ plus_cst_inplace(Image<I>& input, const V& val);
} // end of namespace mln::arith
@@ -136,19 +210,25 @@
mln_trait_op_plus(L,R)
operator+(const Image<L>& lhs, const Image<R>& rhs)
{
+ trace::entering("operator::plus");
mln_precondition(exact(rhs).domain() = exact(lhs).domain());
- mln_trait_op_plus(L,R) tmp;
- initialize(tmp, lhs);
- arith::plus(lhs, rhs, tmp);
- return tmp;
+
+ mln_trait_op_plus(L,R) output = arith::plus(lhs, rhs);
+
+ trace::exiting("operator::plus");
+ return output;
}
template <typename L, typename R>
L&
operator+=(Image<L>& lhs, const Image<R>& rhs)
{
+ trace::entering("operator::plus_eq");
mln_precondition(exact(rhs).domain() = exact(lhs).domain());
+
arith::plus_inplace(lhs, rhs);
+
+ trace::exiting("operator::plus_eq");
return exact(lhs);
}
@@ -157,19 +237,25 @@
mln_trait_op_plus(I,S)
operator+(const Image<I>& ima, const value::Scalar<S>& s)
{
+ trace::entering("operator::plus");
mln_precondition(exact(ima).has_data());
- mln_trait_op_plus(I,S) tmp;
- initialize(tmp, ima);
- arith::plus_cst(ima, exact(s), tmp);
- return tmp;
+
+ mln_trait_op_plus(I,S) output = arith::plus_cst(ima, exact(s));
+
+ trace::exiting("operator::plus");
+ return output;
}
template <typename I, typename S>
I&
operator+=(Image<I>& ima, const value::Scalar<S>& s)
{
+ trace::entering("operator::plus_eq");
mln_precondition(exact(ima).has_data());
- arith::plus_cst(ima, exact(s), ima);
+
+ arith::plus_cst_inplace(ima, exact(s));
+
+ trace::exiting("operator::plus_eq");
return exact(ima);
}
@@ -183,18 +269,25 @@
template <typename L, typename R, typename O>
void plus_(trait::image::speed::any, const L& lhs,
- trait::image::speed::any, const R& rhs,
- trait::image::speed::any, O& output)
+ trait::image::speed::any, const R& rhs, O& output)
{
mln_piter(L) p(lhs.domain());
for_all(p)
output(p) = lhs(p) + rhs(p);
}
+ template <typename L, typename R, typename F, typename O>
+ void plus_(trait::image::speed::any, const L& lhs,
+ trait::image::speed::any, const R& rhs, const F& f, O& output)
+ {
+ mln_piter(L) p(lhs.domain());
+ for_all(p)
+ output(p) = f(lhs(p) + rhs(p));
+ }
+
template <typename L, typename R, typename O>
void plus_(trait::image::speed::fastest, const L& lhs,
- trait::image::speed::fastest, const R& rhs,
- trait::image::speed::fastest, O& output)
+ trait::image::speed::fastest, const R& rhs, O& output)
{
mln_pixter(const L) lp(lhs);
mln_pixter(const R) rp(rhs);
@@ -203,11 +296,22 @@
op.val() = lp.val() + rp.val();
}
+ template <typename L, typename R, typename F, typename O>
+ void plus_(trait::image::speed::fastest, const L& lhs,
+ trait::image::speed::fastest, const R& rhs, const F& f, O& output)
+ {
+ mln_pixter(const L) lp(lhs);
+ mln_pixter(const R) rp(rhs);
+ mln_pixter(O) op(output);
+ for_all_3(lp, rp, op)
+ op.val() = f(lp.val() + rp.val());
+ }
+
template <typename L, typename R>
void plus_inplace_(trait::image::speed::any, L& lhs,
trait::image::speed::any, const R& rhs)
{
- mln_piter(R) p(rhs.domain());
+ mln_piter(L) p(lhs.domain());
for_all(p)
lhs(p) += rhs(p);
}
@@ -218,7 +322,7 @@
{
mln_pixter(L) lp(lhs);
mln_pixter(const R) rp(rhs);
- for_all_2(rp, lp)
+ for_all_2(lp, rp)
lp.val() += rp.val();
}
@@ -227,38 +331,133 @@
// Facades.
- template <typename L, typename R, typename O>
- void plus(const Image<L>& lhs, const Image<R>& rhs, Image<O>& output)
+
+ template <typename L, typename R>
+ mln_trait_op_plus(L, R)
+ plus(const Image<L>& lhs, const Image<R>& rhs)
+ {
+ trace::entering("arith::plus");
+ mln_precondition(exact(rhs).domain() = exact(lhs).domain());
+
+ mln_trait_op_plus(L, R) output;
+ initialize(output, lhs);
+ impl::plus_(mln_trait_image_speed(L)(), exact(lhs),
+ mln_trait_image_speed(R)(), exact(rhs), output);
+
+ trace::exiting("arith::plus");
+ return output;
+ }
+
+
+ template <typename L, typename R, typename F>
+ mln_ch_value(L, mln_result(F))
+ plus(const Image<L>& lhs, const Image<R>& rhs, const Function_v2v<F>& f)
{
+ trace::entering("arith::plus");
mln_precondition(exact(rhs).domain() = exact(lhs).domain());
- mln_precondition(exact(output).domain() = exact(lhs).domain());
+
+ mln_ch_value(L, mln_result(F)) output;
+ initialize(output, lhs);
impl::plus_(mln_trait_image_speed(L)(), exact(lhs),
- mln_trait_image_speed(R)(), exact(rhs),
- mln_trait_image_speed(O)(), exact(output));
+ mln_trait_image_speed(R)(), exact(rhs), exact(f), output);
+
+ trace::exiting("arith::plus");
+ return output;
+ }
+
+
+ template <typename V, typename L, typename R>
+ mln_ch_value(L, V)
+ plus(const Image<L>& lhs, const Image<R>& rhs)
+ {
+ trace::entering("arith::plus");
+ mln_precondition(exact(rhs).domain() = exact(lhs).domain());
+
+ // Calls the previous version.
+ mln_ch_value(L, V) output = plus(lhs, rhs,
+ mln::fun::v2v::cast<V>());
+
+ trace::exiting("arith::plus");
+ return output;
+ }
+
+
+ template <typename I, typename V>
+ mln_trait_op_plus(I, V)
+ plus_cst(const Image<I>& input, const V& val)
+ {
+ trace::entering("arith::plus_cst");
+ mln_precondition(exact(input).has_data());
+
+ // Calls the previous version.
+ mln_trait_op_plus(I, V) output = plus(input,
+ pw::cst(val) | exact(input).domain());
+
+ trace::exiting("arith::plus_cst");
+ return output;
+ }
+
+
+ template <typename I, typename V, typename F>
+ mln_ch_value(I, mln_result(F))
+ plus_cst(const Image<I>& input, const V& val, const Function_v2v<F>& f)
+ {
+ trace::entering("arith::plus_cst");
+ mln_precondition(exact(input).has_data());
+
+ // Calls the previous version.
+ mln_ch_value(I, mln_result(F)) output = plus(input,
+ pw::cst(val) | exact(input).domain(),
+ f);
+
+ trace::exiting("arith::plus_cst");
+ return output;
}
- template <typename I, typename V, typename O>
- void plus_cst(const Image<I>& input, const V& val, Image<O>& output)
+
+ template <typename W, typename I, typename V>
+ mln_ch_value(I, W)
+ plus_cst(const Image<I>& input, const V& val)
{
- mln_precondition(exact(output).domain() = exact(input).domain());
- plus(input, pw::cst(val) | exact(input).domain(), output);
+ trace::entering("arith::plus_cst");
+ mln_precondition(exact(input).has_data());
+
// Calls the previous version.
+ mln_ch_value(I, W) output = plus_cst(input, val,
+ mln::fun::v2v::cast<W>());
+
+ trace::exiting("arith::plus_cst");
+ return output;
}
+
template <typename L, typename R>
- void plus_inplace(Image<L>& lhs, const Image<R>& rhs)
+ void
+ plus_inplace(Image<L>& lhs, const Image<R>& rhs)
{
- mln_precondition(exact(rhs).domain() <= exact(lhs).domain());
+ trace::entering("arith::plus_inplace");
+ mln_precondition(exact(rhs).domain() = exact(lhs).domain());
+
impl::plus_inplace_(mln_trait_image_speed(L)(), exact(lhs),
mln_trait_image_speed(R)(), exact(rhs));
+
+ trace::exiting("arith::plus_inplace");
}
+
template <typename I, typename V>
- void plus_cst_inplace(Image<I>& input, const V& val)
+ I&
+ plus_cst_inplace(Image<I>& input, const V& val)
{
+ trace::entering("arith::plus_cst_inplace");
mln_precondition(exact(input).has_data());
- plus_inplace(input, pw::cst(val) | exact(input).domain());
+
// Calls the previous version.
+ plus_inplace(input,
+ pw::cst(val) | exact(input).domain());
+
+ trace::exiting("arith::plus_cst_inplace");
+ return exact(input);
}
} // end of namespace mln::arith
Index: mln/arith/min.hh
--- mln/arith/min.hh (revision 1405)
+++ mln/arith/min.hh (working copy)
@@ -46,12 +46,13 @@
*
* \param[in] lhs First operand image.
* \param[in] rhs Second operand image.
- * \param[out] output The result image.
+ * \result The result image.
*
- * \pre \p output.domain = \p lhs.domain = \p rhs.domain
+ * \pre \p lhs.domain = \p rhs.domain
*/
- template <typename L, typename R, typename O>
- void min(const Image<L>& lhs, const Image<R>& rhs, Image<O>& output);
+ template <typename L, typename R>
+ mln_concrete(L)
+ min(const Image<L>& lhs, const Image<R>& rhs);
/*! Point-wise min of image \p lhs in image \p rhs.
@@ -59,12 +60,7 @@
* \param[in,out] lhs First operand image.
* \param[in] rhs Second operand image.
*
- * This substraction performs: \n
- * for all p of rhs.domain \n
- * if rhs(p) < lhs(p) \n
- * lhs(p) = rhs(p)
- *
- * \pre \p rhs.domain <= \p lhs.domain
+ * \pre \p rhs.domain = \p lhs.domain
*/
template <typename L, typename R>
void min_inplace(Image<L>& lhs, const Image<R>& rhs);
@@ -77,8 +73,7 @@
template <typename L, typename R, typename O>
void min_(trait::image::speed::any, const L& lhs,
- trait::image::speed::any, const R& rhs,
- trait::image::speed::any, O& output)
+ trait::image::speed::any, const R& rhs, O& output)
{
mln_piter(L) p(lhs.domain());
for_all(p)
@@ -87,8 +82,7 @@
template <typename L, typename R, typename O>
void min_(trait::image::speed::fastest, const L& lhs,
- trait::image::speed::fastest, const R& rhs,
- trait::image::speed::fastest, O& output)
+ trait::image::speed::fastest, const R& rhs, O& output)
{
mln_pixter(const L) lp(lhs);
mln_pixter(const R) rp(rhs);
@@ -101,7 +95,7 @@
void min_inplace_(trait::image::speed::any, L& lhs,
trait::image::speed::any, const R& rhs)
{
- mln_piter(R) p(rhs.domain());
+ mln_piter(L) p(lhs.domain());
for_all(p)
if (rhs(p) < lhs(p))
lhs(p) = rhs(p);
@@ -113,7 +107,7 @@
{
mln_pixter(L) lp(lhs);
mln_pixter(const R) rp(rhs);
- for_all_2(rp, lp)
+ for_all_2(lp, rp)
if (rp.val() < lp.val())
lp.val() = rp.val();
}
@@ -123,22 +117,31 @@
// Facades.
- template <typename L, typename R, typename O>
- void min(const Image<L>& lhs, const Image<R>& rhs, Image<O>& output)
+ template <typename L, typename R>
+ mln_concrete(L) min(const Image<L>& lhs, const Image<R>& rhs)
{
+ trace::entering("arith::min");
mln_precondition(exact(rhs).domain() = exact(lhs).domain());
- mln_precondition(exact(output).domain() = exact(lhs).domain());
+
+ mln_concrete(L) output;
+ initialize(output, lhs);
impl::min_(mln_trait_image_speed(L)(), exact(lhs),
- mln_trait_image_speed(R)(), exact(rhs),
- mln_trait_image_speed(O)(), exact(output));
+ mln_trait_image_speed(R)(), exact(rhs), output);
+
+ trace::exiting("arith::min");
+ return output;
}
template <typename L, typename R>
void min_inplace(Image<L>& lhs, const Image<R>& rhs)
{
- mln_precondition(exact(rhs).domain() <= exact(lhs).domain());
+ trace::entering("arith::min_inplace");
+ mln_precondition(exact(rhs).domain() = exact(lhs).domain());
+
impl::min_inplace_(mln_trait_image_speed(L)(), exact(lhs),
mln_trait_image_speed(R)(), exact(rhs));
+
+ trace::exiting("arith::min_inplace");
}
# endif // ! MLN_INCLUDE_ONLY
Index: mln/arith/includes.hh
--- mln/arith/includes.hh (revision 1405)
+++ mln/arith/includes.hh (working copy)
@@ -37,6 +37,7 @@
# include <mln/value/ops.hh>
# include <mln/pw/cst.hh>
# include <mln/pw/image.hh>
+# include <mln/fun/v2v/cast.hh>
#endif // ! MLN_ARITH_INCLUDES_HH
Index: mln/arith/revert.hh
--- mln/arith/revert.hh (revision 1405)
+++ mln/arith/revert.hh (working copy)
@@ -52,18 +52,24 @@
/*! Point-wise reversion of image \p input.
*
* \param[in] input the input image.
- * \param[out] output The result image.
+ * \result The result image.
*
- * \pre \p output.domain = \p input.domain
+ * \pre \p input.has_data
+ *
+ * It performs: \n
+ * for all p of input.domain \n
+ * output(p) = min + (max - input(p))
*/
- template <typename I, typename O>
- void revert(const Image<I>& input, Image<O>& output);
+ template <typename I>
+ mln_concrete(I) revert(const Image<I>& input);
/*! Point-wise in-place reversion of image \p input.
*
* \param[in,out] input The target image.
*
+ * \pre \p input.has_data
+ *
* It performs: \n
* for all p of input.domain \n
* input(p) = min + (max - input(p))
@@ -78,8 +84,7 @@
{
template <typename I, typename O>
- void revert_(trait::image::speed::any, const I& input,
- trait::image::speed::any, O& output)
+ void revert_(trait::image::speed::any, const I& input, O& output)
{
typedef mln_value(I) V;
mln_piter(I) p(input.domain());
@@ -88,8 +93,7 @@
}
template <typename I, typename O>
- void revert_(trait::image::speed::fastest, const I& input,
- trait::image::speed::fastest, O& output)
+ void revert_(trait::image::speed::fastest, const I& input, O& output)
{
typedef mln_value(I) V;
mln_pixter(const I) ip(input);
@@ -103,20 +107,29 @@
// Facades.
- template <typename I, typename O>
- void revert(const Image<I>& input, Image<O>& output)
+ template <typename I>
+ mln_concrete(I) revert(const Image<I>& input)
{
- mln_precondition(exact(output).domain() = exact(input).domain());
- impl::revert_(mln_trait_image_speed(I)(), exact(input),
- mln_trait_image_speed(O)(), exact(output));
+ trace::entering("arith::revert");
+ mln_precondition(exact(input).has_data());
+
+ mln_concrete(I) output;
+ initialize(output, input);
+ impl::revert_(mln_trait_image_speed(I)(), exact(input), output);
+
+ trace::exiting("arith::revert");
+ return output;
}
template <typename I>
void revert_inplace(Image<I>& input)
{
+ trace::entering("arith::revert_inplace");
mln_precondition(exact(input).has_data());
- impl::revert_(mln_trait_image_speed(I)(), exact(input),
- mln_trait_image_speed(I)(), exact(input));
+
+ impl::revert_(mln_trait_image_speed(I)(), exact(input), exact(input));
+
+ trace::exiting("arith::revert_inplace");
}
# endif // ! MLN_INCLUDE_ONLY
Index: mln/arith/minus.hh
--- mln/arith/minus.hh (revision 1405)
+++ mln/arith/minus.hh (working copy)
@@ -31,63 +31,249 @@
/*! \file mln/arith/minus.hh
*
* \brief Point-wise substraction between images.
+ *
+ * \todo Speedup; some versions are not optimal.
*/
-# include <mln/core/concept/image.hh>
+# include <mln/arith/includes.hh>
namespace mln
{
+
+ namespace trait
+ {
+
+ template <typename L, typename R>
+ struct set_binary_< op::minus, Image, L, Image, R >
+ {
+ typedef mln_trait_op_minus(mln_value(L), mln_value(R)) value;
+ typedef mln_ch_value(L, value) ret;
+ };
+
+ template <typename I, typename S>
+ struct set_binary_< op::minus, Image, I, mln::value::Scalar, S >
+ {
+ typedef mln_trait_op_minus(mln_value(I), S) value;
+ typedef mln_ch_value(I, value) ret;
+ };
+
+ } // end of namespace mln::trait
+
+
+
+ template <typename L, typename R>
+ mln_trait_op_minus(L,R)
+ operator-(const Image<L>& lhs, const Image<R>& rhs);
+
+
+ template <typename L, typename R>
+ L&
+ operator-=(Image<L>& lhs, const Image<R>& rhs);
+
+
+ template <typename I, typename S>
+ mln_trait_op_minus(I,S)
+ operator-(const Image<I>& ima, const value::Scalar<S>& s);
+
+
+ template <typename I, typename S>
+ I&
+ operator-=(Image<I>& ima, const value::Scalar<S>& s);
+
+
+
namespace arith
{
- /*! Point-wise substraction of images \p lhs and \p rhs.
+ /*! Point-wise addition of images \p lhs and \p rhs.
*
* \param[in] lhs First operand image.
* \param[in] rhs Second operand image.
- * \param[out] output The result image.
+ * \result The result image.
*
- * \pre \p output.domain = \p lhs.domain = \p rhs.domain
+ * \pre \p lhs.domain = \p rhs.domain
*/
- template <typename L, typename R, typename O>
- void minus(const Image<L>& lhs, const Image<R>& rhs, Image<O>& output);
+ template <typename L, typename R>
+ mln_trait_op_minus(L, R)
+ minus(const Image<L>& lhs, const Image<R>& rhs);
- /*! Point-wise substraction of image \p lhs in image \p rhs.
+ /*! Point-wise addition of images \p lhs and \p rhs.
*
- * \param[in,out] lhs First operand image (subject to substraction).
- * \param[in] rhs Second operand image (to be substracted to \p lhs).
+ * \param[in] lhs First operand image.
+ * \param[in] rhs Second operand image.
+ * \param[in] f Function.
+ * \result The result image.
*
- * This substraction performs: \n
+ * \pre \p lhs.domain = \p rhs.domain
+ */
+ template <typename L, typename R, typename F>
+ mln_ch_value(L, mln_result(F))
+ minus(const Image<L>& lhs, const Image<R>& rhs, const Function_v2v<F>& f);
+
+
+ /*! Point-wise addition of images \p lhs and \p rhs.
+ *
+ * \param[in] lhs First operand image.
+ * \param[in] rhs Second operand image.
+ * \result The result image.
+ *
+ * The free parameter \c V sets the destination value type.
+ *
+ * \pre \p lhs.domain = \p rhs.domain
+ */
+ template <typename V, typename L, typename R>
+ mln_ch_value(L, V)
+ minus(const Image<L>& lhs, const Image<R>& rhs);
+
+
+ /*! Point-wise addition of image \p rhs in image \p lhs.
+ *
+ * \param[in,out] lhs First operand image (subject to addition).
+ * \param[in] rhs Second operand image (to be added to \p lhs).
+ *
+ * This addition performs: \n
* for all p of rhs.domain \n
* lhs(p) -= rhs(p)
*
- * \pre \p rhs.domain <= \p lhs.domain
+ * \pre \p rhs.domain = \p lhs.domain
*/
template <typename L, typename R>
- void minus_inplace(Image<L>& lhs, const Image<R>& rhs);
+ void
+ minus_inplace(Image<L>& lhs, const Image<R>& rhs);
+
+
+ /*! Point-wise addition of the value \p val to image \p input.
+ *
+ * \param[in] input The image.
+ * \param[in] val The value.
+ * \result The result image.
+ *
+ * \pre \p input.has_data
+ */
+ template <typename I, typename V>
+ mln_trait_op_minus(I, V)
+ minus_cst(const Image<I>& input, const V& val);
+
+
+ /*! Point-wise addition of the value \p val to image \p input.
+ *
+ * \param[in] input The image.
+ * \param[in] val The value.
+ * \param[in] f Function.
+ * \result The result image.
+ *
+ * \pre \p input.has_data
+ */
+ template <typename I, typename V, typename F>
+ mln_ch_value(I, mln_result(F))
+ minus_cst(const Image<I>& input, const V& val, const Function_v2v<F>& f);
+
+
+ /*! Point-wise addition of the value \p val to image \p input.
+ *
+ * \param[in,out] input The image.
+ * \param[in] val The value.
+ *
+ * \pre \p input.has_data
+ */
+ template <typename I, typename V>
+ I&
+ minus_cst_inplace(Image<I>& input, const V& val);
+
+
+ } // end of namespace mln::arith
+
+
# ifndef MLN_INCLUDE_ONLY
+
+ template <typename L, typename R>
+ mln_trait_op_minus(L,R)
+ operator-(const Image<L>& lhs, const Image<R>& rhs)
+ {
+ trace::entering("operator::minus");
+ mln_precondition(exact(rhs).domain() = exact(lhs).domain());
+
+ mln_trait_op_minus(L,R) output = arith::minus(lhs, rhs);
+
+ trace::exiting("operator::minus");
+ return output;
+ }
+
+ template <typename L, typename R>
+ L&
+ operator-=(Image<L>& lhs, const Image<R>& rhs)
+ {
+ trace::entering("operator::minus_eq");
+ mln_precondition(exact(rhs).domain() = exact(lhs).domain());
+
+ arith::minus_inplace(lhs, rhs);
+
+ trace::exiting("operator::minus_eq");
+ return exact(lhs);
+ }
+
+
+ template <typename I, typename S>
+ mln_trait_op_minus(I,S)
+ operator-(const Image<I>& ima, const value::Scalar<S>& s)
+ {
+ trace::entering("operator::minus");
+ mln_precondition(exact(ima).has_data());
+
+ mln_trait_op_minus(I,S) output = arith::minus_cst(ima, exact(s));
+
+ trace::exiting("operator::minus");
+ return output;
+ }
+
+ template <typename I, typename S>
+ I&
+ operator-=(Image<I>& ima, const value::Scalar<S>& s)
+ {
+ trace::entering("operator::minus_eq");
+ mln_precondition(exact(ima).has_data());
+
+ arith::minus_cst_inplace(ima, exact(s));
+
+ trace::exiting("operator::minus_eq");
+ return exact(ima);
+ }
+
+
+
+ namespace arith
+ {
+
namespace impl
{
template <typename L, typename R, typename O>
void minus_(trait::image::speed::any, const L& lhs,
- trait::image::speed::any, const R& rhs,
- trait::image::speed::any, O& output)
+ trait::image::speed::any, const R& rhs, O& output)
{
mln_piter(L) p(lhs.domain());
for_all(p)
output(p) = lhs(p) - rhs(p);
}
+ template <typename L, typename R, typename F, typename O>
+ void minus_(trait::image::speed::any, const L& lhs,
+ trait::image::speed::any, const R& rhs, const F& f, O& output)
+ {
+ mln_piter(L) p(lhs.domain());
+ for_all(p)
+ output(p) = f(lhs(p) - rhs(p));
+ }
+
template <typename L, typename R, typename O>
void minus_(trait::image::speed::fastest, const L& lhs,
- trait::image::speed::fastest, const R& rhs,
- trait::image::speed::fastest, O& output)
+ trait::image::speed::fastest, const R& rhs, O& output)
{
mln_pixter(const L) lp(lhs);
mln_pixter(const R) rp(rhs);
@@ -96,11 +282,22 @@
op.val() = lp.val() - rp.val();
}
+ template <typename L, typename R, typename F, typename O>
+ void minus_(trait::image::speed::fastest, const L& lhs,
+ trait::image::speed::fastest, const R& rhs, const F& f, O& output)
+ {
+ mln_pixter(const L) lp(lhs);
+ mln_pixter(const R) rp(rhs);
+ mln_pixter(O) op(output);
+ for_all_3(lp, rp, op)
+ op.val() = f(lp.val() - rp.val());
+ }
+
template <typename L, typename R>
void minus_inplace_(trait::image::speed::any, L& lhs,
trait::image::speed::any, const R& rhs)
{
- mln_piter(R) p(rhs.domain());
+ mln_piter(L) p(lhs.domain());
for_all(p)
lhs(p) -= rhs(p);
}
@@ -111,7 +308,7 @@
{
mln_pixter(L) lp(lhs);
mln_pixter(const R) rp(rhs);
- for_all_2(rp, lp)
+ for_all_2(lp, rp)
lp.val() -= rp.val();
}
@@ -120,28 +317,123 @@
// Facades.
- template <typename L, typename R, typename O>
- void minus(const Image<L>& lhs, const Image<R>& rhs, Image<O>& output)
+
+ template <typename L, typename R>
+ mln_trait_op_minus(L, R)
+ minus(const Image<L>& lhs, const Image<R>& rhs)
{
+ trace::entering("arith::minus");
mln_precondition(exact(rhs).domain() = exact(lhs).domain());
- mln_precondition(exact(output).domain() = exact(lhs).domain());
+
+ mln_trait_op_minus(L, R) output;
+ initialize(output, lhs);
impl::minus_(mln_trait_image_speed(L)(), exact(lhs),
- mln_trait_image_speed(R)(), exact(rhs),
- mln_trait_image_speed(O)(), exact(output));
+ mln_trait_image_speed(R)(), exact(rhs), output);
+
+ trace::exiting("arith::minus");
+ return output;
}
+
+ template <typename L, typename R, typename F>
+ mln_ch_value(L, mln_result(F))
+ minus(const Image<L>& lhs, const Image<R>& rhs, const Function_v2v<F>& f)
+ {
+ trace::entering("arith::minus");
+ mln_precondition(exact(rhs).domain() = exact(lhs).domain());
+
+ mln_ch_value(L, mln_result(F)) output;
+ initialize(output, lhs);
+ impl::minus_(mln_trait_image_speed(L)(), exact(lhs),
+ mln_trait_image_speed(R)(), exact(rhs), exact(f), output);
+
+ trace::exiting("arith::minus");
+ return output;
+ }
+
+
+ template <typename V, typename L, typename R>
+ mln_ch_value(L, V)
+ minus(const Image<L>& lhs, const Image<R>& rhs)
+ {
+ trace::entering("arith::minus");
+ mln_precondition(exact(rhs).domain() = exact(lhs).domain());
+
+ // Calls the previous version.
+ mln_ch_value(L, V) output = minus(lhs, rhs,
+ mln::fun::v2v::cast<V>());
+
+ trace::exiting("arith::minus");
+ return output;
+ }
+
+
+ template <typename I, typename V>
+ mln_trait_op_minus(I, V)
+ minus_cst(const Image<I>& input, const V& val)
+ {
+ trace::entering("arith::minus_cst");
+ mln_precondition(exact(input).has_data());
+
+ // Calls the previous version.
+ mln_trait_op_minus(I, V) output = minus(input,
+ pw::cst(val) | exact(input).domain());
+
+ trace::exiting("arith::minus_cst");
+ return output;
+ }
+
+
+ template <typename I, typename V, typename F>
+ mln_ch_value(I, mln_result(F))
+ minus_cst(const Image<I>& input, const V& val, const Function_v2v<F>& f)
+ {
+ trace::entering("arith::minus_cst");
+ mln_precondition(exact(input).has_data());
+
+ // Calls the previous version.
+ mln_ch_value(I, mln_result(F)) output = minus(input,
+ pw::cst(val) | exact(input).domain(),
+ f);
+
+ trace::exiting("arith::minus_cst");
+ return output;
+ }
+
+
template <typename L, typename R>
- void minus_inplace(Image<L>& lhs, const Image<R>& rhs)
+ void
+ minus_inplace(Image<L>& lhs, const Image<R>& rhs)
{
- mln_precondition(exact(rhs).domain() <= exact(lhs).domain());
+ trace::entering("arith::minus_inplace");
+ mln_precondition(exact(rhs).domain() = exact(lhs).domain());
+
impl::minus_inplace_(mln_trait_image_speed(L)(), exact(lhs),
mln_trait_image_speed(R)(), exact(rhs));
+
+ trace::exiting("arith::minus_inplace");
}
-# endif // ! MLN_INCLUDE_ONLY
+
+ template <typename I, typename V>
+ I&
+ minus_cst_inplace(Image<I>& input, const V& val)
+ {
+ trace::entering("arith::minus_cst_inplace");
+ mln_precondition(exact(input).has_data());
+
+ // Calls the previous version.
+ minus_inplace(input,
+ pw::cst(val) | exact(input).domain());
+
+ trace::exiting("arith::minus_cst_inplace");
+ return exact(input);
+ }
} // end of namespace mln::arith
+# endif // ! MLN_INCLUDE_ONLY
+
} // end of namespace mln
Index: mln/value/cast.hh
--- mln/value/cast.hh (revision 1405)
+++ mln/value/cast.hh (working copy)
@@ -34,6 +34,7 @@
*/
# include <mln/core/concept/value.hh>
+# include <mln/value/equiv.hh>
namespace mln
@@ -56,24 +57,34 @@
template <typename S>
const S&
- cast_(const S& src, ...)
+ cast_(const void*, const S& src)
{
return src;
}
- template <typename T, typename S>
- typename S::equiv // FIXME: Is-that equiv here?
- cast_(const T&, const Value<S>& src)
+ template <typename O, typename S>
+ const S&
+ cast_(const Object<O>*, const S& src)
+ {
+ return src;
+ }
+
+ template <typename V, typename S>
+ mln_value_equiv(S)
+ cast_(const Value<V>*, const S& src)
{
- return exact(src);
+ return mln::value::equiv(src);
}
} // end of namespace mln::value::internal
+
template <typename Dest, typename Src>
Dest cast(const Src& src)
{
- return internal::cast_(src, src);
+ // FIXME: Add static_cast<Dest>?
+ // FIXME: Add exact()?
+ return internal::cast_(&src, src);
}
# endif // ! MLN_INCLUDE_ONLY
Index: mln/value/builtin/ops.hh
--- mln/value/builtin/ops.hh (revision 1405)
+++ mln/value/builtin/ops.hh (working copy)
@@ -185,7 +185,6 @@
// Operator "Builtin minus Object" is a special case.
-
# define mln_internal_decl_bi_minus_obj_(Builtin) \
\
template <typename O> \
@@ -194,7 +193,6 @@
\
struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n
-
# define mln_internal_def_bi_minus_obj_(Builtin) \
\
template <typename O> \
@@ -227,7 +225,6 @@
// Operator "Builtin 'div or mod' Object" is a special case.
-
# define mln_internal_decl_bi_dvmd_obj_(Symb, Name, Builtin) \
\
template <typename O> \
@@ -236,7 +233,6 @@
\
struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n
-
# define mln_internal_def_bi_dvmd_obj_(Symb, Name, Builtin) \
\
template <typename O> \
@@ -264,7 +260,6 @@
\
struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n
-
# define mln_internal_op_builtins_cmp_(De, Symb, Name) \
\
mln_internal_##De##_op_cmp_(Symb, Name, signed char); \
@@ -280,6 +275,48 @@
\
struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n
+
+
+// Operator "Builtin Op= Object" is a special case.
+
+
+# define mln_internal_decl_bi_opeq_obj_(Symb, Builtin) \
+ \
+ template <typename O> \
+ Builtin & \
+ operator Symb##= (Builtin & lhs, const Object<O>& rhs); \
+ \
+ struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n
+
+# define mln_internal_def_bi_opeq_obj_(Symb, Builtin) \
+ \
+ template <typename O> \
+ Builtin & \
+ operator Symb##= (Builtin & lhs, const Object<O>& rhs) \
+ { \
+ lhs Symb##= exact(rhs).to_equiv(); \
+ return lhs; \
+ } \
+ \
+ struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n
+
+# define mln_internal_builtins_opeq_obj_(De, Symb) \
+ \
+ mln_internal_##De##_bi_opeq_obj_(Symb, signed char); \
+ mln_internal_##De##_bi_opeq_obj_(Symb, unsigned char); \
+ mln_internal_##De##_bi_opeq_obj_(Symb, signed short); \
+ mln_internal_##De##_bi_opeq_obj_(Symb, unsigned short); \
+ mln_internal_##De##_bi_opeq_obj_(Symb, signed int); \
+ mln_internal_##De##_bi_opeq_obj_(Symb, unsigned int); \
+ mln_internal_##De##_bi_opeq_obj_(Symb, signed long); \
+ mln_internal_##De##_bi_opeq_obj_(Symb, unsigned long); \
+ mln_internal_##De##_bi_opeq_obj_(Symb, float); \
+ mln_internal_##De##_bi_opeq_obj_(Symb, double); \
+ \
+ struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n
+
+
+
// FIXME: What about pointers, arrays, bool, etc.
// FIXME: Mod is not defined for float and double...
@@ -339,11 +376,10 @@
template<> struct set_precise_unary_< op::uminus, unsigned short > { typedef int ret; };
template<> struct set_precise_unary_< op::uminus, signed int > { typedef signed int ret; };
- // Disabled cause no correct result can be obtained
- // e.g., (- unsigned int) is an (unsigned int)!
- template<> struct set_precise_unary_< op::uminus, unsigned int > {};
- template<> struct set_precise_unary_< op::uminus, signed long > {};
- template<> struct set_precise_unary_< op::uminus, unsigned long > {};
+ template<> struct set_precise_unary_< op::uminus, unsigned int > { typedef signed int ret; };
+ template<> struct set_precise_unary_< op::uminus, signed long > { typedef signed long ret; };
+ template<> struct set_precise_unary_< op::uminus, unsigned long > { typedef signed long ret; };
+
template<> struct set_precise_unary_< op::uminus, bool > {};
template<> struct set_precise_unary_< op::uminus, float > { typedef float ret; };
@@ -356,11 +392,20 @@
// A couple of builtins => promotion...
mln_internal_set_builtin_trait_is_promotion_(op::plus);
- mln_internal_set_builtin_trait_is_promotion_(op::minus);
mln_internal_set_builtin_trait_is_promotion_(op::times);
mln_internal_set_builtin_trait_is_promotion_(op::div);
mln_internal_set_builtin_trait_is_promotion_(op::mod);
+ // mln_internal_set_builtin_trait_is_promotion_(op::minus);
+
+ template <typename Bl, typename Br>
+ struct set_binary_< op::minus,
+ mln::value::Built_In, Bl, mln::value::Built_In, Br >
+ {
+ typedef mln_trait_op_uminus(Br) minus_Br;
+ typedef mln_trait_promote(Bl, minus_Br) ret;
+ };
+
// For comparisons (such as "less-than"), we get bool.
mln_internal_set_builtin_trait_is_bool_(op::eq);
@@ -495,6 +540,15 @@
// FIXME: ...
+ // Ops "bi Op= obj"
+ mln_internal_builtins_opeq_obj_(decl, +);
+ mln_internal_builtins_opeq_obj_(decl, -);
+ mln_internal_builtins_opeq_obj_(decl, *);
+ mln_internal_builtins_opeq_obj_(decl, /);
+ mln_internal_builtins_opeq_obj_(decl, %);
+
+
+
# ifndef MLN_INCLUDE_ONLY
mln_internal_op_obj_builtins_(def, +, plus);
@@ -521,6 +575,14 @@
// FIXME: Add less, etc.
+ // Ops "bi Op= obj"
+ mln_internal_builtins_opeq_obj_(def, +);
+ mln_internal_builtins_opeq_obj_(def, -);
+ mln_internal_builtins_opeq_obj_(def, *);
+ mln_internal_builtins_opeq_obj_(def, /);
+ mln_internal_builtins_opeq_obj_(def, %);
+
+
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln
Index: mln/convert/to_image.hh
--- mln/convert/to_image.hh (revision 1405)
+++ mln/convert/to_image.hh (working copy)
@@ -124,6 +124,8 @@
template <typename S>
image1d<std::size_t> to_image(const mln::histo::data<S>& h);
+
+
# ifndef MLN_INCLUDE_ONLY
template <typename S>
Index: mln/fun/ops.hh
--- mln/fun/ops.hh (revision 1405)
+++ mln/fun/ops.hh (working copy)
@@ -35,6 +35,7 @@
# include <mln/core/concept/function.hh>
# include <mln/fun/internal/selector.hh>
+# include <mln/trait/all.hh>
@@ -47,7 +48,8 @@
struct Name##_##Out##_expr_ \
: public Function_##Out < Name##_##Out##_expr_<L,R> > \
{ \
- typedef mln_result(L) result; \
+ typedef typename mln::trait::op:: Name < mln_result(L), \
+ mln_result(R) >::ret result; \
\
Name##_##Out##_expr_(const L& l, const R& r) \
: l_(l), r_(r) \
@@ -67,6 +69,18 @@
\
} \
\
+ namespace trait \
+ { \
+ \
+ template <typename L, typename R> \
+ struct set_binary_< op::Name, \
+ Function_##In, L, \
+ Function_##In, R > \
+ { \
+ typedef fun::Name##_##Out##_expr_<L,R> ret; \
+ }; \
+ } \
+ \
template <typename L, typename R> \
fun::Name##_##Out##_expr_<L,R> \
operator Symbol (const Function_##In<L>& lhs, const Function_##In<R>& rhs) \
@@ -75,7 +89,7 @@
return tmp; \
} \
\
- struct dummy
+ struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n
# define mln_decl_unary_expr_(In, Out, Name, Symbol) \
@@ -87,7 +101,7 @@
struct Name##_##Out##_expr_ \
: public Function_##Out< Name##_##Out##_expr_<F> > \
{ \
- typedef mln_result(F) result; \
+ typedef typename mln::trait::op:: Name < mln_result(F) >::ret result; \
\
Name##_##Out##_expr_(const F& f) \
: f_(f) \
@@ -106,6 +120,16 @@
\
} \
\
+ namespace trait \
+ { \
+ template <typename F> \
+ struct set_unary_< op::Name, \
+ Function_##In, F > \
+ { \
+ typedef fun::Name##_##Out##_expr_<F> ret; \
+ }; \
+ } \
+ \
template <typename F> \
fun::Name##_##Out##_expr_<F> \
operator Symbol (const Function_##In<F>& f) \
@@ -114,7 +138,7 @@
return tmp; \
} \
\
- struct dummy
+ struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n
@@ -130,11 +154,11 @@
mln_decl_binary_expr_(p2v, p2b, geq, >=);
mln_decl_binary_expr_(p2v, p2b, greater, >);
- mln_decl_binary_expr_(p2b, p2b, and, &&);
- mln_decl_binary_expr_(p2b, p2b, or, ||);
- mln_decl_binary_expr_(p2b, p2b, xor, ^);
+ mln_decl_binary_expr_(p2b, p2b, and_, &&);
+ mln_decl_binary_expr_(p2b, p2b, or_, ||);
+ mln_decl_binary_expr_(p2b, p2b, xor_, ^);
- mln_decl_unary_expr_(p2b, p2b, not, !);
+ mln_decl_unary_expr_(p2b, p2b, not_, !);
mln_decl_binary_expr_(p2v, p2v, plus, +);
mln_decl_binary_expr_(p2v, p2v, minus, -);
@@ -155,11 +179,11 @@
mln_decl_binary_expr_(v2v, v2b, geq, >=);
mln_decl_binary_expr_(v2v, v2b, greater, >);
- mln_decl_binary_expr_(v2b, v2b, and, &&);
- mln_decl_binary_expr_(v2b, v2b, or, ||);
- mln_decl_binary_expr_(v2b, v2b, xor, ^);
+ mln_decl_binary_expr_(v2b, v2b, and_, &&);
+ mln_decl_binary_expr_(v2b, v2b, or_, ||);
+ mln_decl_binary_expr_(v2b, v2b, xor_, ^);
- mln_decl_unary_expr_(v2b, v2b, not, !);
+ mln_decl_unary_expr_(v2b, v2b, not_, !);
} // end of namespace mln
Index: mln/fun/cast.hh
--- mln/fun/cast.hh (revision 0)
+++ mln/fun/cast.hh (revision 0)
@@ -0,0 +1,84 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// 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_FUN_CAST_HH
+# define MLN_FUN_CAST_HH
+
+/*! \file mln/fun/cast.hh
+ *
+ * \brief FIXME.
+ */
+
+# include <mln/core/concept/function.hh>
+
+
+namespace mln
+{
+
+ namespace fun
+ {
+
+ // FIXME: Doc!
+ template <typename V, typename F>
+ struct cast_p2v_expr_ : public Function_p2v< cast_p2v_expr_<V,F> >
+ {
+ typedef V result;
+
+ cast_p2v_expr_(const F& f)
+ : f_(f)
+ {}
+
+ template <typename P>
+ V operator()(const P& p) const
+ {
+ return static_cast<V>(f_(p)); // FIXME: value::cast?
+ }
+
+ protected:
+ const F f_;
+ };
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename V, typename F>
+ cast_p2v_expr_<V, F>
+ cast(const Function_p2v<F>& f)
+ {
+ cast_p2v_expr_<V, F> tmp(exact(f));
+ return tmp;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::fun
+
+} // end of namespace mln
+
+
+#endif // ! MLN_FUN_CAST_HH
Index: mln/fun/v2v/saturate.hh
--- mln/fun/v2v/saturate.hh (revision 1405)
+++ mln/fun/v2v/saturate.hh (working copy)
@@ -87,16 +87,21 @@
V
saturate<V>::operator()(const W& w) const
{
+ // FIXME: Check that W is a larger type than V; otherwise
+ // alt code.
+ static const W min_W = mln::value::cast<W>(min_);
+ static const W max_W = mln::value::cast<W>(max_);
+
// FIXME: Below we need something more powerful that mlc_converts_to
- // FIXME: for instance, with W=int_s<10u> and V=int_u<8u>, it does not
- // FIXME: works cause the cast is not obvious...
+ // for instance, with W=int_s<10u> and V=int_u<8u>, it does not
+ // works cause the cast is not obvious...
// mlc_converts_to(W, V)::check();
- V w_ = mln::value::cast<V>(w);
- if (w_ < min_)
+
+ if (w < min_W)
return min_;
- if (w_ > max_)
+ if (w > max_W)
return max_;
- return w_;
+ return mln::value::cast<W>(w);
}
# endif // ! MLN_INCLUDE_ONLY
Index: mln/fun/v2v/all.hh
--- mln/fun/v2v/all.hh (revision 1405)
+++ mln/fun/v2v/all.hh (working copy)
@@ -50,6 +50,7 @@
# include <mln/fun/v2v/abs.hh>
+# include <mln/fun/v2v/cast.hh>
# include <mln/fun/v2v/enc.hh>
# include <mln/fun/v2v/id.hh>
# include <mln/fun/v2v/linear.hh>
Index: mln/fun/v2v/cast.hh
--- mln/fun/v2v/cast.hh (revision 0)
+++ mln/fun/v2v/cast.hh (revision 0)
@@ -0,0 +1,80 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// 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_FUN_V2V_CAST_HH
+# define MLN_FUN_V2V_CAST_HH
+
+/*! \file mln/fun/v2v/cast.hh
+ *
+ * \brief FIXME.
+ */
+
+# include <mln/core/concept/function.hh>
+# include <mln/value/cast.hh>
+
+
+namespace mln
+{
+
+ namespace fun
+ {
+
+ namespace v2v
+ {
+
+ // FIXME: Doc!
+
+ template <typename V>
+ struct cast : public Function_v2v< cast<V> >
+ {
+ typedef V result;
+
+ template <typename W>
+ V operator()(const W& w) const;
+ };
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename V>
+ template <typename W>
+ V
+ cast<V>::operator()(const W& w) const
+ {
+ return mln::value::cast<V>(w);
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::fun::v2v
+
+ } // end of namespace mln::fun
+
+} // end of namespace mln
+
+
+#endif // ! MLN_FUN_V2V_CAST_HH
Index: mln/morpho/thickening.hh
--- mln/morpho/thickening.hh (revision 1405)
+++ mln/morpho/thickening.hh (working copy)
@@ -47,26 +47,30 @@
*
* This operator is THICK_B = Id + HMT_B, where B = (Bfg, Bbg).
*/
- template <typename I, typename Wfg, typename Wbg, typename O>
- void thickening(const Image<I>& input,
- const Window<Wfg>& win_fg, const Window<Wbg>& win_bg,
- Image<O>& output);
+ template <typename I, typename Wfg, typename Wbg>
+ mln_concrete(I)
+ thickening(const Image<I>& input,
+ const Window<Wfg>& win_fg, const Window<Wbg>& win_bg);
# ifndef MLN_INCLUDE_ONLY
- template <typename I, typename Wfg, typename Wbg, typename O>
- void thickening(const Image<I>& input,
- const Window<Wfg>& win_fg, const Window<Wbg>& win_bg,
- Image<O>& output)
+ template <typename I, typename Wfg, typename Wbg>
+ mln_concrete(I)
+ thickening(const Image<I>& input,
+ const Window<Wfg>& win_fg, const Window<Wbg>& win_bg)
{
- mln_precondition(exact(output).domain() = exact(input).domain());
+ trace::entering("morpho::thickening");
+ mln_precondition(exact(input).has_data());
mln_precondition(exact(win_bg).is_centered());
+ mln_precondition(! exact(win_fg).is_empty());
mln_precondition(set::inter(exact(win_fg), exact(win_bg)).is_empty());
- O temp(exact(input).domain());
- hit_or_miss(input, win_fg, win_bg, temp);
- morpho::plus(input, temp, output);
+ mln_concrete(I) output = morpho::plus( input,
+ hit_or_miss(input, win_fg, win_bg) );
+
+ trace::exiting("morpho::thickening");
+ return output;
}
# endif // ! MLN_INCLUDE_ONLY
Index: mln/morpho/plus.hh
--- mln/morpho/plus.hh (revision 1405)
+++ mln/morpho/plus.hh (working copy)
@@ -49,16 +49,16 @@
/*! Morphological plus: either a "logical or" (if morpho on sets)
* or an "arithmetical plus" (if morpho on functions).
*/
- template <typename I, typename J, typename O>
- void plus(const Image<I>& lhs, const Image<J>& rhs,
- Image<O>& output);
-
- /*! Morphological plus, inplace version: either a "logical or" (if
- * morpho on sets) or an "arithmetical plus" (if morpho on
- * functions).
- */
template <typename I, typename J>
- void plus_inplace(Image<I>& lhs, const Image<J>& rhs);
+ mln_concrete(I) plus(const Image<I>& lhs, const Image<J>& rhs);
+
+
+// /*! Morphological plus, inplace version: either a "logical or" (if
+// * morpho on sets) or an "arithmetical plus" (if morpho on
+// * functions).
+// */
+// template <typename I, typename J>
+// void plus_inplace(Image<I>& lhs, const Image<J>& rhs);
# ifndef MLN_INCLUDE_ONLY
@@ -66,20 +66,22 @@
namespace impl
{
- template <typename I, typename J, typename O>
- void plus_(trait::image::kind::logic, // binary => morphology on sets
- const Image<I>& lhs, const Image<J>& rhs,
- Image<O>& output)
+ // Binary => morphology on sets.
+
+ template <typename I, typename J>
+ mln_concrete(I) plus_(trait::image::kind::logic,
+ const I& lhs, const J& rhs)
{
- return logical::or_(lhs, rhs, output);
+ return logical::or_(lhs, rhs);
}
- template <typename K, typename I, typename J, typename O>
- void plus_(K, // otherwise => morphology on functions
- const Image<I>& lhs, const Image<J>& rhs,
- Image<O>& output)
+ // Otherwise => morphology on functions.
+
+ template <typename I, typename J>
+ mln_concrete(I) plus_(trait::image::kind::any,
+ const I& lhs, const J& rhs)
{
- return arith::plus(lhs, rhs, output);
+ return arith::plus<mln_value(I)>(lhs, rhs);
}
} // end of namespace mln::morpho::impl
@@ -87,21 +89,26 @@
// Facades.
- template <typename I, typename J, typename O>
- void plus(const Image<I>& lhs, const Image<J>& rhs, Image<O>& output)
- {
- mln_precondition(exact(rhs).domain() = exact(lhs).domain());
- mln_precondition(exact(output).domain() = exact(lhs).domain());
- impl::plus_(mln_trait_image_kind(I)(), exact(lhs), exact(rhs), output);
- }
-
template <typename I, typename J>
- void plus_inplace(Image<I>& lhs, const Image<J>& rhs)
+ mln_concrete(I) plus(const Image<I>& lhs, const Image<J>& rhs)
{
+ trace::entering("morpho::plus");
mln_precondition(exact(rhs).domain() = exact(lhs).domain());
- morpho::plus(lhs, rhs, lhs); // Calls the previous version.
+
+ mln_concrete(I) output = impl::plus_(mln_trait_image_kind(I)(),
+ exact(lhs), exact(rhs));
+
+ trace::exiting("morpho::plus");
+ return output;
}
+// template <typename I, typename J>
+// void plus_inplace(Image<I>& lhs, const Image<J>& rhs)
+// {
+// mln_precondition(exact(rhs).domain() = exact(lhs).domain());
+// morpho::plus(lhs, rhs, lhs); // Calls the previous version.
+// }
+
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln::morpho
Index: mln/morpho/min.hh
--- mln/morpho/min.hh (revision 1405)
+++ mln/morpho/min.hh (working copy)
@@ -49,9 +49,10 @@
/*! Morphological min: either a logical "and" (if morpho on sets)
* or an arithmetical min (if morpho on functions).
*/
- template <typename I, typename J, typename O>
- void min(const Image<I>& lhs, const Image<J>& rhs,
- Image<O>& output);
+ template <typename I, typename J>
+ mln_concrete(I)
+ min(const Image<I>& lhs, const Image<J>& rhs);
+
/*! Morphological min, inplace version: either a logical "and" (if
* morpho on sets) or an arithmetical min (if morpho on
@@ -66,36 +67,36 @@
namespace impl
{
+ // Binary => morphology on sets.
+
template <typename I, typename J, typename O>
- void min_(trait::image::kind::logic, // binary => morphology on sets
- const Image<I>& lhs, const Image<J>& rhs,
- Image<O>& output)
+ mln_concrete(I) min_(trait::image::kind::logic,
+ const I& lhs, const J& rhs)
{
- return logical::and_(lhs, rhs, output);
+ return logical::and_(lhs, rhs);
}
- template <typename K, typename I, typename J, typename O>
- void min_(K, // otherwise => morphology on functions
- const Image<I>& lhs, const Image<J>& rhs,
- Image<O>& output)
+ template <typename I, typename J>
+ void min_inplace_(trait::image::kind::logic,
+ I& lhs, const J& rhs)
{
- return arith::min(lhs, rhs, output);
+ logical::and_inplace(lhs, rhs);
}
- // in place
+ // Otherwise => morphology on functions.
template <typename I, typename J>
- void min_inplace_(trait::image::kind::logic, // binary => morphology on sets
- Image<I>& lhs, const Image<J>& rhs)
+ mln_concrete(I) min_(trait::image::kind::any,
+ const I& lhs, const J& rhs)
{
- return logical::and_inplace(lhs, rhs);
+ return arith::min(lhs, rhs);
}
- template <typename K, typename I, typename J>
- void min_inplace_(K, // otherwise => morphology on functions
- Image<I>& lhs, const Image<J>& rhs)
+ template <typename I, typename J>
+ void min_inplace_(trait::image::kind::any,
+ I& lhs, const J& rhs)
{
- return arith::min_inplace(lhs, rhs);
+ arith::min_inplace(lhs, rhs);
}
} // end of namespace mln::morpho::impl
@@ -103,19 +104,28 @@
// Facades.
- template <typename I, typename J, typename O>
- void min(const Image<I>& lhs, const Image<J>& rhs, Image<O>& output)
+ template <typename I, typename J>
+ mln_concrete(I)
+ min(const Image<I>& lhs, const Image<J>& rhs)
{
+ trace::entering("morpho::min");
mln_precondition(exact(rhs).domain() = exact(lhs).domain());
- mln_precondition(exact(output).domain() = exact(lhs).domain());
- impl::min_(mln_trait_image_kind(I)(), exact(lhs), exact(rhs), output);
+
+ mln_concrete(I) output = impl::min_(mln_trait_image_kind(I)(), exact(lhs), exact(rhs));
+
+ trace::exiting("morpho::min");
+ return output;
}
template <typename I, typename J>
void min_inplace(Image<I>& lhs, const Image<J>& rhs)
{
+ trace::entering("morpho::min_inplace");
mln_precondition(exact(rhs).domain() = exact(lhs).domain());
+
impl::min_inplace_(mln_trait_image_kind(I)(), exact(lhs), exact(rhs));
+
+ trace::exiting("morpho::min_inplace_");
}
# endif // ! MLN_INCLUDE_ONLY
Index: mln/morpho/laplacian.hh
--- mln/morpho/laplacian.hh (revision 1405)
+++ mln/morpho/laplacian.hh (working copy)
@@ -53,24 +53,42 @@
Image<O>& output);
+ template <typename I, typename W>
+ mln_trait_op_minus_twice(mln_concrete(I))
+ laplacian(const Image<I>& input, const Window<W>& win);
+
+
# ifndef MLN_INCLUDE_ONLY
template <typename I, typename W, typename O>
void laplacian(const Image<I>& input, const Window<W>& win, Image<O>& output)
{
+ trace::entering("morpho::laplacian");
mln_precondition(exact(output).domain() = exact(input).domain());
mln_precondition(! exact(win).is_empty());
- dilation(input, win, output); // output = dilation
- morpho::minus_inplace(output, input); // now output = dilation - input
+ mln_concrete(I)
+ d_I = morpho::minus(dilation(input, win), input),
+ e_I = morpho::minus(input, erosion(input, win));
+ level::fill(output, d_I - e_I);
- O temp(exact(input).domain());
- {
- O temp_(exact(input).domain());
- erosion(input, win, temp_); // temp_ = erosion
- morpho::minus(input, temp_, temp); // temp = input - erosion
+ trace::exiting("morpho::laplacian");
}
- morpho::minus_inplace(output, temp); // now output = (dilation - input) - (input - erosion)
+
+ template <typename I, typename W>
+ mln_trait_op_minus_twice(mln_concrete(I))
+ laplacian(const Image<I>& input, const Window<W>& win)
+ {
+ trace::entering("morpho::laplacian");
+ mln_precondition(exact(input).has_data());
+ mln_precondition(! exact(win).is_empty());
+
+ mln_trait_op_minus_twice(mln_concrete(I)) output;
+ initialize(output, input);
+ laplacian(input, win, output); // Calls previous version.
+
+ trace::exiting("morpho::laplacian");
+ return output;
}
# endif // ! MLN_INCLUDE_ONLY
Index: mln/morpho/minus.hh
--- mln/morpho/minus.hh (revision 1405)
+++ mln/morpho/minus.hh (working copy)
@@ -49,16 +49,16 @@
/*! Morphological minus: either a logical "and not" (if morpho on
* sets) or an arithmetical minus (if morpho on functions).
*/
- template <typename I, typename J, typename O>
- void minus(const Image<I>& lhs, const Image<J>& rhs,
- Image<O>& output);
-
- /*! Morphological minus, inplace version: either a logical "and
- * not" (if morpho on sets) or an arithmetical minus (if morpho
- * on functions).
- */
template <typename I, typename J>
- void minus_inplace(Image<I>& lhs, const Image<J>& rhs);
+ mln_concrete(I) minus(const Image<I>& lhs, const Image<J>& rhs);
+
+
+// /*! Morphological minus, inplace version: either a logical "and
+// * not" (if morpho on sets) or an arithmetical minus (if morpho
+// * on functions).
+// */
+// template <typename I, typename J>
+// void minus_inplace(Image<I>& lhs, const Image<J>& rhs);
# ifndef MLN_INCLUDE_ONLY
@@ -66,20 +66,22 @@
namespace impl
{
- template <typename I, typename J, typename O>
- void minus_(trait::image::kind::logic, // binary => morphology on sets
- const Image<I>& lhs, const Image<J>& rhs,
- Image<O>& output)
+ // Binary => morphology on sets.
+
+ template <typename I, typename J>
+ mln_concrete(I) minus_(trait::image::kind::logic,
+ const I& lhs, const J& rhs)
{
- return logical::and_not(lhs, rhs, output);
+ return logical::and_not(lhs, rhs);
}
- template <typename K, typename I, typename J, typename O>
- void minus_(K, // otherwise => morphology on functions
- const Image<I>& lhs, const Image<J>& rhs,
- Image<O>& output)
+ // Otherwise => morphology on functions.
+
+ template <typename I, typename J>
+ mln_concrete(I) minus_(trait::image::kind::any,
+ const I& lhs, const J& rhs)
{
- return arith::minus(lhs, rhs, output);
+ return arith::minus<mln_value(I)>(lhs, rhs);
}
} // end of namespace mln::morpho::impl
@@ -87,21 +89,27 @@
// Facades.
- template <typename I, typename J, typename O>
- void minus(const Image<I>& lhs, const Image<J>& rhs, Image<O>& output)
- {
- mln_precondition(exact(rhs).domain() = exact(lhs).domain());
- mln_precondition(exact(output).domain() = exact(lhs).domain());
- impl::minus_(mln_trait_image_kind(I)(), exact(lhs), exact(rhs), output);
- }
-
template <typename I, typename J>
- void minus_inplace(Image<I>& lhs, const Image<J>& rhs)
+ mln_concrete(I)
+ minus(const Image<I>& lhs, const Image<J>& rhs)
{
+ trace::entering("morpho::minus");
mln_precondition(exact(rhs).domain() = exact(lhs).domain());
- morpho::minus(lhs, rhs, lhs); // Calls the previous version.
+
+ mln_concrete(I) output = impl::minus_(mln_trait_image_kind(I)(),
+ exact(lhs), exact(rhs));
+
+ trace::exiting("morpho::minus");
+ return output;
}
+// template <typename I, typename J>
+// void minus_inplace(Image<I>& lhs, const Image<J>& rhs)
+// {
+// mln_precondition(exact(rhs).domain() = exact(lhs).domain());
+// morpho::minus(lhs, rhs, lhs); // Calls the previous version.
+// }
+
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln::morpho
Index: mln/morpho/gradient.hh
--- mln/morpho/gradient.hh (revision 1405)
+++ mln/morpho/gradient.hh (working copy)
@@ -48,82 +48,73 @@
*
* This operator is d_B - e_B.
*/
- template <typename I, typename W, typename O>
- void gradient(const Image<I>& input, const Window<W>& win,
- Image<O>& output);
+ template <typename I, typename W>
+ mln_concrete(I) gradient(const Image<I>& input, const Window<W>& win);
/*! Morphological internal gradient.
*
* This operator is Id - e_B.
*/
- template <typename I, typename W, typename O>
- void gradient_internal(const Image<I>& input, const Window<W>& win,
- Image<O>& output);
+ template <typename I, typename W>
+ mln_concrete(I) gradient_internal(const Image<I>& input, const Window<W>& win);
/*! Morphological external gradient.
*
* This operator is d_B - Id.
*/
- template <typename I, typename W, typename O>
- void gradient_external(const Image<I>& input, const Window<W>& win,
- Image<O>& output);
+ template <typename I, typename W>
+ mln_concrete(I) gradient_external(const Image<I>& input, const Window<W>& win);
# ifndef MLN_INCLUDE_ONLY
- template <typename I, typename W, typename O>
- void gradient(const Image<I>& input_, const Window<W>& win_, Image<O>& output_)
+ template <typename I, typename W>
+ mln_concrete(I) gradient(const Image<I>& input, const Window<W>& win)
{
- const I& input = exact(input_);
- const W& win = exact(win_);
- O& output = exact(output_);
-
- mln_precondition(output.domain() = input.domain());
- mln_precondition(! win.is_empty());
-
- dilation(input, win, output); // output = dilation
- O temp(input.domain());
- erosion(input, win, temp); // temp = erosion
- morpho::minus_inplace(output, temp); // now output = dilation - erosion
+ trace::entering("morpho::gradient");
+ mln_precondition(exact(input).has_data());
+ mln_precondition(! exact(win).is_empty());
+
+ mln_concrete(I) output = morpho::minus(dilation(input, win),
+ erosion(input, win));
mln_postcondition(test::positive(output));
+ trace::exiting("morpho::gradient");
+ return output;
}
- template <typename I, typename W, typename O>
- void gradient_internal(const Image<I>& input_, const Window<W>& win_,
- Image<O>& output_)
+
+ template <typename I, typename W>
+ mln_concrete(I) gradient_internal(const Image<I>& input, const Window<W>& win)
{
- const I& input = exact(input_);
- const W& win = exact(win_);
- O& output = exact(output_);
-
- mln_precondition(output.domain() = input.domain());
- mln_precondition(! win.is_empty());
-
- O temp(input.domain());
- erosion(input, win, temp); // temp = erosion
- morpho::minus(input, temp, output); // output = input - erosion
+ trace::entering("morpho::gradient_internal");
+ mln_precondition(exact(input).has_data());
+ mln_precondition(! exact(win).is_empty());
+
+ mln_concrete(I) output = morpho::minus(input,
+ erosion(input, win));
mln_postcondition(test::positive(output));
+ trace::exiting("morpho::gradient_internal");
+ return output;
}
- template <typename I, typename W, typename O>
- void gradient_external(const Image<I>& input_, const Window<W>& win_,
- Image<O>& output_)
- {
- const I& input = exact(input_);
- const W& win = exact(win_);
- O& output = exact(output_);
- mln_precondition(output.domain() = input.domain());
- mln_precondition(! win.is_empty());
+ template <typename I, typename W>
+ mln_concrete(I) gradient_external(const Image<I>& input, const Window<W>& win)
+ {
+ trace::entering("morpho::gradient_external");
+ mln_precondition(exact(input).has_data());
+ mln_precondition(! exact(win).is_empty());
- dilation(input, win, output); // output = dilation
- morpho::minus_inplace(output, input); // now output = dilation - input
+ mln_concrete(I) output = morpho::minus(dilation(input, win),
+ input);
mln_postcondition(test::positive(output));
+ trace::exiting("morpho::gradient_external");
+ return output;
}
# endif // ! MLN_INCLUDE_ONLY
Index: mln/morpho/contrast.hh
--- mln/morpho/contrast.hh (revision 1405)
+++ mln/morpho/contrast.hh (working copy)
@@ -48,28 +48,25 @@
*
* This operator is Id + wth_B - bth_B.
*/
- template <typename I, typename W, typename O>
- void contrast(const Image<I>& input, const Window<W>& win,
- Image<O>& output);
+ template <typename I, typename W>
+ mln_concrete(I) contrast(const Image<I>& input, const Window<W>& win);
# ifndef MLN_INCLUDE_ONLY
- template <typename I, typename W, typename O>
- void contrast(const Image<I>& input_, const Window<W>& win_, Image<O>& output_)
+ template <typename I, typename W>
+ mln_concrete(I) contrast(const Image<I>& input, const Window<W>& win)
{
- const I& input = exact(input_);
- const W& win = exact(win_);
- O& output = exact(output_);
-
- mln_precondition(output.domain() = input.domain());
- mln_precondition(! win.is_empty());
-
- top_hat_white(input, win, output); // output = wth
- morpho::plus_inplace(output, input); // now output = wth + input
- O temp(input.domain());
- top_hat_black(input, win, temp); // temp = bth
- morpho::minus_inplace(output, temp); // now output = wth + input - bth
+ trace::entering("morpho::contrast");
+ mln_precondition(exact(input).has_data());
+ mln_precondition(! exact(win).is_empty());
+
+ mln_concrete(I) output = arith::plus( input,
+ top_hat_white(input, win) - top_hat_black(input, win),
+ fun::v2v::saturate<mln_value(I)>() );
+
+ trace::exiting("morpho::contrast");
+ return output;
}
# endif // ! MLN_INCLUDE_ONLY
Index: mln/morpho/thick_miss.hh
--- mln/morpho/thick_miss.hh (revision 1405)
+++ mln/morpho/thick_miss.hh (working copy)
@@ -47,26 +47,31 @@
*
* This operator is THICK_B = Id + HMTopeBG_B, where B = (Bfg, Bbg).
*/
- template <typename I, typename Wfg, typename Wbg, typename O>
- void thick_miss(const Image<I>& input,
- const Window<Wfg>& win_fg, const Window<Wbg>& win_bg,
- Image<O>& output);
+ template <typename I, typename Wfg, typename Wbg>
+ mln_concrete(I)
+ thick_miss(const Image<I>& input,
+ const Window<Wfg>& win_fg, const Window<Wbg>& win_bg);
# ifndef MLN_INCLUDE_ONLY
- template <typename I, typename Wfg, typename Wbg, typename O>
- void thick_miss(const Image<I>& input,
- const Window<Wfg>& win_fg, const Window<Wbg>& win_bg,
- Image<O>& output)
+ template <typename I, typename Wfg, typename Wbg>
+ mln_concrete(I)
+ thick_miss(const Image<I>& input,
+ const Window<Wfg>& win_fg, const Window<Wbg>& win_bg)
{
+ trace::entering("morpho::thick_miss");
mln_precondition(exact(output).domain() = exact(input).domain());
mln_precondition(exact(win_miss).is_centered());
mln_precondition(set::inter(exact(win_fg), exact(win_bg)).is_empty());
- O temp(exact(input).domain());
- hit_or_miss_background_opening(input, win_fg, win_bg, temp);
- morpho::plus(input, temp, output);
+ mln_concrete(I)
+ output = morpho::plus( input,
+ hit_or_miss_background_opening(input,
+ win_fg, win_bg) );
+
+ trace::exiting("morpho::thick_miss");
+ return output;
}
# endif // ! MLN_INCLUDE_ONLY
Index: mln/morpho/closing.hh
--- mln/morpho/closing.hh (revision 1405)
+++ mln/morpho/closing.hh (working copy)
@@ -46,27 +46,24 @@
*
* This operator is e_{-B} o d_B.
*/
- template <typename I, typename W, typename O>
- void closing(const Image<I>& input, const Window<W>& win, Image<O>& output);
+ template <typename I, typename W>
+ mln_concrete(I) closing(const Image<I>& input, const Window<W>& win);
# ifndef MLN_INCLUDE_ONLY
- template <typename I, typename W, typename O>
- void closing(const Image<I>& input_, const Window<W>& win_, Image<O>& output_)
+ template <typename I, typename W>
+ mln_concrete(I) closing(const Image<I>& input, const Window<W>& win)
{
- const I& input = exact(input_);
- const W& win = exact(win_);
- O& output = exact(output_);
-
- mln_precondition(output.domain() = input.domain());
- mln_precondition(! win.is_empty());
-
- O temp(input.domain());
- dilation(input, win, temp);
- erosion(temp, geom::sym(win), output);
+ trace::entering("morpho::closing");
+ mln_precondition(exact(input).has_data());
+ mln_precondition(! exact(win).is_empty());
+
+ mln_concrete(I) output = erosion(dilation(input, win), geom::sym(win));
mln_postcondition(output >= input);
+ trace::exiting("morpho::closing");
+ return output;
}
# endif // ! MLN_INCLUDE_ONLY
Index: mln/morpho/top_hat.hh
--- mln/morpho/top_hat.hh (revision 1405)
+++ mln/morpho/top_hat.hh (working copy)
@@ -49,18 +49,18 @@
*
* This operator is Id - ope_B.
*/
- template <typename I, typename W, typename O>
- void top_hat_white(const Image<I>& input, const Window<W>& win,
- Image<O>& output);
+ template <typename I, typename W>
+ mln_concrete(I)
+ top_hat_white(const Image<I>& input, const Window<W>& win);
/*! Morphological black top-hat (for background / dark objects).
*
* This operator is clo_B - Id.
*/
- template <typename I, typename W, typename O>
- void top_hat_black(const Image<I>& input, const Window<W>& win,
- Image<O>& output);
+ template <typename I, typename W>
+ mln_concrete(I)
+ top_hat_black(const Image<I>& input, const Window<W>& win);
/*! Morphological self-complementary top-hat.
@@ -70,62 +70,56 @@
* = (input - opening) + (closing - input) \n
* = closing - opening. \n
*/
- template <typename I, typename W, typename O>
- void top_hat_self_complementary(const Image<I>& input, const Window<W>& win,
- Image<O>& output);
+ template <typename I, typename W>
+ mln_concrete(I)
+ top_hat_self_complementary(const Image<I>& input, const Window<W>& win);
# ifndef MLN_INCLUDE_ONLY
- template <typename I, typename W, typename O>
- void top_hat_white(const Image<I>& input_, const Window<W>& win_, Image<O>& output_)
+ template <typename I, typename W>
+ mln_concrete(I) top_hat_white(const Image<I>& input, const Window<W>& win)
{
- const I& input = exact(input_);
- const W& win = exact(win_);
- O& output = exact(output_);
-
- mln_precondition(output.domain() = input.domain());
- mln_precondition(! win.is_empty());
-
- O temp(input.domain());
- opening(input, win, temp); // temp = opening
- morpho::minus(input, temp, output); // output = input - opening
+ trace::entering("morpho::top_hat_white");
+ mln_precondition(exact(input).has_data());
+ mln_precondition(! exact(win).is_empty());
+
+ mln_concrete(I) output = morpho::minus(input,
+ opening(input, win));
mln_postcondition(test::positive(output));
+ trace::exiting("morpho::top_hat_white");
+ return output;
}
- template <typename I, typename W, typename O>
- void top_hat_black(const Image<I>& input_, const Window<W>& win_, Image<O>& output_)
+ template <typename I, typename W>
+ mln_concrete(I) top_hat_black(const Image<I>& input, const Window<W>& win)
{
- const I& input = exact(input_);
- const W& win = exact(win_);
- O& output = exact(output_);
-
- mln_precondition(output.domain() = input.domain());
- mln_precondition(! win.is_empty());
+ trace::entering("morpho::top_hat_black");
+ mln_precondition(exact(input).has_data());
+ mln_precondition(! exact(win).is_empty());
- closing(input, win, output); // output = closing
- morpho::minus_inplace(output, input); // now output = closing - input
+ mln_concrete(I) output = morpho::minus(closing(input, win),
+ input);
mln_postcondition(test::positive(output));
+ trace::exiting("morpho::top_hat_black");
+ return output;
}
- template <typename I, typename W, typename O>
- void top_hat_self_complementary(const Image<I>& input_, const Window<W>& win_, Image<O>& output_)
+ template <typename I, typename W>
+ mln_concrete(I) top_hat_self_complementary(const Image<I>& input, const Window<W>& win)
{
- const I& input = exact(input_);
- const W& win = exact(win_);
- O& output = exact(output_);
-
- mln_precondition(output.domain() = input.domain());
- mln_precondition(! win.is_empty());
-
- closing(input, win, output); // output = closing
- O temp(input.domain());
- opening(input, win, temp); // temp = opening
- morpho::minus_inplace(output, temp); // now output = closing - opening
+ trace::entering("morpho::top_hat_self_complementary");
+ mln_precondition(exact(input).has_data());
+ mln_precondition(! exact(win).is_empty());
+
+ mln_concrete(I) output = morpho::minus(closing(input, win),
+ opening(input, win));
mln_postcondition(test::positive(output));
+ trace::exiting("morpho::top_hat_self_complementary");
+ return output;
}
# endif // ! MLN_INCLUDE_ONLY
Index: mln/morpho/complementation.hh
--- mln/morpho/complementation.hh (revision 1405)
+++ mln/morpho/complementation.hh (working copy)
@@ -50,8 +50,8 @@
* morpho on sets) or an arithmetical complementation (if morpho
* on functions).
*/
- template <typename I, typename O>
- void complementation(const Image<I>& input, Image<O>& output);
+ template <typename I>
+ mln_concrete(I) complementation(const Image<I>& input);
/*! Morphological complementation, inplace version: either a
@@ -67,20 +67,41 @@
namespace impl
{
- template <typename I, typename O>
- void complementation_(trait::image::kind::logic, // binary => morphology on sets
- const Image<I>& input,
- Image<O>& output)
+ // Binary => morphology on sets.
+
+ template <typename I>
+ mln_concrete(I)
+ complementation_(trait::image::kind::logic,
+ const Image<I>& input)
+ {
+ return logical::not_(input);
+ }
+
+ template <typename I>
+ void
+ complementation_inplace_(trait::image::kind::logic,
+ Image<I>& input)
+ {
+ logical::not_inplace(input);
+ }
+
+
+ // Otherwise => morphology on functions.
+
+ template <typename I>
+ mln_concrete(I)
+ complementation_(trait::image::kind::any,
+ const Image<I>& input)
{
- return logical::not_(input, output);
+ return arith::revert(input);
}
- template <typename K, typename I, typename O>
- void complementation_(K, // otherwise => morphology on functions
- const Image<I>& input,
- Image<O>& output)
+ template <typename I>
+ void
+ complementation_inplace_(trait::image::kind::any,
+ Image<I>& input)
{
- return arith::revert(input, output);
+ arith::revert_inplace(input);
}
} // end of namespace mln::morpho::impl
@@ -88,18 +109,29 @@
// Facades.
- template <typename I, typename O>
- void complementation(const Image<I>& input, Image<O>& output)
+ template <typename I>
+ mln_concrete(I) complementation(const Image<I>& input)
{
- mln_precondition(exact(output).domain() = exact(input).domain());
- impl::complementation_(mln_trait_image_kind(I)(), exact(input), output);
+ trace::entering("morpho::complementation");
+ mln_precondition(exact(input).has_data());
+
+ mln_concrete(I) output = impl::complementation_(mln_trait_image_kind(I)(),
+ input);
+
+ trace::exiting("morpho::complementation");
+ return output;
}
template <typename I>
void complementation_inplace(Image<I>& input)
{
+ trace::entering("morpho::complementation_inplace");
mln_precondition(exact(input).has_data());
- morpho::complementation(input, input); // Calls the previous version.
+
+ impl::complementation_inplace_(mln_trait_image_kind(I)(),
+ input);
+
+ trace::exiting("morpho::complementation_inplace");
}
# endif // ! MLN_INCLUDE_ONLY
Index: mln/morpho/opening.hh
--- mln/morpho/opening.hh (revision 1405)
+++ mln/morpho/opening.hh (working copy)
@@ -46,27 +46,24 @@
*
* This operator is d_{-B} o e_B.
*/
- template <typename I, typename W, typename O>
- void opening(const Image<I>& input, const Window<W>& win, Image<O>& output);
+ template <typename I, typename W>
+ mln_concrete(I) opening(const Image<I>& input, const Window<W>& win);
# ifndef MLN_INCLUDE_ONLY
- template <typename I, typename W, typename O>
- void opening(const Image<I>& input_, const Window<W>& win_, Image<O>& output_)
+ template <typename I, typename W>
+ mln_concrete(I) opening(const Image<I>& input, const Window<W>& win)
{
- const I& input = exact(input_);
- const W& win = exact(win_);
- O& output = exact(output_);
-
- mln_precondition(output.domain() = input.domain());
- mln_precondition(! win.is_empty());
-
- O temp(input.domain());
- erosion(input, win, temp);
- dilation(temp, geom::sym(win), output);
+ trace::entering("morpho::opening");
+ mln_precondition(exact(input).has_data());
+ mln_precondition(! exact(win).is_empty());
+
+ mln_concrete(I) output = dilation(erosion(input, win), geom::sym(win));
mln_postcondition(output <= input);
+ trace::exiting("morpho::opening");
+ return output;
}
# endif // ! MLN_INCLUDE_ONLY
Index: mln/morpho/dilation.hh
--- mln/morpho/dilation.hh (revision 1405)
+++ mln/morpho/dilation.hh (working copy)
@@ -51,6 +51,10 @@
template <typename I, typename W, typename O>
void dilation(const Image<I>& input, const Window<W>& win, Image<O>& output);
+ template <typename I, typename W>
+ mln_concrete(I) dilation(const Image<I>& input, const Window<W>& win);
+
+
# ifndef MLN_INCLUDE_ONLY
@@ -194,6 +198,20 @@
mln_postcondition(output >= input);
}
+ template <typename I, typename W>
+ mln_concrete(I)
+ dilation(const Image<I>& input, const Window<W>& win)
+ {
+ trace::entering("morpho::dilation");
+
+ mln_concrete(I) output;
+ initialize(output, input);
+ dilation(input, win, output);
+
+ trace::exiting("morpho::dilation");
+ return output;
+ }
+
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln::morpho
Index: mln/morpho/thin_fit.hh
--- mln/morpho/thin_fit.hh (revision 1405)
+++ mln/morpho/thin_fit.hh (working copy)
@@ -47,26 +47,31 @@
*
* This operator is THIN_B = Id - HMTope_B where B = (Bfg, Bbg).
*/
- template <typename I, typename Wfg, typename Wbg, typename O>
- void thin_fit(const Image<I>& input,
- const Window<Wfg>& win_fg, const Window<Wbg>& win_bg,
- Image<O>& output);
+ template <typename I, typename Wfg, typename Wbg>
+ mln_concrete(I)
+ thin_fit(const Image<I>& input,
+ const Window<Wfg>& win_fg, const Window<Wbg>& win_bg);
# ifndef MLN_INCLUDE_ONLY
- template <typename I, typename Wfg, typename Wbg, typename O>
- void thin_fit(const Image<I>& input,
- const Window<Wfg>& win_fg, const Window<Wbg>& win_bg,
- Image<O>& output)
+ template <typename I, typename Wfg, typename Wbg>
+ mln_concrete(I)
+ thin_fit(const Image<I>& input,
+ const Window<Wfg>& win_fg, const Window<Wbg>& win_bg)
{
- mln_precondition(exact(output).domain() = exact(input).domain());
+ trace::entering("morpho::thin_fit");
+ mln_precondition(exact(input).has_data());
mln_precondition(exact(win_fg).is_centered());
mln_precondition(set::inter(exact(win_fg), exact(win_bg)).is_empty());
- O temp(exact(input).domain());
- hit_or_miss_opening(input, win_fg, win_bg, temp);
- morpho::minus(input, temp, output);
+ mln_concrete(I)
+ output = morpho::minus( input,
+ hit_or_miss_opening(input,
+ win_fg, win_bg) );
+
+ trace::exiting("morpho::thin_fit");
+ return output;
}
# endif // ! MLN_INCLUDE_ONLY
Index: mln/morpho/includes.hh
--- mln/morpho/includes.hh (revision 1405)
+++ mln/morpho/includes.hh (working copy)
@@ -45,11 +45,12 @@
# include <mln/accu/min_h.hh>
# include <mln/accu/max_h.hh>
+# include <mln/fun/v2v/saturate.hh>
+
# include <mln/level/compare.hh>
# include <mln/level/fill.hh>
# include <mln/test/positive.hh>
-
# include <mln/border/resize.hh>
# include <mln/border/fill.hh>
Index: mln/morpho/thinning.hh
--- mln/morpho/thinning.hh (revision 1405)
+++ mln/morpho/thinning.hh (working copy)
@@ -36,6 +36,8 @@
# include <mln/morpho/hit_or_miss.hh>
# include <mln/morpho/thickening.hh>
+#include <mln/io/pgm/save.hh>
+
namespace mln
{
@@ -48,37 +50,32 @@
*
* This operator is THIN_B = Id - HMT_B, where B = (Bfg, Bbg).
*/
- template <typename I, typename Wfg, typename Wbg, typename O>
- void thinning(const Image<I>& input,
- const Window<Wfg>& win_fg, const Window<Wbg>& win_bg,
- Image<O>& output);
+ template <typename I, typename Wfg, typename Wbg>
+ mln_concrete(I)
+ thinning(const Image<I>& input,
+ const Window<Wfg>& win_fg, const Window<Wbg>& win_bg);
# ifndef MLN_INCLUDE_ONLY
- template <typename I, typename Wfg, typename Wbg, typename O>
- void thinning(const Image<I>& input,
- const Window<Wfg>& win_fg, const Window<Wbg>& win_bg,
- Image<O>& output)
+ template <typename I, typename Wfg, typename Wbg>
+ mln_concrete(I)
+ thinning(const Image<I>& input,
+ const Window<Wfg>& win_fg, const Window<Wbg>& win_bg)
{
- mln_precondition(exact(output).domain() = exact(input).domain());
+ trace::entering("morpho::thinning");
+ mln_precondition(exact(input).has_data());
mln_precondition(exact(win_fg).is_centered());
+ mln_precondition(! exact(win_bg).is_empty());
mln_precondition(set::inter(exact(win_fg), exact(win_bg)).is_empty());
- O temp(exact(input).domain());
- hit_or_miss(input, win_fg, win_bg, temp);
- morpho::minus(input, temp, output);
- // FIXME: Pass postcondition!
-# ifndef NDEBUG
- {
- O temp(exact(input).domain());
- complementation(input, temp);
- O output_(exact(input).domain());
- thickening(temp, win_bg, win_fg, output_);
- complementation_inplace(output_);
- mln_postcondition(output_ = output);
- }
-# endif // ! NDEBUG
+ mln_concrete(I) output = morpho::minus( input,
+ hit_or_miss(input, win_fg, win_bg) );
+
+ mln_postcondition( complementation( thickening( complementation(input),
+ win_bg, win_fg ) ) = output);
+ trace::exiting("morpho::thinning");
+ return output;
}
# endif // ! MLN_INCLUDE_ONLY
Index: mln/morpho/hit_or_miss.hh
--- mln/morpho/hit_or_miss.hh (revision 1405)
+++ mln/morpho/hit_or_miss.hh (working copy)
@@ -38,6 +38,7 @@
# include <mln/morpho/includes.hh>
# include <mln/pw/all.hh>
# include <mln/fun/p2v/ternary.hh>
+# include <mln/fun/cast.hh>
# include <mln/literal/zero.hh>
@@ -55,46 +56,51 @@
*
* This operator is HMT_(Bh,Bm) = e_Bh /\ (e_Bm o C).
*/
- template <typename I, typename Wh, typename Wm, typename O>
- void hit_or_miss(const Image<I>& input,
- const Window<Wh>& win_hit, const Window<Wm>& win_miss,
- Image<O>& output);
+ template <typename I, typename Wh, typename Wm>
+ mln_concrete(I)
+ hit_or_miss(const Image<I>& input,
+ const Window<Wh>& win_hit, const Window<Wm>& win_miss);
+
/*! Morphological hit-or-miss opening.
*
* This operator is HMTope_(Bh,Bm) = d_(-Bh) o HMT_(Bh,Bm).
*/
- template <typename I, typename Wh, typename Wm, typename O>
- void hit_or_miss_opening(const Image<I>& input,
- const Window<Wh>& win_hit, const Window<Wm>& win_miss,
- Image<O>& output);
+ template <typename I, typename Wh, typename Wm>
+ mln_concrete(I)
+ hit_or_miss_opening(const Image<I>& input,
+ const Window<Wh>& win_hit, const Window<Wm>& win_miss);
+
/*! Morphological hit-or-miss opening of the background.
*
* This operator is HMTopeBG = HMTope_(Bm,Bh) o C = d_(-Bm) o HMT_(Bh,Bm).
*/
- template <typename I, typename Wh, typename Wm, typename O>
- void hit_or_miss_background_opening(const Image<I>& input,
- const Window<Wh>& win_hit, const Window<Wm>& win_miss,
- Image<O>& output);
+ template <typename I, typename Wh, typename Wm>
+ mln_concrete(I)
+ hit_or_miss_background_opening(const Image<I>& input,
+ const Window<Wh>& win_hit, const Window<Wm>& win_miss);
+
/*! Morphological hit-or-miss closing.
*
* This operator is C o HMTope o C.
*/
- template <typename I, typename Wh, typename Wm, typename O>
- void hit_or_miss_closing(const Image<I>& input,
- const Window<Wh>& win_hit, const Window<Wm>& win_miss,
- Image<O>& output);
+ template <typename I, typename Wh, typename Wm>
+ mln_concrete(I)
+ hit_or_miss_closing(const Image<I>& input,
+ const Window<Wh>& win_hit, const Window<Wm>& win_miss);
+
/*! Morphological hit-or-miss closing of the background.
*
* This operator is C o HMTopeBG o C.
*/
- template <typename I, typename Wh, typename Wm, typename O>
- void hit_or_miss_background_closing(const Image<I>& input,
- const Window<Wh>& win_hit, const Window<Wm>& win_miss,
- Image<O>& output);
+ template <typename I, typename Wh, typename Wm>
+ mln_concrete(I)
+ hit_or_miss_background_closing(const Image<I>& input,
+ const Window<Wh>& win_hit, const Window<Wm>& win_miss);
+
# ifndef MLN_INCLUDE_ONLY
@@ -102,164 +108,172 @@
namespace impl
{
+
// Preconditions.
- template <typename I, typename Wh, typename Wm, typename O>
+ template <typename I, typename Wh, typename Wm>
void hit_or_miss_preconditions_(const Image<I>& input,
- const Window<Wh>& win_hit, const Window<Wm>& win_miss,
- Image<O>& output)
+ const Window<Wh>& win_hit, const Window<Wm>& win_miss)
{
- mln_precondition(exact(output).domain() = exact(input).domain());
+ mln_precondition(exact(input).has_data());
mln_precondition(set::inter(exact(win_hit), exact(win_miss)).is_empty());
}
+
// On sets.
- template <typename I, typename Wh, typename Wm, typename O>
- void hit_or_miss_(trait::image::kind::logic, // binary => morphology on sets
- const Image<I>& input,
- const Window<Wh>& win_hit, const Window<Wm>& win_miss,
- Image<O>& output)
+ template <typename I, typename Wh, typename Wm>
+ mln_concrete(I)
+ hit_or_miss_(trait::image::kind::logic,
+ const I& input,
+ const Wh& win_hit, const Wm& win_miss)
{
- erosion(input, win_hit, output); // output = ero(input)_hit
-
- O temp_1(exact(input).domain());
- complementation(input, temp_1); // temp1 = C(input)
-
- O temp_2(exact(input).domain());
- erosion(temp_1, win_miss, temp_2); // temp_2 = ero(C(input))_miss
-
- logical::and_inplace(output, temp_2); // output = ero(input)_hit /\ ero(C(input))_miss
+ return logical::and_(erosion(input, win_hit),
+ erosion(complementation(input), win_miss));
}
+
// On functions.
- template <typename K,
- typename I, typename Wh, typename Wm, typename O>
- void hit_or_miss_(K, // otherwise => morphology on functions
- const Image<I>& input,
- const Window<Wh>& win_hit, const Window<Wm>& win_miss,
- Image<O>& output)
+ template <typename I, typename Wh, typename Wm>
+ mln_concrete(I)
+ hit_or_miss_(trait::image::kind::any,
+ const I& input,
+ const Wh& win_hit, const Wm& win_miss)
{
- typedef mln_value(O) V;
+ typedef mln_value(I) V;
+ mln_value(I) zero_V = literal::zero;
+
+ mln_concrete(I) output;
+ initialize(output, input);
if (constrained_hit_or_miss) // CHMT.
{
- if (exact(win_hit).is_centered())
+ if (win_hit.is_centered())
{
- O ero_fg(exact(input).domain()), dil_bg(exact(input).domain());
- erosion(input, win_hit, ero_fg);
- dilation(input, win_miss, dil_bg);
+ mln_concrete(I)
+ ero_fg = erosion(input, win_hit),
+ dil_bg = dilation(input, win_miss);
level::fill(output,
fun::p2v::ternary(pw::value(input) = pw::value(ero_fg)
&& pw::value(dil_bg) < pw::value(input),
- pw::value(input) - pw::value(dil_bg),
- pw::cst( V(literal::zero) )));
-
- // FIXME: Replace 'pw::cst(V::zero)' by 'pw::cst(V(literal::zero))'
- // FIXME: and then by 'literal::zero'!
+ fun::cast<V>(pw::value(input) - pw::value(dil_bg)),
+ pw::cst(zero_V)));
}
- else if (exact(win_miss).is_centered())
+ else if (win_miss.is_centered())
{
- O ero_bg(exact(input).domain()), dil_fg(exact(input).domain());
- erosion(input, win_miss, ero_bg);
- dilation(input, win_hit, dil_fg);
+ mln_concrete(I)
+ ero_bg = erosion(input, win_miss),
+ dil_fg = dilation(input, win_hit);
level::fill(output,
fun::p2v::ternary(pw::value(input) = pw::value(dil_fg)
&& pw::value(ero_bg) > pw::value(input),
- pw::value(ero_bg) - pw::value(input),
- pw::cst( V(literal::zero) )));
+ fun::cast<V>(pw::value(ero_bg) - pw::value(input)),
+ pw::cst(zero_V)));
}
else
- level::fill(output, V(literal::zero));
+ level::fill(output, zero_V);
}
else // Unconstrained: UHMT.
{
- O ero(exact(input).domain()), dil(exact(input).domain());
- erosion(input, win_hit, ero);
- dilation(input, win_miss, dil);
+ mln_concrete(I)
+ ero = erosion(input, win_hit),
+ dil = dilation(input, win_miss);
level::fill(output,
fun::p2v::ternary(pw::value(dil) < pw::value(ero),
- pw::value(ero) - pw::value(dil),
- pw::cst( V(literal::zero) )));
+ fun::cast<V>(pw::value(ero) - pw::value(dil)),
+ pw::cst(zero_V)));
}
+
+ return output;
}
+
} // end of mln::morpho::impl
- template <typename I, typename Wh, typename Wm, typename O>
- void hit_or_miss(const Image<I>& input,
- const Window<Wh>& win_hit, const Window<Wm>& win_miss,
- Image<O>& output)
+
+ template <typename I, typename Wh, typename Wm>
+ mln_concrete(I)
+ hit_or_miss(const Image<I>& input,
+ const Window<Wh>& win_hit, const Window<Wm>& win_miss)
+ {
+ trace::entering("morpho::hit_or_miss");
+ impl::hit_or_miss_preconditions_(input, win_hit, win_miss);
+
+ mln_concrete(I) output = impl::hit_or_miss_(mln_trait_image_kind(I)(),
+ exact(input),
+ exact(win_hit), exact(win_miss));
+
+ trace::exiting("morpho::hit_or_miss");
+ return output;
+ }
+
+
+ template <typename I, typename Wh, typename Wm>
+ mln_concrete(I)
+ hit_or_miss_opening(const Image<I>& input,
+ const Window<Wh>& win_hit, const Window<Wm>& win_miss)
{
- impl::hit_or_miss_preconditions_(input, win_hit, win_miss, output);
- impl::hit_or_miss_(mln_trait_image_kind(I)(), input, win_hit, win_miss, output);
+ trace::entering("morpho::hit_or_miss_opening");
+ impl::hit_or_miss_preconditions_(input, win_hit, win_miss);
+
+ mln_concrete(I) output = dilation( hit_or_miss(input, win_hit, win_miss),
+ geom::sym(win_hit) );
+
+ trace::exiting("morpho::hit_or_miss_opening");
+ return output;
}
- template <typename I, typename Wh, typename Wm, typename O>
- void hit_or_miss_opening(const Image<I>& input,
- const Window<Wh>& win_hit, const Window<Wm>& win_miss,
- Image<O>& output)
+
+ template <typename I, typename Wh, typename Wm>
+ mln_concrete(I)
+ hit_or_miss_background_opening(const Image<I>& input,
+ const Window<Wh>& win_hit, const Window<Wm>& win_miss)
{
- impl::hit_or_miss_preconditions_(input, win_hit, win_miss, output);
+ trace::entering("morpho::hit_or_miss_background_opening");
+ impl::hit_or_miss_preconditions_(input, win_hit, win_miss);
- O temp(exact(input).domain());
- hit_or_miss(input, win_hit, win_miss, temp);
- dilation(temp, geom::sym(win_hit), output);
- // FIXME: Postcondition.
+ mln_concrete(I) output = hit_or_miss_opening(complementation(input), win_miss, win_hit);
+
+ mln_postcondition( dilation( hit_or_miss(input, win_hit, win_miss),
+ geom::sym(win_miss) ) = output);
+ trace::exiting("morpho::hit_or_miss_background_opening");
+ return output;
}
- template <typename I, typename Wh, typename Wm, typename O>
- void hit_or_miss_background_opening(const Image<I>& input,
- const Window<Wh>& win_hit, const Window<Wm>& win_miss,
- Image<O>& output)
- {
- impl::hit_or_miss_preconditions_(input, win_hit, win_miss, output);
- O temp(exact(input).domain());
- complementation(input, temp);
- hit_or_miss_opening(temp, win_miss, win_hit, output);
-# ifndef NDEBUG
- {
- O temp(exact(input).domain());
- hit_or_miss(input, win_hit, win_miss, temp);
- O output_(exact(input).domain());
- dilation(temp, geom::sym(win_miss), output_);
- mln_postcondition(output_ = output);
- }
-# endif // ! NDEBUG
- }
-
- template <typename I, typename Wh, typename Wm, typename O>
- void hit_or_miss_closing(const Image<I>& input,
- const Window<Wh>& win_hit, const Window<Wm>& win_miss,
- Image<O>& output)
- {
- impl::hit_or_miss_preconditions_(input, win_hit, win_miss, output);
- I temp(input.domain());
- complementation(input, temp);
- hit_or_miss_opening(temp, win_hit, win_miss, output);
- complementation_inplace(output);
+
+ template <typename I, typename Wh, typename Wm>
+ mln_concrete(I)
+ hit_or_miss_closing(const Image<I>& input,
+ const Window<Wh>& win_hit, const Window<Wm>& win_miss)
+ {
+ trace::entering("morpho::hit_or_miss_closing");
+ impl::hit_or_miss_preconditions_(input, win_hit, win_miss);
+
+ mln_concrete(I) output = complementation( hit_or_miss_opening( complementation(input),
+ win_hit, win_miss ) );
+
// FIXME: Postcondition.
+ trace::exiting("morpho::hit_or_miss_closing");
+ return output;
}
- template <typename I, typename Wh, typename Wm, typename O>
- void hit_or_miss_background_closing(const Image<I>& input,
- const Window<Wh>& win_hit, const Window<Wm>& win_miss,
- Image<O>& output)
- {
- impl::hit_or_miss_preconditions_(input, win_hit, win_miss, output);
- hit_or_miss_closing(input, win_miss, win_hit, output);
-# ifndef NDEBUG
- {
- O temp(exact(input).domain());
- complementation(input, temp);
- O output_(exact(input).domain());
- hit_or_miss_background_opening(temp, win_hit, win_miss, output_);
- complementation_inplace(output_);
- mln_postcondition(output_ = output);
- }
-# endif // ! NDEBUG
+
+ template <typename I, typename Wh, typename Wm>
+ mln_concrete(I)
+ hit_or_miss_background_closing(const Image<I>& input,
+ const Window<Wh>& win_hit, const Window<Wm>& win_miss)
+ {
+ trace::entering("morpho::hit_or_miss_background_closing");
+ impl::hit_or_miss_preconditions_(input, win_hit, win_miss);
+
+ mln_concrete(I) output = hit_or_miss_closing(input, win_miss, win_hit);
+
+ mln_postcondition( complementation( hit_or_miss_background_opening( complementation(input),
+ win_hit, win_miss ) ) = output );
+ trace::exiting("morpho::hit_or_miss_background_closing");
+ return output;
}
# endif // ! MLN_INCLUDE_ONLY
Index: mln/logical/and.hh
--- mln/logical/and.hh (revision 1405)
+++ mln/logical/and.hh (working copy)
@@ -48,24 +48,24 @@
*
* \param[in] lhs First operand image.
* \param[in] rhs Second operand image.
- * \param[out] output The result image.
+ * \result The result image.
*
- * \pre \p output.domain = \p lhs.domain = \p rhs.domain
+ * \pre \p lhs.domain = \p rhs.domain
*/
- template <typename L, typename R, typename O>
- void and_(const Image<L>& lhs, const Image<R>& rhs, Image<O>& output);
+ template <typename L, typename R>
+ mln_concrete(L) and_(const Image<L>& lhs, const Image<R>& rhs);
/*! Point-wise in-place "logical and" of image \p rhs in image \p lhs.
*
- * \param[in] lhs First operand image.
- * \param[in,out] rhs Second operand image.
+ * \param[in,out] lhs First operand image.
+ * \param[in] rhs Second operand image.
*
* It performs: \n
* for all p of rhs.domain \n
* lhs(p) = lhs(p) and rhs(p)
*
- * \pre \p rhs.domain <= \p lhs.domain
+ * \pre \p rhs.domain >= \p lhs.domain
*/
template <typename L, typename R>
void and_inplace(Image<L>& lhs, const Image<R>& rhs);
@@ -78,8 +78,7 @@
template <typename L, typename R, typename O>
void and__(trait::image::speed::any, const L& lhs,
- trait::image::speed::any, const R& rhs,
- trait::image::speed::any, O& output)
+ trait::image::speed::any, const R& rhs, O& output)
{
mln_piter(L) p(lhs.domain());
for_all(p)
@@ -88,8 +87,7 @@
template <typename L, typename R, typename O>
void and__(trait::image::speed::fastest, const L& lhs,
- trait::image::speed::fastest, const R& rhs,
- trait::image::speed::fastest, O& output)
+ trait::image::speed::fastest, const R& rhs, O& output)
{
mln_pixter(const L) lp(lhs);
mln_pixter(const R) rp(rhs);
@@ -103,23 +101,31 @@
// Facades.
- template <typename L, typename R, typename O>
- void and_(const Image<L>& lhs, const Image<R>& rhs, Image<O>& output)
+ template <typename L, typename R>
+ mln_concrete(L) and_(const Image<L>& lhs, const Image<R>& rhs)
{
+ trace::entering("logical::and_");
mln_precondition(exact(rhs).domain() = exact(lhs).domain());
- mln_precondition(exact(output).domain() = exact(lhs).domain());
+
+ mln_concrete(L) output;
+ initialize(output, lhs);
impl::and__(mln_trait_image_speed(L)(), exact(lhs),
- mln_trait_image_speed(R)(), exact(rhs),
- mln_trait_image_speed(O)(), exact(output));
+ mln_trait_image_speed(R)(), exact(rhs), output);
+
+ trace::exiting("logical::and_");
+ return output;
}
template <typename L, typename R>
void and_inplace(Image<L>& lhs, const Image<R>& rhs)
{
- mln_precondition(exact(rhs).domain() <= exact(lhs).domain());
+ trace::entering("logical::and_inplace");
+ mln_precondition(exact(rhs).domain() >= exact(lhs).domain());
+
impl::and__(mln_trait_image_speed(L)(), exact(lhs),
- mln_trait_image_speed(R)(), exact(rhs),
- mln_trait_image_speed(L)(), exact(lhs));
+ mln_trait_image_speed(R)(), exact(rhs), exact(lhs));
+
+ trace::exiting("logical::and_inplace");
}
# endif // ! MLN_INCLUDE_ONLY
Index: mln/logical/and_not.hh
--- mln/logical/and_not.hh (revision 1405)
+++ mln/logical/and_not.hh (working copy)
@@ -48,24 +48,24 @@
*
* \param[in] lhs First operand image.
* \param[in] rhs Second operand image.
- * \param[out] output The result image.
+ * \result The result image.
*
- * \pre \p output.domain = \p lhs.domain = \p rhs.domain
+ * \pre \p lhs.domain = \p rhs.domain
*/
- template <typename L, typename R, typename O>
- void and_not(const Image<L>& lhs, const Image<R>& rhs, Image<O>& output);
+ template <typename L, typename R>
+ mln_concrete(L) and_not(const Image<L>& lhs, const Image<R>& rhs);
/*! Point-wise in-place logical "and not" of image \p rhs in image \p lhs.
*
- * \param[in] lhs First operand image.
- * \param[in,out] rhs Second operand image.
+ * \param[in,out] lhs First operand image.
+ * \param[in] rhs Second operand image.
*
* It performs: \n
* for all p of rhs.domain \n
* lhs(p) = lhs(p) and not rhs(p)
*
- * \pre \p rhs.domain <= \p lhs.domain
+ * \pre \p rhs.domain >= \p lhs.domain
*/
template <typename L, typename R>
void and_not_inplace(Image<L>& lhs, const Image<R>& rhs);
@@ -78,8 +78,7 @@
template <typename L, typename R, typename O>
void and_not_(trait::image::speed::any, const L& lhs,
- trait::image::speed::any, const R& rhs,
- trait::image::speed::any, O& output)
+ trait::image::speed::any, const R& rhs, O& output)
{
mln_piter(L) p(lhs.domain());
for_all(p)
@@ -88,8 +87,7 @@
template <typename L, typename R, typename O>
void and_not_(trait::image::speed::fastest, const L& lhs,
- trait::image::speed::fastest, const R& rhs,
- trait::image::speed::fastest, O& output)
+ trait::image::speed::fastest, const R& rhs, O& output)
{
mln_pixter(const L) lp(lhs);
mln_pixter(const R) rp(rhs);
@@ -103,23 +101,31 @@
// Facades.
- template <typename L, typename R, typename O>
- void and_not(const Image<L>& lhs, const Image<R>& rhs, Image<O>& output)
+ template <typename L, typename R>
+ mln_concrete(L) and_not(const Image<L>& lhs, const Image<R>& rhs)
{
+ trace::entering("logical::and_not");
mln_precondition(exact(rhs).domain() = exact(lhs).domain());
- mln_precondition(exact(output).domain() = exact(lhs).domain());
+
+ mln_concrete(L) output;
+ initialize(output, lhs);
impl::and_not_(mln_trait_image_speed(L)(), exact(lhs),
- mln_trait_image_speed(R)(), exact(rhs),
- mln_trait_image_speed(O)(), exact(output));
+ mln_trait_image_speed(R)(), exact(rhs), output);
+
+ trace::exiting("logical::and_not");
+ return output;
}
template <typename L, typename R>
void and_not_inplace(Image<L>& lhs, const Image<R>& rhs)
{
- mln_precondition(exact(rhs).domain() <= exact(lhs).domain());
+ trace::entering("logical::and_not_inplace");
+ mln_precondition(exact(rhs).domain() >= exact(lhs).domain());
+
impl::and_not_(mln_trait_image_speed(L)(), exact(lhs),
- mln_trait_image_speed(R)(), exact(rhs),
- mln_trait_image_speed(L)(), exact(lhs));
+ mln_trait_image_speed(R)(), exact(rhs), exact(lhs));
+
+ trace::exiting("logical::and_not_inplace");
}
# endif // ! MLN_INCLUDE_ONLY
Index: mln/logical/or.hh
--- mln/logical/or.hh (revision 1405)
+++ mln/logical/or.hh (working copy)
@@ -48,24 +48,24 @@
*
* \param[in] lhs First operand image.
* \param[in] rhs Second operand image.
- * \param[out] output The result image.
+ * \result The result image.
*
- * \pre \p output.domain = \p lhs.domain = \p rhs.domain
+ * \pre \p lhs.domain = \p rhs.domain
*/
- template <typename L, typename R, typename O>
- void or_(const Image<L>& lhs, const Image<R>& rhs, Image<O>& output);
+ template <typename L, typename R>
+ mln_concrete(L) or_(const Image<L>& lhs, const Image<R>& rhs);
/*! Point-wise in-place "logical or" of image \p rhs in image \p lhs.
*
- * \param[in] lhs First operand image.
- * \param[in,out] rhs Second operand image.
+ * \param[in,out] lhs First operand image.
+ * \param[in] rhs Second operand image.
*
* It performs: \n
- * for all p of rhs.domain \n
+ * for all p of lhs.domain \n
* lhs(p) = lhs(p) or rhs(p)
*
- * \pre \p rhs.domain <= \p lhs.domain
+ * \pre \p rhs.domain >= \p lhs.domain
*/
template <typename L, typename R>
void or_inplace(Image<L>& lhs, const Image<R>& rhs);
@@ -78,8 +78,7 @@
template <typename L, typename R, typename O>
void or__(trait::image::speed::any, const L& lhs,
- trait::image::speed::any, const R& rhs,
- trait::image::speed::any, O& output)
+ trait::image::speed::any, const R& rhs, O& output)
{
mln_piter(L) p(lhs.domain());
for_all(p)
@@ -88,8 +87,7 @@
template <typename L, typename R, typename O>
void or__(trait::image::speed::fastest, const L& lhs,
- trait::image::speed::fastest, const R& rhs,
- trait::image::speed::fastest, O& output)
+ trait::image::speed::fastest, const R& rhs, O& output)
{
mln_pixter(const L) lp(lhs);
mln_pixter(const R) rp(rhs);
@@ -103,23 +101,31 @@
// Facades.
- template <typename L, typename R, typename O>
- void or_(const Image<L>& lhs, const Image<R>& rhs, Image<O>& output)
+ template <typename L, typename R>
+ mln_concrete(L) or_(const Image<L>& lhs, const Image<R>& rhs)
{
+ trace::entering("logical::or_");
mln_precondition(exact(rhs).domain() = exact(lhs).domain());
- mln_precondition(exact(output).domain() = exact(lhs).domain());
+
+ mln_concrete(L) output;
+ initialize(output, lhs);
impl::or__(mln_trait_image_speed(L)(), exact(lhs),
- mln_trait_image_speed(R)(), exact(rhs),
- mln_trait_image_speed(O)(), exact(output));
+ mln_trait_image_speed(R)(), exact(rhs), output);
+
+ trace::exiting("logical::or_");
+ return output;
}
template <typename L, typename R>
void or_inplace(Image<L>& lhs, const Image<R>& rhs)
{
- mln_precondition(exact(rhs).domain() <= exact(lhs).domain());
+ trace::entering("logical::or_inplace");
+ mln_precondition(exact(rhs).domain() >= exact(lhs).domain());
+
impl::or__(mln_trait_image_speed(L)(), exact(lhs),
- mln_trait_image_speed(R)(), exact(rhs),
- mln_trait_image_speed(L)(), exact(lhs));
+ mln_trait_image_speed(R)(), exact(rhs), exact(lhs));
+
+ trace::exiting("logical::or_inplace");
}
# endif // ! MLN_INCLUDE_ONLY
Index: mln/logical/not.hh
--- mln/logical/not.hh (revision 1405)
+++ mln/logical/not.hh (working copy)
@@ -47,12 +47,12 @@
/*! Point-wise "logical not" of image \p input.
*
* \param[in] input the input image.
- * \param[out] output The result image.
+ * \result The result image.
*
- * \pre \p output.domain = \p input.domain
+ * \pre \p input.has_data
*/
- template <typename I, typename O>
- void not_(const Image<I>& input, Image<O>& output);
+ template <typename I>
+ mln_concrete(I) not_(const Image<I>& input);
/*! Point-wise in-place "logical not" of image \p input.
@@ -73,8 +73,7 @@
{
template <typename I, typename O>
- void not__(trait::image::speed::any, const I& input,
- trait::image::speed::any, O& output)
+ void not__(trait::image::speed::any, const I& input, O& output)
{
mln_piter(I) p(input.domain());
for_all(p)
@@ -82,8 +81,7 @@
}
template <typename I, typename O>
- void not__(trait::image::speed::fastest, const I& input,
- trait::image::speed::fastest, O& output)
+ void not__(trait::image::speed::fastest, const I& input, O& output)
{
mln_pixter(const I) ip(input);
mln_pixter(O) op(output);
@@ -96,20 +94,27 @@
// Facades.
- template <typename I, typename O>
- void not_(const Image<I>& input, Image<O>& output)
+ template <typename I>
+ mln_concrete(I) not_(const Image<I>& input)
{
- mln_precondition(exact(output).domain() = exact(input).domain());
- impl::not__(mln_trait_image_speed(I)(), exact(input),
- mln_trait_image_speed(O)(), exact(output));
+ trace::entering("logical::not");
+ mln_precondition(exact(input).has_data());
+
+ mln_concrete(I) output;
+ initialize(output, input);
+ impl::not__(mln_trait_image_speed(I)(), exact(input), output);
+
+ trace::exiting("logical::not");
+ return output;
}
template <typename I>
void not_inplace(Image<I>& input)
{
+ trace::entering("logical::not_inplace");
mln_precondition(exact(input).has_data());
- impl::not__(mln_trait_image_speed(I)(), exact(input),
- mln_trait_image_speed(I)(), exact(input));
+ impl::not__(mln_trait_image_speed(I)(), exact(input), exact(input));
+ trace::exiting("logical::not_inplace");
}
# endif // ! MLN_INCLUDE_ONLY
Index: img/picasso.pbm
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: img/picasso.pbm
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
1
0
https://svn.lrde.epita.fr/svn/oln/trunk/milena
Hum. Sorry.
Index: ChangeLog
from Roland Levillain <roland(a)lrde.epita.fr>
Revert the renaming of mln/labeling.
* mln/labelling: Rename as...
* mln/labeling: ...this.
0 files changed
1
0