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
November 2008
- 14 participants
- 266 discussions
12 Nov '08
https://svn.lrde.epita.fr/svn/oln/branches/cleanup-2008/milena
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Update labeling routines to modern conventions.
* mln/morpho/erosion.spe.hh
(erosion_dispatch_wrt_win): Add check over win simplicity.
* mln/labeling/flat_zones.hh,
* mln/labeling/level.hh,
* mln/labeling/foreground.hh,
* mln/labeling/regional_minima.hh,
* mln/labeling/regional_maxima.hh,
* mln/labeling/compute.hh,
* mln/labeling/level.spe.hh,
* mln/labeling/background.hh: Partial update w.r.t. routine
naming and style.
* mln/labeling/all.hh (todo): New.
labeling/all.hh | 13 ++++----
labeling/background.hh | 26 ++++++++---------
labeling/compute.hh | 11 +++----
labeling/flat_zones.hh | 21 ++++++-------
labeling/foreground.hh | 26 ++++++++---------
labeling/level.hh | 67 ++++++++++++++++++++++++++++++++++++--------
labeling/level.spe.hh | 42 +++++++--------------------
labeling/regional_maxima.hh | 14 ++++-----
labeling/regional_minima.hh | 14 ++++-----
morpho/erosion.spe.hh | 4 ++
10 files changed, 133 insertions(+), 105 deletions(-)
Index: mln/morpho/erosion.spe.hh
--- mln/morpho/erosion.spe.hh (revision 2841)
+++ mln/morpho/erosion.spe.hh (working copy)
@@ -58,6 +58,8 @@
///
/// \todo Warning: we should also have the "arbitrary" versions working
/// on sets (not only on functions!)
+///
+/// \todo HERE Factor dispatch for lines...
# ifndef MLN_INCLUDE_ONLY
@@ -1384,6 +1386,8 @@
&&
mlc_is_a(mln_site(I), Gpoint)::value
&&
+ mln_is_simple_window(W)::value
+ &&
mlc_not_equal(mln_trait_image_value_storage(I),
trait::image::value_storage::disrupted)::value };
return erosion_dispatch_wrt_arbitrary_win(metal::bool_<test>(),
Index: mln/labeling/flat_zones.hh
--- mln/labeling/flat_zones.hh (revision 2841)
+++ mln/labeling/flat_zones.hh (working copy)
@@ -29,10 +29,9 @@
#ifndef MLN_LABELING_FLAT_ZONES_HH
# define MLN_LABELING_FLAT_ZONES_HH
-/*! \file mln/labeling/flat_zones.hh
- *
- * \brief Connected component labeling of the flat zones of an image.
- */
+/// \file mln/labeling/flat_zones.hh
+///
+/// Connected component labeling of the flat zones of an image.
# include <mln/core/concept/image.hh>
# include <mln/core/concept/neighborhood.hh>
@@ -93,7 +92,7 @@
// end of requirements
- flat_zones_functor(const I_& input, const N_& nbh)
+ flat_zones_functor(const I& input, const N& nbh)
: input(input),
nbh(nbh),
s(input.domain())
@@ -108,16 +107,16 @@
template <typename I, typename N, typename L>
mln_ch_value(I, L)
- flat_zones_(const I& input, const N& nbh, L& nlabels)
+ flat_zones(const Image<I>& input, const Neighborhood<N>& nbh, L& nlabels)
{
- trace::entering("labeling::impl::generic::flat_zones_");
+ trace::entering("labeling::impl::generic::flat_zones");
typedef flat_zones_functor<I,N,L> F;
- F f(input, nbh);
+ F f(exact(input), exact(nbh));
canvas::labeling<F> run(f);
nlabels = run.nlabels;
- trace::exiting("labeling::impl::generic::flat_zones_");
+ trace::exiting("labeling::impl::generic::flat_zones");
return run.output;
}
@@ -136,13 +135,13 @@
L& nlabels)
{
trace::entering("labeling::flat_zones");
+
const I& input = exact(input_);
const N& nbh = exact(nbh_);
mln_precondition(input.has_data());
// Calls the only (generic) impl.
- mln_ch_value(I, L) output =
- impl::generic::flat_zones_(input, nbh, nlabels);
+ mln_ch_value(I, L) output = impl::generic::flat_zones(input, nbh, nlabels);
trace::exiting("labeling::flat_zones");
return output;
Index: mln/labeling/level.hh
--- mln/labeling/level.hh (revision 2841)
+++ mln/labeling/level.hh (working copy)
@@ -67,6 +67,32 @@
# ifndef MLN_INCLUDE_ONLY
+
+ // Tests.
+
+ namespace internal
+ {
+
+ template <typename I, typename N, typename L>
+ void
+ level_tests(const Image<I>& input, const mln_value(I)& val, const Neighborhood<N>& nbh,
+ L& nlabels)
+ {
+ mln_precondition(exact(input).has_data());
+ // mln_precondition(exact(nbh).is_valid());
+
+ (void) input;
+ (void) val;
+ (void) nbh;
+ (void) nlabels;
+ }
+
+ } // end of namespace mln::labeling::internal
+
+
+
+ // Generic implementation.
+
namespace impl
{
@@ -101,7 +127,7 @@
const mln_value(I_)& val;
- level_functor(const I_& input, const mln_value(I_)& val, const N_& nbh)
+ level_functor(const I& input, const mln_value(I)& val, const N& nbh)
: input(input),
nbh(nbh),
s(input.domain()),
@@ -117,19 +143,22 @@
template <typename I, typename N, typename L>
mln_ch_value(I, L)
- level_(const I& input, const mln_value(I)& val, const N& nbh,
+ level(const Image<I>& input, const mln_value(I)& val,
+ const Neighborhood<N>& nbh,
L& nlabels)
{
- trace::entering("labeling::impl::generic::level_");
+ trace::entering("labeling::impl::generic::level");
+
+ internal::level_tests(input, val, nbh, nlabels);
typedef level_functor<I,N,L> F;
- F f(input, val, nbh);
+ F f(exact(input), val, exact(nbh));
canvas::labeling<F> run(f);
nlabels = run.nlabels;
// FIXME: Handle run.status
- trace::exiting("labeling::impl::generic::level_");
+ trace::exiting("labeling::impl::generic::level");
return run.output;
}
@@ -139,20 +168,36 @@
} // end of namespace mln::labeling::impl
+ // Dispatch.
+
+ namespace internal
+ {
+
+ template <typename I, typename N, typename L>
+ mln_ch_value(I, L)
+ level_dispatch(const Image<I>& input, const mln_value(I)& val, const Neighborhood<N>& nbh,
+ L& nlabels)
+ {
+ return impl::generic::level(input, val, nbh, nlabels);
+ }
+
+ } // end of namespace mln::labeling::internal
+
+
// Facade.
template <typename I, typename N, typename L>
mln_ch_value(I, L)
- level(const Image<I>& input, const mln_value(I)& val,
- const Neighborhood<N>& nbh, L& nlabels)
+ level(const Image<I>& input, const mln_value(I)& val, const Neighborhood<N>& nbh,
+ L& nlabels)
{
trace::entering("labeling::level");
- mln_precondition(exact(input).has_data());
- mln_ch_value(I, L) output =
- impl::level_(mln_trait_image_speed(I)(),
- exact(input), val, exact(nbh), nlabels);
+ internal::level_tests(input, val, nbh, nlabels);
+
+ mln_ch_value(I, L) output;
+ output = internal::level_dispatch(input, val, nbh, nlabels);
trace::exiting("labeling::level");
return output;
Index: mln/labeling/all.hh
--- mln/labeling/all.hh (revision 2841)
+++ mln/labeling/all.hh (working copy)
@@ -28,10 +28,12 @@
#ifndef MLN_LABELING_ALL_HH
# define MLN_LABELING_ALL_HH
-/*! \file mln/labeling/all.hh
- *
- * \brief File that includes all labeling routines.
- */
+/// \file mln/labeling/all.hh
+///
+/// File that includes all labeling routines.
+///
+/// \todo Many files in this directory have to be updated with the
+/// test and dispatch mechanisms.
namespace mln
@@ -47,9 +49,7 @@
namespace generic {}
}
-
}
-
}
# include <mln/labeling/background.hh>
@@ -61,4 +61,5 @@
# include <mln/labeling/regional_maxima.hh>
# include <mln/labeling/regional_minima.hh>
+
#endif // ! MLN_LABELING_ALL_HH
Index: mln/labeling/foreground.hh
--- mln/labeling/foreground.hh (revision 2841)
+++ mln/labeling/foreground.hh (working copy)
@@ -29,11 +29,10 @@
#ifndef MLN_LABELING_FOREGROUND_HH
# define MLN_LABELING_FOREGROUND_HH
-/*! \file mln/labeling/foreground.hh
- *
- * \brief Connected component labeling of the object part in a binary
- * image.
- */
+/// \file mln/labeling/foreground.hh
+///
+/// Connected component labeling of the object part in a binary
+/// image.
# include <mln/labeling/level.hh>
@@ -59,27 +58,28 @@
*
* \see mln::labeling::level
*/
- template <typename I, typename N>
- mln_ch_value(I, unsigned)
+ template <typename I, typename N, typename L>
+ mln_ch_value(I, L)
foreground(const Image<I>& input, const Neighborhood<N>& nbh,
- unsigned& nlabels);
+ L& nlabels);
# ifndef MLN_INCLUDE_ONLY
- template <typename I, typename N>
+ template <typename I, typename N, typename L>
inline
- mln_ch_value(I, unsigned)
+ mln_ch_value(I, L)
foreground(const Image<I>& input, const Neighborhood<N>& nbh,
- unsigned& nlabels)
+ L& nlabels)
{
trace::entering("labeling::foreground");
+
mlc_equal(mln_trait_image_kind(I),
mln::trait::image::kind::binary)::check();
mln_precondition(exact(input).has_data());
+ // mln_precondition(exact(nbh).is_valid());
- mln_ch_value(I, unsigned) output =
- labeling::level(input, true, nbh, nlabels);
+ mln_ch_value(I, L) output = labeling::level(input, true, nbh, nlabels);
trace::exiting("labeling::foreground");
return output;
Index: mln/labeling/regional_minima.hh
--- mln/labeling/regional_minima.hh (revision 2841)
+++ mln/labeling/regional_minima.hh (working copy)
@@ -30,8 +30,8 @@
# define MLN_LABELING_REGIONAL_MINIMA_HH
/// \file mln/labeling/regional_minima.hh
-/// \brief Connected component labeling of the regional minima of an
-/// image.
+///
+/// Connected component labeling of the regional minima of an image.
# include <mln/core/concept/image.hh>
# include <mln/core/concept/neighborhood.hh>
@@ -124,9 +124,9 @@
template <typename I, typename N, typename L>
mln_ch_value(I, L)
- regional_minima_(const I& input, const N& nbh, L& nlabels)
+ regional_minima(const I& input, const N& nbh, L& nlabels)
{
- trace::entering("labeling::impl::generic::regional_minima_");
+ trace::entering("labeling::impl::generic::regional_minima");
// FIXME: abort if L is not wide enough to encode the set of
// minima.
@@ -136,7 +136,7 @@
canvas::labeling<F> run(f);
nlabels = run.nlabels;
- trace::exiting("labeling::impl::generic::regional_minima_");
+ trace::exiting("labeling::impl::generic::regional_minima");
return run.output;
}
@@ -155,13 +155,13 @@
L& nlabels)
{
trace::entering("labeling::regional_minima");
+
const I& input = exact(input_);
const N& nbh = exact(nbh_);
mln_precondition(input.has_data());
// Calls the only (generic) impl.
- mln_ch_value(I, L) output =
- impl::generic::regional_minima_(input, nbh, nlabels);
+ mln_ch_value(I, L) output = impl::generic::regional_minima(input, nbh, nlabels);
trace::exiting("labeling::regional_minima");
return output;
Index: mln/labeling/regional_maxima.hh
--- mln/labeling/regional_maxima.hh (revision 2841)
+++ mln/labeling/regional_maxima.hh (working copy)
@@ -30,8 +30,8 @@
# define MLN_LABELING_REGIONAL_MAXIMA_HH
/// \file mln/labeling/regional_maxima.hh
-/// \brief Connected component labeling of the regional maxima of an
-/// image.
+///
+/// Connected component labeling of the regional maxima of an image.
# include <mln/core/concept/image.hh>
# include <mln/core/concept/neighborhood.hh>
@@ -118,10 +118,10 @@
template <typename I, typename N, typename L>
mln_ch_value(I, L)
- regional_maxima_(const I& input, const N& nbh,
+ regional_maxima(const I& input, const N& nbh,
L& nlabels)
{
- trace::entering("labeling::impl::generic::regional_maxima_");
+ trace::entering("labeling::impl::generic::regional_maxima");
// FIXME: abort if L is not wide enough to encode the set of
// maxima.
@@ -131,7 +131,7 @@
canvas::labeling<F> run(f);
nlabels = run.nlabels;
- trace::exiting("labeling::impl::generic::regional_maxima_");
+ trace::exiting("labeling::impl::generic::regional_maxima");
return run.output;
}
@@ -150,13 +150,13 @@
L& nlabels)
{
trace::entering("labeling::regional_maxima");
+
const I& input = exact(input_);
const N& nbh = exact(nbh_);
mln_precondition(input.has_data());
// Calls the only (generic) impl.
- mln_ch_value(I, L) output =
- impl::generic::regional_maxima_(input, nbh, nlabels);
+ mln_ch_value(I, L) output = impl::generic::regional_maxima(input, nbh, nlabels);
trace::exiting("labeling::regional_maxima");
return output;
Index: mln/labeling/compute.hh
--- mln/labeling/compute.hh (revision 2841)
+++ mln/labeling/compute.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2008 EPITA Research and Development Laboratory
+// 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
@@ -28,11 +28,10 @@
#ifndef MLN_LABELING_COMPUTE_HH
# define MLN_LABELING_COMPUTE_HH
-/*! \file mln/labeling/compute.hh
- *
- * \brief Compute accumulators onto sites/values of each labeled component
- * of an image.
- */
+/// \file mln/labeling/compute.hh
+///
+/// Compute accumulators onto sites/values of each labeled component
+/// of an image.
# include <mln/core/concept/meta_accumulator.hh>
# include <mln/util/array.hh>
Index: mln/labeling/level.spe.hh
--- mln/labeling/level.spe.hh (revision 2841)
+++ mln/labeling/level.spe.hh (working copy)
@@ -39,8 +39,7 @@
# error "Forbidden inclusion of *.spe.hh"
# endif // ! MLN_LABELING_LEVEL_HH
-# include <mln/border/adjust.hh>
-# include <mln/border/fill.hh>
+# include <mln/extension/adjust_fill.hh>
# include <mln/value/other.hh>
@@ -78,7 +77,8 @@
template <typename I, typename N, typename L>
mln_ch_value(I, L)
- level_(const I& input, const mln_value(I)& val, const N& nbh,
+ level(const Image<I>& input, const mln_value(I)& val,
+ const Neighborhood<N>& nbh,
L& nlabels);
} // end of namespace mln::labeling::impl::generic
@@ -124,17 +124,19 @@
};
- // Fastest routine.
+ // Fastest implementation.
template <typename I, typename N, typename L>
mln_ch_value(I, L)
- level_fastest_(const I& input, const mln_value(I)& val, const N& nbh,
+ level_fastest(const Image<I>& input, const mln_value(I)& val,
+ const Neighborhood<N>& nbh,
L& nlabels)
{
- trace::entering("labeling::impl::level_fastest_");
+ trace::entering("labeling::impl::level_fastest");
+
+ // FIXME: HERE
- border::adjust(input, nbh.delta());
- border::fill(input, value::other(val));
+ extension::adjust_fill(input, nbh.delta(), value::other(val));
typedef level_fastest_functor<I,N,L> F;
F f(input, val, nbh);
@@ -143,32 +145,10 @@
nlabels = run.nlabels;
// FIXME: Handle run.status
- trace::exiting("labeling::impl::level_fastest_");
+ trace::exiting("labeling::impl::level_fastest");
return run.output;
}
-
- // Disjunction between "fastest" and "not fastest".
-
- template <typename I, typename N, typename L>
- mln_ch_value(I, L)
- level_(trait::image::speed::any,
- const I& input, const mln_value(I)& val, const N& nbh,
- L& nlabels)
- {
- return generic::level_(input, val, nbh, nlabels);
- }
-
-// template <typename I, typename N, typename L>
-// mln_ch_value(I, L)
-// level_(trait::image::speed::fastest,
-// const I& input, const mln_value(I)& val, const N& nbh,
-// L& nlabels)
-// {
-// return level_fastest_(input, val, nbh, nlabels);
-// }
-
-
} // end of namespace mln::labeling::impl
Index: mln/labeling/background.hh
--- mln/labeling/background.hh (revision 2841)
+++ mln/labeling/background.hh (working copy)
@@ -29,11 +29,10 @@
#ifndef MLN_LABELING_BACKGROUND_HH
# define MLN_LABELING_BACKGROUND_HH
-/*! \file mln/labeling/background.hh
- *
- * \brief Connected component labeling of the background in a binary
- * image.
- */
+/// \file mln/labeling/background.hh
+///
+/// Connected component labeling of the background in a binary
+/// image.
# include <mln/labeling/level.hh>
@@ -59,27 +58,28 @@
*
* \see mln::labeling::level
*/
- template <typename I, typename N>
- mln_ch_value(I, unsigned)
+ template <typename I, typename N, typename L>
+ mln_ch_value(I, L)
background(const Image<I>& input, const Neighborhood<N>& nbh,
- unsigned& nlabels);
+ L& nlabels);
# ifndef MLN_INCLUDE_ONLY
- template <typename I, typename N>
+ template <typename I, typename N, typename L>
inline
- mln_ch_value(I, unsigned)
+ mln_ch_value(I, L)
background(const Image<I>& input, const Neighborhood<N>& nbh,
- unsigned& nlabels)
+ L& nlabels)
{
trace::entering("labeling::background");
+
mlc_equal(mln_trait_image_kind(I),
mln::trait::image::kind::binary)::check();
mln_precondition(exact(input).has_data());
+ // mln_precondition(exact(nbh).is_valid());
- mln_ch_value(I, unsigned) output =
- labeling::level(input, false, nbh, nlabels);
+ mln_ch_value(I, L) output = labeling::level(input, false, nbh, nlabels);
trace::exiting("labeling::background");
return output;
1
0
12 Nov '08
https://svn.lrde.epita.fr/svn/oln/branches/cleanup-2008/milena
Index: ChangeLog
from Nicolas Ballas <ballas(a)lrde.epita.fr>
Fix conversion problems in linear::gaussian.
* tests/linear/gaussian.cc: Update tests.
* mln/linear/gaussian.hh: Fix conversion issues.
* doc/tutorial/design/include/imagetours.tex: Update documentation.
doc/tutorial/design/include/imagetours.tex | 17 +++-----
mln/linear/gaussian.hh | 61 +++++++++++++++++++++++++----
tests/linear/gaussian.cc | 7 +++
3 files changed, 68 insertions(+), 17 deletions(-)
Index: tests/linear/gaussian.cc
--- tests/linear/gaussian.cc (revision 2840)
+++ tests/linear/gaussian.cc (working copy)
@@ -38,6 +38,7 @@
#include <mln/io/pgm/save.hh>
#include <mln/level/transform.hh>
+#include <mln/level/paste.hh>
#include <mln/math/round.hh>
#include <mln/linear/gaussian.hh>
@@ -57,4 +58,10 @@
image2d<value::int_u8> out = linear::gaussian(lena, 5.1f);
io::pgm::save(out, "out.pgm");
+
+
+ image2d<float> lenaf(lena.domain());
+ level::paste(lena, lenaf);
+
+ image2d<float> outf = linear::gaussian(lenaf, 5.1f);
}
Index: doc/tutorial/design/include/imagetours.tex
--- doc/tutorial/design/include/imagetours.tex (revision 2840)
+++ doc/tutorial/design/include/imagetours.tex (working copy)
@@ -34,16 +34,15 @@
In the Milena library, an image can be seen as an application
$site$ to $value$.
A $site$ is a localized object in space.
-Points in $1D$, $2D$ or $3D$, are the sites objects commonly used in the
+Points $1D$, $2D$ or $3D$ are the sites objects commonly used in the
library.
-However, the $site$ concept allows Milena to deal with complicated image type
-(for instance see the \verb+graph_image+ type).
+%%However, the $site$ concept allows Milena to deal with complicated image type
+%%(for instance see the \verb+graph_image+ type).
-So, an image is composed by a set of localized objects, $sites$, that
-compose the definition domain of the image.
+An image is composed by a set of localized objects ($sites$): the definition domain of the image.
A value is associated to each site of the image. This is the destination domain
of the image.
-To access to a value of an image named $ima$ localized at the point p, we
+To access to a value localized at the site p in an image named $ima$, we
just use the mathematics notation: \verb+ima(p)+.
Obviously, every image types of Milena provide an access $site$ to $value$,
@@ -65,11 +64,11 @@
In this document, we will used the following naming convention for the
image types parameters:
\begin{itemize}
-\item{\verb+T+:} represents an image value type.
-\item{\verb+S+:} represents a type of a $sites$ set.
+\item{\verb+T+:} represents an image $value$ type.
+\item{\verb+S+:} represents a type of a $sites$ $set$ type.
\item{\verb+F+:} is a type of a function $site$ to $value$.
\item{\verb+P+:} represents a $site$ type.
-\item{\verb+I+:} represents an image type.
+\item{\verb+I+:} represents an $image$ type.
\end{itemize}
\subsection{Primary images}
Index: mln/linear/gaussian.hh
--- mln/linear/gaussian.hh (revision 2840)
+++ mln/linear/gaussian.hh (working copy)
@@ -470,7 +470,7 @@
template <class I, class F, class O>
inline
void
- generic_filter_common_(trait::value::nature::scalar,
+ generic_filter_common_(trait::value::nature::floating,
const Image<I>& in,
const F& coef,
float sigma,
@@ -487,15 +487,14 @@
generic_filter_(mln_trait_image_dimension(I)(),
work_img, coef, i);
- // FIXME deal with overflow problem
- // for instance, when we paste a float image into a int_u8 images.
+ // We don't need to convert work_img
level::paste(work_img, out);
}
template <class I, class F, class O>
inline
void
- generic_filter_common_(trait::value::nature::scalar,
+ generic_filter_common_(trait::value::nature::floating,
const Image<I>& in,
const F& coef,
float sigma,
@@ -512,12 +511,60 @@
generic_filter_(mln_trait_image_dimension(I)(),
work_img, coef, dir);
- // FIXME deal with overflow problem
- // for instance, when we paste a float image into a int_u8 images.
+ // We don't need to convert work_img
level::paste(work_img, out);
}
+ template <class I, class F, class O>
+ inline
+ void
+ generic_filter_common_(trait::value::nature::scalar,
+ const Image<I>& in,
+ const F& coef,
+ float sigma,
+ Image<O>& out)
+ {
+ mln_ch_value(O, float) work_img(exact(in).domain());
+ level::paste(in, work_img);
+ extension::adjust_fill(work_img, 4, 0);
+
+ // On tiny sigma, Derich algorithm doesn't work.
+ // It is the same thing that to convolve with a Dirac.
+ if (sigma > 0.006)
+ for (int i = 0; i < I::site::dim; ++i)
+ generic_filter_(mln_trait_image_dimension(I)(),
+ work_img, coef, i);
+
+ // Convert work_img into result type
+ level::paste(level::stretch(mln_value(I)(), work_img), out);
+ }
+
+ template <class I, class F, class O>
+ inline
+ void
+ generic_filter_common_(trait::value::nature::scalar,
+ const Image<I>& in,
+ const F& coef,
+ float sigma,
+ Image<O>& out,
+ int dir)
+ {
+ mln_ch_value(O, float) work_img(exact(in).domain());
+ level::paste(in, work_img);
+ extension::adjust_fill(work_img, 4, 0);
+
+ // On tiny sigma, Derich algorithm doesn't work.
+ // It is the same thing that to convolve with a Dirac.
+ if (sigma > 0.006)
+ generic_filter_(mln_trait_image_dimension(I)(),
+ work_img, coef, dir);
+
+ // Convert work_img into result type
+ level::paste(level::stretch(mln_value(I)(), work_img), out);
+ }
+
+
template <class I, class F, class O>
inline
@@ -565,10 +612,8 @@
} // end of namespace mln::linear::impl
-
// Facade.
-
/*! Apply an approximated gaussian filter of \p sigma on \p input.
* on a specific direction \p dir
* if \p dir = 0, the filter is applied on the first image dimension.
1
0
https://svn.lrde.epita.fr/svn/oln/branches/cleanup-2008/milena/sandbox
Index: ChangeLog
from Ugo Jardonnet <jardonnet(a)lrde.epita.fr>
INIM: Classif: Final Upgrade.
* inim/classif/src/max_tree.hh: Fix comment.
* inim/classif/src/proj.hh: Add specific projection.
* inim/classif/src/v2.cc: Add efficient technique based
histo value merging.
max_tree.hh | 7 +++++--
proj.hh | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++----
v2.cc | 50 ++++++++++++++++++++++++++++++++------------------
3 files changed, 91 insertions(+), 24 deletions(-)
Index: inim/classif/src/max_tree.hh
--- inim/classif/src/max_tree.hh (revision 2838)
+++ inim/classif/src/max_tree.hh (working copy)
@@ -153,6 +153,7 @@
return mean_color;
}
+ // Filter method
template<typename X>
void lumberjack(const X& ima, const mln_value(X)& lambda)
{
@@ -177,8 +178,9 @@
std::cout << std::endl;
}
+ // Fusion method
template<typename X>
- void nuclear_fusion(const X& ima, const mln_value(X)& lambda)
+ void nuclear_fusion(const X& ima, double lambda)
{
unsigned progress = 0;
unsigned step = s.nsites() / 100;
@@ -188,7 +190,8 @@
mln_fwd_piter(S) p(s);
for_all(p)
{
- if (fabs(1 - ima(new_parent(p)) / ima(p)) < lambda)
+ if (ima(p) != 0)
+ if (fabs(1. - ima(new_parent(p)) / (double) ima(p)) < lambda)
is_active(p) = false;
++progress;
Index: inim/classif/src/display.hh
Index: inim/classif/src/proj.hh
--- inim/classif/src/proj.hh (revision 2838)
+++ inim/classif/src/proj.hh (working copy)
@@ -35,6 +35,7 @@
#include <mln/accu/maj_h.hh>
#include <mln/literal/white.hh>
#include <mln/literal/colors.hh>
+#include <mln/make/vec.hh>
namespace mln
{
@@ -59,11 +60,11 @@
save_class(const image3d<T>& histo, const image3d<U>& ws,
K mean, const char * fn)
{
- accu::maj_h<value::int_u8> max_1;
- image2d<value::int_u8> hproj = proj(histo, max_1);
+ accu::maj_h<value::int_u8> maj_1;
+ image2d<value::int_u8> hproj = proj(histo, maj_1);
- accu::maj_h<value::int_u8> max_2;
- image2d<value::int_u8> proj_class = proj(ws, max_2);
+ accu::maj_h<value::int_u8> maj_2;
+ image2d<value::int_u8> proj_class = proj(ws, maj_2);
//std::cout << histo;
@@ -82,6 +83,55 @@
io::ppm::save(out, fn);
}
+ template <typename T, typename I, typename A>
+ image2d<mln_result(A)>
+ proj_vec(const image3d<T>& input, const I& histo, A)
+ {
+ image2d<A> acc(geom::nslis(input), geom::nrows(input));
+ mln_piter(image3d<T>) p(input.domain());
+ for_all(p) // 3d
+ if (histo(p) != literal::zero)
+ acc.at(p.sli(), p.row()).take(input(p));
+
+ image2d<mln_result(A)> output(acc.domain());
+ level::paste(acc, output);
+ return output;
+ }
+
+ template <typename I, typename T, typename U, typename V>
+ void
+ save_class_v2(const I& ima, const T& histo, image3d<U>& mean,
+ const image3d<V>& parent, unsigned f,
+ const char * fn)
+ {
+ image3d<value::rgb8> out3d(histo.domain());
+
+ mln_piter(I) p(ima.domain());
+ for_all(p)
+ {
+ point3d p3 = point3d(ima(p).red() / f,
+ ima(p).green() / f,
+ ima(p).blue() / f);
+ out3d(p3) = convert::to<value::rgb8>(mean(parent(p3)));
+ }
+
+ //FIXME: maj_h implies set is finite, mx set is ordered
+ accu::mean<mln::algebra::vec<3u, float> > maj_2;
+ image2d<mln::algebra::vec<3u, float> > mproj =
+ proj_vec(out3d, histo, maj_2);
+
+ image2d<value::rgb8> out(geom::nslis(histo), geom::nrows(histo));
+ level::fill(out, literal::white);
+
+ mln_piter(image2d<value::int_u8>) p1(out.domain());
+ for_all(p1)
+ {
+ out(p1) = convert::to<value::rgb8>(mproj(p1));
+ }
+
+ io::ppm::save(out, fn);
+ }
+
} // end of namespace mln
#endif /* MLN_PROJ_HH */
Index: inim/classif/src/v2.cc
--- inim/classif/src/v2.cc (revision 2838)
+++ inim/classif/src/v2.cc (working copy)
@@ -30,7 +30,6 @@
const value::int_u8 v = 256 / f; // FIXME
image3d<unsigned> histo(v,v,v);
level::fill(histo, 0);
- unsigned i = 0;
mln_piter(I) p(ima.domain());
for_all(p)
@@ -55,11 +54,11 @@
}
template <typename I, typename J, typename N>
-unsigned
+void
process_max_tree(const I& ima, const J& histo, const N& nbh,
- double density_lambda, unsigned volume_lambda,
- unsigned nb_represent_lambda, unsigned color_lambda,
- unsigned div_factor)
+ double density_lambda, double value_lambda,
+ unsigned volume_lambda, unsigned nb_represent_lambda,
+ unsigned color_lambda, unsigned div_factor)
{
max_tree_<J,N> run(histo, nbh);
@@ -70,13 +69,20 @@
image3d< algebra::vec<3, double> > mean_color = run.compute_mean_color();
image3d<double> density = compute_density(nb_represent, volume);
- // Density closing
+ // Density fusion
if (density_lambda > 0.00001)
{
- std::cout << "Density cutting" << std::endl;
+ std::cout << "Density fusion" << std::endl;
run.nuclear_fusion(density, density_lambda);
}
+ // value fusion
+ if (value_lambda > 0.00001)
+ {
+ std::cout << "Value fusion" << std::endl;
+ run.nuclear_fusion(histo, value_lambda);
+ }
+
// Volume cutting
if (volume_lambda != 0)
{
@@ -115,7 +121,9 @@
for_all(p)
if (run.is_active(p))
{
- std::cerr << mean_color(p) << "\t\t" << nb_class << "\t\t" << density(p) << "\t\t" << volume(p) << "\t\t" << nb_represent(p) << std::endl;
+ std::cerr << mean_color(p) << "\t\t" << nb_class
+ << "\t\t" << density(p) << "\t\t" << volume(p)
+ << "\t\t" << nb_represent(p) << std::endl;
++nb_class;
}
@@ -125,13 +133,21 @@
// Write the image w.r.t. the max tree
run.to_ppm(ima, "out.ppm", div_factor, mean_color);
+
+ //proj
+ save_class_v2(ima, histo, mean_color, run.new_parent,
+ div_factor, "histo.ppm");
}
bool usage(int argc, char ** argv)
{
- if (argc != 7)
+ if (argc != 8)
{
- std::cout << "usage: " << argv[0] << " image div_factor density_lambda volume_lambda nb_represent_lambda color_lambda" << std::endl;
+ std::cout << "usage: " << argv[0] << " image div_factor "
+ << "density_lambda value_lambda volume_lambda "
+ << "nb_represent_lambda color_lambda" << std::endl;
+ std::cout << "Help: A value of 0 for any lambda means "
+ << "the related action won't be performed" << std::endl;
return false;
}
@@ -149,17 +165,15 @@
int div_factor = atoi(argv[2]);
float density_lambda = atof(argv[3]);
- unsigned volume_lambda = atoi(argv[4]);
- unsigned nb_represent_lambda = atoi(argv[5]);
- unsigned color_lambda = atoi(argv[6]);
+ float value_lambda = atof(argv[4]);
+ unsigned volume_lambda = atoi(argv[5]);
+ unsigned nb_represent_lambda = atoi(argv[6]);
+ unsigned color_lambda = atoi(argv[7]);
//make histo
image3d<unsigned> histo = fill_histo(ima, div_factor);
- //proj
- accu::mean<unsigned, unsigned, unsigned> mean;
- image2d<unsigned> phisto = proj(histo, mean);
-
// Process max_tree
- process_max_tree(ima, histo, c6(), density_lambda, volume_lambda, nb_represent_lambda, color_lambda, div_factor);
+ process_max_tree(ima, histo, c6(), density_lambda, value_lambda,
+ volume_lambda, nb_represent_lambda, color_lambda, div_factor);
}
1
0
https://svn.lrde.epita.fr/svn/oln/branches/cleanup-2008/milena
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Make erosion work on nD images.
* mln/core/image/image1d.hh: Layout doc.
(element): Precise doc. Fix precondition.
(element): Rename ind as i (less ambiguous).
* mln/core/image/image3d.hh: Fix doc.
(element): Rename o as i to be consistent.
* mln/border/fill.hh (fill_size_n): Factor const cast.
* mln/win/segment1d.hh: Upgrade doc style.
* mln/win/line.hh: Likewise.
* mln/morpho/erosion.spe.hh: Likewise.
(erosion_chooses_arbitrary): Remove; such a test has to be a
static chek (at compile-time!)
(erosion_dispatch_wrt_arbitrary_win): New.
(erosion_dispatch_wrt_win): Turn dispatch into static.
border/fill.hh | 6 ++--
core/image/image1d.hh | 27 ++++++++++---------
core/image/image3d.hh | 29 +++++++++++---------
morpho/erosion.spe.hh | 70 +++++++++++++++++++++++++-------------------------
win/line.hh | 10 +++----
win/segment1d.hh | 8 ++---
6 files changed, 79 insertions(+), 71 deletions(-)
Index: mln/core/image/image1d.hh
--- mln/core/image/image1d.hh (revision 2836)
+++ mln/core/image/image1d.hh (working copy)
@@ -30,7 +30,8 @@
# define MLN_CORE_IMAGE_IMAGE1D_HH
/// \file mln/core/image/image1d.hh
-/// \brief Definition of the basic mln::image1d class.
+///
+/// Definition of the basic mln::image1d class.
# include <mln/core/internal/fixme.hh>
# include <mln/core/internal/image_primary.hh>
@@ -206,11 +207,13 @@
/// Give a hook to the value buffer.
T* buffer();
- /// Read-only access to the image value located at (\p ind).
- const T& element(unsigned ind) const;
-
- /// Read-write access to the image value located at (\p ind).
- T& element(unsigned ind);
+ /// Read-only access to the \p i-th image value (including the
+ /// border).
+ const T& element(unsigned i) const;
+
+ /// Read-write access to the \p i-th image value (including the
+ /// border).
+ T& element(unsigned i);
/// Give the number of cells (points including border ones).
unsigned nelements() const;
@@ -445,19 +448,19 @@
template <typename T>
inline
const T&
- image1d<T>::element(unsigned ind) const
+ image1d<T>::element(unsigned i) const
{
- mln_precondition(this->has(point1d(ind)));
- return this->data_->buffer_[ind];
+ mln_precondition(i < nelements());
+ return this->data_->buffer_[i];
}
template <typename T>
inline
T&
- image1d<T>::element(unsigned ind)
+ image1d<T>::element(unsigned i)
{
- mln_precondition(this->has(point1d(ind)));
- return this->data_->buffer_[ind];
+ mln_precondition(i < nelements());
+ return this->data_->buffer_[i];
}
template <typename T>
Index: mln/core/image/image3d.hh
--- mln/core/image/image3d.hh (revision 2836)
+++ mln/core/image/image3d.hh (working copy)
@@ -30,7 +30,8 @@
# define MLN_CORE_IMAGE_IMAGE3D_HH
/// \file mln/core/image/image3d.hh
-/// \brief Definition of the basic mln::image3d class.
+///
+/// Definition of the basic mln::image3d class.
# include <mln/core/internal/fixme.hh>
# include <mln/core/internal/image_primary.hh>
@@ -192,16 +193,18 @@
/// Read-write access to the image value located at point \p p.
T& operator()(const point3d& p);
- /// Read-only access to the image value located at offset \p o.
- const T& element(unsigned o) const;
+ /// Read-only access to the image value located at index \p i.
+ const T& element(unsigned i) const;
- /// Read-write access to the image value located at offset \p o.
- T& element(unsigned o);
+ /// Read-write access to the image value located at index \p i.
+ T& element(unsigned i);
- /// Read-only access to the image value located at (\p ind).
+ /// Read-only access to the image value located at (\p sli, \p
+ /// row, \p col).
const T& at(int sli, int row, int col) const;
- /// Read-write access to the image value located at (\p ind).
+ /// Read-write access to the image value located at (\p sli, \p
+ /// row, \p col).
T& at(int sli, int row, int col);
@@ -463,19 +466,19 @@
template <typename T>
inline
const T&
- image3d<T>::element(unsigned o) const
+ image3d<T>::element(unsigned i) const
{
- mln_precondition(o < nelements());
- return *(data_->buffer_ + o);
+ mln_precondition(i < nelements());
+ return *(data_->buffer_ + i);
}
template <typename T>
inline
T&
- image3d<T>::element(unsigned o)
+ image3d<T>::element(unsigned i)
{
- mln_precondition(o < nelements());
- return *(data_->buffer_ + o);
+ mln_precondition(i < nelements());
+ return *(data_->buffer_ + i);
}
template <typename T>
Index: mln/border/fill.hh
--- mln/border/fill.hh (revision 2836)
+++ mln/border/fill.hh (working copy)
@@ -117,7 +117,7 @@
{
trace::entering("border::impl::fill_size_n");
- const I& ima = exact(ima_);
+ I& ima = const_cast<I&>( exact(ima_) );
internal::fill_tests(ima, v);
typedef mln_psite(I) P;
@@ -129,11 +129,11 @@
{
unsigned end = ima.index_of_point (pl);
for (unsigned i = st; i < end; ++i)
- (const_cast<I&>(ima)).element(i) = v;
+ ima.element(i) = v;
st = end + len_r;
}
for (unsigned i = st; i < ima.nelements (); ++i)
- const_cast<I&>(ima).element(i) = v;
+ ima.element(i) = v;
trace::exiting("border::impl::fill_size_n");
}
Index: mln/win/segment1d.hh
--- mln/win/segment1d.hh (revision 2836)
+++ mln/win/segment1d.hh (working copy)
@@ -1,4 +1,5 @@
// 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_WIN_SEGMENT1D_HH
# define MLN_WIN_SEGMENT1D_HH
-/*! \file mln/win/segment1d.hh
- *
- * \brief Definition of the mln::win::segment1d window.
- */
+/// \file mln/win/segment1d.hh
+///
+/// Definition of the mln::win::segment1d window.
# include <mln/win/line.hh>
# include <mln/core/grids.hh>
Index: mln/win/line.hh
--- mln/win/line.hh (revision 2836)
+++ mln/win/line.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
@@ -28,10 +29,9 @@
#ifndef MLN_WIN_LINE_HH
# define MLN_WIN_LINE_HH
-/*! \file mln/win/line.hh
- *
- * \brief Definition of the mln::win::line window.
- */
+/// \file mln/win/line.hh
+///
+/// Definition of the mln::win::line window.
# include <mln/core/internal/classical_window_base.hh>
# include <mln/core/dpoint.hh>
Index: mln/morpho/erosion.spe.hh
--- mln/morpho/erosion.spe.hh (revision 2836)
+++ mln/morpho/erosion.spe.hh (working copy)
@@ -52,13 +52,13 @@
# include <mln/canvas/browsing/backdiagonal2d.hh>
-/*! \file mln/morpho/erosion.spe.hh
- *
- * \brief Specialization for mln::morpho::erosion.
- *
- * \todo Warning: we should also have the "arbitrary" versions working
- * on sets (not only on functions!)
- */
+/// \file mln/morpho/erosion.spe.hh
+///
+/// Specialization for mln::morpho::erosion.
+///
+/// \todo Warning: we should also have the "arbitrary" versions working
+/// on sets (not only on functions!)
+
# ifndef MLN_INCLUDE_ONLY
@@ -1231,26 +1231,6 @@
// dispatch for arbitrary elements
template <typename I, typename W>
- bool
- erosion_chooses_arbitrary(const I&, const W& win)
- {
- return
- win.size() >= 10 // size is not too small
- &&
- // 2d case only
- mlc_equal(mln_trait_image_dimension(I),
- trait::image::dimension::two_d)::value
- &&
- // on a grid
- mlc_is_a(mln_site(I),
- Gpoint)::value
- &&
- // continuous data
- mlc_not_equal(mln_trait_image_value_storage(I),
- trait::image::value_storage::disrupted)::value;
- }
-
- template <typename I, typename W>
mln_concrete(I)
erosion_dispatch_for_arbitrary(trait::image::speed::fastest,
const I& input, const W& win)
@@ -1372,22 +1352,44 @@
return ima;
}
+
// dispatch w.r.t. win
+
template <typename I, typename W>
mln_concrete(I)
- erosion_dispatch_wrt_win(const I& input, const W& win)
+ erosion_dispatch_wrt_arbitrary_win(metal::true_,
+ const I& input, const W& win)
{
- // FIXME: De-activate because, when win is multiple,
- // win::shift does not work. We have to introduce
- // props from windows, then re-write win::shift.
-
- if (erosion_chooses_arbitrary(input, win))
return erosion_dispatch_for_arbitrary(input, win);
- else
+ }
+
+ template <typename I, typename W>
+ mln_concrete(I)
+ erosion_dispatch_wrt_arbitrary_win(metal::false_,
+ const I& input, const W& win)
+ {
return erosion_dispatch_for_generic(input, win);
}
+ template <typename I, typename W>
+ mln_concrete(I)
+ erosion_dispatch_wrt_win(const I& input, const W& win)
+ {
+ // FIXME:
+ // The test "win.size() >= 10" (size is not too small) has been
+ // de-activated...
+ enum { test = mlc_equal(mln_trait_image_dimension(I),
+ trait::image::dimension::two_d)::value
+ &&
+ mlc_is_a(mln_site(I), Gpoint)::value
+ &&
+ mlc_not_equal(mln_trait_image_value_storage(I),
+ trait::image::value_storage::disrupted)::value };
+ return erosion_dispatch_wrt_arbitrary_win(metal::bool_<test>(),
+ input, win);
+ }
+
template <typename I>
mln_concrete(I)
erosion_dispatch_wrt_win(const I& input, const win::rectangle2d& win)
1
0
https://svn.lrde.epita.fr/svn/oln/branches/cleanup-2008/milena/sandbox
Index: ChangeLog
from Ugo Jardonnet <ugo.jardonnet(a)lrde.epita.fr>
INIM: Classif: Update gif creation.
* inim/classif/src/display.hh: Display watershed class.
* inim/classif/src/iccvg04.cc: Modify output info.
* inim/classif/src/proj.hh: Beautify.
* inim/classif/Makefile: Remove warning in non debug.
Makefile | 4 ++--
src/display.hh | 28 +++++++++++++++-------------
src/iccvg04.cc | 7 +++----
src/proj.hh | 3 ++-
4 files changed, 22 insertions(+), 20 deletions(-)
Index: inim/classif/src/display.hh
--- inim/classif/src/display.hh (revision 2835)
+++ inim/classif/src/display.hh (working copy)
@@ -34,6 +34,7 @@
#include <mln/geom/nslis.hh>
#include <mln/value/all.hh>
#include <mln/core/image/image3d.hh>
+#include <mln/literal/colors.hh>
#include <sys/stat.h>
#include <sstream>
@@ -44,29 +45,30 @@
namespace mln
{
- template <typename I>
- void display(const I& ima, const char * dir)
+ template <typename I, typename J, typename K>
+ void display(const I& histo, const J& ws, K mean, const char * dir)
{
mkdir(dir, 0777);
chdir(dir);
- image2d< mln_value(I) > out(geom::nrows(ima), geom::ncols(ima));
+ image2d< value::rgb8 > out(geom::nrows(histo), geom::ncols(histo));
+ level::fill(out, literal::white);
- for (int s = 0; s < geom::nslis(ima); ++s)
+ for (int s = 0; s < geom::nslis(histo); ++s)
{
- // image2d< value::int_u8 > out(geom::nrows(ima), geom::ncols(ima));
- for (int r = 0; r < geom::nrows(ima); ++r)
+ for (int r = 0; r < geom::nrows(histo); ++r)
+ for (int c = 0; c < geom::ncols(histo); ++c)
+ if (histo(point3d(s,r,c)) > 0)
{
- for (int c = 0; c < geom::ncols(ima); ++c)
- {
- out(point2d(r, c)) = ima(point3d(s, r, c));
- }
+ if (ws(point3d(s,r,c)) > 0)
+ out(point2d(r, c)) = convert::to<value::rgb8>(mean[ws(point3d(s,r,c))]);
+ else
+ out(point2d(r, c)) = literal::red;
}
std::ostringstream is;
- is << "out_" << s << ".pgm";
-
- io::pgm::save(out, is.str());
+ is << "out_00" << s << ".ppm";
+ io::ppm::save(out, is.str());
}
chdir("..");
Index: inim/classif/src/iccvg04.cc
--- inim/classif/src/iccvg04.cc (revision 2835)
+++ inim/classif/src/iccvg04.cc (working copy)
@@ -93,9 +93,7 @@
point3d p3(ima(p).red() / f, ima(p).green() / f, ima(p).blue() / f);
int w = ws(p3);
- //check if we are not on a border of the WS
- if (w == 0)
- border++;
+ //Even if we are not on a border of the WS
count[w] += histo(p3);
sum[w] += histo(p3) * convert::to< algebra::vec<3, value::int_u8> >(p3);
@@ -103,7 +101,7 @@
convert::to<algebra::vec<3, value::int_u8> >(p3) << std::endl;
}
- std::cout << border << std::endl;
+ std::cout << "dyke point : " << count[0] << std::endl;
for (int i = 0; i < nbasins + 1; ++i)
{
std::cout << "sum[" << i << "] = " << sum[i] * f << " / " << count[i] << " == ";
@@ -132,6 +130,7 @@
io::ppm::save(out, "out.ppm");
save_class(histo, ws, sum, "palette.ppm");
+ display(histo, ws, sum, "histo");
}
bool usage(int argc, char ** argv)
Index: inim/classif/src/proj.hh
--- inim/classif/src/proj.hh (revision 2835)
+++ inim/classif/src/proj.hh (working copy)
@@ -34,6 +34,7 @@
#include <mln/accu/mean.hh>
#include <mln/accu/maj_h.hh>
#include <mln/literal/white.hh>
+#include <mln/literal/colors.hh>
namespace mln
{
@@ -67,8 +68,8 @@
//std::cout << histo;
image2d<value::rgb8> out(proj_class.domain());
-
level::fill(out, literal::white);
+
mln_piter(image2d<value::int_u8>) p(proj_class.domain());
for_all(p)
if (hproj(p) > 0)
Index: inim/classif/Makefile
--- inim/classif/Makefile (revision 2835)
+++ inim/classif/Makefile (working copy)
@@ -21,14 +21,14 @@
$(ICCVG): $(ICCVG_SRC)
- g++ $(ICCVG_INCLUDES) -Wall -W -O1 -DNDEBUG $(ICCVG_SRC) -o $(ICCVG)
+ g++ $(ICCVG_INCLUDES) -O1 -DNDEBUG $(ICCVG_SRC) -o $(ICCVG)
$(ICCVG_DBG): $(ICCVG_SRC)
g++ $(ICCVG_INCLUDES) -Wall -W -O0 -g3 -ggdb3 $(ICCVG_SRC) -o $(ICCVG_DBG)
$(V2): $(V2_SRC)
- g++ $(V2_INCLUDES) -Wall -W -O1 -DNDEBUG $(V2_SRC) -o $(V2)
+ g++ $(V2_INCLUDES) -O1 -DNDEBUG $(V2_SRC) -o $(V2)
$(V2_DBG): $(V2_SRC) .dep_v2
1
0
https://svn.lrde.epita.fr/svn/oln/branches/cleanup-2008/milena
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
De-activate fastest labeling level.
* tests/labeling/level.cc: Update.
* mln/canvas/labeling.hh (todo): New.
(init): Fix warning with g++-4.3.
Some updates.
* mln/labeling/level.hh: Upgrade doc style.
Fix copyright.
* mln/labeling/level.spe.hh: Likewise.
(todo): New.
(level_): De-activate fastest dispatch; the underlying code
cannot work! E.g., p is a pixter on input, yet used in accessing
output.
(level_fastest_functor): Update.
mln/canvas/labeling.hh | 23 +++++++++++++----------
mln/labeling/level.hh | 12 ++++++------
mln/labeling/level.spe.hh | 32 +++++++++++++++++---------------
tests/labeling/level.cc | 13 +++++++------
4 files changed, 43 insertions(+), 37 deletions(-)
Index: tests/labeling/level.cc
--- tests/labeling/level.cc (revision 2834)
+++ tests/labeling/level.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/labeling/level.cc
- *
- * \brief Test on mln::labeling::level.
- */
+/// \file tests/labeling/level.cc
+///
+/// Test on mln::labeling::level.
#include <mln/core/image/image2d.hh>
#include <mln/core/alias/neighb2d.hh>
@@ -60,7 +60,8 @@
{
image2d<unsigned> labels = labeling::level(lena, l, c4(), n);
unsigned npix =
- accu::compute<accu::count>(labels | (pw::value(labels) != pw::cst(0u)));
+ accu::compute(accu::meta::count(),
+ labels | (pw::value(labels) != pw::cst(0u)));
npixels += npix;
}
mln_assertion(npixels == lena.nsites());
Index: mln/canvas/labeling.hh
--- mln/canvas/labeling.hh (revision 2834)
+++ mln/canvas/labeling.hh (working copy)
@@ -1,4 +1,5 @@
// 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
@@ -29,8 +30,10 @@
# define MLN_CANVAS_LABELING_HH
/// \file mln/canvas/labeling.hh
-/// \brief Connected component labeling of the object part in a binary
-/// image.
+///
+/// Connected component labeling of the object part in a binary image.
+///
+/// \todo Make the fastest version work.
# include <mln/core/concept/image.hh>
# include <mln/level/fill.hh>
@@ -159,7 +162,7 @@
mln::level::fill(deja_vu, false);
initialize(parent, f.input);
initialize(output, f.input);
- mln::level::fill(output, literal::zero);
+ mln::level::fill(output, L(literal::zero));
nlabels = 0;
}
@@ -271,7 +274,7 @@
{
initialize(parent, f.input);
for (unsigned p = 0; p < parent.nelements(); ++p)
- parent[p] = p; // make_set
+ parent.element(p) = p; // make_set
initialize(output, f.input);
mln::level::fill(output, 0); // FIXME: Use literal::zero.
nlabels = 0;
@@ -315,11 +318,11 @@
status = false;
return;
}
- output[p] = ++nlabels;
+ output(p) = ++nlabels;
}
}
else
- output[p] = output[parent[p]];
+ output(p) = output(parent.element(p));
}
status = true;
}
@@ -328,17 +331,17 @@
bool
labeling_fastest<F>::is_root(unsigned p) const
{
- return parent[p] == p;
+ return parent.element(p) == p;
}
template <typename F>
unsigned
labeling_fastest<F>::find_root(unsigned x)
{
- if (parent[x] == x)
+ if (parent.element(x) == x)
return x;
else
- return parent[x] = find_root(parent[x]);
+ return parent.element(x) = find_root(parent.element(x));
}
template <typename F>
@@ -348,7 +351,7 @@
unsigned r = find_root(n);
if (r != p)
{
- parent[r] = p;
+ parent.element(r) = p;
f.merge_attr(r, p);
}
}
Index: mln/labeling/level.hh
--- mln/labeling/level.hh (revision 2834)
+++ mln/labeling/level.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
@@ -28,11 +29,10 @@
#ifndef MLN_LABELING_LEVEL_HH
# define MLN_LABELING_LEVEL_HH
-/*! \file mln/labeling/level.hh
- *
- * \brief Connected component labeling of the image objects at a given
- * level.
- */
+/// \file mln/labeling/level.hh
+///
+/// Connected component labeling of the image objects at a given
+/// level.
# include <mln/core/concept/image.hh>
# include <mln/core/concept/neighborhood.hh>
Index: mln/labeling/level.spe.hh
--- mln/labeling/level.spe.hh (revision 2834)
+++ mln/labeling/level.spe.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
@@ -28,10 +29,11 @@
#ifndef MLN_LABELING_LEVEL_SPE_HH
# define MLN_LABELING_LEVEL_SPE_HH
-/*! \file mln/labeling/level.spe.hh
- *
- * \brief Specialization for mln::labeling::level.
- */
+/// \file mln/labeling/level.spe.hh
+///
+/// Specialization for mln::labeling::level.
+///
+/// \todo Re-activate the fastest version in dispatch...
# ifndef MLN_LABELING_LEVEL_HH
# error "Forbidden inclusion of *.spe.hh"
@@ -99,8 +101,8 @@
const N& nbh;
const S& s;
- bool handles(unsigned p) const { return input[p] == val; }
- bool equiv(unsigned n, unsigned) const { return input[n] == val; }
+ bool handles(unsigned p) const { return input.element(p) == val; }
+ bool equiv(unsigned n, unsigned) const { return input.element(n) == val; }
void init() {}
bool labels(unsigned) const { return true; }
@@ -157,14 +159,14 @@
return generic::level_(input, val, nbh, nlabels);
}
- template <typename I, typename N, typename L>
- mln_ch_value(I, L)
- level_(trait::image::speed::fastest,
- const I& input, const mln_value(I)& val, const N& nbh,
- L& nlabels)
- {
- return level_fastest_(input, val, nbh, nlabels);
- }
+// template <typename I, typename N, typename L>
+// mln_ch_value(I, L)
+// level_(trait::image::speed::fastest,
+// const I& input, const mln_value(I)& val, const N& nbh,
+// L& nlabels)
+// {
+// return level_fastest_(input, val, nbh, nlabels);
+// }
} // end of namespace mln::labeling::impl
1
0
cleanup-2008 2834: Add accu snake_2d and transform; revamp accu compute.
by Thierry Geraud 10 Nov '08
by Thierry Geraud 10 Nov '08
10 Nov '08
https://svn.lrde.epita.fr/svn/oln/branches/cleanup-2008/milena
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Add accu snake_2d and transform; revamp accu compute.
* tests/accu/snake_2d.cc: New.
* mln/accu/snake_2d.hh: New.
* mln/accu/transform.hh: New.
* mln/core/image/image2d.hh (include): Re-activate make/image2d.
* tests/accu/transform.cc: New.
* tests/accu/compute.cc (FIXME): Fix.
* tests/accu/Makefile.am: Update.
* mln/accu/min.hh: Fix (c) and upgrade doc layout.
* mln/accu/count.hh: Likewise.
(untake): New.
* mln/accu/compute.hh: Revamp w.r.t. convention.
* mln/transform/influence_zone_geodesic.hh: Fix guard.
* mln/transform/distance.hh: Upgrade doc layout.
* mln/transform/distance_geodesic.hh: Fix guard.
* tests/transform/Makefile.am: Update.
* mln/morpho/erosion.hh: Fix layout.
mln/accu/compute.hh | 83 ++++++++++++--
mln/accu/count.hh | 28 ++++
mln/accu/min.hh | 8 -
mln/accu/snake_2d.hh | 130 +++++++++++++++++++----
mln/accu/transform.hh | 175 +++++++++++++++++++++++++++++++
mln/core/image/image2d.hh | 2
mln/morpho/erosion.hh | 10 +
mln/transform/distance.hh | 9 -
mln/transform/distance_geodesic.hh | 2
mln/transform/influence_zone_geodesic.hh | 3
tests/accu/Makefile.am | 4
tests/accu/compute.cc | 26 +---
tests/accu/snake_2d.cc | 52 +++++++++
tests/accu/transform.cc | 62 ++++++++++
tests/transform/Makefile.am | 6 -
15 files changed, 533 insertions(+), 67 deletions(-)
Index: tests/accu/transform.cc
--- tests/accu/transform.cc (revision 0)
+++ tests/accu/transform.cc (revision 0)
@@ -0,0 +1,62 @@
+// 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.cc
+///
+/// Tests on mln::accu::transform.
+
+#include <mln/core/image/image2d.hh>
+#include <mln/accu/transform.hh>
+
+#include <mln/accu/count.hh>
+#include <mln/win/rectangle2d.hh>
+
+#include <mln/pw/all.hh>
+#include <mln/level/compare.hh>
+
+
+int main()
+{
+ using namespace mln;
+
+ image2d<int> ima(4, 5);
+ win::rectangle2d rec(3, 3);
+
+ {
+ image2d<unsigned>
+ out = accu::transform(ima, accu::count<int>(), rec),
+ ref(ima.domain());
+ mln_assertion(out == (pw::cst(rec.size()) | ima.domain()));
+ }
+
+ {
+ image2d<unsigned>
+ out = accu::transform(ima, accu::meta::count(), rec),
+ ref(ima.domain());
+ mln_assertion(out == (pw::cst(rec.size()) | ima.domain()));
+ }
+}
Index: tests/accu/compute.cc
--- tests/accu/compute.cc (revision 2833)
+++ tests/accu/compute.cc (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
@@ -25,31 +26,24 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-/*! \file tests/accu/compute.cc
- *
- * \brief Tests on mln::accu::compute.
- */
+/// \file tests/accu/compute.cc
+///
+/// Tests on mln::accu::compute.
#include <mln/core/image/image2d.hh>
#include <mln/value/int_u8.hh>
+#include <mln/accu/count.hh>
#include <mln/accu/compute.hh>
-#include <mln/level/compute.hh>
-#include <mln/accu/min.hh>
int main()
{
using namespace mln;
using typename value::int_u8;
- // FIXME : make this test compile
-// int_u8 vs[3][3] = { {9,8,7},
-// {6,5,4},
-// {3,2,1} };
-
-// image2d<int_u8> ima = make::image(vs);
-// int a = accu::compute<accu::min>(ima);
-
-// std::cout << a << std::endl;
+ unsigned n = 3;
+ image2d<int_u8> ima(n, n);
+ unsigned c = accu::compute(accu::meta::count(), ima);
+ mln_assertion(c = n * n);
}
Index: tests/accu/Makefile.am
--- tests/accu/Makefile.am (revision 2833)
+++ tests/accu/Makefile.am (working copy)
@@ -19,6 +19,8 @@
nil \
pair \
rank \
+ snake_2d \
+ transform \
tuple
all_accus_SOURCES = all_accus.cc
@@ -37,6 +39,8 @@
nil_SOURCES = nil.cc
pair_SOURCES = pair.cc
rank_SOURCES = rank.cc
+snake_2d_SOURCES = snake_2d.cc
+transform_SOURCES = transform.cc
tuple_SOURCES = tuple.cc
TESTS = $(check_PROGRAMS)
Index: tests/accu/snake_2d.cc
--- tests/accu/snake_2d.cc (revision 0)
+++ tests/accu/snake_2d.cc (revision 0)
@@ -0,0 +1,52 @@
+// 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/snake_2d.cc
+///
+/// Tests on mln::accu::snake_2d.
+
+#include <mln/core/image/image2d.hh>
+#include <mln/accu/snake_2d.hh>
+#include <mln/accu/count.hh>
+#include <mln/win/rectangle2d.hh>
+#include <mln/pw/all.hh>
+#include <mln/level/compare.hh>
+
+
+int main()
+{
+ using namespace mln;
+
+ image2d<int> ima(4, 5);
+ win::rectangle2d rec(3, 3);
+
+ image2d<unsigned>
+ out = accu::snake_2d(accu::meta::count(), ima, rec),
+ ref(ima.domain());
+
+ mln_assertion(out == (pw::cst(rec.size()) | ima.domain()));
+}
Index: tests/transform/Makefile.am
--- tests/transform/Makefile.am (revision 2833)
+++ tests/transform/Makefile.am (working copy)
@@ -3,8 +3,12 @@
include $(top_srcdir)/milena/tests/tests.mk
check_PROGRAMS = \
- distance
+ distance \
+ distance_geodesic \
+ influence_zone_geodesic
distance_SOURCES = distance.cc
+distance_geodesic_SOURCES = distance_geodesic.cc
+influence_zone_geodesic_SOURCES = influence_zone_geodesic.cc
TESTS = $(check_PROGRAMS)
Index: mln/core/image/image2d.hh
--- mln/core/image/image2d.hh (revision 2833)
+++ mln/core/image/image2d.hh (working copy)
@@ -691,7 +691,7 @@
# include <mln/make/image.hh>
-// # include <mln/make/image2d.hh>
+# include <mln/make/image2d.hh>
#endif // ! MLN_CORE_IMAGE_IMAGE2D_HH
Index: mln/accu/snake_2d.hh
--- mln/accu/snake_2d.hh (revision 2832)
+++ mln/accu/snake_2d.hh (working copy)
@@ -1,16 +1,90 @@
-#include <mln/core/alias/neighb2d.hh>
+// 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_SNAKE_2D_HH
+# define MLN_ACCU_SNAKE_2D_HH
+
+/// \file mln/accu/snake_2d.hh
+///
+/// Run an accumulator in a snake-like browsing.
+
+#include <mln/core/concept/image.hh>
+#include <mln/core/concept/meta_accumulator.hh>
+#include <mln/core/alias/window2d.hh>
#include <mln/win/diff.hh>
#include <mln/win/shift.hh>
-#include <mln/extension/adjust_fill.hh>
+#include <mln/extension/adjust.hh>
#include <mln/canvas/browsing/snake_generic.hh>
+
+
namespace mln
{
+ namespace accu
+ {
+
+
+ template <typename A, typename I, typename W>
+ mln_ch_value(I, mln_result(A))
+ snake_2d(const Accumulator<A>&, const Image<I>& input, const Window<W>& win);
+
+
+ template <typename A, typename I, typename W>
+ mln_ch_value(I, mln_accu_with(A, mln_value(I))::result)
+ snake_2d(const Meta_Accumulator<A>&, const Image<I>& input, const Window<W>& win);
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace internal
+ {
+
+
+ template <typename I, typename W>
+ void snake_2d_tests(const Image<I>& input_, const Window<W>& win_)
+ {
+ const I& input = exact(input_);
+ const W& win = exact(win_);
+
+ mln_precondition(input.has_data());
+ mln_precondition(! win.is_empty());
+ // mln_precondition(! win.is_valid());
+
+ (void) input;
+ (void) win;
+ }
+
+
template <typename I, typename W, typename A>
- struct snake2d_functor
+ struct snake_2d_functor
{
- typedef snake2d_functor<I,W, A> self;
+ typedef snake_2d_functor<I,W, A> self;
typedef void (self::*move_fun)();
typedef mln_deduce(I, psite, delta) dpsite;
@@ -44,9 +118,9 @@
std::vector<move_fun> moves;
std::vector<dpsite> dps;
- snake2d_functor(const I& input, const W& win)
- : input(input),
- win(win),
+ snake_2d_functor(const Image<I>& input, const Window<W>& win)
+ : input(exact(input)),
+ win(exact(win)),
accu(),
win_left_fwd(win::shift(win, mln::left) - win),
@@ -155,36 +229,54 @@
};
+
+ } // end of namespace mln::accu::internal
+
+
+
template <typename A, typename I, typename W>
inline
mln_ch_value(I, mln_result(A))
- snake2d(const Accumulator<A>&, const Image<I>& input, const Window<W>& win)
+ snake_2d(const Accumulator<A>&, const Image<I>& input, const Window<W>& win)
{
- trace::entering("accu::snake2d");
+ trace::entering("accu::snake_2d");
- typedef snake2d_functor<I, W, A> F;
- F f(exact(input), exact(win));
- canvas::browsing::snake_generic(f);
+ internal::snake_2d_tests(input, win);
- trace::exiting("accu::snake2d");
+ extension::adjust(input, win);
+ internal::snake_2d_functor<I, W, A> f(input, win);
+ canvas::browsing::snake_generic(f);
+ trace::exiting("accu::snake_2d");
return f.output;
}
+
template <typename A, typename I, typename W>
inline
mln_ch_value(I, mln_accu_with(A, mln_value(I))::result)
- snake2d(const Meta_Accumulator<A>&, const Image<I>& input, const Window<W>& win)
+ snake_2d(const Meta_Accumulator<A>&, const Image<I>& input, const Window<W>& win)
{
- trace::entering("accu::snake2d");
+ trace::entering("accu::snake_2d");
+
+ internal::snake_2d_tests(input, win);
typedef mln_accu_with(A, mln_value(I)) A_;
- typedef snake2d_functor<I, W, A_> F;
- F f(exact(input), exact(win));
+
+ extension::adjust(input, win);
+ internal::snake_2d_functor<I, W, A_> f(input, win);
canvas::browsing::snake_generic(f);
- trace::exiting("accu::snake2d");
+ trace::exiting("accu::snake_2d");
return f.output;
}
-} // mln
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::accu
+
+} // end of namespace mln
+
+
+#endif // ! MLN_ACCU_SNAKE_2D_HH
Property changes on: mln/accu/snake_2d.hh
___________________________________________________________________
Added: svn:mergeinfo
Index: mln/accu/transform.hh
--- mln/accu/transform.hh (revision 0)
+++ mln/accu/transform.hh (revision 0)
@@ -0,0 +1,175 @@
+// 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_HH
+# define MLN_ACCU_TRANSFORM_HH
+
+/// \file mln/accu/transform.hh
+///
+/// Transform an image by applying locally an accumulator on its
+/// values.
+///
+/// \todo Specialize for fastest images.
+
+# include <mln/core/concept/meta_accumulator.hh>
+# include <mln/core/concept/image.hh>
+# include <mln/core/concept/window.hh>
+# include <mln/extension/adjust.hh>
+
+
+namespace mln
+{
+
+ namespace accu
+ {
+
+ template <typename I, typename A, typename W>
+ mln_ch_value(I, mln_result(A))
+ transform(const Image<I>& input,
+ const Accumulator<A>& a,
+ const Window<W>& win);
+
+ template <typename I, typename A, typename W>
+ mln_ch_value(I, mln_accu_with(A, mln_value(I))::result)
+ transform(const Image<I>& input,
+ const Meta_Accumulator<A>& a,
+ const Window<W>& win);
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ namespace impl
+ {
+
+ namespace generic
+ {
+
+ template <typename I, typename A, typename W>
+ mln_ch_value(I, mln_result(A))
+ transform(const Image<I>& input_,
+ const Accumulator<A>& a_,
+ const Window<W>& win_)
+ {
+ trace::entering("accu::impl::generic::transform");
+
+ const I& input = exact(input_);
+ A a = exact(a_);
+ const W& win = exact(win_);
+
+ mln_precondition(input.has_data());
+ // mln_precondition(win.is_valid());
+
+ extension::adjust(input, win);
+
+ mln_ch_value(I, mln_result(A)) output;
+ initialize(output, input);
+
+ mln_piter(I) p(input.domain());
+ mln_qiter(W) q(win, p);
+ for_all(p)
+ {
+ a.init();
+ for_all(q)
+ a.take(input(q));
+ output(p) = a.to_result();
+ }
+
+ trace::exiting("accu::impl::generic::transform");
+ return output;
+ }
+
+ } // end of namespace mln::accu::impl::generic
+
+ } // end of namespace mln::accu::impl
+
+
+ namespace internal
+ {
+
+ template <typename I, typename A, typename W>
+ inline
+ mln_ch_value(I, mln_result(A))
+ transform_dispatch(const Image<I>& input,
+ const Accumulator<A>& a,
+ const Window<W>& win)
+ {
+ return impl::generic::transform(input, a, win);
+ }
+
+ } // end of namespace mln::accu::internal
+
+
+
+ template <typename I, typename A, typename W>
+ inline
+ mln_ch_value(I, mln_result(A))
+ transform(const Image<I>& input,
+ const Accumulator<A>& a,
+ const Window<W>& win)
+ {
+ trace::entering("accu::transform");
+
+ mln_precondition(exact(input).has_data());
+ // mln_precondition(exact(win).is_valid());
+
+ mln_ch_value(I, mln_result(A)) output;
+ output = internal::transform_dispatch(input, a, win);
+
+ trace::exiting("accu::transform");
+ return output;
+ }
+
+ template <typename I, typename A, typename W>
+ mln_ch_value(I, mln_accu_with(A, mln_value(I))::result)
+ transform(const Image<I>& input,
+ const Meta_Accumulator<A>&,
+ const Window<W>& win)
+ {
+ trace::entering("accu::transform");
+
+ mln_precondition(exact(input).has_data());
+ // mln_precondition(exact(win).is_valid());
+
+ typedef mln_accu_with(A, mln_value(I)) A_;
+ A_ a;
+ mln_ch_value(I, mln_result(A_)) output;
+ output = internal::transform_dispatch(input, a, win);
+
+ trace::exiting("accu::transform");
+ return output;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::accu
+
+} // end of namespace mln
+
+
+#endif // ! MLN_ACCU_TRANSFORM_HH
Index: mln/accu/min.hh
--- mln/accu/min.hh (revision 2833)
+++ mln/accu/min.hh (working copy)
@@ -1,4 +1,5 @@
// 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_ACCU_MIN_HH
# define MLN_ACCU_MIN_HH
-/*! \file mln/accu/min.hh
- *
- * \brief Define an accumulator that computes a min.
- */
+/// \file mln/accu/min.hh
+///
+/// Define an accumulator that computes a min.
# include <mln/accu/internal/base.hh>
# include <mln/core/concept/meta_accumulator.hh>
Index: mln/accu/count.hh
--- mln/accu/count.hh (revision 2833)
+++ mln/accu/count.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
@@ -29,11 +30,13 @@
# define MLN_ACCU_COUNT_HH
/// \file mln/accu/count.hh
+///
/// \brief Define an accumulator that counts.
# include <mln/accu/internal/base.hh>
# include <mln/core/concept/meta_accumulator.hh>
+
namespace mln
{
@@ -55,6 +58,9 @@
void take(const argument&);
void take(const count<T>& other);
+ void untake(const argument&);
+ void untake(const count<T>& other);
+
/// Force the value of the counter to \a c.
void set_value(unsigned c);
/// \}
@@ -71,6 +77,7 @@
unsigned count_;
};
+
namespace meta
{
@@ -87,6 +94,7 @@
} // end of namespace mln::accu::meta
+
# ifndef MLN_INCLUDE_ONLY
template <typename T>
@@ -115,6 +123,15 @@
template <typename T>
inline
void
+ count<T>::untake(const argument&)
+ {
+ mln_precondition(count_ > 0);
+ --count_;
+ }
+
+ template <typename T>
+ inline
+ void
count<T>::take(const count<T>& other)
{
count_ += other.count_;
@@ -122,6 +139,15 @@
template <typename T>
inline
+ void
+ count<T>::untake(const count<T>& other)
+ {
+ mln_precondition(other.count_ <= count_);
+ count_ -= other.count_;
+ }
+
+ template <typename T>
+ inline
unsigned
count<T>::to_result() const
{
Index: mln/accu/compute.hh
--- mln/accu/compute.hh (revision 2833)
+++ mln/accu/compute.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,15 +29,15 @@
#ifndef MLN_ACCU_COMPUTE_HH
# define MLN_ACCU_COMPUTE_HH
-/*! \file mln/accu/compute.hh
- *
- * \brief Define an accumulator that computes image pixels.
- */
+/// \file mln/accu/compute.hh
+///
+/// Compute an accumulator on image pixels, i.e., couples (site,
+/// value).
+///
+/// \todo Specialize for fastest images.
# include <mln/core/concept/meta_accumulator.hh>
-# include <mln/core/concept/accumulator.hh>
# include <mln/core/concept/image.hh>
-# include <mln/metal/is_a.hh>
# include <mln/util/pix.hh>
@@ -58,7 +59,7 @@
*/
template <typename A, typename I>
mln_result(A)
- compute(const Image<I>& input);
+ compute(const Accumulator<A>& a, const Image<I>& input);
/*! \brief Make an accumulator compute the pixels of the image \p input.
@@ -73,34 +74,86 @@
*/
template <typename A, typename I>
mln_accu_with(A, util::pix<I>)::result
- compute(const Image<I>& input);
+ compute(const Meta_Accumulator<A>& a, const Image<I>& input);
# ifndef MLN_INCLUDE_ONLY
+
+ namespace impl
+ {
+
+ namespace generic
+ {
+
template <typename A, typename I>
- inline
mln_result(A)
- compute(const Image<I>& input_)
+ compute(const Accumulator<A>&, const Image<I>& input_)
{
- mlc_is_a(A, Accumulator)::check();
+ trace::entering("accu::impl::generic::compute");
+
const I& input = exact(input_);
+ mln_precondition(input.has_data());
+
A a;
mln_piter(I) p(input.domain());
for_all(p)
a.take(make::pix(input, p));
+
+ trace::exiting("accu::impl::generic::compute");
return a.to_result();
}
+ } // end of namespace mln::accu::impl::generic
+
+ } // end of namespace mln::accu::impl
+
+
+ namespace internal
+ {
+
+ template <typename A, typename I>
+ inline
+ mln_result(A)
+ compute_dispatch(const Accumulator<A>& a, const Image<I>& input)
+ {
+ return impl::generic::compute(a, input);
+ }
+
+ } // end of namespace mln::accu::internal
+
+
+
+ template <typename A, typename I>
+ inline
+ mln_result(A)
+ compute(const Accumulator<A>& a, const Image<I>& input)
+ {
+ trace::entering("accu::compute");
+
+ mln_precondition(exact(input).has_data());
+ mln_result(A) output = internal::compute_dispatch(a, input);
+
+ trace::exiting("accu::compute");
+ return output;
+ }
+
template <typename A, typename I>
inline
mln_accu_with(A, util::pix<I>)::result
- compute(const Image<I>& input)
+ compute(const Meta_Accumulator<A>&, const Image<I>& input)
{
- mlc_is_a(A, Meta_Accumulator)::check();
+ trace::entering("accu::compute");
+
+ mln_precondition(exact(input).has_data());
+
typedef mln_accu_with(A, util::pix<I>) A_;
- return compute<A_>(input);
+ A_ a;
+ mln_result(A_) output = internal::compute_dispatch(a, input);
+
+ trace::exiting("accu::compute");
+ return output;
}
# endif // ! MLN_INCLUDE_ONLY
Index: mln/transform/influence_zone_geodesic.hh
--- mln/transform/influence_zone_geodesic.hh (revision 2833)
+++ mln/transform/influence_zone_geodesic.hh (working copy)
@@ -50,7 +50,6 @@
# ifndef MLN_INCLUDE_ONLY
-
namespace internal
{
@@ -107,4 +106,4 @@
} // end of namespace mln
-#endif // ! MLN_TRANSFORM_DISTANCE_HH
+#endif // ! MLN_TRANSFORM_INFLUENCE_ZONE_GEODESIC_HH
Index: mln/transform/distance.hh
--- mln/transform/distance.hh (revision 2833)
+++ mln/transform/distance.hh (working copy)
@@ -28,10 +28,11 @@
#ifndef MLN_TRANSFORM_DISTANCE_HH
# define MLN_TRANSFORM_DISTANCE_HH
-/*! \file mln/transform/distance.hh
- *
- * \brief Discrete distance transform.
- */
+/// \file mln/transform/distance.hh
+///
+/// Discrete distance transform.
+///
+/// \todo Make a canvas out of it.
# include <vector>
# include <mln/core/concept/image.hh>
Index: mln/transform/distance_geodesic.hh
--- mln/transform/distance_geodesic.hh (revision 2833)
+++ mln/transform/distance_geodesic.hh (working copy)
@@ -104,4 +104,4 @@
} // end of namespace mln
-#endif // ! MLN_TRANSFORM_DISTANCE_HH
+#endif // ! MLN_TRANSFORM_DISTANCE_GEODESIC_HH
Index: mln/morpho/erosion.hh
--- mln/morpho/erosion.hh (revision 2833)
+++ mln/morpho/erosion.hh (working copy)
@@ -1,4 +1,5 @@
// 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
@@ -29,6 +30,7 @@
# define MLN_MORPHO_EROSION_HH
/// \file mln/morpho/erosion.hh
+///
/// \brief Morphological erosion.
# include <mln/morpho/includes.hh>
@@ -63,11 +65,13 @@
{
const I& input = exact(input_);
const W& win = exact(win_);
+
+ mln_precondition(input.has_data());
+ mln_precondition(! win.is_empty());
+ // mln_precondition(win.is_valid());
+
(void) input;
(void) win;
-
- mln_precondition(exact(input).has_data());
- mln_precondition(! exact(win).is_empty());
}
} // end of mln::morpho::internal
1
0
10 Nov '08
https://svn.lrde.epita.fr/svn/oln/branches/cleanup-2008/milena/sandbox
Index: ChangeLog
from Nicolas Ballas <ballas(a)lrde.epita.fr>
INIM: Add the final code for edges dectection.
* ballas/color/min_tree_area_filter.cc: Update
* ballas/color/min_tree_color.cc,
* ballas/color/min_tree_volume_filter.cc: Update output.
* ballas/color/min_tree_height_filter.cc: New min tree filter.
* ballas/color/min_tree_color_v2.cc: New, color filter.
min_tree_area_filter.cc | 8
min_tree_color.cc | 8
min_tree_color_v2.cc | 530 ++++++++++++++++++++++++++++++++++++++++++++
min_tree_height_filter.cc | 550 ++++++++++++++++++++++++++++++++++++++++++++++
min_tree_volume_filter.cc | 74 ++++--
5 files changed, 1151 insertions(+), 19 deletions(-)
Index: ballas/color/min_tree_volume_filter.cc
--- ballas/color/min_tree_volume_filter.cc (revision 2832)
+++ ballas/color/min_tree_volume_filter.cc (working copy)
@@ -10,9 +10,8 @@
# include <mln/make/double_neighb2d.hh>
# include <mln/core/site_set/p_centered.hh>
-# include <mln/literal/origin.hh>
+
# include <mln/literal/black.hh>
-# include <mln/literal/white.hh>
# include <mln/value/int_u8.hh>
# include <mln/value/int_u16.hh>
@@ -23,17 +22,24 @@
# include <mln/io/ppm/load.hh>
# include <mln/io/ppm/save.hh>
-# include <mln/morpho/closing_area.hh>
+# include <mln/accu/min_max.hh>
+
+# include <mln/fun/i2v/array.hh>
+# include <mln/fun/p2v/iota.hh>
# include <mln/level/paste.hh>
# include <mln/level/fill.hh>
# include <mln/level/transform.hh>
# include <mln/extension/fill.hh>
+# include <mln/morpho/closing_area.hh>
+
+
# include <mln/debug/println.hh>
# include "src/distance.hh"
+
namespace mln
{
template <typename I, typename N, typename Ic, typename Nc>
@@ -58,9 +64,8 @@
// attached data:
int lambda;
mln_ch_value(I, int) volume;
- //mln_ch_value(Ic, value::rgb8) values;
- //initialize(values, ref);
- //mln_ch_value(I, int) comp;
+ mln_ch_value(Ic, value::rgb8) color;
+
min_tree_(const I& f, const N& nbh, const Ic& ref, const Nc& nbhc,
int lambda)
@@ -82,10 +87,10 @@
initialize(resp, f);
initialize(zpar, f);
initialize(volume, f);
- //initialize(comp, f);
+ initialize(color, f);
mln::level::fill(deja_vu, false);
- //mln::level::fill(resp, false);
+ mln::level::fill(color, value::rgb8(255, 255, 255));
mln::level::fill(volume, 0);
s = level::sort_psites_increasing(f);
@@ -127,7 +132,7 @@
if (resp(p) && (volume(p) < lambda))
{
resp(p) = false;
- update_data(parent(p), volume(p));
+ update_data(parent(p), volume(p), color(p));
}
}
}
@@ -186,6 +191,11 @@
void init_data(const point& p)
{
+ // init volume
+ volume(p) = f(p);
+
+
+ // init color
int red =0, green = 0, blue = 0;
mln_niter(Nc) n(nbhc, p);
@@ -200,8 +210,11 @@
green /= 2;
blue /= 2;
- volume(p) = distance(value::rgb8(red, green, blue),
- value::rgb8(0, 0, 0));
+ color(p).red() = red;
+ color(p).green() = green;
+ color(p).blue() = blue;
+
+
resp(p) = true;
}
@@ -210,15 +223,24 @@
if (f(p) == f(r))
{
resp(p) = false;
+
+ // merge volume
volume(r) += volume(p);
+
+ // merge color
+ color(r) = (color(r) + color(p)) / 2;
}
}
- void update_data(const point& p, int val)
+ void update_data(const point& p, int val, value::rgb8 c)
{
+ // update volume
volume(p) += val;
+ // update color
+ color(p) = (color(p) + c) / 2;
+
if (parent(p) != p && !resp(p))
- update_data(parent(p), val);
+ update_data(parent(p), val, color(p));
}
};
@@ -382,6 +404,8 @@
}
+
+
template <typename I, typename N, typename Ic, typename Nc>
unsigned min_tree(const I& f, const N& nbh, const Ic& ref, const Nc& nbhc,
int lambda)
@@ -390,18 +414,19 @@
min_tree_<I,N,Ic,Nc> run(f, nbh, ref, nbhc, lambda);
+
mln_piter(I) p(f.domain());
unsigned nnodes = 0;
for_all(p)
{
if (run.is_node(p))
- {
++nnodes;
}
- }
colorize colors(nnodes);
image2d<value::rgb8> tmp(ref.domain());
+ level::fill(tmp, literal::black);
+ image2d<value::rgb8> tmp2(ref.domain());
level::fill(tmp, ref);
mln_piter(I) q(f.domain());
@@ -410,35 +435,46 @@
{
if (run.is_node(q))
{
- tmp(q) = colors(i);
+ tmp(q) = run.color(q);
+ tmp2(q) = colors(i);
i++;
}
}
+
mln_piter(I) r(f.domain());
for_all(r)
{
if (!run.is_node(r))
{
tmp(r) = tmp(run.find_representative(r));
+ tmp2(r) = tmp2(run.find_representative(r));
}
}
image2d<value::rgb8> to_display(tmp.domain());
+ image2d<value::rgb8> to_display2(tmp2.domain());
- level::fill(to_display, value::rgb8(255, 255, 255));
+ level::fill(to_display, literal::black);
level::paste((tmp | is_edge), to_display);
level::paste(morpho::dilation(to_display, c4()), to_display);
- io::ppm::save(display_edge(tmp, literal::black, 3),
- "edge.ppm");
+ level::fill(to_display2, literal::black);
+ level::paste((tmp2 | is_edge), to_display2);
+ level::paste(morpho::dilation(to_display2, c4()), to_display2);
+
+
+ io::ppm::save(display_edge(tmp, literal::black, 3), "edge.ppm");
io::ppm::save(tmp, "full.ppm");
io::ppm::save(cells2image(to_display), "colorize.ppm");
+ io::ppm::save(display_edge(tmp2, literal::black, 3), "edge2.ppm");
+ io::ppm::save(cells2image(to_display2), "colorize2.ppm");
return nnodes;
}
+
template <typename I>
I
do_it(I& input, int lambda, unsigned& nbasins)
Index: ballas/color/min_tree_area_filter.cc
--- ballas/color/min_tree_area_filter.cc (revision 2832)
+++ ballas/color/min_tree_area_filter.cc (working copy)
@@ -38,6 +38,14 @@
# include <mln/debug/println.hh>
+# if 0
+# include <mln/core/concept/image.hh>
+# include <mln/core/concept/neighborhood.hh>
+# include <mln/util/pix.hh>
+# include <mln/morpho/includes.hh>
+# include <mln/level/sort_psites.hh>
+#endif
+
# include "src/distance.hh"
namespace mln
Index: ballas/color/min_tree_height_filter.cc
--- ballas/color/min_tree_height_filter.cc (revision 0)
+++ ballas/color/min_tree_height_filter.cc (revision 0)
@@ -0,0 +1,550 @@
+# include <mln/core/var.hh>
+
+# include <mln/core/image/image2d.hh>
+# include <mln/core/image/image_if.hh>
+# include <mln/core/image/extended.hh>
+# include <mln/core/routine/extend.hh>
+
+# include <mln/core/alias/window2d.hh>
+# include <mln/core/alias/neighb2d.hh>
+# include <mln/make/double_neighb2d.hh>
+# include <mln/core/site_set/p_centered.hh>
+
+
+# include <mln/literal/black.hh>
+
+# include <mln/value/int_u8.hh>
+# include <mln/value/int_u16.hh>
+# include <mln/io/pgm/load.hh>
+# include <mln/io/pgm/save.hh>
+
+# include <mln/value/rgb8.hh>
+# include <mln/io/ppm/load.hh>
+# include <mln/io/ppm/save.hh>
+
+# include <mln/accu/min_max.hh>
+
+# include <mln/fun/i2v/array.hh>
+# include <mln/fun/p2v/iota.hh>
+
+# include <mln/level/paste.hh>
+# include <mln/level/fill.hh>
+# include <mln/level/transform.hh>
+# include <mln/extension/fill.hh>
+
+# include <mln/morpho/closing_area.hh>
+
+
+# include <mln/debug/println.hh>
+
+# include "src/distance.hh"
+
+
+namespace mln
+{
+ template <typename I, typename N, typename Ic, typename Nc>
+ struct min_tree_
+ {
+ typedef mln_site(I) point;
+ typedef p_array<point> S;
+
+ // in:
+ const I& f;
+ const N& nbh;
+ const Ic& ref;
+ const Nc& nbhc;
+
+ // aux:
+ S s;
+ mln_ch_value(I, bool) deja_vu;
+ mln_ch_value(I, point) parent;
+ mln_ch_value(I, bool) resp;
+ mln_ch_value(I, point) zpar;
+
+ // attached data:
+ int lambda;
+ mln_ch_value(I, int) height;
+ mln_ch_value(Ic, value::rgb8) color;
+
+
+ min_tree_(const I& f, const N& nbh, const Ic& ref, const Nc& nbhc,
+ int lambda)
+ : f(f),
+ nbh(nbh),
+ ref(ref),
+ nbhc(nbhc),
+ lambda(lambda)
+ {
+ run();
+ }
+
+ void run()
+ {
+ // init
+ {
+ initialize(deja_vu, f);
+ initialize(parent, f);
+ initialize(resp, f);
+ initialize(zpar, f);
+ initialize(height, f);
+ initialize(color, f);
+
+ mln::level::fill(deja_vu, false);
+ mln::level::fill(color, value::rgb8(255, 255, 255));
+ mln::level::fill(height, 0);
+
+ s = level::sort_psites_increasing(f);
+ }
+
+ // first pass
+ {
+ mln_fwd_piter(S) p(s);
+ mln_niter(N) n(nbh, p);
+ for_all(p)
+ {
+ make_set(p);
+ for_all(n)
+ if (f.has(n) && deja_vu(n))
+ do_union(n, p);
+ deja_vu(p) = true;
+ }
+ }
+
+ // second pass: canonization
+ {
+ mln_bkd_piter(S) p(s);
+ for_all(p)
+ {
+ point q = parent(p);
+ if (f(parent(q)) == f(q))
+ {
+ parent(p) = parent(q);
+ resp(q) = false;
+ }
+ }
+ }
+
+ // third pass: Merging region with height < lambda
+ {
+ mln_fwd_piter(S) p(s);
+ for_all(p)
+ {
+ if (resp(p) && (height(p) < lambda))
+ {
+ resp(p) = false;
+ update_data(parent(p), height(p), color(p));
+ }
+ }
+ }
+
+ } // end of run()
+
+ void make_set(const point& p)
+ {
+ parent(p) = p;
+ zpar(p) = p;
+ init_data(p);
+ }
+
+ void set_parent(const point& r, const point& p)
+ {
+ parent(r) = p;
+ merge_data(r, p);
+ }
+
+ bool is_root(const point& p) const
+ {
+ return parent(p) == p;
+ }
+
+ bool is_node(const point& p) const
+ {
+ //return is_root(p) || f(parent(p)) != f(p);
+ return (is_root(p) || resp(p));
+ }
+
+ point find_root(const point& x)
+ {
+ if (zpar(x) == x)
+ return x;
+ else
+ return zpar(x) = find_root(zpar(x));
+ }
+
+ point find_representative(const point& x)
+ {
+ if (parent(x) == x || resp(x))
+ return x;
+ else
+ return find_representative(parent(x));
+ }
+
+ void do_union(const point& n, const point& p)
+ {
+ point r = find_root(n);
+ if (r != p)
+ {
+ set_parent(r, p);
+ zpar(r) = p;
+ }
+ }
+
+ void init_data(const point& p)
+ {
+ // init height
+ height(p) = f(p);
+
+
+ // init color
+ int red =0, green = 0, blue = 0;
+
+ mln_niter(Nc) n(nbhc, p);
+ for_all(n)
+ {
+ red += ref(n).red();
+ green += ref(n).green();
+ blue += ref(n).blue();
+ }
+
+ red /= 2;
+ green /= 2;
+ blue /= 2;
+
+ color(p).red() = red;
+ color(p).green() = green;
+ color(p).blue() = blue;
+
+
+ resp(p) = true;
+ }
+
+ void merge_data(const point& r, const point& p)
+ {
+ if (f(p) == f(r))
+ {
+ resp(p) = false;
+
+ // merge height
+ height(r) += height(r) > height(p) ? height(r) : height(p);
+
+ // merge color
+ color(r) = (color(r) + color(p)) / 2;
+ }
+ }
+
+ void update_data(const point& p, int val, value::rgb8 c)
+ {
+ // update height
+ height(p) = height(p) > val ? height(p) : val;
+ // update color
+ color(p) = (color(p) + c) / 2;
+
+ if (parent(p) != p && !resp(p))
+ update_data(parent(p), val, color(p));
+ }
+
+ };
+}
+
+namespace mln
+{
+ image2d<value::int_u16> convert_to_grey(const image2d<value::rgb8>& data)
+ {
+ image2d<value::int_u16> output(data.domain());
+ mln_piter_(image2d<value::int_u16>) p(output.domain());
+ for_all(p)
+ output(p) = (int) (data(p).red() * 0.3 + data(p).green() * 0.58 + data(p).blue()) * 0.12;
+ return output;
+ }
+} // end of mln
+
+namespace mln
+{
+
+ struct colorize : Function_v2v< colorize >
+ {
+ typedef value::rgb8 result;
+ colorize(unsigned max)
+ : lut(max + 1)
+ {
+ lut[0] = literal::black;
+ for (unsigned i = 1; i <= max; ++i)
+ lut[i] = result(100 + std::rand() % 150,
+ 100 + std::rand() % 150,
+ 100 + std::rand() % 150);
+ }
+ result operator()(unsigned i) const
+ {
+ return lut[i];
+ }
+ std::vector<result> lut;
+ };
+
+ 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);
+ level::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)
+ output.at(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)
+ output.at(row + i, col) = ima(p);
+ }
+ return output;
+ }
+
+
+ template <typename I>
+ I display_edge(const I& ima, unsigned zoom)
+ {
+ unsigned nrows = ima.nrows() / 2 + 1;
+ unsigned ncols = ima.ncols() / 2 + 1;
+ I output(nrows * (zoom + 1) - 1,
+ ncols * (zoom + 1) - 1);
+
+ mln_VAR( cell, ima | is_cell );
+ mln_piter(cell_t) q(cell.domain());
+ for_all(q)
+ {
+ unsigned row = (q.row() / 2) * (zoom + 1);
+ unsigned col = (q.col() / 2) * (zoom + 1);
+ for (unsigned i = 0; i < zoom; ++i)
+ for (unsigned j = 0; j < zoom; ++j)
+ output.at(row + i, col + j) = ima(q);
+ }
+
+ 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)
+ output.at(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)
+ output.at(row + i, col) = ima(p);
+ }
+ return output;
+ }
+
+
+ namespace morpho
+ {
+
+ template <typename I, typename N>
+ mln_concrete(I)
+ dilation(const I& input, const N& nbh)
+ {
+ typedef mln_value(I) V;
+
+ mln_concrete(I) output;
+ initialize(output, input);
+
+ mln_piter(I) p(input.domain());
+ mln_niter(N) n(nbh, p);
+ for_all(p)
+ {
+ for_all(n)
+ if (input.has(n) && input(n) != value::rgb8(0,0,0))
+ output(p) = input(n);
+ }
+ return output;
+ }
+ } // mln::morpho
+
+} // mln
+
+
+
+template <typename T>
+mln::image2d<T>
+image2cells(const mln::image2d<T>& input)
+{
+ mln::image2d<T> output(2 * input.nrows() - 1,
+ 2 * input.ncols() - 1);
+ for (unsigned row = 0; row < input.nrows(); ++row)
+ for (unsigned col = 0; col < input.ncols(); ++col)
+ output.at(2 * row, 2 * col) = input.at(row, col);
+ return output;
+}
+
+
+template <typename T>
+mln::image2d<T>
+cells2image(const mln::image2d<T>& input)
+{
+ mln::image2d<T> output((input.nrows() + 1) / 2,
+ (input.ncols() + 1) / 2);
+ for (unsigned row = 0; row < input.nrows(); row += 2)
+ for (unsigned col = 0; col < input.ncols(); col += 2)
+ output.at(row / 2, col / 2) = input.at(row, col);
+ return output;
+}
+
+
+
+
+template <typename I, typename N, typename Ic, typename Nc>
+unsigned min_tree(const I& f, const N& nbh, const Ic& ref, const Nc& nbhc,
+ int lambda)
+{
+ using namespace mln;
+
+ min_tree_<I,N,Ic,Nc> run(f, nbh, ref, nbhc, lambda);
+
+
+ mln_piter(I) p(f.domain());
+ unsigned nnodes = 0;
+ for_all(p)
+ {
+ if (run.is_node(p))
+ ++nnodes;
+ }
+
+ colorize colors(nnodes);
+ image2d<value::rgb8> tmp(ref.domain());
+ level::fill(tmp, literal::black);
+ image2d<value::rgb8> tmp2(ref.domain());
+ level::fill(tmp, ref);
+
+ mln_piter(I) q(f.domain());
+ unsigned int i = 0;
+ for_all(q)
+ {
+ if (run.is_node(q))
+ {
+ tmp(q) = run.color(q);
+ tmp2(q) = colors(i);
+ i++;
+ }
+ }
+
+ mln_piter(I) r(f.domain());
+ for_all(r)
+ {
+ if (!run.is_node(r))
+ {
+ tmp(r) = tmp(run.find_representative(r));
+ tmp2(r) = tmp2(run.find_representative(r));
+ }
+ }
+
+ image2d<value::rgb8> to_display(tmp.domain());
+ image2d<value::rgb8> to_display2(tmp2.domain());
+
+ level::fill(to_display, literal::black);
+ level::paste((tmp | is_edge), to_display);
+ level::paste(morpho::dilation(to_display, c4()), to_display);
+
+ level::fill(to_display2, literal::black);
+ level::paste((tmp2 | is_edge), to_display2);
+ level::paste(morpho::dilation(to_display2, c4()), to_display2);
+
+
+ io::ppm::save(display_edge(tmp, literal::black, 3), "edge.ppm");
+ io::ppm::save(tmp, "full.ppm");
+ io::ppm::save(cells2image(to_display), "colorize.ppm");
+
+ io::ppm::save(display_edge(tmp2, literal::black, 3), "edge2.ppm");
+ io::ppm::save(cells2image(to_display2), "colorize2.ppm");
+
+ return nnodes;
+}
+
+
+
+template <typename I>
+I
+do_it(I& input, int lambda, unsigned& nbasins)
+{
+ using namespace mln;
+
+ /// Graph creation
+ I graph;
+ create_graph(input, graph, value::rgb8(0, 0, 0));
+
+ // Initialization
+ image2d<value::int_u16> ima = convert_to_grey(graph);
+
+ // Neigbhorhood
+ // 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));
+
+ 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));
+
+ // Algorithm
+ distance(extend((graph | is_edge).rw(), pw::value(graph)), e2c, ima);
+
+ io::pgm::save(ima, "edge.pgm");
+
+ nbasins = min_tree((ima | is_edge), e2e, graph, e2c, lambda);
+
+ return graph;
+}
+
+void usage(char* argv[])
+{
+ std::cerr << "usage: " << argv[0] << " input.pgm lambda" << std::endl;
+ std::cerr << " lambda >= 0" << std::endl;
+ abort();
+}
+
+int main(int argc, char* argv[])
+{
+ using namespace mln;
+
+ if (argc != 3)
+ usage(argv);
+
+ int lambda = atoi(argv[2]);
+ if (lambda < 0)
+ usage(argv);
+
+ image2d<value::rgb8> ima;
+ io::ppm::load(ima, argv[1]);
+
+ unsigned nbasins;
+ image2d<value::rgb8> output = do_it(ima, lambda, nbasins);
+
+ //io::ppm::save(output, argv[3]);
+}
Index: ballas/color/min_tree_color.cc
--- ballas/color/min_tree_color.cc (revision 2832)
+++ ballas/color/min_tree_color.cc (working copy)
@@ -38,6 +38,14 @@
# include <mln/debug/println.hh>
+# if 0
+# include <mln/core/concept/image.hh>
+# include <mln/core/concept/neighborhood.hh>
+# include <mln/util/pix.hh>
+# include <mln/morpho/includes.hh>
+# include <mln/level/sort_psites.hh>
+#endif
+
# include "src/distance.hh"
namespace mln
Index: ballas/color/min_tree_color_v2.cc
--- ballas/color/min_tree_color_v2.cc (revision 0)
+++ ballas/color/min_tree_color_v2.cc (revision 0)
@@ -0,0 +1,530 @@
+# include <mln/core/var.hh>
+
+# include <mln/core/image/image2d.hh>
+# include <mln/core/image/image_if.hh>
+# include <mln/core/image/extended.hh>
+# include <mln/core/routine/extend.hh>
+
+# include <mln/core/alias/window2d.hh>
+# include <mln/core/alias/neighb2d.hh>
+# include <mln/make/double_neighb2d.hh>
+# include <mln/core/site_set/p_centered.hh>
+
+
+# include <mln/literal/black.hh>
+
+# include <mln/value/int_u8.hh>
+# include <mln/value/int_u16.hh>
+# include <mln/io/pgm/load.hh>
+# include <mln/io/pgm/save.hh>
+
+# include <mln/value/rgb8.hh>
+# include <mln/io/ppm/load.hh>
+# include <mln/io/ppm/save.hh>
+
+# include <mln/accu/min_max.hh>
+
+# include <mln/fun/i2v/array.hh>
+# include <mln/fun/p2v/iota.hh>
+
+# include <mln/level/paste.hh>
+# include <mln/level/fill.hh>
+# include <mln/level/transform.hh>
+# include <mln/extension/fill.hh>
+
+# include <mln/morpho/closing_area.hh>
+
+
+# include <mln/debug/println.hh>
+
+# include "src/distance.hh"
+
+namespace mln
+{
+ template <typename I, typename N, typename Ic, typename Nc>
+ struct min_tree_
+ {
+ typedef mln_site(I) point;
+ typedef p_array<point> S;
+
+ // in:
+ const I& f;
+ const N& nbh;
+ const Ic& ref;
+ const Nc& nbhc;
+
+ // aux:
+ S s;
+ mln_ch_value(I, bool) deja_vu;
+ mln_ch_value(I, point) parent;
+ mln_ch_value(I, bool) resp;
+ mln_ch_value(I, point) zpar;
+
+ // attached data:
+ unsigned lambda;
+ mln_ch_value(I, value::rgb8) color;
+ //mln_ch_value(Ic, value::rgb8) values;
+ //initialize(values, ref);
+ //mln_ch_value(I, int) comp;
+
+ min_tree_(const I& f, const N& nbh, const Ic& ref, const Nc& nbhc,
+ int lambda)
+ : f(f),
+ nbh(nbh),
+ ref(ref),
+ nbhc(nbhc),
+ lambda(lambda)
+ {
+ run();
+ }
+
+ void run()
+ {
+ // init
+ {
+ initialize(deja_vu, f);
+ initialize(parent, f);
+ initialize(resp, f);
+ initialize(zpar, f);
+ initialize(color, f);
+
+ mln::level::fill(deja_vu, false);
+ mln::level::fill(color, value::rgb8(255, 255, 255));
+
+ s = level::sort_psites_increasing(f);
+ }
+
+ // first pass
+ {
+ mln_fwd_piter(S) p(s);
+ mln_niter(N) n(nbh, p);
+ for_all(p)
+ {
+ make_set(p);
+ for_all(n)
+ if (f.has(n) && deja_vu(n))
+ do_union(n, p);
+ deja_vu(p) = true;
+ }
+ }
+
+ // second pass: canonization
+ {
+ mln_bkd_piter(S) p(s);
+ for_all(p)
+ {
+ point q = parent(p);
+ if (f(parent(q)) == f(q))
+ {
+ parent(p) = parent(q);
+ resp(q) = false;
+ }
+ }
+ }
+
+ // third pass: Merging region with distance(color) < lambda
+ {
+ mln_fwd_piter(S) p(s);
+ for_all(p)
+ {
+ point q = parent(p);
+ if (resp(p) && distance(color(p), color(q)) < lambda)
+ {
+ resp(p) = false;
+ update_data(q, color(p));
+ }
+ }
+ }
+
+ } // end of run()
+
+ void make_set(const point& p)
+ {
+ parent(p) = p;
+ zpar(p) = p;
+ init_data(p);
+ }
+
+ void set_parent(const point& r, const point& p)
+ {
+ parent(r) = p;
+ merge_data(r, p);
+ }
+
+ bool is_root(const point& p) const
+ {
+ return parent(p) == p;
+ }
+
+ bool is_node(const point& p) const
+ {
+ //return is_root(p) || f(parent(p)) != f(p);
+ return (is_root(p) || resp(p));
+ }
+
+ point find_root(const point& x)
+ {
+ if (zpar(x) == x)
+ return x;
+ else
+ return zpar(x) = find_root(zpar(x));
+ }
+
+ point find_representative(const point& x)
+ {
+ if (parent(x) == x || resp(x))
+ return x;
+ else
+ return find_representative(parent(x));
+ }
+
+ void do_union(const point& n, const point& p)
+ {
+ point r = find_root(n);
+ if (r != p)
+ {
+ set_parent(r, p);
+ zpar(r) = p;
+ }
+ }
+
+ void init_data(const point& p)
+ {
+ int red =0, green = 0, blue = 0;
+
+ mln_niter(Nc) n(nbhc, p);
+ for_all(n)
+ {
+ red += ref(n).red();
+ green += ref(n).green();
+ blue += ref(n).blue();
+ }
+
+ red /= 2;
+ green /= 2;
+ blue /= 2;
+
+ color(p).red() = red;
+ color(p).green() = green;
+ color(p).blue() = blue;
+
+ resp(p) = true;
+ }
+
+ void merge_data(const point& r, const point& p)
+ {
+ if (f(p) == f(r))
+ {
+ resp(p) = false;
+ color(r) = (color(r) + color(p)) / 2;
+ }
+ }
+
+ void update_data(const point& p, value::rgb8 val)
+ {
+ color(p) = (color(p) + val) / 2;
+ if (parent(p) != p && !resp(p))
+ update_data(parent(p), color(p));
+ }
+
+ };
+}
+
+namespace mln
+{
+ image2d<value::int_u16> convert_to_grey(const image2d<value::rgb8>& data)
+ {
+ image2d<value::int_u16> output(data.domain());
+ mln_piter_(image2d<value::int_u16>) p(output.domain());
+ for_all(p)
+ output(p) = (int) (data(p).red() * 0.3 + data(p).green() * 0.58 + data(p).blue()) * 0.12;
+ return output;
+ }
+} // end of mln
+
+namespace mln
+{
+
+ struct colorize : Function_v2v< colorize >
+ {
+ typedef value::rgb8 result;
+ colorize(unsigned max)
+ : lut(max + 1)
+ {
+ lut[0] = literal::black;
+ for (unsigned i = 1; i <= max; ++i)
+ lut[i] = result(100 + std::rand() % 150,
+ 100 + std::rand() % 150,
+ 100 + std::rand() % 150);
+ }
+ result operator()(unsigned i) const
+ {
+ return lut[i];
+ }
+ std::vector<result> lut;
+ };
+
+ 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);
+ level::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)
+ output.at(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)
+ output.at(row + i, col) = ima(p);
+ }
+ return output;
+ }
+
+ template <typename I>
+ I display_edge(const I& ima, unsigned zoom)
+ {
+ unsigned nrows = ima.nrows() / 2 + 1;
+ unsigned ncols = ima.ncols() / 2 + 1;
+ I output(nrows * (zoom + 1) - 1,
+ ncols * (zoom + 1) - 1);
+
+ mln_VAR( cell, ima | is_cell );
+ mln_piter(cell_t) q(cell.domain());
+ for_all(q)
+ {
+ unsigned row = (q.row() / 2) * (zoom + 1);
+ unsigned col = (q.col() / 2) * (zoom + 1);
+ for (unsigned i = 0; i < zoom; ++i)
+ for (unsigned j = 0; j < zoom; ++j)
+ output.at(row + i, col + j) = ima(q);
+ }
+
+ 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)
+ output.at(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)
+ output.at(row + i, col) = ima(p);
+ }
+ return output;
+ }
+
+
+ namespace morpho
+ {
+
+ template <typename I, typename N>
+ mln_concrete(I)
+ dilation(const I& input, const N& nbh)
+ {
+ typedef mln_value(I) V;
+
+ mln_concrete(I) output;
+ initialize(output, input);
+
+ mln_piter(I) p(input.domain());
+ mln_niter(N) n(nbh, p);
+ for_all(p)
+ {
+ for_all(n)
+ if (input.has(n) && input(n) != value::rgb8(0,0,0))
+ output(p) = input(n);
+ }
+ return output;
+ }
+ } // mln::morpho
+
+} // mln
+
+
+
+template <typename T>
+mln::image2d<T>
+image2cells(const mln::image2d<T>& input)
+{
+ mln::image2d<T> output(2 * input.nrows() - 1,
+ 2 * input.ncols() - 1);
+ for (unsigned row = 0; row < input.nrows(); ++row)
+ for (unsigned col = 0; col < input.ncols(); ++col)
+ output.at(2 * row, 2 * col) = input.at(row, col);
+ return output;
+}
+
+
+template <typename T>
+mln::image2d<T>
+cells2image(const mln::image2d<T>& input)
+{
+ mln::image2d<T> output((input.nrows() + 1) / 2,
+ (input.ncols() + 1) / 2);
+ for (unsigned row = 0; row < input.nrows(); row += 2)
+ for (unsigned col = 0; col < input.ncols(); col += 2)
+ output.at(row / 2, col / 2) = input.at(row, col);
+ return output;
+}
+
+
+template <typename I, typename N, typename Ic, typename Nc>
+unsigned min_tree(const I& f, const N& nbh, const Ic& ref, const Nc& nbhc,
+ int lambda)
+{
+ using namespace mln;
+
+ min_tree_<I,N,Ic,Nc> run(f, nbh, ref, nbhc, lambda);
+
+
+ mln_piter(I) p(f.domain());
+ unsigned nnodes = 0;
+ for_all(p)
+ {
+ if (run.is_node(p))
+ ++nnodes;
+ }
+
+ colorize colors(nnodes);
+ image2d<value::rgb8> tmp(ref.domain());
+ level::fill(tmp, literal::black);
+ image2d<value::rgb8> tmp2(ref.domain());
+ level::fill(tmp, ref);
+
+ mln_piter(I) q(f.domain());
+ unsigned int i = 0;
+ for_all(q)
+ {
+ if (run.is_node(q))
+ {
+ tmp(q) = run.color(q);
+ tmp2(q) = colors(i);
+ i++;
+ }
+ }
+
+ mln_piter(I) r(f.domain());
+ for_all(r)
+ {
+ if (!run.is_node(r))
+ {
+ tmp(r) = tmp(run.find_representative(r));
+ tmp2(r) = tmp2(run.find_representative(r));
+ }
+ }
+
+ image2d<value::rgb8> to_display(tmp.domain());
+ image2d<value::rgb8> to_display2(tmp2.domain());
+
+ level::fill(to_display, literal::black);
+ level::paste((tmp | is_edge), to_display);
+ level::paste(morpho::dilation(to_display, c4()), to_display);
+
+ level::fill(to_display2, literal::black);
+ level::paste((tmp2 | is_edge), to_display2);
+ level::paste(morpho::dilation(to_display2, c4()), to_display2);
+
+
+ io::ppm::save(display_edge(tmp, literal::black, 3), "edge.ppm");
+ io::ppm::save(tmp, "full.ppm");
+ io::ppm::save(cells2image(to_display), "colorize.ppm");
+
+ io::ppm::save(display_edge(tmp2, literal::black, 3), "edge2.ppm");
+ io::ppm::save(cells2image(to_display2), "colorize2.ppm");
+
+ return nnodes;
+}
+
+
+template <typename I>
+I
+do_it(I& input, int lambda, unsigned& nbasins)
+{
+ using namespace mln;
+
+ /// Graph creation
+ I graph;
+ create_graph(input, graph, value::rgb8(0, 0, 0));
+
+ // Initialization
+ image2d<value::int_u16> ima = convert_to_grey(graph);
+
+ // Neigbhorhood
+ // 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));
+
+ 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));
+
+ // Algorithm
+ distance(extend((graph | is_edge).rw(), pw::value(graph)), e2c, ima);
+
+ io::pgm::save(ima, "edge.pgm");
+
+ nbasins = min_tree((ima | is_edge), e2e, graph, e2c, lambda);
+
+ return graph;
+}
+
+void usage(char* argv[])
+{
+ std::cerr << "usage: " << argv[0] << " input.pgm lambda" << std::endl;
+ std::cerr << " lambda >= 0" << std::endl;
+ abort();
+}
+
+int main(int argc, char* argv[])
+{
+ using namespace mln;
+
+ if (argc != 3)
+ usage(argv);
+
+ int lambda = atoi(argv[2]);
+ if (lambda < 0)
+ usage(argv);
+
+ image2d<value::rgb8> ima;
+ io::ppm::load(ima, argv[1]);
+
+ unsigned nbasins;
+ image2d<value::rgb8> output = do_it(ima, lambda, nbasins);
+
+ //io::ppm::save(output, argv[3]);
+}
1
0
cleanup-2008 2832: Rely on a canvas to compute iz and distance transforms.
by Thierry Geraud 10 Nov '08
by Thierry Geraud 10 Nov '08
10 Nov '08
https://svn.lrde.epita.fr/svn/oln/branches/cleanup-2008/milena
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Rely on a canvas to compute iz and distance transforms.
* tests/transform/influence_zone_geodesic.cc: Slight change.
* mln/debug/println.hh: New overload to display a message.
* mln/canvas/distance_geodesic.hh: New.
* mln/transform/influence_zone_geodesic.hh: Update.
* mln/transform/distance_geodesic.hh: Update.
mln/canvas/distance_geodesic.hh | 81 ++++++++----------------
mln/debug/println.hh | 28 ++++++--
mln/transform/distance_geodesic.hh | 84 +++++--------------------
mln/transform/influence_zone_geodesic.hh | 96 ++++++-----------------------
tests/transform/influence_zone_geodesic.cc | 2
5 files changed, 91 insertions(+), 200 deletions(-)
Index: tests/transform/influence_zone_geodesic.cc
--- tests/transform/influence_zone_geodesic.cc (revision 2831)
+++ tests/transform/influence_zone_geodesic.cc (working copy)
@@ -53,6 +53,6 @@
0, 0, 0, 0, 0, 0, 0 };
image2d<int_u8> input = make::image2d(vals);
- image2d<int_u8> output = transform::influence_zone_geodesic(input, c4(), int_u8(1));
+ image2d<int_u8> output = transform::influence_zone_geodesic(input, c4(), int_u8(2));
debug::println(output);
}
Index: mln/debug/println.hh
--- mln/debug/println.hh (revision 2831)
+++ mln/debug/println.hh (working copy)
@@ -1,4 +1,5 @@
// 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,12 +29,11 @@
#ifndef MLN_DEBUG_PRINTLN_HH
# define MLN_DEBUG_PRINTLN_HH
-/*! \file mln/debug/println.hh
- *
- * \brief Print an image on the standard output.
- *
- * \todo Revamp.
- */
+/// \file mln/debug/println.hh
+///
+/// Print an image on the standard output.
+///
+/// \todo Revamp.
# include <mln/core/concept/image.hh>
# include <mln/core/concept/window.hh>
@@ -43,6 +43,7 @@
// Specializations are in:
# include <mln/debug/println.spe.hh>
+
namespace mln
{
@@ -53,6 +54,11 @@
template <typename I>
void println(const Image<I>& input);
+ /// Print the message \p msg and the image \p input on the
+ /// standard output.
+ template <typename I>
+ void println(const std::string& msg, const Image<I>& input);
+
# ifndef MLN_INCLUDE_ONLY
@@ -75,7 +81,8 @@
} // end of namespace mln::debug::impl
- // Facade.
+ // Facades.
+
template <typename I>
inline
void
@@ -87,6 +94,13 @@
trace::exiting("debug::println");
}
+ template <typename I>
+ void println(const std::string& msg, const Image<I>& input)
+ {
+ std::cout << msg << std::endl;
+ println(input);
+ }
+
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln::debug
Index: mln/transform/influence_zone_geodesic.hh
--- mln/transform/influence_zone_geodesic.hh (revision 2831)
+++ mln/transform/influence_zone_geodesic.hh (working copy)
@@ -32,13 +32,8 @@
///
/// Discrete geodesic distance transform.
-# include <mln/core/concept/image.hh>
-# include <mln/core/concept/neighborhood.hh>
-# include <mln/core/site_set/p_queue_fast.hh>
-# include <mln/core/routine/clone.hh>
-# include <mln/level/fill.hh>
-
-# include <mln/debug/println.hh>
+# include <mln/canvas/distance_geodesic.hh>
+# include <mln/literal/zero.hh>
namespace mln
@@ -55,99 +50,54 @@
# ifndef MLN_INCLUDE_ONLY
- namespace impl
- {
- namespace generic
+ namespace internal
{
- template <typename I, typename N, typename D>
- mln_concrete(I)
- influence_zone_geodesic(const Image<I>& input_, const Neighborhood<N>& nbh_,
- D max)
+ template <typename I>
+ struct iz_functor
{
- trace::entering("transform::impl::generic::influence_zone_geodesic");
-
- const I& input = exact(input_);
- const N& nbh = exact(nbh_);
-
- mln_precondition(input.has_data());
-
- mln_ch_value(I, D) dmap; // Distance map is aux data.
- initialize(dmap, input);
-
+ typedef mln_value(I) V;
typedef mln_site(I) P;
- p_queue_fast<P> q;
- mln_concrete(I) output = clone(input);
+ mln_concrete(I) output;
- // Initialization.
- {
- level::fill(dmap, max);
- mln_piter(I) p(input.domain());
- mln_niter(N) n(nbh, p);
- for_all(p)
- if (input(p) != 0) // p in a component
- {
- dmap(p) = 0;
- for_all(n)
- if (input.domain().has(n) && input(n) == 0) // n in background
+ void init(const I& input)
{
- q.push(p);
- break;
- }
+ output = clone(input);
}
+ bool inqueue_p_wrt_input_p(const V& input_p)
+ {
+ return input_p != 0u;
}
-
- // Propagation.
+ bool inqueue_p_wrt_input_n(const V& input_n)
{
- P p;
- mln_niter(N) n(nbh, p);
- while (! q.is_empty())
- {
- p = q.pop_front();
- if (dmap(p) == max)
- {
- // Saturation so stop.
- q.clear();
- break;
+ return input_n == 0u;
}
- for_all(n)
- if (input.domain().has(n) && dmap(n) == max)
+ void process(const P& p, const P& n)
{
- dmap(n) = dmap(p) + 1;
output(n) = output(p);
- q.push(n);
- }
- }
}
+ };
- trace::exiting("transform::impl::generic::influence_zone_geodesic");
- return output;
- }
+ } // end of namespace mln::transform::internal
- } // end of namespace mln::transform::impl::generic
-
- } // end of namespace mln::transform::impl
-
-
- // Facade.
template <typename I, typename N, typename D>
- inline
mln_concrete(I)
influence_zone_geodesic(const Image<I>& input, const Neighborhood<N>& nbh,
- D distance_max)
+ D max)
{
trace::entering("transform::influence_zone_geodesic");
- // FIXME: tests.
+ mln_precondition(exact(input).has_data());
+ // mln_precondition(exact(nbh).is_valid());
- mln_concrete(I) output;
- output = impl::generic::influence_zone_geodesic(input, nbh, distance_max);
+ internal::iz_functor<I> f;
+ (void) mln::canvas::distance_geodesic(input, nbh, max, f);
trace::exiting("transform::influence_zone_geodesic");
- return output;
+ return f.output;
}
# endif // ! MLN_INCLUDE_ONLY
Index: mln/transform/distance_geodesic.hh
--- mln/transform/distance_geodesic.hh (revision 2831)
+++ mln/transform/distance_geodesic.hh (working copy)
@@ -32,10 +32,7 @@
///
/// Discrete geodesic distance transform.
-# include <mln/core/concept/image.hh>
-# include <mln/core/concept/neighborhood.hh>
-# include <mln/core/site_set/p_queue_fast.hh>
-# include <mln/level/fill.hh>
+# include <mln/canvas/distance_geodesic.hh>
@@ -53,79 +50,34 @@
# ifndef MLN_INCLUDE_ONLY
- namespace impl
- {
- namespace generic
+ namespace internal
{
- template <typename I, typename N, typename D>
- mln_ch_value(I, D)
- distance_geodesic(const Image<I>& input_, const Neighborhood<N>& nbh_, D max)
+ template <typename I>
+ struct distance_functor
{
- trace::entering("transform::impl::generic::distance_geodesic");
-
- const I& input = exact(input_);
- const N& nbh = exact(nbh_);
-
- mln_precondition(input.has_data());
-
- mln_ch_value(I, D) output;
- initialize(output, input);
-
+ typedef mln_value(I) V;
typedef mln_site(I) P;
- p_queue_fast<P> q;
- // Initialization.
+ void init(const I&)
{
- level::fill(output, max);
- mln_piter(I) p(input.domain());
- mln_niter(N) n(nbh, p);
- for_all(p)
- if (input(p) == true) // p in object
- {
- output(p) = 0;
- for_all(n)
- if (input.domain().has(n) && input(n) == false) // n in background
- {
- q.push(p);
- break;
- }
}
- }
-
- // Propagation.
+ bool inqueue_p_wrt_input_p(const V& input_p)
{
- P p;
- mln_niter(N) n(nbh, p);
- while (! q.is_empty())
- {
- p = q.pop_front();
- for_all(n)
- if (input.domain().has(n) && output(n) == max)
- {
- output(n) = output(p) + 1;
- if (output(n) == max)
- {
- // Saturation so stop.
- q.clear();
- break;
- }
- q.push(n);
- }
+ return input_p == true;
}
+ bool inqueue_p_wrt_input_n(const V& input_n)
+ {
+ return input_n == false;
}
-
- trace::exiting("transform::impl::generic::distance_geodesic");
- return output;
+ void process(const P&, const P&)
+ {
}
+ };
- } // end of namespace mln::transform::impl::generic
-
- } // end of namespace mln::transform::impl
-
+ } // end of namespace mln::transform::internal
- // Facade.
template <typename I, typename N, typename D>
inline
@@ -134,10 +86,12 @@
{
trace::entering("transform::distance_geodesic");
- // FIXME: tests.
+ mln_precondition(exact(input).has_data());
+ // mln_precondition(exact(nbh).is_valid());
mln_ch_value(I, D) output;
- output = impl::generic::distance_geodesic(input, nbh, max);
+ internal::distance_functor<I> f;
+ output = mln::canvas::distance_geodesic(input, nbh, max, f);
trace::exiting("transform::distance_geodesic");
return output;
Index: mln/canvas/distance_geodesic.hh
--- mln/canvas/distance_geodesic.hh (revision 2830)
+++ mln/canvas/distance_geodesic.hh (working copy)
@@ -25,12 +25,12 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-#ifndef MLN_TRANSFORM_INFLUENCE_ZONE_GEODESIC_HH
-# define MLN_TRANSFORM_INFLUENCE_ZONE_GEODESIC_HH
+#ifndef MLN_CANVAS_DISTANCE_GEODESIC_HH
+# define MLN_CANVAS_DISTANCE_GEODESIC_HH
-/// \file mln/transform/influence_zone_geodesic.hh
+/// \file mln/canvas/distance_geodesic.hh
///
-/// Discrete geodesic distance transform.
+/// Discrete geodesic distance canvas.
# include <mln/core/concept/image.hh>
# include <mln/core/concept/neighborhood.hh>
@@ -38,40 +38,37 @@
# include <mln/core/routine/clone.hh>
# include <mln/level/fill.hh>
-# include <mln/debug/println.hh>
-
namespace mln
{
- namespace transform
+ namespace canvas
{
- /// Discrete geodesic distance transform.
- template <typename I, typename N, typename D>
- mln_concrete(I)
- influence_zone_geodesic(const Image<I>& input, const Neighborhood<N>& nbh, D max);
+ /// Discrete geodesic distance canvas.
+ template <typename I, typename N, typename D,
+ typename F>
+ mln_ch_value(I, D)
+ distance_geodesic(const Image<I>& input, const Neighborhood<N>& nbh, D max,
+ F& functor);
# ifndef MLN_INCLUDE_ONLY
- namespace impl
- {
-
- namespace generic
- {
- template <typename I, typename N, typename D>
- mln_concrete(I)
- influence_zone_geodesic(const Image<I>& input_, const Neighborhood<N>& nbh_,
- D max)
+ template <typename I, typename N, typename D,
+ typename F>
+ mln_ch_value(I, D)
+ distance_geodesic(const Image<I>& input_, const Neighborhood<N>& nbh_, D max,
+ F& functor)
{
- trace::entering("transform::impl::generic::influence_zone_geodesic");
+ trace::entering("canvas::distance_geodesic");
const I& input = exact(input_);
const N& nbh = exact(nbh_);
mln_precondition(input.has_data());
+ // mln_precondition(nbh.is_valid());
mln_ch_value(I, D) dmap; // Distance map is aux data.
initialize(dmap, input);
@@ -79,19 +76,19 @@
typedef mln_site(I) P;
p_queue_fast<P> q;
- mln_concrete(I) output = clone(input);
-
// Initialization.
{
+ functor.init(input); // <-- init
level::fill(dmap, max);
mln_piter(I) p(input.domain());
mln_niter(N) n(nbh, p);
for_all(p)
- if (input(p) != 0) // p in a component
+ if (functor.inqueue_p_wrt_input_p(input(p))) // <-- inqueue_p_wrt_input_p
{
dmap(p) = 0;
for_all(n)
- if (input.domain().has(n) && input(n) == 0) // n in background
+ if (input.domain().has(n) &&
+ functor.inqueue_p_wrt_input_n(input(n))) // <-- inqueue_p_wrt_input_n
{
q.push(p);
break;
@@ -116,45 +113,21 @@
if (input.domain().has(n) && dmap(n) == max)
{
dmap(n) = dmap(p) + 1;
- output(n) = output(p);
+ functor.process(p, n); // <- process
q.push(n);
}
}
}
- trace::exiting("transform::impl::generic::influence_zone_geodesic");
- return output;
- }
-
- } // end of namespace mln::transform::impl::generic
-
- } // end of namespace mln::transform::impl
-
-
- // Facade.
-
- template <typename I, typename N, typename D>
- inline
- mln_concrete(I)
- influence_zone_geodesic(const Image<I>& input, const Neighborhood<N>& nbh,
- D distance_max)
- {
- trace::entering("transform::influence_zone_geodesic");
-
- // FIXME: tests.
-
- mln_concrete(I) output;
- output = impl::generic::influence_zone_geodesic(input, nbh, distance_max);
-
- trace::exiting("transform::influence_zone_geodesic");
- return output;
+ trace::exiting("canvas::distance_geodesic");
+ return dmap;
}
# endif // ! MLN_INCLUDE_ONLY
- } // end of namespace mln::transform
+ } // end of namespace mln::canvas
} // end of namespace mln
-#endif // ! MLN_TRANSFORM_DISTANCE_HH
+#endif // ! MLN_CANVAS_DISTANCE_GEODESIC_HH
Property changes on: mln/canvas/distance_geodesic.hh
___________________________________________________________________
Added: svn:mergeinfo
1
0
https://svn.lrde.epita.fr/svn/oln/branches/cleanup-2008/milena
Index: ChangeLog
from Nicolas Ballas <ballas(a)lrde.epita.fr>
Fix in mln_value_quant_from_ macro.
* mln/trait/value_.hh: Fix a bug.
* mln/core/image/flat_image.hh: Fix warning.
* mln/level/fill_with_value.spe.hh: Update.
* mln/level/paste.hh,
* mln/level/fill_with_value.hh: Update documentations.
core/image/flat_image.hh | 3 +++
level/fill_with_value.hh | 7 +++----
level/fill_with_value.spe.hh | 2 +-
level/paste.hh | 1 +
trait/value_.hh | 5 +++--
5 files changed, 11 insertions(+), 7 deletions(-)
Index: mln/trait/value_.hh
--- mln/trait/value_.hh (revision 2830)
+++ mln/trait/value_.hh (working copy)
@@ -49,7 +49,7 @@
# define mln_trait_value_kind(V) typename mln::trait::value_< V >::kind
# define mln_trait_value_kind_(V) mln::trait::value_< V >::kind
# define mln_trait_value_quant(V) typename mln::trait::value_< V >::quant
-# define mln_trait_value_quant_(V) mln::trait::value_< V >::quant
+# define mln_trait_value_quant_(V) mln::trait::bvalue_< V >::quant
# define mln_nbits(V) mln::trait::value_< V >::nbits
@@ -67,8 +67,9 @@
+/// FIXME: check that the -1 is correct
# define mln_value_quant_from_(C) \
- mlc_if(mln::metal::bool_<( C > 65536 || C == 0 )>, \
+ mlc_if(mln::metal::bool_<( C > 65536 || C == 0 || C == -1)>, \
mln::trait::value::quant::high, \
mln::trait::value::quant::low)
Index: mln/core/image/flat_image.hh
--- mln/core/image/flat_image.hh (revision 2830)
+++ mln/core/image/flat_image.hh (working copy)
@@ -252,6 +252,9 @@
mln_precondition(this->has_data());
mln_precondition(old_val == this->data_->val_);
this->data_->val_ = new_val;
+
+ /// Avoid warning when NDEBUG is set
+ (void) old_val;
}
template <typename T, typename S>
Index: mln/level/fill_with_value.spe.hh
--- mln/level/fill_with_value.spe.hh (revision 2830)
+++ mln/level/fill_with_value.spe.hh (working copy)
@@ -77,8 +77,8 @@
{
trace::entering("level::impl::fill_with_value_one_block");
-
I& ima = exact(ima_);
+
internal::fill_with_value_tests(ima, val);
mln_precondition(((mlc_is(mln_trait_image_pw_io(I),
trait::image::pw_io::read_write)::value ||
Index: mln/level/paste.hh
--- mln/level/paste.hh (revision 2830)
+++ mln/level/paste.hh (working copy)
@@ -88,6 +88,7 @@
mln_precondition(exact(input).has_data());
mln_precondition(exact(input).domain() <= exact(output).domain());
+ // Avoid warning when compiling with NDEBUG
(void)input;
(void)output;
}
Index: mln/level/fill_with_value.hh
--- mln/level/fill_with_value.hh (revision 2830)
+++ mln/level/fill_with_value.hh (working copy)
@@ -77,12 +77,11 @@
inline
void fill_with_value_tests(Image<I>& ima, const V&)
{
- // Avoid a warning about an undefined variable when NDEBUG
- // is not defined.
- (void) ima;
-
mlc_converts_to(mln_exact(V), mln_value(I))::check();
mln_precondition(exact(ima).has_data());
+
+ // Avoid a warning about an undefined variable when NDEBUG
+ (void) ima;
}
} // end of namespace mln::level::internal
1
0