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/sandbox
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Start a code to segment color images.
* geraud/color: New directory.
* geraud/color/segment.cc: New.
* geraud/wst_edge.cc: Move...
* geraud/laurent/wst_edge.cc: ...here.
segment.cc | 254 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 254 insertions(+)
Property changes on: geraud/laurent/wst_edge.cc
___________________________________________________________________
Added: svn:mergeinfo
Index: geraud/color/segment.cc
--- geraud/color/segment.cc (revision 0)
+++ geraud/color/segment.cc (revision 0)
@@ -0,0 +1,254 @@
+# include <mln/core/var.hh>
+
+# include <mln/core/image/image2d.hh>
+# include <mln/core/alias/neighb2d.hh>
+
+# include <mln/core/image/image_if.hh>
+# include <mln/core/routine/extend.hh>
+# include <mln/pw/all.hh>
+
+# include <mln/io/ppm/load.hh>
+# include <mln/io/pgm/save.hh>
+# include <mln/io/ppm/save.hh>
+# include <mln/math/diff_abs.hh>
+
+# include <mln/make/double_neighb2d.hh>
+# include <mln/data/paste.hh>
+# include <mln/morpho/closing_volume.hh>
+# include <mln/morpho/meyer_wst.hh>
+# include <mln/morpho/dilation.hh>
+# include <mln/morpho/erosion.hh>
+
+# include <mln/debug/println.hh>
+
+
+namespace mln
+{
+
+ // Functions.
+
+ inline
+ bool is_row_odd(const point2d& p)
+ {
+ return p.row() % 2;
+ }
+
+ inline
+ bool is_square(const point2d& p)
+ {
+ return p.row() % 2 == 0 && p.col() % 2 == 0;
+ }
+
+ inline
+ bool is_edge(const point2d& p)
+ {
+ return p.row() % 2 + p.col() % 2 == 1;
+ }
+
+ inline
+ bool is_point(const point2d& p)
+ {
+ return p.row() % 2 && p.col() % 2;
+ }
+
+
+ // Transforms.
+
+ template <typename I>
+ I display_edge(const I& ima, mln_value(I) bg, unsigned zoom)
+ {
+ unsigned nrows = ima.nrows() / 2 + 1;
+ unsigned ncols = ima.ncols() / 2 + 1;
+ I output(nrows * (zoom + 1) - 1,
+ ncols * (zoom + 1) - 1);
+ data::fill(output, bg);
+ mln_VAR( edge, ima | is_edge );
+ mln_piter(edge_t) p(edge.domain());
+ for_all(p)
+ if (p.row() % 2) // horizontal edge
+ {
+ unsigned row = (p.row() / 2 + 1) * (zoom + 1) - 1;
+ unsigned col = (p.col() / 2) * (zoom + 1);
+ for (unsigned i = 0; i < zoom; ++i)
+ opt::at(output, row, col + i) = ima(p);
+ }
+ else // vertical edge
+ {
+ unsigned row = (p.row() / 2) * (zoom + 1);
+ unsigned col = (p.col() / 2 + 1) * (zoom + 1) - 1;
+ for (unsigned i = 0; i < zoom; ++i)
+ opt::at(output, row + i, col) = ima(p);
+ }
+ return output;
+ }
+
+ template <typename T>
+ image2d<T>
+ image2squares(const image2d<T>& input)
+ {
+ image2d<T> output(2 * input.nrows() - 1,
+ 2 * input.ncols() - 1);
+ for (int row = 0; row < input.nrows(); ++row)
+ for (int col = 0; col < input.ncols(); ++col)
+ opt::at(output, 2 * row, 2 * col) = opt::at(input, row, col);
+ return output;
+ }
+
+ template <typename T>
+ image2d<T>
+ squares2image(const image2d<T>& input)
+ {
+ image2d<T> output((input.nrows() + 1) / 2,
+ (input.ncols() + 1) / 2);
+ for (int row = 0; row < input.nrows(); row += 2)
+ for (int col = 0; col < input.ncols(); col += 2)
+ opt::at(output, row / 2, col / 2) =
+ opt::at(input, row, col);
+ return output;
+ }
+
+
+
+ // Distance.
+
+ value::int_u8 dist(const value::rgb8& c1, const value::rgb8& c2)
+ {
+ unsigned d = 0;
+ d += (math::diff_abs(c1.red(), c2.red()) + 2) / 3;
+ d += (math::diff_abs(c1.green(), c2.green()) + 2) / 3;
+ d += (math::diff_abs(c1.blue(), c2.blue()) + 2) / 3;
+ if (d > 255)
+ d = 255;
+ return d;
+ }
+
+ template <typename I, typename N>
+ image2d<value::int_u8>
+ dist(const I& input, const N& nbh)
+ {
+ image2d<value::int_u8> output;
+ initialize(output, input);
+ data::fill(output, 0);
+
+ mln_piter(I) p(input.domain());
+ mln_niter(N) n(nbh, p);
+ for_all(p)
+ {
+ n.start();
+ value::rgb8 c1 = input(n);
+ n.next();
+ value::rgb8 c2 = input(n);
+ output(p) = dist(c1, c2);
+ }
+
+ return output;
+ }
+
+
+} // mln
+
+
+
+void usage(char* argv[])
+{
+ std::cerr << "usage: " << argv[0] << " input.ppm n output.ppm" << std::endl;
+ std::cerr << " n >= 2" << std::endl;
+ abort();
+}
+
+
+
+int main(int argc, char* argv[])
+{
+ using namespace mln;
+ using value::int_u8;
+ using value::rgb8;
+
+ if (argc != 4)
+ usage(argv);
+
+ image2d<rgb8> raw_input, input;
+
+ io::ppm::load(raw_input, argv[1]);
+ input = image2squares(raw_input);
+
+ // e2c
+
+ bool e2c_h[] = { 0, 1, 0,
+ 0, 0, 0,
+ 0, 1, 0 };
+
+ bool e2c_v[] = { 0, 0, 0,
+ 1, 0, 1,
+ 0, 0, 0 };
+
+ mln_VAR( e2c, make::double_neighb2d(is_row_odd, e2c_h, e2c_v) );
+
+
+
+ image2d<int_u8> G = dist(extend(input | is_edge, pw::value(input)),
+ e2c);
+
+ mln_VAR(G_edges, G | is_edge);
+
+ /*
+ {
+ io::pgm::save(display_edge(G, 0, 3),
+ "temp_G.pgm");
+ }
+ */
+
+ // e2e
+
+ bool e2e_h[] = { 0, 0, 1, 0, 0,
+ 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 0,
+ 0, 1, 0, 1, 0,
+ 0, 0, 1, 0, 0 };
+
+ bool e2e_v[] = { 0, 0, 0, 0, 0,
+ 0, 1, 0, 1, 0,
+ 1, 0, 0, 0, 1,
+ 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 0 };
+
+ mln_VAR( e2e, make::double_neighb2d(is_row_odd, e2e_h, e2e_v) );
+
+ data::paste( morpho::closing_volume(G_edges, e2e, 50), G_edges );
+
+ /*
+ {
+ io::pgm::save(display_edge(G_edges.unmorph_(), 0, 3),
+ "temp_G_closed.pgm");
+ }
+ */
+
+ int_u8 nbasins;
+ mln_VAR(W_edges, morpho::meyer_wst(G_edges, e2e, nbasins));
+
+ /*
+ {
+ io::pgm::save(display_edge(W_edges.unmorph_(), 0, 3),
+ "temp_W_edges.pgm");
+ }
+ */
+
+ mln_VAR(W_all, W_edges.unmorph_());
+
+
+ mln_VAR(W_squares, W_all | is_square);
+ data::paste(morpho::dilation(extend(W_squares, pw::value(W_all)),
+ c4().win()),
+ W_all);
+
+ mln_VAR(W_points, W_all | is_point);
+ data::paste(morpho::erosion(extend(W_points, pw::value(W_all)),
+ c4().win()),
+ W_all);
+
+
+ {
+ io::pgm::save(W_all, "temp_W_all.pgm");
+ }
+
+}
1
0
* tests/fun/x2x/rotation.cc: Check if the sites which are part of the
rotated image are part of the original image _domain_. Call
domain().has() instead of has().
Interpolated sites which were part of the domain needed a larger
extension in order to be computed correctly.
---
milena/ChangeLog | 10 ++++++++++
milena/tests/fun/x2x/rotation.cc | 19 +++++++++++--------
2 files changed, 21 insertions(+), 8 deletions(-)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index d08a017..74d2d1f 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,5 +1,15 @@
2009-01-09 Guillaume Lazzara <z(a)lrde.epita.fr>
+ Fix fun::x2x::rotation test.
+
+ * tests/fun/x2x/rotation.cc: Check if the sites which are part of the
+ rotated image are part of the original image _domain_. Call
+ domain().has() instead of has().
+ Interpolated sites which were part of the domain needed a larger
+ extension in order to be computed correctly.
+
+2009-01-09 Guillaume Lazzara <z(a)lrde.epita.fr>
+
Fix level::stretch.
* mln/level/stretch.hh: Use double variables instead of float because
diff --git a/milena/tests/fun/x2x/rotation.cc b/milena/tests/fun/x2x/rotation.cc
index 7835ac9..b96c551 100644
--- a/milena/tests/fun/x2x/rotation.cc
+++ b/milena/tests/fun/x2x/rotation.cc
@@ -1,4 +1,5 @@
-// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2007, 2008, 2009 EPITA Research and Development
+// Laboratory (LRDE)
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -39,6 +40,7 @@
#include <mln/core/image/interpolated.hh>
#include <mln/make/vec.hh>
#include <mln/fun/x2v/bilinear.hh>
+#include <mln/extension/adjust.hh>
#include "tests/data.hh"
@@ -51,21 +53,22 @@ int main()
algebra::vec<2,float> axis;
axis[0] = 0;
axis[1] = 1;
-
- image2d<int_u8> lena;
+ typedef image2d<int_u8> ima_t;
+ ima_t lena;
io::pgm::load(lena, MLN_IMG_DIR "/lena.pgm");
- image2d<int_u8> out(lena.domain());
- interpolated<image2d<int_u8>, fun::x2v::bilinear> inter(lena);
+ ima_t out;
+ initialize(out, lena);
- fun::x2x::rotation<2,float> rot1(0.1, axis);
+ interpolated<ima_t, fun::x2v::bilinear> inter(lena);
- mln_piter_(image2d<int_u8>) p(out.domain());
+ fun::x2x::rotation<2,float> rot1(0.1, axis);
+ mln_piter_(ima_t) p(out.domain());
for_all(p)
{
algebra::vec<2,float> v = rot1.inv()(p.to_site().to_vec());
- if (inter.has(v))
+ if (inter.domain().has(v))
out(p) = inter(v);
else
out(p) = 255;
--
1.5.6.5
1
0
* mln/level/stretch.hh: Use double variables instead of float because
of precision issues. See ticket #179.
---
milena/ChangeLog | 7 +++++++
milena/mln/level/stretch.hh | 16 ++++++++++------
2 files changed, 17 insertions(+), 6 deletions(-)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 6364251..d08a017 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,5 +1,12 @@
2009-01-09 Guillaume Lazzara <z(a)lrde.epita.fr>
+ Fix level::stretch.
+
+ * mln/level/stretch.hh: Use double variables instead of float because
+ of precision issues. See ticket #179.
+
+2009-01-09 Guillaume Lazzara <z(a)lrde.epita.fr>
+
Add from_double_to_value dispatch in from_to.
* mln/convert/from_to.hxx: add more forward declarations.
diff --git a/milena/mln/level/stretch.hh b/milena/mln/level/stretch.hh
index e91dbe7..80190b4 100644
--- a/milena/mln/level/stretch.hh
+++ b/milena/mln/level/stretch.hh
@@ -1,5 +1,5 @@
-// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
-// (LRDE)
+// Copyright (C) 2007, 2008, 2009 EPITA Research and Development
+// Laboratory (LRDE)
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -44,6 +44,8 @@
# include <mln/level/transform.hh>
+# include <mln/value/internal/encoding.hh>
+# include <iomanip>
namespace mln
{
@@ -84,21 +86,23 @@ namespace mln
estim::min_max(input, min_, max_);
if (max_ != min_)
{
- float
+ //FIXME: we would like to use float instead of double but we
+ //can't for precision reasons. See ticket #179.
+ double
min = float(min_),
max = float(max_),
epsilon = mln_epsilon(float),
- m = 0.0f - 0.5f + epsilon,
M = mln_max(V) + 0.5f - epsilon,
+ m = 0.0f - 0.5f + epsilon,
a = (M - m) / (max - min),
b = (m * max - M * min) / (max - min);
- fun::v2v::linear<float, float, V> f(a, b);
+ fun::v2v::linear<double, double, V> f(a, b);
output = level::transform(input, f);
}
else
{
initialize(output, input);
- // trace::warning("output has no significative data!");
+ trace::warning("output has no significative data!");
}
trace::exiting("level::impl::stretch");
--
1.5.6.5
1
0
* mln/convert/from_to.hxx: add more forward declarations.
* mln/convert/impl/all.hh: include from_double_to_value.hh.
* mln/convert/impl/from_double_to_value.hh: new file. Add a new
dispatch for double conversion.
---
milena/ChangeLog | 11 ++
milena/mln/convert/from_to.hxx | 13 ++
milena/mln/convert/impl/all.hh | 1 +
milena/mln/convert/impl/from_double_to_value.hh | 157 +++++++++++++++++++++++
4 files changed, 182 insertions(+), 0 deletions(-)
create mode 100644 milena/mln/convert/impl/from_double_to_value.hh
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 2a5fb87..6364251 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,5 +1,16 @@
2009-01-09 Guillaume Lazzara <z(a)lrde.epita.fr>
+ Add from_double_to_value dispatch in from_to.
+
+ * mln/convert/from_to.hxx: add more forward declarations.
+
+ * mln/convert/impl/all.hh: include from_double_to_value.hh.
+
+ * mln/convert/impl/from_double_to_value.hh: new file. Add a new
+ dispatch for double conversion.
+
+2009-01-09 Guillaume Lazzara <z(a)lrde.epita.fr>
+
Remove a useless test in level/median.
* tests/level/Makefile.am,
diff --git a/milena/mln/convert/from_to.hxx b/milena/mln/convert/from_to.hxx
index 793da8b..e2cbe3d 100644
--- a/milena/mln/convert/from_to.hxx
+++ b/milena/mln/convert/from_to.hxx
@@ -194,6 +194,19 @@ namespace mln
void
from_to_(const Value<F>& from, Value<T>& to);
+ // double-> Value
+ template <typename V>
+ void
+ from_to_(const double& from, Value<V>& to);
+
+ // double-> unsigned
+ void
+ from_to_(const double& from, unsigned& to);
+
+ // double-> int
+ void
+ from_to_(const double& from, int& to);
+
// float -> Value
template <typename V>
void
diff --git a/milena/mln/convert/impl/all.hh b/milena/mln/convert/impl/all.hh
index a7ef79b..1a33732 100644
--- a/milena/mln/convert/impl/all.hh
+++ b/milena/mln/convert/impl/all.hh
@@ -33,6 +33,7 @@
/// File that includes all from-to conversion routines.
+# include <mln/convert/impl/from_double_to_value.hh>
# include <mln/convert/impl/from_float_to_value.hh>
# include <mln/convert/impl/from_image_to_site_set.hh>
# include <mln/convert/impl/from_int_to_value.hh>
diff --git a/milena/mln/convert/impl/from_double_to_value.hh b/milena/mln/convert/impl/from_double_to_value.hh
new file mode 100644
index 0000000..fc1d23e
--- /dev/null
+++ b/milena/mln/convert/impl/from_double_to_value.hh
@@ -0,0 +1,157 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef MLN_CONVERT_IMPL_FROM_DOUBLE_TO_VALUE_HH
+# define MLN_CONVERT_IMPL_FROM_DOUBLE_TO_VALUE_HH
+
+/// \file mln/convert/impl/from_double_to_value.hh
+///
+/// General conversion procedure from a double to a value.
+///
+/// \todo Augment code + add checks.
+
+# include <utility>
+# include <mln/value/concept/integer.hh>
+# include <mln/value/concept/floating.hh>
+# include <mln/core/concept/value.hh>
+# include <mln/math/round.hh>
+
+
+
+
+namespace mln
+{
+
+ namespace convert
+ {
+
+ /// Conversion of a double \p from towards a value \p to.
+ template <typename V>
+ void
+ from_to(const double& from, Value<V>& to);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace impl
+ {
+
+ // Case 1:
+
+ template <typename V>
+ inline
+ void
+ from_double_to_value(const double& from,
+ mln::value::Integer<V>& to)
+ {
+ exact(to) = math::round<V>()(from);
+ }
+
+ // Case 2:
+
+ template <typename V>
+ inline
+ void
+ from_double_to_value(const double& from,
+ mln::value::Floating<V>& to)
+ {
+ exact(to) = from;
+ }
+
+
+ // Default: no conversion defined.
+
+ template <typename V>
+ inline
+ void
+ from_double_to_value(const double& from,
+ Value<V>& to)
+ {
+ mlc_abort(V)::check();
+ }
+
+ } // end of namespace mln::convert::impl
+
+
+ namespace internal
+ {
+
+ template <typename V>
+ inline
+ void
+ from_double_to_value_dispatch(const double& from, Value<V>& to)
+ {
+ impl::from_double_to_value(from, exact(to));
+ }
+
+ } // end of namespace mln::convert::internal
+
+
+ namespace over_load
+ {
+
+ // Facades.
+
+
+ // double-> Value
+ template <typename V>
+ inline
+ void
+ from_to_(const double& from, Value<V>& to)
+ {
+ internal::from_double_to_value_dispatch(from, to);
+ }
+
+ // double-> unsigned
+ inline
+ void
+ from_to_(const double& from,
+ unsigned& to)
+ {
+ mln_precondition(from >= 0);
+ to = math::round<unsigned>()(from);
+ }
+
+ // double-> int
+ inline
+ void
+ from_to_(const double& from,
+ int& to)
+ {
+ to = math::round<int>()(from);
+ }
+
+ } // end of namespace mln::convert::over_load
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::convert
+
+} // end of namespace mln
+
+
+#endif // ! MLN_CONVERT_IMPL_FROM_DOUBLE_TO_VALUE_HH
--
1.5.6.5
1
0
* tests/level/Makefile.am,
* tests/level/median_.cc: remove this test. It is already tested by
level/median/approx/median.cc.
* mln/level/approx/median.hh,
* tests/level/approx/median.cc,
* tests/level/median.cc: fix copyright.
---
milena/ChangeLog | 12 ++++++++
milena/mln/level/approx/median.hh | 2 +-
milena/tests/level/Makefile.am | 2 -
milena/tests/level/approx/median.cc | 4 +-
milena/tests/level/median.cc | 4 +-
milena/tests/level/median_.cc | 48 -----------------------------------
6 files changed, 17 insertions(+), 55 deletions(-)
delete mode 100644 milena/tests/level/median_.cc
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 61a8e60..2a5fb87 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,5 +1,17 @@
2009-01-09 Guillaume Lazzara <z(a)lrde.epita.fr>
+ Remove a useless test in level/median.
+
+ * tests/level/Makefile.am,
+ * tests/level/median_.cc: remove this test. It is already tested by
+ level/median/approx/median.cc.
+
+ * mln/level/approx/median.hh,
+ * tests/level/approx/median.cc,
+ * tests/level/median.cc: fix copyright.
+
+2009-01-09 Guillaume Lazzara <z(a)lrde.epita.fr>
+
Provide a default implementation of center_at_() in
site_relative_iterator_base.
diff --git a/milena/mln/level/approx/median.hh b/milena/mln/level/approx/median.hh
index 8156b1c..5bf1a9e 100644
--- a/milena/mln/level/approx/median.hh
+++ b/milena/mln/level/approx/median.hh
@@ -1,4 +1,4 @@
-// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2009 EPITA Research and Development Laboratory
// (LRDE)
//
// This file is part of the Olena Library. This library is free
diff --git a/milena/tests/level/Makefile.am b/milena/tests/level/Makefile.am
index 0d34bc3..39f3a63 100644
--- a/milena/tests/level/Makefile.am
+++ b/milena/tests/level/Makefile.am
@@ -12,7 +12,6 @@ check_PROGRAMS = \
compute \
convert \
median \
- median_ \
median_fast \
saturate \
sort_psites \
@@ -28,7 +27,6 @@ compare_SOURCES = compare.cc
compute_SOURCES = compute.cc
convert_SOURCES = convert.cc
median_SOURCES = median.cc
-median__SOURCES = median_.cc
median_fast_SOURCES = median_fast.cc
saturate_SOURCES = saturate.cc
sort_psites_SOURCES = sort_psites.cc
diff --git a/milena/tests/level/approx/median.cc b/milena/tests/level/approx/median.cc
index d9e39c4..7dd3f12 100644
--- a/milena/tests/level/approx/median.cc
+++ b/milena/tests/level/approx/median.cc
@@ -1,5 +1,5 @@
-// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
-// (LRDE)
+// Copyright (C) 2007, 2008, 2009 EPITA Research and Development
+// Laboratory (LRDE)
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
diff --git a/milena/tests/level/median.cc b/milena/tests/level/median.cc
index 48f6adb..0d749e2 100644
--- a/milena/tests/level/median.cc
+++ b/milena/tests/level/median.cc
@@ -1,5 +1,5 @@
-// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
-// (LRDE)
+// Copyright (C) 2007, 2008, 2009 EPITA Research and Development
+// Laboratory (LRDE)
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
diff --git a/milena/tests/level/median_.cc b/milena/tests/level/median_.cc
deleted file mode 100644
index 3d97c7c..0000000
--- a/milena/tests/level/median_.cc
+++ /dev/null
@@ -1,48 +0,0 @@
-#include <mln/core/image/image2d.hh>
-#include <mln/win/rectangle2d.hh>
-#include <mln/make/box2d.hh>
-
-#include <mln/io/pgm/load.hh>
-#include <mln/io/pgm/save.hh>
-
-#include <mln/value/int_u8.hh>
-#include <mln/level/median.hh>
-
-#include "tests/data.hh"
-
-#include <mln/debug/iota.hh>
-#include <mln/debug/println.hh>
-
-
-int main()
-{
- using namespace mln;
- using value::int_u8;
-
- {
- border::thickness = 5;
- box2d bb = make::box2d(0, 0, 3, 3);
- image2d<int_u8> ima(bb);
- debug::iota(ima);
- debug::println(ima);
-
- win::rectangle2d rect(3, 3);
- image2d<int_u8> out(ima.domain());
-
- level::impl::median_(ima, rect, out);
- }
-
-
- {
- win::rectangle2d rect(21, 21);
- border::thickness = 6;
-
- image2d<int_u8> lena;
- io::pgm::load(lena, MLN_IMG_DIR "/lena.pgm");
- image2d<int_u8> out(lena.domain());
-
- level::impl::median_(lena, rect, out);
- io::pgm::save(out, "out.pgm");
- }
-
-}
--
1.5.6.5
1
0
09 Jan '09
#176: Fix override of center_at() in graph and complex iterators
---------------------+------------------------------------------------------
Reporter: lazzara | Owner: Olena Team
Type: defect | Status: new
Priority: major | Milestone:
Component: Milena | Version: 1.0
Keywords: |
---------------------+------------------------------------------------------
Graph and complex iterators inherit from site_relative_iterator_base.
site_relative_iterator_base provides center_at() but do not allow derived
classes to implement their own.
Graph and complex iterators need to update an underlying iterator while
calling center_at() which is not possible currently, except by overriding
center_at().
We may add the following call in site_relative_iterator_base::center_at():
exact(this)->center_at_();
And rename center_at() to center_at_() in the following files:
- mln/core/image/graph_window_piter.hh
- mln/core/image/complex_neighborhood_piter.hh
--
Ticket URL: <https://trac.lrde.org/olena/ticket/176>
Olena <http://olena.lrde.epita.fr>
Olena, a generic and efficient C++ image processing library.
1
2
3142: Provide a default implementation of center_at_() in site_relative_iterator_base.
by Guillaume Lazzara 09 Jan '09
by Guillaume Lazzara 09 Jan '09
09 Jan '09
* mln/core/dpsites_piter.hh,
* mln/core/neighb.hh,
* mln/win/multiple_size.hh: remove empty implementation of center_at_().
* mln/core/image/complex_neighborhood_piter.hh: add a new line.
* mln/core/internal/site_relative_iterator_base.hh: add default
implementation of center_at_().
---
milena/ChangeLog | 14 ++++++++++
milena/mln/core/dpsites_piter.hh | 28 +------------------
.../mln/core/image/complex_neighborhood_piter.hh | 4 ++-
.../core/internal/site_relative_iterator_base.hh | 16 ++++++++++-
milena/mln/core/neighb.hh | 28 +------------------
milena/mln/win/multiple_size.hh | 15 +---------
6 files changed, 38 insertions(+), 67 deletions(-)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 4696e60..61a8e60 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,3 +1,17 @@
+2009-01-09 Guillaume Lazzara <z(a)lrde.epita.fr>
+
+ Provide a default implementation of center_at_() in
+ site_relative_iterator_base.
+
+ * mln/core/dpsites_piter.hh,
+ * mln/core/neighb.hh,
+ * mln/win/multiple_size.hh: remove empty implementation of center_at_().
+
+ * mln/core/image/complex_neighborhood_piter.hh: add a new line.
+
+ * mln/core/internal/site_relative_iterator_base.hh: add default
+ implementation of center_at_().
+
2009-01-08 Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Cleanup level approx median.
diff --git a/milena/mln/core/dpsites_piter.hh b/milena/mln/core/dpsites_piter.hh
index 91709d7..b2cd978 100644
--- a/milena/mln/core/dpsites_piter.hh
+++ b/milena/mln/core/dpsites_piter.hh
@@ -1,5 +1,5 @@
-// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
-// (LRDE)
+// Copyright (C) 2007, 2008, 2009 EPITA Research and Development
+// Laboratory (LRDE)
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -74,10 +74,6 @@ namespace mln
/// Go to the next point.
void do_next_();
- /// Set the reference psite.
- template <typename Pref>
- void center_at_(const Pref&);
-
/// Compute the current psite.
mln_psite(V) compute_p_() const;
@@ -120,10 +116,6 @@ namespace mln
/// Go to the next point.
void do_next_();
- /// Do some work while setting the reference site.
- template <typename Pref>
- void center_at_(const Pref&);
-
/// Compute the current psite.
mln_psite(V) compute_p_() const;
@@ -187,14 +179,6 @@ namespace mln
}
template <typename V>
- template <typename Pref>
- inline
- void
- dpsites_fwd_piter<V>::center_at_(const Pref&)
- {
- }
-
- template <typename V>
inline
mln_psite(V)
dpsites_fwd_piter<V>::compute_p_() const
@@ -253,14 +237,6 @@ namespace mln
}
template <typename V>
- template <typename Pref>
- inline
- void
- dpsites_bkd_piter<V>::center_at_(const Pref&)
- {
- }
-
- template <typename V>
inline
mln_psite(V)
dpsites_bkd_piter<V>::compute_p_() const
diff --git a/milena/mln/core/image/complex_neighborhood_piter.hh b/milena/mln/core/image/complex_neighborhood_piter.hh
index 0a91f30..32beda6 100644
--- a/milena/mln/core/image/complex_neighborhood_piter.hh
+++ b/milena/mln/core/image/complex_neighborhood_piter.hh
@@ -1,4 +1,5 @@
-// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory
+// (LRDE)
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -90,6 +91,7 @@ namespace mln
/// Set the reference psite.
template <typename Pref>
void center_at_(const Pref& c);
+
/// Compute the current psite.
psite compute_p_() const;
/// \}
diff --git a/milena/mln/core/internal/site_relative_iterator_base.hh b/milena/mln/core/internal/site_relative_iterator_base.hh
index 7a662b6..ffa5c33 100644
--- a/milena/mln/core/internal/site_relative_iterator_base.hh
+++ b/milena/mln/core/internal/site_relative_iterator_base.hh
@@ -1,4 +1,5 @@
-// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory
+// (LRDE)
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -112,6 +113,11 @@ namespace mln
private:
+ // Allows inherited classes to do extra work while centering.
+ // Default implementation.
+ template <typename P>
+ void center_at_(const P& c);
+
/// The psite designated by this iterator.
mln_psite(S) p_;
};
@@ -228,6 +234,14 @@ namespace mln
return exact(*this);
}
+ template <typename S, typename E>
+ template <typename P>
+ inline
+ void
+ site_relative_iterator_base<S,E>::center_at_(const P& c)
+ {
+ }
+
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln::internal
diff --git a/milena/mln/core/neighb.hh b/milena/mln/core/neighb.hh
index d509af0..d5f0e83 100644
--- a/milena/mln/core/neighb.hh
+++ b/milena/mln/core/neighb.hh
@@ -1,5 +1,5 @@
-// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
-// (LRDE)
+// Copyright (C) 2007, 2008, 2009 EPITA Research and Development
+// Laboratory (LRDE)
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -140,10 +140,6 @@ namespace mln
/// Go to the next point.
void do_next_();
- /// Do some work while centering the iterator.
- template <typename Pref>
- void center_at_(const Pref&);
-
/// Compute the current psite.
mln_psite(W) compute_p_() const;
@@ -182,10 +178,6 @@ public:
/// Go to the next point.
void do_next_();
- /// Do some work while centering the iterator.
- template <typename Pref>
- void center_at_(const Pref&);
-
/// Compute the current psite.
mln_psite(W) compute_p_() const;
@@ -318,14 +310,6 @@ protected:
}
template <typename W>
- template <typename Pref>
- inline
- void
- neighb_fwd_niter<W>::center_at_(const Pref&)
- {
- }
-
- template <typename W>
inline
mln_psite(W)
neighb_fwd_niter<W>::compute_p_() const
@@ -386,14 +370,6 @@ protected:
}
template <typename W>
- template <typename Pref>
- inline
- void
- neighb_bkd_niter<W>::center_at_(const Pref&)
- {
- }
-
- template <typename W>
inline
mln_psite(W)
neighb_bkd_niter<W>::compute_p_() const
diff --git a/milena/mln/win/multiple_size.hh b/milena/mln/win/multiple_size.hh
index 86ccaed..8760b9c 100644
--- a/milena/mln/win/multiple_size.hh
+++ b/milena/mln/win/multiple_size.hh
@@ -1,4 +1,5 @@
-// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory
+// (LRDE)
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -155,10 +156,6 @@ namespace mln
/// Go to the next point.
void do_next_();
- /// Do some work while setting the reference site.
- template <typename Pref>
- void center_at_(const Pref&);
-
/// Compute the current psite.
mln_psite(W) compute_p_() const;
@@ -353,14 +350,6 @@ namespace mln
}
template <unsigned n, typename W, typename F>
- template <typename Pref>
- inline
- void
- multiple_size_qiter<n,W,F>::center_at_(const Pref&)
- {
- }
-
- template <unsigned n, typename W, typename F>
inline
mln_psite(W)
multiple_size_qiter<n,W,F>::compute_p_() const
--
1.5.6.5
1
0
https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Cleanup level approx median.
* mln/level/approx/median.hh: Upgrade file doc style.
(median): Return output.
Revamp.
(median_): Remove; awkward.
* mln/accu/transform_line.hh (comment): Fix.
We deal with lines not runs.
(transform_line): Fix extension adjust.
* mln/morpho/general.spe.hh (general_line): New impl.
(general_dispatch_line): Use it.
* tests/level/approx/median.cc: Upgrade file doc style.
Augment tests.
* tests/morpho/general.cc: Augment tests with hline and vline.
mln/accu/transform_line.hh | 14 ++--
mln/level/approx/median.hh | 131 +++++++++++++++++++------------------------
mln/morpho/general.spe.hh | 24 +++++++
tests/level/approx/median.cc | 31 ++++------
tests/morpho/general.cc | 16 ++++-
5 files changed, 117 insertions(+), 99 deletions(-)
Index: mln/level/approx/median.hh
--- mln/level/approx/median.hh (revision 3140)
+++ mln/level/approx/median.hh (working copy)
@@ -1,4 +1,5 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
+// (LRDE)
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -28,10 +29,9 @@
#ifndef MLN_LEVEL_APPROX_MEDIAN_HH
# define MLN_LEVEL_APPROX_MEDIAN_HH
-/*! \file mln/level/approx/median.hh
- *
- * \brief Approximates of some median filters of an image.
- */
+/// \file mln/level/approx/median.hh
+///
+/// Approximates of some median filters of an image.
# include <mln/level/median.hh>
# include <mln/win/rectangle2d.hh>
@@ -44,6 +44,7 @@
#include <time.h>
+
namespace mln
{
@@ -58,125 +59,109 @@
*
* \param[in] input The image to be filtered.
* \param[in] win The rectangle.
- * \param[in,out] output The output image.
*
* The approximation is based on a vertical median ran after
* an horizontal median.
*
* \pre \p input and \p output have to be initialized.
*/
- template <typename I, typename O>
- void median(const Image<I>& input, const win::rectangle2d& win,
- Image<O>& output);
+ template <typename I>
+ mln_concrete(I)
+ median(const Image<I>& input, const win::rectangle2d& win);
+
/*! Compute in \p output an approximate of the median filter of
* image \p input by the 2D disk \p win.
*
* \param[in] input The image to be filtered.
* \param[in] win The disk.
- * \param[in,out] output The output image.
*
* The approximation is based on a vertical median and
* an horizontal median an two diagonal median.
*
* \pre \p input and \p output have to be initialized.
*/
- template <typename I, typename O>
- void median(const Image<I>& input, const win::disk2d& win,
- Image<O>& output);
+ template <typename I>
+ mln_concrete(I)
+ median(const Image<I>& input, const win::disk2d& win);
+
/*! Compute in \p output an approximate of the median filter of
* image \p input by the 2D octagon \p win.
*
* \param[in] input The image to be filtered.
* \param[in] win The octagon.
- * \param[in,out] output The output image.
*
* The approximation is based on a vertical median and
* an horizontal median an two diagonal median.
*
* \pre \p input and \p output have to be initialized.
*/
- template <typename I, typename O>
- void median(const Image<I>& input, const win::octagon2d& win,
- Image<O>& output);
+ template <typename I>
+ mln_concrete(I)
+ median(const Image<I>& input, const win::octagon2d& win);
+
# ifndef MLN_INCLUDE_ONLY
- namespace impl
- {
- template <typename I, typename O>
+ // Facades.
+
+
+ template <typename I>
inline
- void median_(const I& input, const unsigned length,
- O& output)
+ mln_concrete(I)
+ median(const Image<I>& input, const win::rectangle2d& win)
{
- const unsigned len = length / 3 + 1;
+ trace::entering("level::approx::median");
- O
- tmp1(output.domain()),
- tmp2(output.domain());
- {
- clock_t c = clock();
- level::median(input, win::diag2d(len), tmp1);
- std::cout << "diag " << float(clock() - c) / CLOCKS_PER_SEC << std::endl;
- }
- {
- clock_t c = clock();
- level::median(tmp1, win::backdiag2d(len), tmp2);
- std::cout << "back " << float(clock() - c) / CLOCKS_PER_SEC << std::endl;
- }
- {
- clock_t c = clock();
- level::median(tmp2, win::hline2d(len), tmp1);
- std::cout << "hlin " << float(clock() - c) / CLOCKS_PER_SEC << std::endl;
- }
- {
- clock_t c = clock();
- level::median(tmp1, win::vline2d(len), output);
- std::cout << "vlin " << float(clock() - c) / CLOCKS_PER_SEC << std::endl;
- }
+ mln_concrete(I) output;
- }
+ win::hline2d win1(win.width());
+ output = level::median(input, win1);
- } // end of namespace mln::level::approx::impl
+ win::vline2d win2(win.height());
+ output = level::median(output, win2);
+ trace::exiting("level::approx::median");
+ return output;
+ }
- // Facades.
- template <typename I, typename O>
+ template <typename I>
inline
- void median(const Image<I>& input_, const win::rectangle2d& win,
- Image<O>& output_)
+ mln_concrete(I)
+ median(const Image<I>& input, const win::disk2d& win)
{
- const I& input = exact(input_);
- O& output = exact(output_);
- mln_assertion(output.domain() == input.domain());
-
- O tmp(output.domain());
- level::median(input, win::hline2d(win.width()), tmp);
- level::median(tmp, win::vline2d(win.height()), output);
- }
+ trace::entering("level::approx::median");
- template <typename I, typename O>
- inline
- void median(const Image<I>& input, const win::disk2d& win,
- Image<O>& output)
- {
- mln_assertion(exact(output).domain() == exact(input).domain());
+ const unsigned len = win.length() / 3 + 1;
+ mln_concrete(I) output;
+
+ win::diag2d win1(len);
+ output = level::median(input, win1);
+
+ win::backdiag2d win2(len);
+ output = level::median(output, win2);
+
+ win::hline2d win3(len);
+ output = level::median(input, win3);
- impl::median_(exact(input), win.length(), exact(output));
+ win::vline2d win4(len);
+ output = level::median(output, win4);
+
+ trace::exiting("level::approx::median");
+ return output;
}
- template <typename I, typename O>
+
+ template <typename I>
inline
- void median(const Image<I>& input, const win::octagon2d& win,
- Image<O>& output)
+ mln_concrete(I)
+ median(const Image<I>& input, const win::octagon2d& win)
{
- mln_assertion(exact(output).domain() == exact(input).domain());
-
- impl::median_(exact(input), win.length(), exact(output));
+ return median(input, win::disk2d(win.length()));
}
# endif // ! MLN_INCLUDE_ONLY
Index: mln/accu/transform_line.hh
--- mln/accu/transform_line.hh (revision 3140)
+++ mln/accu/transform_line.hh (working copy)
@@ -129,7 +129,7 @@
do
{
- // Start the run.
+ // Start the line.
// ---------------
qt = p;
@@ -146,8 +146,8 @@
if (input.has(p))
output(p) = a.to_result();
- // Browse the run.
- // ---------------
+ // Browse the line.
+ // ----------------
while (p_dir < pmax_dir)
{
@@ -165,8 +165,8 @@
p_dir = pmin_dir;
- // Go to the next run.
- // -------------------
+ // Go to the next line.
+ // --------------------
for (int c = P::dim - 1; c >= 0; --c)
{
@@ -203,7 +203,7 @@
internal::transform_line_tests(a, input);
- extension::adjust(input, length);
+ extension::adjust(input, length / 2);
mln_ch_value(I, mln_result(A)) output;
output = impl::generic::transform_line(a, input, length, dir);
@@ -226,7 +226,7 @@
internal::transform_line_tests(a_, input);
- extension::adjust(input, length);
+ extension::adjust(input, length / 2);
mln_ch_value(I, mln_result(A_)) output;
output = impl::generic::transform_line(a_, input, length, dir);
Index: mln/morpho/general.spe.hh
--- mln/morpho/general.spe.hh (revision 3140)
+++ mln/morpho/general.spe.hh (working copy)
@@ -40,6 +40,7 @@
# include <mln/win/rectangle2d.hh>
# include <mln/accu/transform_directional.hh>
+# include <mln/accu/transform_line.hh>
# include <mln/accu/transform_snake.hh>
# include <mln/accu/transform_stop.hh>
# include <mln/accu/transform_diagonal.hh>
@@ -238,7 +239,7 @@
extension::adjust_fill(input, geom::delta(win) + 1, op.neutral(input));
mln_concrete(I) output;
- output = accu::transform_directional(op.accu_incr(input), input, win, dir);
+ output = accu::transform_directional(op.accu_incr(input), input, win, dir); // FIXME: Use _line.
trace::exiting("morpho::impl:general_directional");
return output;
@@ -248,6 +249,25 @@
template <typename Op, typename I, typename W>
inline
mln_concrete(I)
+ general_line(const Op& op, const Image<I>& input, const Window<W>& win_)
+ {
+ trace::entering("morpho::impl:general_line");
+
+ const W& win = exact(win_);
+
+ extension::adjust_fill(input, geom::delta(win), op.neutral(input));
+ mln_concrete(I) output;
+ output = accu::transform_line(op.accu_incr(input), input,
+ win.length(), win.dir);
+
+ trace::exiting("morpho::impl:general_line");
+ return output;
+ }
+
+
+ template <typename Op, typename I, typename W>
+ inline
+ mln_concrete(I)
general_diagonal_2d(const Op& op, const Image<I>& input, const Window<W>& win)
{
trace::entering("morpho::impl:general_diagonal_2d");
@@ -398,7 +418,7 @@
general_dispatch_line(metal::true_,
const Op& op, const I& input, const W& win)
{
- return impl::general_directional(op, input, win, W::dir);
+ return impl::general_line(op, input, win);
}
template <typename Op, typename I, typename W>
Index: tests/level/approx/median.cc
--- tests/level/approx/median.cc (revision 3140)
+++ tests/level/approx/median.cc (working copy)
@@ -1,4 +1,5 @@
-// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
+// (LRDE)
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -25,14 +26,11 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-/*! \file tests/level/approx/median.cc
- *
- * \brief Test on mln::level::approx::median.
- */
+/// \file tests/level/approx/median.cc
+///
+/// Test on mln::level::approx::median.
#include <mln/core/image/image2d.hh>
-#include <mln/win/rectangle2d.hh>
-#include <mln/win/octagon2d.hh>
#include <mln/io/pgm/load.hh>
#include <mln/io/pgm/save.hh>
@@ -48,16 +46,17 @@
using namespace mln;
using value::int_u8;
- win::rectangle2d rect(51, 51);
- win::octagon2d oct(13);
- border::thickness = 52;
-
image2d<int_u8> lena;
io::pgm::load(lena, MLN_IMG_DIR "/lena.pgm");
- image2d<int_u8> out(lena.domain());
- // FIXME: Dead code?
-// level::approx::median(lena, rect, out);
- level::approx::median(lena, oct, out);
- io::pgm::save(out, "out.pgm");
+ {
+ win::octagon2d oct(51);
+ image2d<int_u8> out = level::approx::median(lena, oct);
+ io::pgm::save(out, "out_oct.pgm");
+ }
+ {
+ win::rectangle2d rec(51, 51);
+ image2d<int_u8> out = level::approx::median(lena, rec);
+ io::pgm::save(out, "out_rec.pgm");
+ }
}
Index: tests/morpho/general.cc
--- tests/morpho/general.cc (revision 3140)
+++ tests/morpho/general.cc (working copy)
@@ -97,14 +97,28 @@
out = morpho::impl::general_directional(dil, lena, rec, 1);
mln_assertion(out == ref);
- /*
// Hline.
ref = morpho::impl::generic::general_on_function(ero, lena, hline);
+ out = morpho::impl::general_directional(ero, lena, hline, 1);
+ mln_assertion(out == ref);
+
+ out = morpho::impl::general_line(ero, lena, hline);
+ mln_assertion(out == ref);
+
+
// Vline.
ref = morpho::impl::generic::general_on_function(ero, lena, vline);
+ out = morpho::impl::general_directional(ero, lena, vline, 0);
+ mln_assertion(out == ref);
+
+ out = morpho::impl::general_line(ero, lena, vline);
+ mln_assertion(out == ref);
+
+ /*
+
// Diag2d.
ref = morpho::impl::generic::erosion_on_function(lena, diag2d);
1
0
https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Fix accu::histo_h and cleanup level::median.
* mln/level/median.hh (internal::median_tests): New.
(median_dir): Remove; useless, better replace by handling
win::line!
(impl::median): Rename as...
(impl::generic::median): ...this.
Update.
(impl::median_line): New.
(internal::mediant_dispatch): New.
(include): Update.
* mln/accu/transform_line.hh: New.
* mln/accu/all.hh: Update.
* tests/level/median_dir.cc: Remove.
There is no median_dir.hh file so having this test is dull!
* tests/level/median_hline2d.cc: Likewise.
* tests/level/median.cc: Merge tests from removed files.
* tests/level/Makefile.am: Update.
* mln/accu/histo.hh (init): Fix.
Forgetting to set sum_ to 0 leads to errors in median
filtering...
* mln/accu/median_h.hh: Upgrade file doc style.
* mln/canvas/browsing/dir_struct_elt_incr_update.hh:
Add some debug information; I think that this code is bugged...
* tests/accu/transform_snake.cc,
* tests/accu/transform_diagonal.cc,
* tests/accu/transform_directional.cc
(ref): Remove unused object.
* tests/accu/median_h.cc: Upgrade file doc style.
* tests/accu/transform_line.cc: New.
* tests/accu/Makefile.am: Update.
mln/accu/all.hh | 1
mln/accu/histo.hh | 6
mln/accu/median_h.hh | 3
mln/accu/transform_line.hh | 245 ++++++++++++++++++++++
mln/canvas/browsing/dir_struct_elt_incr_update.hh | 19 +
mln/level/median.hh | 198 +++++++----------
tests/accu/Makefile.am | 2
tests/accu/median_h.cc | 12 -
tests/accu/transform_diagonal.cc | 8
tests/accu/transform_directional.cc | 4
tests/accu/transform_line.cc | 51 ++++
tests/accu/transform_snake.cc | 5
tests/level/Makefile.am | 4
tests/level/median.cc | 31 +-
14 files changed, 436 insertions(+), 153 deletions(-)
Index: mln/level/median.hh
--- mln/level/median.hh (revision 3139)
+++ mln/level/median.hh (working copy)
@@ -41,10 +41,11 @@
# include <mln/win/shift.hh>
# include <mln/win/diff.hh>
+# include <mln/win/line.hh>
# include <mln/canvas/browsing/snake_fwd.hh>
-# include <mln/canvas/browsing/dir_struct_elt_incr_update.hh>
# include <mln/accu/median_h.hh>
+# include <mln/accu/transform_line.hh>
namespace mln
@@ -62,36 +63,33 @@
*
* \pre \p input and \p output have to be initialized.
*/
- template <typename I, typename W, typename O>
- void median(const Image<I>& input, const Window<W>& win,
- Image<O>& output);
+ template <typename I, typename W>
+ mln_concrete(I)
+ median(const Image<I>& input, const Window<W>& win);
- /*! Compute in \p output the median filter of image \p input in
- * the direction \p dir with strength \p length.
- *
- * \param[in] input The image to be filtered.
- * \param[in] dir The filtering direction.
- * \param[in] length The filtering strength.
- * \param[out] output The output image.
- *
- * \pre \p input and \p output have to be initialized.
- * \pre \p dir is between 0 and less than the image dimension.
- * \pre \p length has to be odd.
- */
- template <typename I, typename O>
- void median_dir(const Image<I>& input, unsigned dir, unsigned length,
- Image<O>& output);
+# ifndef MLN_INCLUDE_ONLY
+ namespace internal
+ {
+ template <typename I, typename W>
+ void
+ median_tests(const Image<I>& input, const Window<W>& win)
+ {
+ mln_precondition(exact(input).is_valid());
+ // mln_precondition(exact(win).is_valid());
+ (void) input;
+ (void) win;
+ }
+
+ } // end of namespace level::internal
-# ifndef MLN_INCLUDE_ONLY
namespace impl
{
-
// Functors.
@@ -184,140 +182,108 @@
- template <typename I_, typename O>
- struct median_dir_t
+ namespace generic
{
- typedef I_ I;
- enum { dim = I::site::dim };
- // i/o
- const I& input;
- const unsigned dir;
- const unsigned length;
- O& output;
-
- // aux data
- mln_psite(I) p;
- accu::median_h<mln_value(I)> med;
-
- // ctor
+ template <typename I, typename W>
inline
- median_dir_t(const I& input, unsigned dir, unsigned length, O& output)
- : // i/o
- input(input),
- dir(dir),
- length(length),
- output(exact(output)),
- // aux data
- p(),
- med()
+ mln_concrete(I)
+ median(const Image<I>& input, const Window<W>& win)
{
- }
+ trace::entering("level::impl::generic::median");
- inline
- void init()
- {
- }
+ mlc_equal(mln_trait_image_quant(I),
+ trait::image::quant::low)::check();
+ internal::median_tests(input, win);
- inline
- void init_line()
- {
- med.init();
- }
+ extension::adjust(input, win);
- inline
- void add_point(mln_psite(I) pt)
- {
- med.take(input(pt));
- }
+ typedef mln_concrete(I) O;
+ O output;
+ initialize(output, input);
+ median_t<I,W,O> f(exact(input), exact(win), output);
+ canvas::browsing::snake_fwd(f);
- inline
- void remove_point(mln_psite(I) pu)
- {
- med.untake(input(pu));
+ trace::exiting("level::impl::generic::median");
+ return output;
}
- inline
- void next()
- {
- if (output.has(p))
- output(p) = med.to_result();
- }
+ } // end of namespace mln::level::impl::generic
+
+ template <typename I,
+ typename M, unsigned i, typename C>
inline
- void final()
+ mln_concrete(I)
+ median_line(const Image<I>& input, const win::line<M,i,C>& win)
{
+ trace::entering("level::impl::median_line");
+
+ mlc_equal(mln_trait_image_quant(I),
+ trait::image::quant::low)::check();
+ internal::median_tests(input, win);
+
+ accu::median_h<mln_value(I)> a;
+ mln_concrete(I) output = accu::transform_line(a, input, win.length(), i);
+
+ trace::exiting("level::impl::median_line");
+ return output;
}
- }; // end of median_dir_t
+
+ } // end of namespace mln::level::impl
- template <typename I, typename O>
+ namespace internal
+ {
+
+ template <typename I, typename W>
inline
- void median_dir_(const Image<I>& input, unsigned dir, unsigned length, O& output)
+ mln_concrete(I)
+ median_dispatch_wrt_win(const Image<I>& input, const Window<W>& win)
{
- median_dir_t<I,O> f(exact(input), dir, length, output);
- canvas::browsing::dir_struct_elt_incr_update(f);
+ return impl::generic::median(input, win);
}
-
- template <typename I, typename W, typename O>
+ template <typename I,
+ typename M, unsigned i, typename C>
inline
- void median_(const Image<I>& input, const Window<W>& win, O& output)
+ mln_concrete(I)
+ median_dispatch_wrt_win(const Image<I>& input, const win::line<M,i,C>& win)
{
- // FIXME: resize border!
- median_t<I,W,O> f(exact(input), exact(win), output);
- canvas::browsing::snake_fwd(f);
+ return impl::median_line(input, win);
}
-# ifdef MLN_CORE_WIN_LINE_HH
- template <typename I, typename M, unsigned i, typename C, typename O>
+ template <typename I, typename W>
inline
- void median_(const Image<I>& input, const win::line<M,i,C>& win, O& output)
+ mln_concrete(I)
+ median_dispatch(const Image<I>& input, const Window<W>& win)
{
- median_dir(input, i, win.length(), output); // FIXME: Make 1 explicit!
+ return median_dispatch_wrt_win(input, exact(win));
}
-# endif // ! MLN_CORE_WIN_LINE_HH
-
- } // end of namespace mln::level::impl
+ } // end of namespace level::internal
- // Facades.
+ // Facade.
- template <typename I, typename W, typename O>
- void median(const Image<I>& input, const Window<W>& win,
- Image<O>& output)
+ template <typename I, typename W>
+ mln_concrete(I)
+ median(const Image<I>& input, const Window<W>& win)
{
trace::entering("level::median");
- mln_assertion(exact(output).domain() == exact(input).domain());
- impl::median_(exact(input), exact(win), exact(output));
-
- trace::exiting("level::median");
- }
-
- template <typename I, typename O>
- void median_dir(const Image<I>& input, unsigned dir, unsigned length,
- Image<O>& output)
- {
- trace::entering("level::median_dir");
-
- mlc_is(mln_trait_image_value_io(O), trait::image::value_io::read_write)::check();
- mlc_is(mln_trait_image_localization(I),
- trait::image::localization::basic_grid)::check();
- mlc_converts_to(mln_value(I), mln_value(O))::check();
-
- mln_precondition(exact(output).domain() == exact(input).domain());
- typedef mln_psite(I) P;
- mln_precondition(dir < P::dim);
- mln_precondition(length % 2 == 1);
+ mlc_equal(mln_trait_image_quant(I),
+ trait::image::quant::low)::check();
- impl::median_dir_(exact(input), dir, length, exact(output));
+ internal::median_tests(input, win);
+ mln_concrete(I) output;
+ output = internal::median_dispatch(input, win);
- trace::exiting("level::median_dir");
+ trace::exiting("level::median");
+ return output;
}
# endif // ! MLN_INCLUDE_ONLY
Index: mln/accu/transform_line.hh
--- mln/accu/transform_line.hh (revision 0)
+++ mln/accu/transform_line.hh (revision 0)
@@ -0,0 +1,245 @@
+// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef MLN_ACCU_TRANSFORM_LINE_HH
+# define MLN_ACCU_TRANSFORM_LINE_HH
+
+/// \file mln/accu/transform_line.hh
+///
+/// Run an accumulator over a line (in a particular direction).
+///
+/// \todo Import code from sandox/geraud/browsing/fwd.cc to handle the
+/// case of no-domain-extension.
+///
+/// \todo Specialize for fastest images.
+
+# include <mln/core/concept/image.hh>
+# include <mln/core/concept/meta_accumulator.hh>
+# include <mln/extension/adjust.hh>
+
+
+
+namespace mln
+{
+
+ namespace accu
+ {
+
+
+ template <typename A, typename I>
+ mln_ch_value(I, mln_result(A))
+ transform_line(const Accumulator<A>& a,
+ const Image<I>& input,
+ unsigned length, unsigned dir);
+
+ template <typename A, typename I>
+ mln_ch_value(I, mln_accu_with(A, mln_value(I))::result)
+ transform_line(const Meta_Accumulator<A>& a,
+ const Image<I>& input,
+ unsigned length, unsigned dir);
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ // Tests.
+
+ namespace internal
+ {
+
+ template <typename A, typename I>
+ void transform_line_tests(const Accumulator<A>& a_, const Image<I>& input_)
+ {
+ A a = exact(a_);
+ const I& input = exact(input_);
+
+ mln_precondition(input.is_valid());
+ mln_psite(I)* p;
+ mln_precondition(sizeof(a.take(input(*p)), 0) == sizeof(int));
+
+ (void) p;
+ (void) a;
+ (void) input;
+ }
+
+ } // end of namespace mln::accu::internal
+
+
+ namespace impl
+ {
+
+ namespace generic
+ {
+
+ template <typename A, typename I>
+ inline
+ mln_ch_value(I, mln_result(A))
+ transform_line(const Accumulator<A>& a_,
+ const Image<I>& input_,
+ unsigned length, unsigned dir)
+ {
+ trace::entering("accu::impl::transform_line");
+
+ const I& input = exact(input_);
+ A a = exact(a_);
+
+ internal::transform_line_tests(a, input);
+
+ mln_ch_value(I, mln_result(A)) output;
+ initialize(output, input);
+
+ typedef mln_psite(I) P;
+ const P
+ pmin = input.domain().pmin(),
+ pmax = input.domain().pmax();
+ const def::coord
+ pmax_dir = pmax[dir],
+ pmin_dir = pmin[dir];
+
+ P p = pmin, // Starting point.
+ qt, qu;
+ def::coord& p_dir = p [dir];
+ def::coord& qt_dir = qt[dir];
+ def::coord& qu_dir = qu[dir];
+
+ do
+ {
+
+ // Start the run.
+ // ---------------
+
+ qt = p;
+ qt_dir = p_dir - length / 2;
+ qu = qt;
+ a.init();
+
+ for (unsigned i = 0; i < length; ++i)
+ {
+ if (input.has(qt))
+ a.take(input(qt));
+ qt_dir++;
+ }
+ if (input.has(p))
+ output(p) = a.to_result();
+
+ // Browse the run.
+ // ---------------
+
+ while (p_dir < pmax_dir)
+ {
+ ++p_dir;
+ if (input.has(qt))
+ a.take(input(qt));
+ if (input.has(qu))
+ a.untake(input(qu));
+ if (input.has(p))
+ output(p) = a.to_result();
+ qt_dir++;
+ qu_dir++;
+ }
+
+ p_dir = pmin_dir;
+
+
+ // Go to the next run.
+ // -------------------
+
+ for (int c = P::dim - 1; c >= 0; --c)
+ {
+ if (c == int(dir))
+ continue;
+ if (p[c] != pmax[c])
+ {
+ ++p[c];
+ break;
+ }
+ p[c] = pmin[c];
+ }
+
+ } while (p != pmin);
+
+ trace::exiting("accu::impl::transform_line");
+ return output;
+ }
+
+ } // end of namespace mln::accu::impl::generic
+
+ } // end of namespace mln::accu::impl
+
+
+
+ template <typename A, typename I>
+ inline
+ mln_ch_value(I, mln_result(A))
+ transform_line(const Accumulator<A>& a,
+ const Image<I>& input,
+ unsigned length, unsigned dir)
+ {
+ trace::entering("accu::transform_line");
+
+ internal::transform_line_tests(a, input);
+
+ extension::adjust(input, length);
+ mln_ch_value(I, mln_result(A)) output;
+ output = impl::generic::transform_line(a, input, length, dir);
+
+ trace::exiting("accu::transform_line");
+ return output;
+ }
+
+
+ template <typename A, typename I>
+ inline
+ mln_ch_value(I, mln_accu_with(A, mln_value(I))::result)
+ transform_line(const Meta_Accumulator<A>& a,
+ const Image<I>& input,
+ unsigned length, unsigned dir)
+ {
+ trace::entering("accu::transform_line");
+
+ typedef mln_accu_with(A, mln_value(I)) A_;
+ A_ a_ = accu::unmeta(exact(a), mln_value(I)());
+
+ internal::transform_line_tests(a_, input);
+
+ extension::adjust(input, length);
+ mln_ch_value(I, mln_result(A_)) output;
+ output = impl::generic::transform_line(a_, input, length, dir);
+
+ trace::exiting("accu::transform_line");
+ return output;
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::accu
+
+} // end of namespace mln
+
+
+#endif // ! MLN_ACCU_TRANSFORM_LINE_HH
Index: mln/accu/all.hh
--- mln/accu/all.hh (revision 3139)
+++ mln/accu/all.hh (working copy)
@@ -89,6 +89,7 @@
# include <mln/accu/transform_directional.hh>
# include <mln/accu/transform_diagonal.hh>
+# include <mln/accu/transform_line.hh>
# include <mln/accu/transform_snake.hh>
Index: mln/accu/histo.hh
--- mln/accu/histo.hh (revision 3139)
+++ mln/accu/histo.hh (working copy)
@@ -1,4 +1,5 @@
-// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
+// (LRDE)
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -34,7 +35,6 @@
///
/// \todo Use histo::data instead of std::vector!
-
# include <vector>
# include <algorithm>
@@ -44,6 +44,7 @@
# include <mln/value/set.hh>
# include <mln/histo/data.hh>
+
namespace mln
{
@@ -161,6 +162,7 @@
histo<V>::init()
{
h_.clear();
+ sum_ = 0;
}
template <typename V>
Index: mln/accu/median_h.hh
--- mln/accu/median_h.hh (revision 3139)
+++ mln/accu/median_h.hh (working copy)
@@ -1,4 +1,5 @@
-// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
+// (LRDE)
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
Index: mln/canvas/browsing/dir_struct_elt_incr_update.hh
--- mln/canvas/browsing/dir_struct_elt_incr_update.hh (revision 3139)
+++ mln/canvas/browsing/dir_struct_elt_incr_update.hh (working copy)
@@ -137,34 +137,53 @@
f.init_line();
// initialization (before first point of the line)
+ std::cout << "init" << std::endl;
for (ct = pmin_dir; ct < pmin_dir_plus_half_length; ++ ct)
if (f.input.has(pt))
+ {
+ std::cout << '+' << pt << ' ';
f.add_point(pt);
+ }
// left columns (just take new points)
+ std::cout << "left" << std::endl;
for (p_dir = pmin_dir; p_dir <= pmin_dir_plus_half_length; ++p_dir, ++ct)
{
if (f.input.has(pt))
+ {
+ std::cout << '+' << pt << ' ';
f.add_point(pt);
+ }
f.next();
}
// middle columns (both take and untake)
+ std::cout << "middle" << std::endl;
cu = pmin_dir;
for (; p_dir <= pmax_dir_minus_half_length; ++cu, ++p_dir, ++ct)
{
if (f.input.has(pt))
+ {
+ std::cout << '+' << pt << ' ';
f.add_point(pt);
+ }
if (f.input.has(pu))
+ {
+ std::cout << '-' << pu << ' ';
f.remove_point(pu);
+ }
f.next();
}
// right columns (now just untake old points)
+ std::cout << "right" << std::endl;
for (; p_dir <= pmax_dir; ++cu, ++p_dir)
{
if (f.input.has(pu))
+ {
+ std::cout << '-' << pu << ' ';
f.remove_point(pu);
+ }
f.next();
}
Index: tests/level/median.cc
--- tests/level/median.cc (revision 3139)
+++ tests/level/median.cc (working copy)
@@ -1,4 +1,5 @@
-// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
+// (LRDE)
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -25,10 +26,9 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-/*! \file tests/level/median.cc
- *
- * \brief Test on mln::level::median.
- */
+/// \file tests/level/median.cc
+///
+/// Test on mln::level::median.
#include <mln/core/image/image2d.hh>
#include <mln/win/rectangle2d.hh>
@@ -47,13 +47,20 @@
using namespace mln;
using value::int_u8;
- win::rectangle2d rect(5, 5);
- border::thickness = 6;
-
image2d<int_u8> lena;
io::pgm::load(lena, MLN_IMG_DIR "/lena.pgm");
- image2d<int_u8> out(lena.domain());
-
- level::median(lena, rect, out);
- io::pgm::save(out, "out.pgm");
+ {
+ win::rectangle2d rect(51, 51);
+ image2d<int_u8> out = level::median(lena, rect);
+ io::pgm::save(out, "out_rect.pgm");
+ }
+ {
+ win::rectangle2d rect(1, 51);
+ win::hline2d line(51);
+ image2d<int_u8>
+ ref = level::median(lena, rect),
+ out = level::median(lena, line);
+ mln_assertion(out == ref);
+ io::pgm::save(out, "out_line.pgm");
+ }
}
Index: tests/level/Makefile.am
--- tests/level/Makefile.am (revision 3139)
+++ tests/level/Makefile.am (working copy)
@@ -13,9 +13,7 @@
convert \
median \
median_ \
- median_dir \
median_fast \
- median_hline2d \
saturate \
sort_psites \
stretch \
@@ -31,9 +29,7 @@
convert_SOURCES = convert.cc
median_SOURCES = median.cc
median__SOURCES = median_.cc
-median_dir_SOURCES = median_dir.cc
median_fast_SOURCES = median_fast.cc
-median_hline2d_SOURCES = median_hline2d.cc
saturate_SOURCES = saturate.cc
sort_psites_SOURCES = sort_psites.cc
stretch_SOURCES = stretch.cc
Index: tests/accu/transform_snake.cc
--- tests/accu/transform_snake.cc (revision 3139)
+++ tests/accu/transform_snake.cc (working copy)
@@ -44,9 +44,6 @@
image2d<int> ima(4, 5);
win::rectangle2d rec(3, 3);
- image2d<unsigned>
- out = accu::transform_snake(accu::meta::count(), ima, rec),
- ref(ima.domain());
-
+ image2d<unsigned> out = accu::transform_snake(accu::meta::count(), ima, rec);
mln_assertion(out == (pw::cst(rec.size()) | ima.domain()));
}
Index: tests/accu/median_h.cc
--- tests/accu/median_h.cc (revision 3139)
+++ tests/accu/median_h.cc (working copy)
@@ -1,4 +1,5 @@
-// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
+// (LRDE)
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -25,16 +26,16 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-/*! \file tests/accu/median_h.cc
- *
- * \brief Tests on mln::accu::median_h.
- */
+/// \file tests/accu/median_h.cc
+///
+/// Tests on mln::accu::median_h.
#include <mln/core/image/image2d.hh>
#include <mln/value/int_u8.hh>
#include <mln/accu/median_h.hh>
+
int main()
{
using namespace mln;
@@ -66,4 +67,5 @@
mln_assertion(med.to_result() == 7u);
}
+
}
Index: tests/accu/transform_diagonal.cc
--- tests/accu/transform_diagonal.cc (revision 3139)
+++ tests/accu/transform_diagonal.cc (working copy)
@@ -44,17 +44,13 @@
{
win::diag2d w(3);
- image2d<unsigned>
- out = accu::transform_diagonal(accu::meta::count(), ima, w),
- ref(ima.domain());
+ image2d<unsigned> out = accu::transform_diagonal(accu::meta::count(), ima, w);
mln_assertion(out == (pw::cst(w.size()) | ima.domain()));
}
{
win::backdiag2d w(3);
- image2d<unsigned>
- out = accu::transform_diagonal(accu::meta::count(), ima, w),
- ref(ima.domain());
+ image2d<unsigned> out = accu::transform_diagonal(accu::meta::count(), ima, w);
mln_assertion(out == (pw::cst(w.size()) | ima.domain()));
}
Index: tests/accu/transform_line.cc
--- tests/accu/transform_line.cc (revision 0)
+++ tests/accu/transform_line.cc (revision 0)
@@ -0,0 +1,51 @@
+// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+/// \file tests/accu/transform_line.cc
+///
+/// Tests on mln::accu::transform_line.
+
+#include <mln/core/image/image2d.hh>
+#include <mln/accu/transform_line.hh>
+#include <mln/accu/count.hh>
+#include <mln/pw/all.hh>
+#include <mln/level/compare.hh>
+
+
+int main()
+{
+ using namespace mln;
+
+ image2d<unsigned> ima(4, 5);
+ unsigned len = 3;
+ for (unsigned dir = 0; dir < 2; ++dir)
+ {
+ image2d<unsigned> out = accu::transform_line(accu::meta::count(), ima, len, dir);
+ mln_assertion(out == (pw::cst(3) | ima.domain()));
+ }
+
+}
Index: tests/accu/Makefile.am
--- tests/accu/Makefile.am (revision 3139)
+++ tests/accu/Makefile.am (working copy)
@@ -22,6 +22,7 @@
transform \
transform_diagonal \
transform_directional \
+ transform_line \
transform_snake \
tuple
@@ -44,6 +45,7 @@
transform_SOURCES = transform.cc
transform_diagonal_SOURCES = transform_diagonal.cc
transform_directional_SOURCES = transform_directional.cc
+transform_line_SOURCES = transform_line.cc
transform_snake_SOURCES = transform_snake.cc
tuple_SOURCES = tuple.cc
Index: tests/accu/transform_directional.cc
--- tests/accu/transform_directional.cc (revision 3139)
+++ tests/accu/transform_directional.cc (working copy)
@@ -46,9 +46,7 @@
for (unsigned dir = 0; dir < 2; ++dir)
{
- image2d<unsigned>
- out = accu::transform_directional(accu::meta::count(), ima, rec, dir),
- ref(ima.domain());
+ image2d<unsigned> out = accu::transform_directional(accu::meta::count(), ima, rec, dir);
mln_assertion(out == (pw::cst(rec.size()) | ima.domain()));
}
}
1
0
* samples/fill-proto.cc.raw: new file. Inline code inserted in tutorial.
* samples/tuto4_genericity_and_algorithms.cc: Add more code.
* tutorial.tex: add more details. Explain the code.
---
milena/ChangeLog | 10 +
milena/doc/tutorial/samples/fill-proto.cc.raw | 7 +
.../samples/tuto4_genericity_and_algorithms.cc | 13 ++
milena/doc/tutorial/tutorial.tex | 181 +++++++++++++++++---
4 files changed, 183 insertions(+), 28 deletions(-)
create mode 100644 milena/doc/tutorial/samples/fill-proto.cc.raw
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 9472f63..e9d3d63 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,3 +1,13 @@
+2009-01-08 Guillaume Lazzara <z(a)lrde.epita.fr>
+
+ Add more details in step 4 in tutorial.
+
+ * samples/fill-proto.cc.raw: new file. Inline code inserted in tutorial.
+
+ * samples/tuto4_genericity_and_algorithms.cc: Add more code.
+
+ * tutorial.tex: add more details. Explain the code.
+
2009-01-06 Guillaume Lazzara <z(a)lrde.epita.fr>
Add fun::meta::green and fun::meta::blue.
diff --git a/milena/doc/tutorial/samples/fill-proto.cc.raw b/milena/doc/tutorial/samples/fill-proto.cc.raw
new file mode 100644
index 0000000..f0bd0fe
--- /dev/null
+++ b/milena/doc/tutorial/samples/fill-proto.cc.raw
@@ -0,0 +1,7 @@
+namespace data
+{
+
+ template <typename I, typename D>
+ void fill(Image<I>& ima, const D& data);
+
+}
diff --git a/milena/doc/tutorial/samples/tuto4_genericity_and_algorithms.cc b/milena/doc/tutorial/samples/tuto4_genericity_and_algorithms.cc
index ca5e7f4..1c80453 100644
--- a/milena/doc/tutorial/samples/tuto4_genericity_and_algorithms.cc
+++ b/milena/doc/tutorial/samples/tuto4_genericity_and_algorithms.cc
@@ -36,6 +36,19 @@ int main()
lena = duplicate(lena_bak);
// \{
+ p_array<point2d> arr;
+ for (def::coord row = geom::min_row(lena); row < geom::max_row(lena); ++row)
+ for (def::coord col = geom::min_row(lena); col < geom::max_col(lena); ++col)
+ if (((row + col) % 2) == 0)
+ arr.append(point2d(row, col));
+ // \}
+ // \{
+ for (def::coord row = geom::min_row(lena); row < geom::max_row(lena); ++row)
+ for (def::coord col = geom::min_row(lena); col < geom::max_col(lena); ++col)
+ if (((row + col) % 2) == 0)
+ opt::at(lena, row, col) = literal::green;
+ // \}
+ // \{
data::fill((lena | fun::p2b::chess()).rw(), literal::green);
// \}
doc::ppmsave(lena, "tuto4_genericity_and_algorithms");
diff --git a/milena/doc/tutorial/tutorial.tex b/milena/doc/tutorial/tutorial.tex
index d3aca8e..8cae3af 100644
--- a/milena/doc/tutorial/tutorial.tex
+++ b/milena/doc/tutorial/tutorial.tex
@@ -58,6 +58,7 @@
% #1 : section name
% #2 : section title
\newcommand{\doxysection}[2]{%
+\vspace{1cm}
\label{#1}
\backslash endhtmlonly%
\backslash section #1 #2%
@@ -302,14 +303,14 @@ $$
\backslash endhtmlonly
\backslash page tutorial Tutorial
-- \backslash subpage tutoforeword
-- \backslash subpage loadnsave
-- \backslash subpage tutofirstimage
-- \backslash subpage tutochangeimage
-- \backslash subpage tutogenericity
-- \backslash subpage tutoconvimage
-- \backslash subpage tutowinneighb
-- \backslash subpage tutograph
+- \backslash subpage tuto0
+- \backslash subpage tuto1
+- \backslash subpage tuto2
+- \backslash subpage tuto3
+- \backslash subpage tuto4
+- \backslash subpage tuto5
+- \backslash subpage tuto6
+- \backslash subpage tuto7
\backslash page quickref Quick Reference Guide
- \backslash subpage installation
@@ -323,6 +324,7 @@ $$
- \backslash subpage imamemmgmt
- \backslash subpage basicops
- \backslash subpage graphandima
+- \backslash subpage functions
- \backslash subpage arithmops
- \backslash subpage mathtools
- \backslash subpage debugtools
@@ -350,19 +352,19 @@ A copy of the license is provided in the file COPYING.DOC.
\begin{htmlonly}
%====================================
-\doxychapter{tutoforeword}{Step 0: Foreword}
+\doxychapter{tuto0}{Step 0: Foreword}
- image2d
- typical use case
\begin{center}%
- \hspace{1cm} Go to \doxyref{loadnsave}~ \longrightarrow%
+ \hspace{1cm} Go to \doxyref{tuto1}~ \longrightarrow%
\end{center}%
%====================================
-\doxychapter{loadnsave}{Step 1: Load and save images}
+\doxychapter{tuto1}{Step 1: Load and save images}
After this step you shoud know how to:
\begin{itemize}
@@ -396,12 +398,12 @@ The supported file formats and their associated image value types are listed
in section \doxyref{imaio}.
\vspace{2cm}
-\tutotoc{tutoforeword}{tutofirstimage}
+\tutotoc{tuto0}{tuto2}
%====================================
-\doxychapter{tutofirstimage}{Step 2: Create your first image}
+\doxychapter{tuto2}{Step 2: Create your first image}
After this step you should know how to:
\begin{itemize}
@@ -409,7 +411,7 @@ After this step you should know how to:
\item display an image in console mode.
\end{itemize}
-\doxysee{tuto2_first_image.cc}.
+\doxysee{tuto2_first_image.cc}
\vspace{2cm}
@@ -444,12 +446,12 @@ though. A more detailed description can be found in section
\vspace{2cm}
\begin{center}
- \tutotoc{loadnsave}{tutochangeimage}
+ \tutotoc{tuto1}{tuto3}
\end{center}
%====================================
-\doxychapter{tutochangeimage}{Step 3: Read and write images}
+\doxychapter{tuto3}{Step 3: Read and write images}
After this step you should know how to:
\begin{itemize}
@@ -458,7 +460,7 @@ After this step you should know how to:
\end{itemize}
-\doxysee{tuto3_rw_image.cc}.
+\doxysee{tuto3_rw_image.cc}
\vspace{2cm}
First create an empty color image with a \var{box2d} of 40x40 as domain.
@@ -499,12 +501,12 @@ the reference guide.
\vspace{2cm}
\begin{center}
- \tutotoc{tutofirstimage}{tutogenericity}
+ \tutotoc{tuto2}{tuto4}
\end{center}
%====================================
-\doxychapter{tutogenericity}{Step 4: Genericity and algorithms}
+\doxychapter{tuto4}{Step 4: Regions of interest}
After this step you should know how to:
\begin{itemize}
@@ -512,14 +514,55 @@ After this step you should know how to:
\item work only on a region of interest in an image.
\end{itemize}
-\doxysee{tuto4_genericity_and_algorithms.cc}.
+\doxysee{tuto4_genericity_and_algorithms.cc}
\vspace{2cm}
+In the previous step, we used the routine \code{data::fill} in order to change
+the values of an image. It was convenient since we did not need to write any
+loop by hand. The problem was that we could not specificy which region to fill
+with data. This point leads us to talk about the genericity in Olena.
+All along this example we will use the routine \code{data::fill} to illustrate
+the possibilities in Olena but note that every image types passed to the
+routine in this example could be passed to any algorithm in the library
+expecting an image.
+
+One main feature of Olena is to be able to easily work on regions of interest in
+images. According to the way a region of interest is defined, a specific image
+type is associated. Therefore, each algorithm knows exactly what it is working
+on and can behave differently in order to be the most efficient as possible.
+
+
+All along this step, we will use the following image \var{lena} declared as
+follow:
+
\doxycode[1]{tuto4_genericity_and_algorithms}
\doxyimg{small-enlarged}
+\code{data::fill} has the following prototype:
+\doxyrawcode{fill-proto}
+So keep in mind that the first argument we will try to construct in each
+example is an image. Note that this image \must be writable, e.g. non-const.
+
+
+%**************************
+\doxysection{tuto4imadomainsiteset}{Image domain restricted by a site set}
+
+Here, we would like to fill a small square with green in \var{lena}. We want
+this square to be of size 20x20 and to be located at (20,20).
+First, we just need to declare this square which is actually a site set, a
+\type{box2d}.
\doxycode[2]{tuto4_genericity_and_algorithms}
+
+Then, we just need to tell \code{data::fill} that we would like to fill the
+image \var{lena} but only in this restricted part of the image domain.
\doxycode[3]{tuto4_genericity_and_algorithms}
+Operator '|' can be read 'restricted to'. So below, we wrote 'image \var{lena}
+restricted to the region of interest \var{roi}'. Actually this is not directly
+\var{lena} which is restricted but its domain.
+
+Note the use of \code{rw()} which is mandatory due to C++ limitations. In C++,
+the image created by \code{lena | roi} is \code{const}, e.g. read-only, though
+\code{data::fill} expect a \code{non-const} image, e.g. read-write.
\begin{center}
\begin{tabular}{c c c}
@@ -530,7 +573,21 @@ After this step you should know how to:
\end{center}
+%**************************
+\doxysection{tuto4imadomainfun}{Image domain restricted by a function}
+
+Sometimes it may not be easy to construct a site set to restrict an image. For
+instance, if we would like to fill with green one point out of two in the whole
+image, we \textbf{do not want} to write anyloop or construct any site set by hand:
\doxycode[4]{tuto4_genericity_and_algorithms}
+\doxycode[5]{tuto4_genericity_and_algorithms}
+
+A shorter way to get exactly the same result, is to define that behavior by a
+function. In Milena, a function \code{fun::p2v::chess} is available and does
+exactly what we want. Like if it was a site set, simply restrict the image with
+the function.
+
+\doxycode[6]{tuto4_genericity_and_algorithms}
\begin{center}
\begin{tabular}{c c c}
\doxyimg{small-enlarged} & ~\huge{\rightarrow}~ & \doxyfigure[2]{tuto4_genericity_and_algorithms}{3cm} \\
@@ -539,9 +596,41 @@ After this step you should know how to:
\end{tabular}
\end{center}
+Note that the functions provided by default in Olena are actually functors.
+Thus, they must be constructed like any object which why it is written
+\code{lena | fun::p2v::chess()} and not \code{lena | fun::p2v::chess}.
+
+
+FIXME: Talk about C functions once it is possible in Milena.
+
+
+%**************************
+\doxysection{tuto4imadomainmask}{Image domain restricted by a mask}
+
+Sometimes instead of having a site site or a function defining the regions of
+interest we want to work on, we may have a binary image, e.g. a mask. When a
+site has its value set to true, it means it will be considered as part of the
+masked image domain. Otherwise, it will not.
+
+We construct a mask, \var{mask}. It is initialized with the same geometry properties as
+\var{lena}
+(domain, extension...).
+\doxycode[7]{tuto4_genericity_and_algorithms}
+
+Then, we cannot restrict directly \var{lena} with \var{mask}. These two images
+have the same domain, so \code{lena | mask.domain()} would not do anything.
+\var{mask} is a classical image, there is not specific type for mask images.
+Therefore, we need to express that we want that binary image to be considered as
+a mask.
+\doxycode[8]{tuto4_genericity_and_algorithms}
+\code{pw::value(mask)} makes explicit the fact that \var{mask} is actually a
+mask. It means, that for each site of \var{mask}, if its value is set to
+\val{true}, then the value associated to this site in \var{lena} must be set
+to green.
+In this example, we use two images for two different use case: \var{lena} store
+the result and the modifications make by the algorithm and \var{mask} allows the
+algorithm to know whether it must treat a site or not.
-\doxycode[5]{tuto4_genericity_and_algorithms}
-\doxycode[6]{tuto4_genericity_and_algorithms}
\begin{center}
\begin{tabular}{c c c c}
\doxyimg{small-enlarged} &
@@ -553,8 +642,34 @@ After this step you should know how to:
\end{tabular}
\end{center}
-\doxycode[7]{tuto4_genericity_and_algorithms}
-\doxycode[8]{tuto4_genericity_and_algorithms}
+
+%**************************
+\doxysection{tuto4imadomainpredicate}{Image domain restricted by a predicate}
+
+Restricting by a predicate is exactly like restricting with a function. We want
+to talk about that separately in order to present the small routines available.
+They enable the user to write quick and efficient predicate/function.
+
+The two routines are :
+\begin{itemize}
+ \item pw::value(Image), as seen in a previous section, it is a way to express
+ 'for each site value in Image'.
+ \item pw::cst(Value), it is a way to specify a value to which a site value can
+ be compared.
+\end{itemize}
+
+Let's see a common use case.
+First, we binarize lena according to specific criterions, only site values with
+specific colors are set to true in \var{lena_bw}. Others are set to false. This
+image will be used in order to label the components.
+Let's consider a labeled image \var{label}. Each component of \var{lena} is labeled with a unique index.
+Now, we consider that that our region of interest is a component with id 16.
+Then we want to express 'for each site \var{fill} its value in \var{lena} if its
+value in \var{label} is equal to 16'.
+\doxycode[9]{tuto4_genericity_and_algorithms}
+
+
+\doxycode[10]{tuto4_genericity_and_algorithms}
\begin{center}
\begin{tabular}{c c c c}
@@ -571,19 +686,19 @@ After this step you should know how to:
\vspace{2cm}
\begin{center}
- \tutotoc{tutochangeimage}{tutoconvimage}
+ \tutotoc{tuto3}{tuto5}
\end{center}
%====================================
-\doxychapter{tutoconvimage}{Step 5: Conversion between image values}
+\doxychapter{tuto5}{Step 5: Conversion between image values}
%====================================
-\doxychapter{tutowinneighb}{Step 6: Using structural elements with algorithms}
+\doxychapter{tuto6}{Step 6: Using structural elements with algorithms}
%====================================
-\doxychapter{tutograph}{Step 7: Handle graphes with an image}
+\doxychapter{tuto7}{Step 7: Handle graphes with an image}
\end{htmlonly}
@@ -595,6 +710,7 @@ After this step you should know how to:
\doxysection{requirements}{Requirements}
+%----------------
\doxysubsection{compexample}{To compile the user examples}
\begin{itemize}
@@ -605,6 +721,7 @@ After this step you should know how to:
+%----------------
\doxysubsection{compdoc}{To compile the documentation (Optional)}
\begin{itemize}
@@ -616,6 +733,7 @@ After this step you should know how to:
\item the `texinfo' utilities from GNU
\end{itemize}
+%----------------
\doxysubsection{devolena}{To develop in Olena}
\begin{itemize}
\item GNU Autotools (Autoconf 2.54, Automake 1.10)
@@ -2228,6 +2346,13 @@ Output:
%====================================
\newpage
\clearpage
+\doxychapter{functions}{Functions}
+
+FIXME write it
+
+%====================================
+\newpage
+\clearpage
\doxychapter{arithmops}{Arithmetical operators}
FIXME write it
--
1.5.6.5
1
0