Olena-patches
Threads by month
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- 9625 discussions
https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Fix accu::bbox and new fllt try in sandbox.
* mln/core/p_array.hh (append): New overload for p_array.
* mln/accu/bbox.hh (take): Fix. The "else if" was wrong;
is_valid_ was not updated.
* sandbox/geraud/fllt.svg.1.cc: New.
* sandbox/geraud/fllt.cc: New.
mln/accu/bbox.hh | 10 +
mln/core/p_array.hh | 15 ++
sandbox/geraud/fllt.cc | 301 +++++++++++++++++++++++++++++++++++++++++++
sandbox/geraud/fllt.svg.1.cc | 222 +++++++++++++++++++++++++++++++
4 files changed, 546 insertions(+), 2 deletions(-)
Index: mln/core/p_array.hh
--- mln/core/p_array.hh (revision 1873)
+++ mln/core/p_array.hh (working copy)
@@ -93,6 +93,9 @@
/// Append a point \p p.
p_array<P>& append(const P& p);
+ /// Append an array \p other of points.
+ p_array<P>& append(const p_array<P>& other);
+
/// Clear this set.
void clear();
@@ -204,6 +207,18 @@
template <typename P>
inline
+ p_array<P>&
+ p_array<P>::append(const p_array<P>& other)
+ {
+ vect_.insert(vect_.end(),
+ other.vect().begin(), other.vect().end());
+ if (! bb_needs_update_)
+ bb_needs_update_ = true;
+ return *this;
+ }
+
+ template <typename P>
+ inline
void
p_array<P>::clear()
{
Index: mln/accu/bbox.hh
--- mln/accu/bbox.hh (revision 1873)
+++ mln/accu/bbox.hh (working copy)
@@ -134,16 +134,19 @@
{
// 'other' makes '*this' valid
*this = other;
+ is_valid_ = true;
return;
}
// both are valids so:
const box_<P>& o_b = other.b_;
for (unsigned i = 0; i < P::dim; ++i)
+ {
if (o_b.pmin()[i] < b_.pmin()[i])
b_.pmin()[i] = o_b.pmin()[i];
- else if (o_b.pmax()[i] > b_.pmax()[i])
+ if (o_b.pmax()[i] > b_.pmax()[i])
b_.pmax()[i] = o_b.pmax()[i];
}
+ }
template <typename P>
inline
@@ -158,15 +161,18 @@
if (! this->is_valid_)
{
b_ = other;
+ is_valid_ = true;
return;
}
// both are valids so:
for (unsigned i = 0; i < P::dim; ++i)
+ {
if (other.pmin()[i] < b_.pmin()[i])
b_.pmin()[i] = other.pmin()[i];
- else if (other.pmax()[i] > b_.pmax()[i])
+ if (other.pmax()[i] > b_.pmax()[i])
b_.pmax()[i] = other.pmax()[i];
}
+ }
template <typename P>
inline
Index: sandbox/geraud/fllt.svg.1.cc
--- sandbox/geraud/fllt.svg.1.cc (revision 0)
+++ sandbox/geraud/fllt.svg.1.cc (revision 0)
@@ -0,0 +1,222 @@
+// Copyright (C) 2008 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#include <mln/core/image2d.hh>
+#include <mln/core/neighb2d.hh>
+#include <mln/core/p_array.hh>
+#include <mln/core/clone.hh>
+
+#include <mln/value/int_u8.hh>
+# include <mln/value/rgb8.hh>
+
+#include <mln/io/pgm/load.hh>
+#include <mln/io/pgm/save.hh>
+#include <mln/io/ppm/save.hh>
+
+#include <mln/level/fill.hh>
+#include <mln/debug/println.hh>
+#include <mln/labeling/regional_minima.hh>
+#include <mln/accu/bbox.hh>
+
+#include <mln/literal/black.hh>
+#include <mln/literal/white.hh>
+#include <mln/literal/colors.hh>
+
+#include <sstream>
+
+
+namespace mln
+{
+
+ namespace my
+ {
+
+ template <typename N_t>
+ unsigned compute_gN(const N_t& N)
+ {
+ for (unsigned i = 0; i < 256; ++i)
+ if (N[i].npoints() != 0)
+ return i;
+ mln_invariant(0);
+ return 0;
+ }
+
+
+ template <typename I, typename A_t>
+ void save(const I& is, const A_t& A)
+ {
+ static unsigned counter = 0;
+ using value::rgb8;
+
+ image2d<rgb8> temp(is.domain());
+ level::fill(temp, literal::black);
+
+ mln_piter(I) p(is.domain());
+ for_all(p)
+ switch (is(p)) {
+ case 1: // R
+ temp(p) = literal::red;
+ break;
+ case 2: // N
+ temp(p) = literal::green;
+ break;
+ }
+
+ mln_piter(A_t) a(A);
+ for_all(a) // A
+ temp(a) = literal::blue;
+
+ std::stringstream filename;
+ filename << "./temp_" << ++counter << ".ppm";
+ io::ppm::save(temp, filename.str());
+ }
+
+
+ template <typename I, typename Nbh>
+ void fllt(const Image<I>& input_, const Neighborhood<Nbh>& nbh_)
+ {
+ const I& input = exact(input_);
+ const Nbh& nbh = exact(nbh_);
+
+ unsigned l = 0, l_max;
+ mln_ch_value(I, unsigned) reg_min = labeling::regional_minima(input, nbh, l_max);
+
+ // Variables.
+ I u = mln::clone(input);
+ mln_point(I) x0;
+ mln_value(I) g, gN;
+ image2d<unsigned char> is(input.domain());
+ const unsigned in_R = 1, in_N = 2, in_O = 0;
+
+ typedef p_array<mln_point(I)> arr_t;
+ arr_t A;
+ arr_t N[256];
+
+ accu::bbox<mln_point(I)> R_box;
+
+
+ // Step 1.
+ step_1:
+ {
+ if (l == l_max)
+ return;
+ l += 1;
+ mln_piter(I) p(input.domain());
+ for_all(p)
+ if (reg_min(p) == l)
+ break;
+ x0 = p;
+ g = input(x0);
+ }
+
+ // Step 2.
+ step_2:
+ {
+ R_box.init();
+ level::fill(is, in_O);
+ A.append(x0);
+ }
+
+ // Step 3.
+ step_3:
+ {
+ mln_piter(arr_t) a(A);
+ mln_niter(Nbh) x(nbh, a);
+
+ my::save(is, A);
+
+ // R <- R U A
+ for_all(a)
+ is(a) = in_R;
+ R_box.take(A.bbox());
+
+ // N <- N U { x in nbh of A and not in R }
+ for_all(a)
+ for_all(x)
+ if (u.has(x) && is(x) == in_O)
+ {
+ N[u(x)].append(x);
+ is(x) = in_N;
+ }
+ // gN = min u(x) for all x in N
+ gN = compute_gN(N);
+
+ // FIXME: update the number of CC of the border of R
+ }
+
+ // Step 4.
+ step_4:
+ {
+ // a)
+ if (g < gN)
+ {
+ // FIXME: DO the hole thing.
+ A = N[g];
+ N[g].clear();
+ g = gN;
+ gN = compute_gN(N);
+ goto step_3;
+ }
+ // b)
+ else if (g == gN)
+ {
+ A = N[g];
+ N[g].clear();
+ g = gN;
+ gN = compute_gN(N);
+ goto step_3;
+ }
+ // c)
+ else
+ {
+ mln_piter(box_<mln_point(I)>) p(R_box);
+ for_all(p)
+ if (is(p) == in_R)
+ u(p) = g;
+ goto step_1;
+ }
+ }
+
+ }
+
+ } // end of namespace mln::my
+
+} // end of namespace mln
+
+
+int main()
+{
+ using namespace mln;
+ using value::int_u8;
+
+ image2d<int_u8> lena;
+ io::pgm::load(lena, "../../img/tiny.pgm");
+
+ my::fllt(lena, c4());
+ io::pgm::save(lena, "./out.pgm");
+
+}
Index: sandbox/geraud/fllt.cc
--- sandbox/geraud/fllt.cc (revision 0)
+++ sandbox/geraud/fllt.cc (revision 0)
@@ -0,0 +1,301 @@
+// Copyright (C) 2008 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#include <mln/core/image2d.hh>
+#include <mln/core/neighb2d.hh>
+#include <mln/core/p_array.hh>
+#include <mln/core/clone.hh>
+#include <mln/core/image_if_value.hh>
+
+#include <mln/value/int_u8.hh>
+# include <mln/value/rgb8.hh>
+
+#include <mln/io/pgm/load.hh>
+#include <mln/io/pgm/save.hh>
+#include <mln/io/ppm/save.hh>
+
+#include <mln/level/fill.hh>
+#include <mln/debug/println.hh>
+#include <mln/labeling/regional_minima.hh>
+#include <mln/accu/bbox.hh>
+#include <mln/geom/bbox.hh>
+
+#include <mln/literal/black.hh>
+#include <mln/literal/white.hh>
+#include <mln/literal/colors.hh>
+
+#include <sstream>
+
+
+namespace mln
+{
+
+ namespace my
+ {
+
+ template <typename N_t, typename G>
+ void update_gN(const N_t& N, G& gN)
+ {
+ for (unsigned g = 0; g < 256; ++g)
+ if (N[g].npoints() != 0)
+ {
+ gN = g;
+ return;
+ }
+ // if N is empty, gN is the max value.
+ gN = 255;
+ }
+
+
+ template <typename N_t>
+ void print_N(const N_t& N)
+ {
+ for (unsigned i = 0; i < 256; ++i)
+ {
+ if (N[i].npoints() == 0)
+ continue;
+ std::cout << i << ": " << N[i] << std::endl;
+ }
+ }
+
+ template <typename N_t>
+ void clear_N(N_t& N)
+ {
+ for (unsigned i = 0; i < 256; ++i)
+ N[i].clear();
+ }
+
+
+
+ template <typename T>
+ image2d<T> enlarge(const image2d<T>& input, unsigned coef)
+ {
+ unsigned
+ nrows_ = coef * geom::nrows(input),
+ ncols_ = coef * geom::ncols(input);
+ image2d<T> output(nrows_, ncols_);
+ for (int row = 0; row < nrows_; ++row)
+ for (int col = 0; col < ncols_; ++col)
+ output.at(row, col) = input.at(row / coef, col / coef);
+ return output;
+ }
+
+
+ template <typename I>
+ void save(const I& is, const std::string& name = "")
+ {
+ static unsigned counter = 0;
+ using value::rgb8;
+
+ image2d<rgb8> temp(is.domain());
+ level::fill(temp, literal::black);
+
+ mln_piter(I) p(is.domain());
+ for_all(p)
+ switch (is(p)) {
+ case 1: // R
+ temp(p) = literal::red;
+ break;
+ case 2: // N
+ temp(p) = literal::green;
+ break;
+ case 3: // A
+ temp(p) = literal::blue;
+ break;
+ }
+
+ if (name == "")
+ {
+ std::stringstream filename;
+ filename << "./temp_" << ++counter << ".ppm";
+ io::ppm::save(my::enlarge(temp, 10), filename.str());
+ }
+ else
+ io::ppm::save(temp, name);
+ }
+
+
+ template <typename I, typename Nbh>
+ void fllt(const Image<I>& input_, const Neighborhood<Nbh>& nbh_)
+ {
+ const I& input = exact(input_);
+ const Nbh& nbh = exact(nbh_);
+
+ unsigned l = 0, l_max;
+ mln_ch_value(I, unsigned) reg_min = labeling::regional_minima(input, nbh, l_max);
+
+ // Variables.
+ I u = mln::clone(input);
+ mln_point(I) x0;
+ mln_value(I) g, gN;
+ image2d<unsigned char> is(input.domain());
+ const unsigned in_R = 1, in_N = 2, in_A = 3, in_O = 0;
+
+ typedef p_array<mln_point(I)> arr_t;
+ arr_t A, R;
+ R.reserve(input.npoints());
+ arr_t N[256];
+
+ accu::bbox<mln_point(I)> R_box;
+
+ unsigned n_step_1 = 0, n_step_3 = 0;
+
+ // Step 1.
+ step_1:
+ {
+ if (l == l_max)
+ goto the_end;
+
+ ++n_step_1;
+
+ l += 1;
+ mln_piter(I) p(input.domain());
+ for_all(p)
+ if (reg_min(p) == l)
+ break;
+ x0 = p;
+ g = input(x0);
+ }
+
+ // Step 2.
+ step_2:
+ {
+ level::fill(is, in_O);
+ // R <- 0
+ R_box.init();
+ R.clear();
+ // A <- { x0 }
+ A.clear();
+ A.append(x0);
+ is(x0) = in_A;
+ // N <- 0
+ clear_N(N);
+ }
+
+ // Step 3.
+ step_3:
+ {
+ ++n_step_3;
+
+ mln_piter(arr_t) a(A);
+ mln_niter(Nbh) x(nbh, a);
+
+
+ my::save(is);
+
+
+ // R <- R U A
+ if (A.npoints() == 0)
+ goto the_end;
+
+ R.append(A);
+ for_all(a)
+ {
+ mln_invariant(is(a) == in_A);
+ is(a) = in_R;
+ }
+ mln_invariant(R.npoints() == (is | in_R).npoints());
+ R_box.take(A.bbox());
+
+ // N <- N U { x in nbh of A and not in R }
+ for_all(a)
+ for_all(x)
+ if (u.has(x) && is(x) == in_O)
+ {
+ N[u(x)].append(x);
+ is(x) = in_N;
+ }
+ // gN = min u(x) for all x in N
+ update_gN(N, gN);
+
+ // FIXME: update the number of CC of the border of R
+ }
+
+ // Step 4.
+ step_4:
+ {
+ // a)
+ if (g < gN)
+ {
+ g = gN;
+ // FIXME: DO the hole thing.
+ A = N[g];
+ mln_piter(arr_t) a(A);
+ for_all(a)
+ {
+ mln_invariant(is(a) == in_N);
+ is(a) = in_A;
+ }
+ N[g].clear();
+ goto step_3;
+ }
+ // b)
+ else if (g == gN)
+ {
+ A = N[g];
+ mln_piter(arr_t) a(A);
+ for_all(a)
+ {
+ mln_invariant(is(a) == in_N);
+ is(a) = in_A;
+ }
+ N[g].clear();
+ goto step_3;
+ }
+ // c)
+ else
+ {
+ mln_invariant(R_box.to_result() == geom::bbox(is | in_R));
+ mln_piter(arr_t) r(R);
+ for_all(r)
+ u(r) = g;
+ goto step_1;
+ }
+ }
+
+ the_end:
+ std::cout << n_step_1 << ' ' << n_step_3 << std::endl;
+
+ }
+
+ } // end of namespace mln::my
+
+} // end of namespace mln
+
+
+int main()
+{
+ using namespace mln;
+ using value::int_u8;
+
+ image2d<int_u8> lena;
+ io::pgm::load(lena, "../../img/tiny.pgm");
+
+ my::fllt(lena, c4());
+ io::pgm::save(lena, "./out.pgm");
+
+}
1
0
URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena
ChangeLog:
2008-04-17 Caroline Vigouroux <vigour_c(a)epita.fr>
red getters.
* cmy/fun.hh, hsi/fun.hh, xyz/fun.hh, yiq/fun.hh, yuv/fun.hh:
red getters.
* cmy/my_cmy.hh, xyz/my_xyz.hh, yiq/my_yiq.hh, cmy/my_yuv.hh:
color space updated.
* cmy/rgb_to_cmy.hh, hsi/rgb_to_hsi.hh, xyz/rgb_to_xyz.hh,
yiq/rgb_to_yiq.hh, yuv/rgb_to_yuv.hh: conversion updated.
* cmy/test.cc, xyz/test.cc: .
* color/my_hsl.hh: .
* color/my_hsv.hh: .
* color/my_xyz.hh: .
* color/rgb_to_hsi.hh: .
* color/rgb_to_hsl.hh: .
* color/rgb_to_xyz.hh: .
* function.hh: .
* testfun.cc: .
* xyz/testfun.cc: New test.
* xyz: New folder.
* yuv/test.cc: .
---
cmy/fun.hh | 6 ++-
cmy/my_cmy.hh | 59 --------------------------------
cmy/rgb_to_cmy.hh | 6 +++
cmy/test.cc | 10 ++---
color/my_hsl.hh | 79 +++++++++++---------------------------------
color/my_hsv.hh | 65 +++---------------------------------
color/my_xyz.hh | 68 +++++++-------------------------------
color/rgb_to_hsi.hh | 3 -
color/rgb_to_hsl.hh | 41 ++++++++++++++++------
color/rgb_to_xyz.hh | 50 ++++++++++++++++++++-------
function.hh | 49 ---------------------------
hsi/fun.hh | 5 ++
hsi/rgb_to_hsi.hh | 6 ++-
testfun.cc | 8 ++--
xyz/fun.hh | 52 +++++++++++++++++++++++++++++
xyz/my_xyz.hh | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++++
xyz/rgb_to_xyz.hh | 76 ++++++++++++++++++++++++++++++++++++++++++
xyz/test.cc | 28 +++++++++++++++
xyz/testfun.cc | 31 +++++++++++++++++
yiq/fun.hh | 6 ++-
yiq/my_yiq.hh | 55 ------------------------------
yiq/rgb_to_yiq.hh | 6 ++-
yuv/fun.hh | 6 ++-
yuv/my_yuv.hh | 57 -------------------------------
yuv/rgb_to_yuv.hh | 5 ++
yuv/test.cc | 2 -
26 files changed, 437 insertions(+), 435 deletions(-)
Index: trunk/milena/sandbox/vigouroux/yuv/test.cc
===================================================================
--- trunk/milena/sandbox/vigouroux/yuv/test.cc (revision 1872)
+++ trunk/milena/sandbox/vigouroux/yuv/test.cc (revision 1873)
@@ -18,7 +18,7 @@
image2d<value::rgb8> lena;
io::ppm::load(lena, "../../../img/lena.ppm");
- image2d< value::yuv_<double, double, double> > lena_hsi
+ image2d< value::yuv_<float, float, float> > lena_hsi
= level::transform(lena,
fun::v2v::f_rgb_to_yuv_f());
Index: trunk/milena/sandbox/vigouroux/yuv/my_yuv.hh
===================================================================
--- trunk/milena/sandbox/vigouroux/yuv/my_yuv.hh (revision 1872)
+++ trunk/milena/sandbox/vigouroux/yuv/my_yuv.hh (revision 1873)
@@ -80,7 +80,7 @@
V v_;
};
- typedef yuv_<float, float, float> yuv_3x8;
+ typedef yuv_<float, float, float> yuv_f;
typedef yuv_<double, double, double> yuv_d;
@@ -88,59 +88,4 @@
} // end of namespace mln
-// template <unsigned n>
-// struct yuv
-// {
-// public:
-// /// Constructor without argument.
-// yuv<n>();
-
-// /// Constructor from component values.
-// yuv<n>(double y, double u, double v);
-
-// /// Access to component values.
-// double y() const { return this->y_; }
-// double u() const { return this->u_; }
-// double v() const { return this->v_; }
-
-// /// Set component values.
-// void y(double y)
-// {
-// this->y_ = y;
-// }
-// void u(double u)
-// {
-// this->u_ = u;
-// }
-// void v(double v)
-// {
-// mln_precondition(v >= 0);
-// this->v_ = v;
-// }
-
-// private:
-// double y_;
-// double u_;
-// double v_;
-// };
-
-// template <unsigned n>
-// inline
-// yuv<n>::yuv()
-// :y_(0), u_(0), v_(0)
-// {
-// }
-
-// template <unsigned n>
-// inline
-// yuv<n>::yuv(double y, double u, double v)
-// {
-// mln_precondition(v >= 0);
-// this->y_ = y;
-// this->u_ = u;
-// this->v_ = v;
-// }
-// }
-// }
-
#endif // ! MLN_VALUE_YUV_HH
Index: trunk/milena/sandbox/vigouroux/yuv/fun.hh
===================================================================
--- trunk/milena/sandbox/vigouroux/yuv/fun.hh (revision 1872)
+++ trunk/milena/sandbox/vigouroux/yuv/fun.hh (revision 1873)
@@ -1,4 +1,3 @@
-
#include <cmath>
#include <mln/core/image_if_value.hh>
@@ -12,7 +11,8 @@
#include "my_yuv.hh"
-
+#ifndef MLN_YUV_FUN_HH
+# define MLN_YUV_FUN_HH
namespace mln
{
@@ -54,3 +54,5 @@
} // end of namespace fun
} // end of namespace mln
+
+#endif // ! MLN_VALUE_YUV_HH
Index: trunk/milena/sandbox/vigouroux/yuv/rgb_to_yuv.hh
===================================================================
--- trunk/milena/sandbox/vigouroux/yuv/rgb_to_yuv.hh (revision 1872)
+++ trunk/milena/sandbox/vigouroux/yuv/rgb_to_yuv.hh (revision 1873)
@@ -12,6 +12,9 @@
#include "my_yuv.hh"
+#ifndef MLN_RGB_TO_YUV_HH
+# define MLN_RGB_TO_YUV_HH
+
namespace mln
{
@@ -39,6 +42,7 @@
};
typedef f_rgb_to_yuv_< mln::value::yuv_<double, double, double> > f_rgb_to_yuv_d;
+ typedef f_rgb_to_yuv_< mln::value::yuv_<float, float, float> > f_rgb_to_yuv_f;
template <typename T_rgb>
struct f_yuv_to_rgb_ : public Function_v2v< f_yuv_to_rgb_<T_rgb> >
@@ -72,3 +76,4 @@
} // end of namespace mln
+#endif // ! MLN_RGB_TO_YUV_HH
Index: trunk/milena/sandbox/vigouroux/hsi/fun.hh
===================================================================
--- trunk/milena/sandbox/vigouroux/hsi/fun.hh (revision 1872)
+++ trunk/milena/sandbox/vigouroux/hsi/fun.hh (revision 1873)
@@ -11,7 +11,8 @@
#include "../color/my_hsi.hh"
-
+#ifndef MLN_HSI_FUN_HH
+# define MLN_HSI_FUN_HH
namespace mln
{
@@ -62,3 +63,5 @@
} // end of namespace fun
} // end of namespace mln
+
+#endif // ! MLN_HSI_FUN_HH
Index: trunk/milena/sandbox/vigouroux/hsi/rgb_to_hsi.hh
===================================================================
--- trunk/milena/sandbox/vigouroux/hsi/rgb_to_hsi.hh (revision 1872)
+++ trunk/milena/sandbox/vigouroux/hsi/rgb_to_hsi.hh (revision 1873)
@@ -1,4 +1,3 @@
-
#include <cmath>
#include <mln/core/image_if_value.hh>
@@ -12,7 +11,8 @@
#include "my_hsi.hh"
-
+#ifndef MLN_RGB_TO_HSI_HH
+# define MLN_RGB_TO_HSI_HH
namespace mln
{
@@ -106,3 +106,5 @@
} // end of namespace fun
} // end of namespace mln
+
+#endif // ! MLN_RGB_TO_HSI_HH
Index: trunk/milena/sandbox/vigouroux/function.hh
===================================================================
--- trunk/milena/sandbox/vigouroux/function.hh (revision 1872)
+++ trunk/milena/sandbox/vigouroux/function.hh (revision 1873)
@@ -1,4 +1,3 @@
-
#include <mln/core/image_if_value.hh>
#include <mln/core/inplace.hh>
#include <mln/core/w_window2d_int.hh>
@@ -47,7 +46,7 @@
// r = mln::fun::v2v::f_cmy_3x8(col);
// std::cout << "cmy" << std::endl;
// }
-// else if (mlc_is_a(T_col, mln::value::YUV)::value == 1)
+// if (mlc_is_a(T_col, mln::value::YUV)::value == 1)
// {
// r = mln::fun::v2v::f_yuv_3x8(col);
// std::cout << "yuv" << std::endl;
@@ -66,52 +65,6 @@
}
};
-// typedef f_rgb_to_hsi_<value::hsi_f> f_r// gb_to_hsi_f_t;
-
-// f_rgb_to_hsi_f_t f_rgb_to_hsi_f;
-
-
-// template <typename T_rgb>
-// struct f_hsi_to_rgb_ : public Function_v2v< f_hsi_to_rgb_<T_rgb> >
-// {
-// typedef T_rgb result;
-
-// template <typename T_hsi>
-// T_rgb operator()(const T_hsi& hsi) const
-// {
-// typedef typename T_rgb::red_t red_t;
-// typedef typename T_rgb::green_t green_t;
-// typedef typename T_rgb::blue_t blue_t;
-
-// static math::round<red_t> to_r;
-// static math::round<green_t> to_g;
-// static math::round<blue_t> to_b;
-
-// static const float
-// sqrt3_3 = std::sqrt(3) / 3,
-// inv_sqrt6 = 1 / std::sqrt(6),
-// inv_sqrt2 = 1 / std::sqrt(2);
-
-// float
-// h = hsi.hue() / 180.0 * 3.1415,
-// alpha = hsi.sat() * std::cos(h),
-// beta = hsi.sat() * std::sin(h);
-
-
-// red_t r = sqrt3_3 * hsi.inty() + 2 * inv_sqrt6 * beta;
-// green_t g = sqrt3_3 * hsi.inty() + inv_sqrt2 * alpha - inv_sqrt6 * beta;
-// blue_t b = sqrt3_3 * hsi.inty() - inv_sqrt2 * alpha - inv_sqrt6 * beta;
-
-// T_rgb rgb(r, g, b);
-
-// return rgb;
-// }
-// };
-
-// typedef f_hsi_to_rgb_<value::rgb8> f_hsi_to_rgb_3x8_t;
-
-// f_hsi_to_rgb_3x8_t f_hsi_to_rgb_3x8;
-
} // end of namespace fun::v2v
} // end of namespace fun
Index: trunk/milena/sandbox/vigouroux/cmy/rgb_to_cmy.hh
===================================================================
--- trunk/milena/sandbox/vigouroux/cmy/rgb_to_cmy.hh (revision 1872)
+++ trunk/milena/sandbox/vigouroux/cmy/rgb_to_cmy.hh (revision 1873)
@@ -12,6 +12,9 @@
#include "my_cmy.hh"
+#ifndef MLN_RGB_TO_CMY_HH
+# define MLN_RGB_TO_CMY_HH
+
namespace mln
{
@@ -39,6 +42,7 @@
};
typedef f_rgb_to_cmy_< mln::value::cmy_<double, double, double> > f_rgb_to_cmy_d;
+ typedef f_rgb_to_cmy_< mln::value::cmy_<float, float, float> > f_rgb_to_cmy_f;
template <typename T_rgb>
struct f_cmy_to_rgb_ : public Function_v2v< f_cmy_to_rgb_<T_rgb> >
@@ -70,3 +74,5 @@
} // end of namespace fun
} // end of namespace mln
+
+#endif // ! MLN_RGB_TO_CMY_HH
Index: trunk/milena/sandbox/vigouroux/cmy/test.cc
===================================================================
--- trunk/milena/sandbox/vigouroux/cmy/test.cc (revision 1872)
+++ trunk/milena/sandbox/vigouroux/cmy/test.cc (revision 1873)
@@ -1,5 +1,5 @@
-#include "my_yiq.hh"
-#include "rgb_to_yiq.hh"
+#include "my_cmy.hh"
+#include "rgb_to_cmy.hh"
#include <cmath>
@@ -18,11 +18,11 @@
image2d<value::rgb8> lena;
io::ppm::load(lena, "../../../img/lena.ppm");
- image2d< value::yiq_<double, double, double> > lena_hsi
+ image2d< value::cmy_<float, float, float> > lena_hsi
= level::transform(lena,
- fun::v2v::f_rgb_to_yiq_d());
+ fun::v2v::f_rgb_to_cmy_f());
image2d<value::rgb8> lena_rgb = level::transform(lena_hsi,
- fun::v2v::f_yiq_to_rgb_3x8);
+ fun::v2v::f_cmy_to_rgb_3x8);
}
Index: trunk/milena/sandbox/vigouroux/cmy/fun.hh
===================================================================
--- trunk/milena/sandbox/vigouroux/cmy/fun.hh (revision 1872)
+++ trunk/milena/sandbox/vigouroux/cmy/fun.hh (revision 1873)
@@ -1,4 +1,3 @@
-
#include <cmath>
#include <mln/core/image_if_value.hh>
@@ -12,7 +11,8 @@
#include "my_cmy.hh"
-
+#ifndef MLN_CMY_FUN_HH
+# define MLN_CMY_FUN_HH
namespace mln
{
@@ -50,3 +50,5 @@
} // end of namespace fun
} // end of namespace mln
+
+#endif // ! MLN_CMY_FUN_HH
Index: trunk/milena/sandbox/vigouroux/cmy/my_cmy.hh
===================================================================
--- trunk/milena/sandbox/vigouroux/cmy/my_cmy.hh (revision 1872)
+++ trunk/milena/sandbox/vigouroux/cmy/my_cmy.hh (revision 1873)
@@ -80,68 +80,11 @@
Y yellow_;
};
- typedef cmy_<float, float, float> cmy_3x8;
+ typedef cmy_<float, float, float> cmy_f;
typedef cmy_<double, double, double> cmy_d;
} // end of namespace mln::value
} // end of namespace mln
-// template <unsigned n>
-// struct cmy
-// {
-// public:
-// /// Constructor without argument.
-// cmy();
-
-// /// Constructor from component values.
-// cmy(double c, double m, double y);
-
-// /// Access to component values.
-// double c() const { return this->c_; }
-// double m() const { return this->m_; }
-// double y() const { return this->y_; }
-
-// /// Set component values.
-// void c(double c)
-// {
-// mln_precondition(c >= 0);
-// this->c_ = c;
-// }
-// void m(double m)
-// {
-// mln_precondition(m >= 0);
-// this->m_ = m;
-// }
-// void y(double y)
-// {
-// mln_precondition(y >= 0);
-// this->y_ = y;
-// }
-
-// private:
-// double c_;
-// double m_;
-// double y_;
-// };
-
-// template <unsigned n>
-// inline
-// cmy<n>::cmy()
-// :c_(0), m_(0), y_(0)
-// {
-// }
-
-// template <unsigned n>
-// inline
-// cmy<n>::cmy(double c, double m, double y)
-// {
-// mln_precondition(c >= 0);
-// mln_precondition(m >= 0);
-// mln_precondition(y >= 0);
-// this->c_ = c;
-// this->m_ = m;
-// this->y_ = y;
-// }
-
#endif // ! MLN_VALUE_CMY_HH
Index: trunk/milena/sandbox/vigouroux/xyz/test.cc
===================================================================
--- trunk/milena/sandbox/vigouroux/xyz/test.cc (revision 0)
+++ trunk/milena/sandbox/vigouroux/xyz/test.cc (revision 1873)
@@ -0,0 +1,28 @@
+#include "my_xyz.hh"
+#include "rgb_to_xyz.hh"
+
+#include <cmath>
+
+#include <mln/core/image2d.hh>
+#include <mln/value/rgb.hh>
+
+#include <mln/io/ppm/load.hh>
+#include <mln/io/ppm/save.hh>
+#include <mln/math/round.hh>
+#include <mln/level/transform.hh>
+
+int main()
+{
+ using namespace mln;
+
+ image2d<value::rgb8> lena;
+ io::ppm::load(lena, "../../../img/lena.ppm");
+
+ image2d< value::xyz_<float, float, float> > lena_hsi
+ = level::transform(lena,
+ fun::v2v::f_rgb_to_xyz_f_t());
+
+// image2d<value::rgb8> lena_rgb = level::transform(lena_hsi,
+// fun::v2v::f_xyz_to_rgb_3x8);
+}
+
Index: trunk/milena/sandbox/vigouroux/xyz/rgb_to_xyz.hh
===================================================================
--- trunk/milena/sandbox/vigouroux/xyz/rgb_to_xyz.hh (revision 0)
+++ trunk/milena/sandbox/vigouroux/xyz/rgb_to_xyz.hh (revision 1873)
@@ -0,0 +1,76 @@
+#ifndef OLENA_CONVERT_RGBXYZ_HH
+# define OLENA_CONVERT_RGBXYZ_HH
+
+# include <mln/core/image_if_value.hh>
+# include <mln/core/inplace.hh>
+# include <mln/core/w_window2d_int.hh>
+# include <mln/display/show.hh>
+# include <mln/io/ppm/save.hh>
+# include <mln/display/save_and_show.hh>
+# include <mln/level/fill.hh>
+
+# include "my_xyz.hh"
+
+namespace mln
+{
+
+ namespace fun
+ {
+
+ namespace v2v
+ {
+ template <typename T_xyz>
+ struct f_rgb_to_xyz_ : public Function_v2v< f_rgb_to_xyz_<T_xyz> >
+ {
+ typedef T_xyz result;
+
+ template <typename T_rgb>
+ T_xyz operator()(const T_rgb& rgb) const
+ {
+ T_xyz xyz;
+
+ xyz.x() = 0.490 * rgb.red() + 0.310 * rgb.green() + 0.200 * rgb.blue();
+ xyz.y() = 0.177 * rgb.red() + 0.812 * rgb.green() + 0.011 * rgb.blue();
+ xyz.z() = 0.010 * rgb.green() + 0.990 * rgb.blue();
+
+ return xyz;
+ }
+ };
+
+ typedef f_rgb_to_xyz_<value::xyz_f> f_rgb_to_xyz_f_t;
+
+// f_rgb_to_xyz_f_t f_rgb_to_xyz_f;
+
+ template <typename T_rgb>
+ struct f_xyz_to_rgb_ : public Function_v2v< f_xyz_to_rgb_<T_rgb> >
+ {
+ typedef T_rgb result;
+
+ template <typename T_xyz>
+ T_rgb operator()(const T_xyz& xyz) const
+ {
+ int r;
+ int g;
+ int b;
+
+ r = int(2.365 * xyz.x() - 0.896 * xyz.y() - 0.468 * xyz.z());
+ g = int(-0.515 * xyz.x() + 1.425 * xyz.y() + 0.089 * xyz.z());
+ b = int(0.005 * xyz.x() - 0.014 * xyz.y() + 1.01 * xyz.z());
+
+ struct value::rgb<8> rgb(r, g, b);
+
+ return rgb;
+ }
+ };
+
+ typedef f_xyz_to_rgb_<value::rgb8> f_xyz_to_rgb_3x8_t;
+
+ f_xyz_to_rgb_3x8_t f_xyz_to_rgb_3x8;
+
+ } // end of namespace fun::v2v
+
+ } // end of namespace fun
+
+} // end of namespace mln
+
+#endif // OLENA_CONVERT_RGBXYZ_HH
Index: trunk/milena/sandbox/vigouroux/xyz/fun.hh
===================================================================
--- trunk/milena/sandbox/vigouroux/xyz/fun.hh (revision 0)
+++ trunk/milena/sandbox/vigouroux/xyz/fun.hh (revision 1873)
@@ -0,0 +1,52 @@
+#include <cmath>
+
+#include <mln/core/image_if_value.hh>
+#include <mln/core/inplace.hh>
+#include <mln/core/w_window2d_int.hh>
+#include <mln/display/show.hh>
+#include <mln/io/ppm/save.hh>
+#include <mln/display/save_and_show.hh>
+#include <mln/level/fill.hh>
+#include <mln/math/round.hh>
+
+#include "my_xyz.hh"
+
+#ifndef MLN_XYZ_FUN_HH
+# define MLN_XYZ_FUN_HH
+
+namespace mln
+{
+
+
+ namespace fun
+ {
+
+ namespace v2v
+ {
+ template <typename T_rgb>
+ struct f_xyz_ : public Function_v2v< f_xyz_<T_rgb> >
+ {
+ typedef T_rgb result;
+
+ template <typename T_xyz>
+ T_rgb operator()(const T_xyz& xyz) const
+ {
+ int r;
+
+ r = int(xyz.y() + 1.13983 * xyz.y());
+
+ struct value::rgb<8> rgb(r, 0, 0);
+
+ return rgb;
+ }
+ };
+
+ typedef f_xyz_<value::rgb8> f_xyz_get_red;
+
+ } // end of namespace fun::v2v
+
+ } // end of namespace fun
+
+} // end of namespace mln
+
+#endif // ! MLN_VALUE_XYZ_HH
Index: trunk/milena/sandbox/vigouroux/xyz/testfun.cc
===================================================================
--- trunk/milena/sandbox/vigouroux/xyz/testfun.cc (revision 0)
+++ trunk/milena/sandbox/vigouroux/xyz/testfun.cc (revision 1873)
@@ -0,0 +1,31 @@
+#include "my_xyz.hh"
+#include "rgb_to_xyz.hh"
+
+#include <cmath>
+
+#include <mln/core/image2d.hh>
+#include <mln/value/rgb.hh>
+
+#include <mln/io/ppm/load.hh>
+#include <mln/io/ppm/save.hh>
+#include <mln/math/round.hh>
+#include <mln/level/transform.hh>
+
+#include "rgb_to_xyz.hh"
+#include "fun.hh"
+
+int main()
+{
+// typedef mln::value::xyz_d Col;
+ using namespace mln::fun::v2v;
+
+ mln::value::xyz_d col;
+ mln::image2d<mln::value::rgb8> lena;
+ mln::io::ppm::load(lena, "../../../img/lena.ppm");
+
+ mln::image2d<mln::value::xyz_f> lena_xyz = mln::level::transform(lena,
+ mln::fun::v2v::f_rgb_to_xyz_f_t());
+
+ mln::image2d<mln::value::rgb8> lena_rgb = mln::level::transform(lena_xyz,
+ f_xyz_get_red ());
+}
Index: trunk/milena/sandbox/vigouroux/xyz/my_xyz.hh
===================================================================
--- trunk/milena/sandbox/vigouroux/xyz/my_xyz.hh (revision 0)
+++ trunk/milena/sandbox/vigouroux/xyz/my_xyz.hh (revision 1873)
@@ -0,0 +1,93 @@
+#include <mln/value/ops.hh>
+
+#include <mln/value/concept/vectorial.hh>
+#include <mln/value/int_u.hh>
+#include <mln/algebra/vec.hh>
+
+#include <mln/value/float01_8.hh>
+
+#ifndef MLN_VALUE_XYZ_HH
+# define MLN_VALUE_XYZ_HH
+
+namespace mln
+{
+ namespace value
+ {
+
+ template <typename E>
+ struct XYZ
+ :
+ public internal::value_like_< algebra::vec< 3, float01_8 >, // Equivalent.
+ algebra::vec< 3, float01_8 >, // Encoding.
+ algebra::vec< 3, float01_8 >, // Interoperation.
+ XYZ<E> >
+ {
+ };
+
+ template <typename X, typename Y, typename Z>
+ class xyz_ : public XYZ< xyz_<X,Y,Z> >
+ {
+ public:
+
+ typedef X x_type;
+ typedef Y y_type;
+ typedef Z z_type;
+
+ /// Constructor without argument.
+ xyz_()
+ {
+ }
+
+ /// Constructor from component values.
+ xyz_(const X& x, const Y& y, const Z& z)
+ : x_(x),
+ y_(y),
+ z_(z)
+ {
+ }
+
+ /// Read-only access to the x component.
+ const X& x() const
+ {
+ return this->x_;
+ }
+ const Y& y() const
+ {
+ return this->y_;
+ }
+ const Z& z() const
+ {
+ return this->z_;
+ }
+
+ /// Read-write access to the x component.
+ X& x()
+ {
+ return this->x_;
+ }
+ Y& y()
+ {
+ return this->y_;
+ }
+ Z& z()
+ {
+ return this->z_;
+ }
+
+ private:
+ X x_;
+ Y y_;
+ Z z_;
+ };
+
+ typedef xyz_<float, float, float> xyz_f;
+
+ typedef xyz_<double, double, double> xyz_d;
+
+ } // end of namespace mln::value
+
+} // end of namespace mln
+
+
+
+#endif // ! MLN_VALUE_XYZ_HH
Index: trunk/milena/sandbox/vigouroux/yiq/my_yiq.hh
===================================================================
--- trunk/milena/sandbox/vigouroux/yiq/my_yiq.hh (revision 1872)
+++ trunk/milena/sandbox/vigouroux/yiq/my_yiq.hh (revision 1873)
@@ -88,59 +88,4 @@
} // end of namespace mln
-// template <unsigned n>
-// struct yiq
-// {
-// public:
-// /// Constructor without argument.
-// yiq<n>();
-
-// /// Constructor from component values.
-// yiq<n>(double y, double i, double q);
-
-// /// Access to component values.
-// double y() const { return this->y_; }
-// double i() const { return this->i_; }
-// double q() const { return this->q_; }
-
-// /// Set component values.
-// void y(double y)
-// {
-// this->y_ = y;
-// }
-// void i(double i)
-// {
-// this->i_ = i;
-// }
-// void q(double q)
-// {
-// mln_precondition(q >= 0);
-// this->q_ = q;
-// }
-
-// private:
-// double y_;
-// double i_;
-// double q_;
-// };
-
-// template <unsigned n>
-// inline
-// yiq<n>::yiq()
-// :y_(0), i_(0), q_(0)
-// {
-// }
-
-// template <unsigned n>
-// inline
-// yiq<n>::yiq(double y, double i, double q)
-// {
-// mln_precondition(q >= 0);
-// this->y_ = y;
-// this->i_ = i;
-// this->q_ = q;
-// }
-// }
-// }
-
#endif // ! MLN_VALUE_YIQ_HH
Index: trunk/milena/sandbox/vigouroux/yiq/fun.hh
===================================================================
--- trunk/milena/sandbox/vigouroux/yiq/fun.hh (revision 1872)
+++ trunk/milena/sandbox/vigouroux/yiq/fun.hh (revision 1873)
@@ -1,4 +1,3 @@
-
#include <cmath>
#include <mln/core/image_if_value.hh>
@@ -12,7 +11,8 @@
#include "my_yiq.hh"
-
+#ifndef MLN_YIQ_FUN_HH
+# define MLN_YIQ_FUN_HH
namespace mln
{
@@ -50,3 +50,5 @@
} // end of namespace fun
} // end of namespace mln
+
+#endif // ! MLN_YIQ_FUN_HH
Index: trunk/milena/sandbox/vigouroux/yiq/rgb_to_yiq.hh
===================================================================
--- trunk/milena/sandbox/vigouroux/yiq/rgb_to_yiq.hh (revision 1872)
+++ trunk/milena/sandbox/vigouroux/yiq/rgb_to_yiq.hh (revision 1873)
@@ -12,6 +12,9 @@
#include "my_yiq.hh"
+#ifndef MLN_RGB_TO_YIQ_HH
+# define MLN_RGB_TO_YIQ_HH
+
namespace mln
{
@@ -72,5 +75,4 @@
} // end of namespace mln
-
-
+#endif // ! MLN_RGB_TO_YIQ_HH
Index: trunk/milena/sandbox/vigouroux/testfun.cc
===================================================================
--- trunk/milena/sandbox/vigouroux/testfun.cc (revision 1872)
+++ trunk/milena/sandbox/vigouroux/testfun.cc (revision 1873)
@@ -12,18 +12,20 @@
#include <mln/level/transform.hh>
#include "function.hh"
+#include "yuv/my_yuv.hh"
+#include "yuv/fun.hh"
+#include "yuv/rgb_to_yuv.hh"
int main()
{
-// typedef mln::value::hsi_d Col;
using namespace mln::fun::v2v;
mln::value::hsi_d col;
mln::image2d<mln::value::rgb8> lena;
mln::io::ppm::load(lena, "../../img/lena.ppm");
- mln::image2d<mln::value::hsi_f> lena_hsi = mln::level::transform(lena,
- mln::fun::v2v::f_rgb_to_hsi_f);
+ mln::image2d<mln::value::yuv_f> lena_hsi = mln::level::transform(lena,
+ mln::fun::v2v::f_rgb_to_yuv_f());
mln::image2d<mln::value::rgb8> lena_rgb = mln::level::transform(lena_hsi,
f_get_red_<mln::value::rgb8>());
Index: trunk/milena/sandbox/vigouroux/color/rgb_to_hsl.hh
===================================================================
--- trunk/milena/sandbox/vigouroux/color/rgb_to_hsl.hh (revision 1872)
+++ trunk/milena/sandbox/vigouroux/color/rgb_to_hsl.hh (revision 1873)
@@ -11,14 +11,23 @@
# include "my_hsl.hh"
-namespace mln {
- namespace convert {
- struct f_rgb_to_hsl
+namespace mln
{
- struct value::hsl<8>
- doit(const struct value::rgb<8> rgb) const
+
+ namespace fun
+ {
+
+ namespace v2v
+ {
+ template <typename T_hsl>
+ struct f_rgb_to_hsl_ : public Function_v2v< f_rgb_to_hsl_<T_hsl> >
+ {
+ typedef T_hsl result;
+
+ template <typename T_rgb>
+ T_hsl operator()(const T_rgb& rgb) const
{
- struct value::hsl<8> hsl;
+ T_hsl hsl;
double max_in = std::max(rgb.red(), std::max(rgb.blue(), rgb.green()));
double min_in = std::min(rgb.red(), std::min(rgb.blue(), rgb.green()));
@@ -29,16 +38,23 @@
hsl.s();
hsl.l();
- return (hsl);
+ return hsl;
}
};
- struct f_hsl_to_rgb
+ typedef f_rgb_to_hsl_<value::hsl_f> f_rgb_to_hsl_f_t;
+
+ f_rgb_to_hsl_f_t f_rgb_to_hsl_f;
+
+ template <typename T_rgb>
+ struct f_hsl_to_rgb_ : public Function_v2v< f_hsl_to_rgb_<T_rgb> >
{
- struct value::rgb<8>
- doit(const struct value::hsl<8> hsl) const
+ typedef T_rgb result;
+
+ template <typename T_hsl>
+ T_rgb operator()(const T_hsl& hsl) const
{
- struct value::rgb<8> rgb;
+ T_rgb rgb;
int r;
int g;
int b;
@@ -56,10 +72,11 @@
struct value::rgb<8> rgb(r, g, b);
- return (rgb);
+ return rgb;
}
};
}
}
+}
#endif // OLENA_CONVERT_RGBHSL_HH
Index: trunk/milena/sandbox/vigouroux/color/rgb_to_xyz.hh
===================================================================
--- trunk/milena/sandbox/vigouroux/color/rgb_to_xyz.hh (revision 1872)
+++ trunk/milena/sandbox/vigouroux/color/rgb_to_xyz.hh (revision 1873)
@@ -11,27 +11,43 @@
# include "my_xyz.hh"
-namespace mln {
- namespace convert {
- struct f_rgb_to_xyz
+namespace mln
{
- struct value::xyz<8>
- doit(const struct value::rgb<8> rgb) const
+
+ namespace fun
+ {
+
+ namespace v2v
+ {
+ template <typename T_xyz>
+ struct f_rgb_to_xyz_ : public Function_v2v< f_rgb_to_xyz_<T_xyz> >
{
- struct value::xyz<8> xyz;
+ typedef T_xyz result;
+
+ template <typename T_rgb>
+ T_xyz operator()(const T_rgb& rgb) const
+ {
+ T_xyz xyz;
xyz.x(0.490 * rgb.red() + 0.310 * rgb.green() + 0.200 * rgb.blue());
xyz.y(0.177 * rgb.red() + 0.812 * rgb.green() + 0.011 * rgb.blue());
xyz.z(0.010 * rgb.green() + 0.990 * rgb.blue());
- return (xyz);
+ return xyz;
}
};
- struct f_xyz_to_rgb
+ typedef f_rgb_to_xyz_<value::xyz_f> f_rgb_to_xyz_f_t;
+
+ f_rgb_to_xyz_f_t f_rgb_to_xyz_f;
+
+ template <typename T_rgb>
+ struct f_xyz_to_rgb_ : public Function_v2v< f_xyz_to_rgb_<T_rgb> >
{
- struct value::rgb<8>
- doit(const struct value::xyz<8> xyz) const
+ typedef T_rgb result;
+
+ template <typename T_xyz>
+ T_rgb operator()(const T_xyz& xyz) const
{
int r;
int g;
@@ -43,10 +59,18 @@
struct value::rgb<8> rgb(r, g, b);
- return (rgb);
+ return rgb;
}
};
- }
-}
+
+ typedef f_xyz_to_rgb_<value::rgb8> f_xyz_to_rgb_3x8_t;
+
+ f_xyz_to_rgb_3x8_t f_xyz_to_rgb_3x8;
+
+ } // end of namespace fun::v2v
+
+ } // end of namespace fun
+
+} // end of namespace mln
#endif // OLENA_CONVERT_RGBXYZ_HH
Index: trunk/milena/sandbox/vigouroux/color/my_hsl.hh
===================================================================
--- trunk/milena/sandbox/vigouroux/color/my_hsl.hh (revision 1872)
+++ trunk/milena/sandbox/vigouroux/color/my_hsl.hh (revision 1873)
@@ -9,11 +9,17 @@
namespace mln
{
+
namespace value
{
template <typename E>
struct HSL
+ :
+ public internal::value_like_< algebra::vec< 3, float01_8 >, // Equivalent.
+ algebra::vec< 3, float01_8 >, // Encoding.
+ algebra::vec< 3, float01_8 >, // Interoperation.
+ HSL<E> >
{
};
@@ -53,13 +59,27 @@
return this->light_;
}
+ /// Read-write access to the hue component.
+ H& hue()
+ {
+ return this->hue_;
+ }
+ S& sat()
+ {
+ return this->sat_;
+ }
+ L& light()
+ {
+ return this->light_;
+ }
+
private:
H hue_;
S sat_;
L light_;
};
- typedef hsl_<float, float, float> hsl_3x8;
+ typedef hsl_<float, float, float> hsl_f;
typedef hsl_<double, double, double> hsl_d;
@@ -67,61 +87,4 @@
} // end of namespace mln
-// template <unsigned n>
-// struct hsl
-// {
-// public:
-// /// Constructor without argument.
-// hsl<n>();
-
-// /// Constructor from component values.
-// hsl<n>(int h, int s, int l);
-
-// /// Access to component values.
-// double h() const { return this->h_; }
-// double s() const { return this->s_; }
-// double l() const { return this->l_; }
-
-// /// Set component values.
-// void h(double h)
-// {
-// this->h_ = h;
-// }
-// void s(double s)
-// {
-// this->s_ = s;
-// }
-// void l(double l)
-// {
-// mln_precondition(l >= 0);
-// this->l_ = l;
-// }
-
-// private:
-// double h_;
-// double s_;
-// double l_;
-// };
-
-// template <unsigned n>
-// inline
-// hsl<n>::hsl()
-// :h_(0), s_(0), l_(0)
-// {
-// }
-
-// template <unsigned n>
-// inline
-// hsl<n>::hsl(int h, int s, int l)
-// {
-// mln_precondition(h >= 0);
-// mln_precondition(s >= 0);
-// mln_precondition(l >= 0);
-// this->h_ = h;
-// this->s_ = s;
-// this->l_ = l;
-// }
-// }
-// }
-
#endif // ! MLN_VALUE_HSL_HH
Index: trunk/milena/sandbox/vigouroux/color/my_xyz.hh
===================================================================
--- trunk/milena/sandbox/vigouroux/color/my_xyz.hh (revision 1872)
+++ trunk/milena/sandbox/vigouroux/color/my_xyz.hh (revision 1873)
@@ -1,3 +1,11 @@
+#include <mln/value/ops.hh>
+
+#include <mln/value/concept/vectorial.hh>
+#include <mln/value/int_u.hh>
+#include <mln/algebra/vec.hh>
+
+#include <mln/value/float01_8.hh>
+
#ifndef MLN_VALUE_XYZ_HH
# define MLN_VALUE_XYZ_HH
@@ -8,6 +16,11 @@
template <typename E>
struct XYZ
+ :
+ public internal::value_like_< algebra::vec< 3, float01_8 >, // Equivalent.
+ algebra::vec< 3, float01_8 >, // Encoding.
+ algebra::vec< 3, float01_8 >, // Interoperation.
+ XYZ<E> >
{
};
@@ -75,59 +88,6 @@
} // end of namespace mln
-// template <unsigned n>
-// struct xyz
-// {
-// public:
-// /// Constructor without argument.
-// xyz<n>();
-
-// /// Constructor from component values.
-// xyz<n>(double x, double y, double z);
-
-// /// Access to component values.
-// double x() const { return this->x_; }
-// double y() const { return this->y_; }
-// double z() const { return this->z_; }
-
-// /// Set component values.
-// void x(double x)
-// {
-// this->x_ = x;
-// }
-// void y(double y)
-// {
-// this->y_ = y;
-// }
-// void z(double z)
-// {
-// mln_precondition(z >= 0);
-// this->z_ = z;
-// }
-
-// private:
-// double x_;
-// double y_;
-// double z_;
-// };
-
-// template <unsigned n>
-// inline
-// xyz<n>::xyz()
-// :x_(0), y_(0), z_(0)
-// {
-// }
-
-// template <unsigned n>
-// inline
-// xyz<n>::xyz(double x, double y, double z)
-// {
-// mln_precondition(z >= 0);
-// this->x_ = x;
-// this->y_ = y;
-// this->z_ = z;
-// }
-// }
-// }
+
#endif // ! MLN_VALUE_XYZ_HH
Index: trunk/milena/sandbox/vigouroux/color/my_hsv.hh
===================================================================
--- trunk/milena/sandbox/vigouroux/color/my_hsv.hh (revision 1872)
+++ trunk/milena/sandbox/vigouroux/color/my_hsv.hh (revision 1873)
@@ -9,11 +9,17 @@
namespace mln
{
+
namespace value
{
template <typename E>
struct HSV
+ :
+ public internal::value_like_< algebra::vec< 3, float01_8 >, // Equivalent.
+ algebra::vec< 3, float01_8 >, // Encoding.
+ algebra::vec< 3, float01_8 >, // Interoperation.
+ HSV<E> >
{
};
@@ -73,7 +79,7 @@
V value_;
};
- typedef hsv_<float, float, float> hsv_3x8;
+ typedef hsv_<float, float, float> hsv_f;
typedef hsv_<double, double, double> hsv_d;
@@ -81,61 +87,4 @@
} // end of namespace mln
-// template <unsigned n>
-// struct hsv
-// {
-// public:
-// /// Constructor without argument.
-// hsv<n>();
-
-// /// Constructor from component values.
-// hsv<n>(int h, int s, int v);
-
-// /// Access to component values.
-// double h() const { return this->h_; }
-// double s() const { return this->s_; }
-// double v() const { return this->v_; }
-
-// /// Set component values.
-// void h(double h)
-// {
-// this->h_ = h;
-// }
-// void s(double s)
-// {
-// this->s_ = s;
-// }
-// void v(double v)
-// {
-// mln_precondition(v >= 0);
-// this->v_ = v;
-// }
-
-// private:
-// double h_;
-// double s_;
-// double v_;
-// };
-
-// template <unsigned n>
-// inline
-// hsi<n>::hsv()
-// :h_(0), s_(0), v_(0)
-// {
-// }
-
-// template <unsigned n>
-// inline
-// hsv<n>::hsv(int h, int s, int v)
-// {
-// mln_precondition(h >= 0);
-// mln_precondition(s >= 0);
-// mln_precondition(v >= 0);
-// this->h_ = h;
-// this->s_ = s;
-// this->v_ = v;
-// }
-// }
-// }
-
#endif // ! MLN_VALUE_HSV_HH
Index: trunk/milena/sandbox/vigouroux/color/rgb_to_hsi.hh
===================================================================
--- trunk/milena/sandbox/vigouroux/color/rgb_to_hsi.hh (revision 1872)
+++ trunk/milena/sandbox/vigouroux/color/rgb_to_hsi.hh (revision 1873)
@@ -12,12 +12,9 @@
#include "my_hsi.hh"
-
-
namespace mln
{
-
namespace fun
{
1
0
Re: [Olena-patches] [Olena] #7: Miscellaneous tasks related to the Olena 1.0 release process
by Olena 17 Apr '08
by Olena 17 Apr '08
17 Apr '08
#7: Miscellaneous tasks related to the Olena 1.0 release process
-----------------------+----------------------------------------------------
Reporter: levill_r | Owner: levill_r
Type: task | Status: new
Priority: trivial | Milestone: Olena 1.0
Component: other | Version: 1.0
Resolution: | Keywords: release NEWS dates copyright headers
-----------------------+----------------------------------------------------
Changes (by levill_r):
* summary: Miscellaneous tasks related to the Olena 1.0ß release process
=> Miscellaneous tasks related to the Olena 1.0
release process
--
Ticket URL: <https://trac.lrde.org/olena/ticket/7#comment:7>
Olena <http://olena.lrde.epita.fr>
Olena, a generic and efficient C++ image processing library.
1
0
#114: Add support for libfitsio
-----------------------+----------------------------------------------------
Reporter: levill_r | Owner: Olena Team
Type: task | Status: new
Priority: major | Milestone: Olena 1.1
Component: Milena | Version: 1.0
Resolution: | Keywords: autoconf m4 macro
-----------------------+----------------------------------------------------
Changes (by levill_r):
* owner: levill_r => Olena Team
--
Ticket URL: <https://trac.lrde.org/olena/ticket/114#comment:4>
Olena <http://olena.lrde.epita.fr>
Olena, a generic and efficient C++ image processing library.
1
0
#114: Add support for libfitsio
-----------------------+----------------------------------------------------
Reporter: levill_r | Owner: levill_r
Type: task | Status: new
Priority: major | Milestone: Olena 1.1
Component: Milena | Version: 1.0
Resolution: | Keywords: autoconf m4 macro
-----------------------+----------------------------------------------------
Changes (by levill_r):
* milestone: Olena 1.0 => Olena 1.1
Comment:
Move this task to milestone:"Olena 1.1".
--
Ticket URL: <https://trac.lrde.org/olena/ticket/114#comment:3>
Olena <http://olena.lrde.epita.fr>
Olena, a generic and efficient C++ image processing library.
1
0
17 Apr '08
#74: Review the trunk/milena/mln/morpho directory
-----------------------+----------------------------------------------------
Reporter: levill_r | Owner: levill_r
Type: task | Status: assigned
Priority: critical | Milestone: Olena 1.0
Component: Milena | Version: 1.0
Resolution: | Keywords:
-----------------------+----------------------------------------------------
Old description:
> This synthetic ticket pertains to source:trunk/milena/mln/morpho
>
> * Fix documentation.
> * Check style, layout, and typo.
> * Add trace(s) in algorithms.
> * Move specializations to the `*.spe.hh` files.
> * Check `all.hh` presence.
> * Move the tests to its own specific directory.
> * Add the potential missing unit tests and full tests.
>
> Also, in particular:
>
> * Ensure dual operators have « symmetrical » definitions. For instance,
> source:trunk/milena/mln/morpho/dilation.hh and
> source:trunk/milena/mln/morpho/erosion.hh are really different!
> * Remove anything related to so-called « attached neighborhoods » (as
> far as I can remember, only source:trunk/milena/mln/morpho/dilation.hh
> uses the)m; we'll get back to this later, for Olena 1.1 (see #130).
New description:
This synthetic ticket pertains to source:trunk/milena/mln/morpho
* Fix documentation.
* Check style, layout, and typo.
* Add trace(s) in algorithms.
* Move specializations to the `*.spe.hh` files.
* Check `all.hh` presence.
* Move the tests to its own specific directory.
* Add the potential missing unit tests and full tests.
Also, in particular:
* Ensure dual operators have « symmetrical » definitions. For instance,
source:trunk/milena/mln/morpho/dilation.hh and
source:trunk/milena/mln/morpho/erosion.hh are really different!
* Remove anything related to so-called « attached neighborhoods » (as far
as I can remember, only source:trunk/milena/mln/morpho/dilation.hh uses
the)m; we'll get back to this later, for Olena 1.1 (see #130).
* (From #131:) Files source:trunk/milena/mln/morpho/opening_area.hh,
source:trunk/milena/mln/morpho/opening_attribute.hh, etc. and their
routines are called `opening_area` and `opening_attribute`, which is not
elegant. Of course the goal is to put forward the « opening » term; but
IMHO, we should use namespaces to do this, not prefixes. Or rename them
to `area_opening` and `attribute_opening`, which are much more natural.
Comment (by levill_r):
Move some naming remarks from #131 to this ticket.
--
Ticket URL: <https://trac.lrde.org/olena/ticket/74#comment:3>
Olena <http://olena.lrde.epita.fr>
Olena, a generic and efficient C++ image processing library.
1
0
17 Apr '08
#74: Review the trunk/milena/mln/morpho directory
-----------------------+----------------------------------------------------
Reporter: levill_r | Owner: levill_r
Type: task | Status: assigned
Priority: critical | Milestone: Olena 1.0
Component: Milena | Version: 1.0
Resolution: | Keywords:
-----------------------+----------------------------------------------------
Changes (by levill_r):
* status: new => assigned
--
Ticket URL: <https://trac.lrde.org/olena/ticket/74#comment:2>
Olena <http://olena.lrde.epita.fr>
Olena, a generic and efficient C++ image processing library.
1
0
17 Apr '08
#74: Review the trunk/milena/mln/morpho directory
-----------------------+----------------------------------------------------
Reporter: levill_r | Owner: levill_r
Type: task | Status: new
Priority: critical | Milestone: Olena 1.0
Component: Milena | Version: 1.0
Resolution: | Keywords:
-----------------------+----------------------------------------------------
Changes (by levill_r):
* priority: major => critical
Old description:
> This synthetic ticket pertains to source:trunk/milena/mln/morpho
>
> * Fix documentation.
> * Check style, layout, and typo.
> * Add trace(s) in algorithms.
> * Move specializations to the `*.spe.hh` files.
> * Check `all.hh` presence.
> * Move the tests to its own specific directory.
> * Add the potential missing unit tests and full tests.
New description:
This synthetic ticket pertains to source:trunk/milena/mln/morpho
* Fix documentation.
* Check style, layout, and typo.
* Add trace(s) in algorithms.
* Move specializations to the `*.spe.hh` files.
* Check `all.hh` presence.
* Move the tests to its own specific directory.
* Add the potential missing unit tests and full tests.
Also, in particular:
* Ensure dual operators have « symmetrical » definitions. For instance,
source:trunk/milena/mln/morpho/dilation.hh and
source:trunk/milena/mln/morpho/erosion.hh are really different!
* Remove anything related to so-called « attached neighborhoods » (as far
as I can remember, only source:trunk/milena/mln/morpho/dilation.hh uses
the)m; we'll get back to this later, for Olena 1.1 (see #130).
Comment:
* Mention the case of diverging paired files like
source:trunk/milena/mln/morpho/dilation.hh and
source:trunk/milena/mln/morpho/erosion.hh.
* Mention the case(s) of attached neighborhood that should be removed
before the release of Olena 1.0.
--
Ticket URL: <https://trac.lrde.org/olena/ticket/74#comment:1>
Olena <http://olena.lrde.epita.fr>
Olena, a generic and efficient C++ image processing library.
1
0
URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena
ChangeLog:
2008-04-16 Matthieu Garrigues <garrigues(a)lrde.epita.fr>
Add a new level set computation.
* sandbox/garrigues/fllt/fllt_theo.cc: New.
* mln/accu/bbox.hh: Add a method to add a box to an accu::bbox.
---
mln/accu/bbox.hh | 24 ++++
sandbox/garrigues/fllt/fllt_theo.cc | 188 ++++++++++++++++++++++++++++++++++++
2 files changed, 212 insertions(+)
Index: trunk/milena/mln/accu/bbox.hh
===================================================================
--- trunk/milena/mln/accu/bbox.hh (revision 1871)
+++ trunk/milena/mln/accu/bbox.hh (revision 1872)
@@ -60,6 +60,7 @@
void take_as_init(const P& p);
void take(const P& p);
void take(const bbox<P>& other);
+ void take(const box_<P>& other);
const box_<P>& to_result() const;
@@ -146,6 +147,29 @@
template <typename P>
inline
+ void
+ bbox<P>::take(const box_<P>& other)
+ {
+ if (other.npoints() == 0)
+ {
+ // no-op
+ return;
+ }
+ if (! this->is_valid_)
+ {
+ b_ = other;
+ return;
+ }
+ // both are valids so:
+ for (unsigned i = 0; i < P::dim; ++i)
+ if (other.pmin()[i] < b_.pmin()[i])
+ b_.pmin()[i] = other.pmin()[i];
+ else if (other.pmax()[i] > b_.pmax()[i])
+ b_.pmax()[i] = other.pmax()[i];
+ }
+
+ template <typename P>
+ inline
const box_<P>&
bbox<P>::to_result() const
{
Index: trunk/milena/sandbox/garrigues/fllt/fllt_theo.cc
===================================================================
--- trunk/milena/sandbox/garrigues/fllt/fllt_theo.cc (revision 0)
+++ trunk/milena/sandbox/garrigues/fllt/fllt_theo.cc (revision 1872)
@@ -0,0 +1,188 @@
+// Copyright (C) 2008 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#include <mln/core/image2d.hh>
+#include <mln/core/neighb2d.hh>
+#include <mln/core/p_array.hh>
+#include <mln/core/clone.hh>
+
+#include <mln/value/int_u8.hh>
+
+#include <mln/io/pgm/load.hh>
+#include <mln/io/pgm/save.hh>
+
+#include <mln/level/fill.hh>
+#include <mln/debug/println.hh>
+#include <mln/labeling/regional_minima.hh>
+#include <mln/accu/bbox.hh>
+
+
+namespace mln
+{
+
+ namespace my
+ {
+
+ template <typename N_t>
+ unsigned compute_gN(const N_t& N)
+ {
+ for (unsigned i = 0; i < 256; ++i)
+ if (N[i].npoints() != 0)
+ return i;
+ mln_invariant(0);
+ return 0;
+ }
+
+
+ template <typename I, typename Nbh>
+ void fllt(const Image<I>& input_, const Neighborhood<Nbh>& nbh_)
+ {
+ const I& input = exact(input_);
+ const Nbh& nbh = exact(nbh_);
+
+ unsigned l = 0, l_max;
+ mln_ch_value(I, unsigned) reg_min = labeling::regional_minima(input, nbh, l_max);
+
+ // Variables.
+ I u = mln::clone(input);
+ mln_point(I) x0;
+ mln_value(I) g, gN;
+ image2d<unsigned char> is(input.domain());
+ const unsigned in_R = 1, in_N = 2, in_O = 0;
+
+ typedef p_array<mln_point(I)> arr_t;
+ arr_t A;
+ arr_t N[256];
+
+ accu::bbox<mln_point(I)> R_box;
+
+ int cpt = 0;
+
+ // Step 1.
+ step_1:
+ {
+ if (l == l_max)
+ return;
+ l += 1;
+ mln_piter(I) p(input.domain());
+ for_all(p)
+ if (reg_min(p) == l)
+ break;
+ x0 = p;
+ g = input(x0);
+ }
+
+ // Step 2.
+ step_2:
+ {
+ R_box.init();
+ level::fill(is, in_O);
+ A.append(x0);
+ }
+
+ // Step 3.
+ step_3:
+ {
+ mln_piter(arr_t) a(A);
+ mln_niter(Nbh) x(nbh, a);
+
+ // Stop.
+ if (A.npoints() > 0)
+ goto end;
+
+ // R <- R U A
+ for_all(a)
+ is(a) = in_R;
+ mln_assertion(A.npoints() > 0);
+ R_box.take(A.bbox());
+
+ // N <- N U { x in nbh of A and not in R }
+ for_all(a)
+ for_all(x)
+ if (u.has(x) && is(x) != in_R)
+ N[u(x)].append(x);
+
+ // gN = min u(x) for all x in N
+ gN = compute_gN(N);
+
+ // FIXME: update the number of CC of the border of R
+ }
+
+ // Step 4.
+ step_4:
+ {
+ // a)
+ if (g < gN)
+ {
+ // FIXME: DO the hole thing.
+ A = N[g];
+ N[g].clear();
+ g = gN;
+ gN = compute_gN(N);
+ goto step_3;
+ }
+ // b)
+ else if (g == gN)
+ {
+ A = N[g];
+ N[g].clear();
+ g = gN;
+ gN = compute_gN(N);
+ goto step_3;
+ }
+ // c)
+ else
+ {
+ mln_piter(box_<mln_point(I)>) p(R_box);
+ for_all(p)
+ if (is(p) == in_R)
+ u(p) = g;
+ goto step_1;
+ }
+ }
+ end:
+ {
+ }
+ }
+
+ } // end of namespace mln::my
+
+} // end of namespace mln
+
+
+int main()
+{
+ using namespace mln;
+ using value::int_u8;
+
+ image2d<int_u8> lena;
+ io::pgm::load(lena, "small.pgm");
+
+ my::fllt(lena, c4());
+ io::pgm::save(lena, "./out.pgm");
+
+}
1
0
https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Alexandre Abraham <abraham(a)lrde.epita.fr>
Add functional M-Watershed algorithm and tests.
* sandbox/abraham/morpho/basic_najman.hh
(mln::morpho::basic_najman::lca)
(mln::morpho::basic_najman::highest_fork)
(mln::morpho::basic_najman::m-destructible)
(mln::morpho::basic_najman::w-destructible)
(mln::morpho::basic_najman::m-watershed)
(mln::morpho::basic_najman::w-watershed):
New methods.
* sandbox/abraham/morpho/test.cc: Add debug tests.
* sandbox/abraham/morpho/test_component_tree.cc: New,
Add tests for component tree algorithms.
* sandbox/abraham/morpho/images/result_m_watershed.pgm: New,
Reference for m-watershed algorithm.
* sandbox/abraham/morpho/images/result_topo_watershed.pgm: New,
Reference for w-watershed algorithm.
* sandbox/abraham/morpho/images/test_watershed.pgm: New,
Test image for watershed algorithms.
* sandbox/abraham/morpho/images/test_component_mapping.pgm: New,
Reference image for component mapping.
* sandbox/abraham/morpho/test_watershed.cc: New,
Add tests for watershed algorithms.
* sandbox/abraham/morpho/Makefile:
Add rules to compile new tests.
Makefile | 16 +-
basic_najman.hh | 295 +++++++++++++++++++++++++++++++-------
images/test_component_mapping.pgm | 5
test.cc | 15 -
test_component_tree.cc | 224 ++++++++++++++++++++++++++++
test_watershed.cc | 55 +++++++
6 files changed, 542 insertions(+), 68 deletions(-)
Index: sandbox/abraham/morpho/basic_najman.hh
--- sandbox/abraham/morpho/basic_najman.hh (revision 1870)
+++ sandbox/abraham/morpho/basic_najman.hh (working copy)
@@ -1,6 +1,10 @@
#include <mln/level/sort_psites.hh>
#include <mln/level/fill.hh>
#include <mln/core/image2d.hh>
+#include <mln/core/p_set.hh>
+//#include <mln/util/greater_psite.hh>
+#include <queue>
+#include <set>
namespace mln
{
@@ -28,19 +32,19 @@
it.next())
children.append(it.to_psite());
}
+
void addChild(const psite n)
{
children.append(n);
}
}; // struct node
-
+ I pima;
const Image<I>& ima;
const Neighborhood<N>& nbh;
mln_ch_value(I, psite) Par_node;
-
mln_ch_value(I, psite) Par_tree;
- // Par_node is handled by par (from ap_maxtree)
+
mln_ch_value(I, int) Rnk_tree;
mln_ch_value(I, int) Rnk_node;
mln_ch_value(I, psite) subtreeRoot;
@@ -52,7 +56,8 @@
basic_najman(const Image<I>& i,
const Neighborhood<N>& n)
- : ima(i),
+ : pima(exact(i)),
+ ima(i),
nbh(n),
Par_node(exact(i).domain(), exact(i).border()),
Par_tree(exact(i).domain(), exact(i).border()),
@@ -73,7 +78,7 @@
void MakeSet_node(psite x)
{
- Par_node(x) = x; // was Par_node(x) = x;
+ Par_node(x) = x;
Rnk_node(x) = 0;
}
@@ -91,24 +96,6 @@
y = memo;
}
-// bool is_root(const psite& x) const
-// {
-// return Par_node(x) == x;
-// }
-
-// bool is_level_root(const psite& x) const
-// {
-// return is_root(x) || exact(ima)(Par_node(x)) < exact(ima)(x);
-// }
-
-// psite find_level_root(const psite& x)
-// {
-// if (is_level_root(x))
-// return x;
-// else
-// return Par_node(x) = find_level_root(Par_node(x));
-// }
-
psite Find_node(psite x)
{
if (Par_node(x) != x)
@@ -148,7 +135,6 @@
for (int ip = 0; ip < int(S.npoints()); ++ip)
{
psite p = S[ip];
- // isproc(p) = true;
psite curTree = Find_tree(p);
psite curNode = Find_node(subtreeRoot(curTree));
@@ -162,36 +148,22 @@
psite adjNode = Find_node(subtreeRoot(adjTree));
if (curNode != adjNode)
{
- std::cout << "curNode != adjNode; " << nodes(curNode).level << " vs. " << nodes(adjNode).level << std::endl;
if (nodes(curNode).level == nodes(adjNode).level)
{
- // curNode = MergeNode(adjNode, curNode);
- psite tmpNode = MergeNode(adjNode, curNode);
- /*if (tmpNode == curNode)
- nodes(curNode).addChildren(nodes(adjNode));
- else
- nodes(adjNode).addChildren(nodes(curNode));
- nodes(adjNode) = nodes(curNode);*/
- curNode = tmpNode;
+ curNode = MergeNode(adjNode, curNode);
}
else
{
- // we have nodes[curNode].level < nodes[adjNode].level
nodes(curNode).addChild(adjNode);
- //apparemment NON :Par_node[adjNode] = curNode; // car adjNode devient fils de curNode
nodes(curNode).area += nodes(adjNode).area;
nodes(curNode).highest += nodes(adjNode).highest;
}
- // curTree = Link_tree(adjTree, curTree);
- // subtreeRoot(curTree) = curNode;
-
}
curTree = Link_tree(adjTree, curTree);
subtreeRoot(curTree) = curNode;
}
isproc(p) = true;
}
- Root = subtreeRoot(Find_tree(Find_node(psite(0, 0))));
// Pour garder une map de correspondance point <-> local_root
// for (int ip = 0; ip < int(S.size()); ++ip)
// {
@@ -203,6 +175,7 @@
for_all(r)
Par_node(r) = Find_node(r);
+ Root = subtreeRoot(Find_tree(Find_node(psite(0, 0))));
}
@@ -243,7 +216,7 @@
else
if (Rnk_node(x) == Rnk_node(y))
Rnk_node(y) += 1;
- Par_node(x) = y; // was Par_node(x) = y;
+ Par_node(x) = y;
return y;
}
@@ -275,40 +248,254 @@
void print_tree(psite p)
{
node& n = nodes(p);
- std::cout << "psite " << p << "=" << (p.row() * exact(subtreeRoot).domain().len(1) + p.col()) << " : ";
+ std::cout << "psite " << p << "(" << n.level << ")=" << (p.row() * exact(subtreeRoot).domain().len(1) + p.col()) << " : ";
typename p_array<mln_psite(I)>::fwd_piter it(n.children);
- for (it.start();
- it.is_valid();
- it.next())
+ for_all(it)
{
psite q = it.to_psite();
std::cout << q << "=" << (q.row() * subtreeRoot.domain().len(1) + q.col()) << " ";
}
std::cout << std::endl;
- for (it.start();
- it.is_valid();
- it.next())
+ for_all(it)
{
print_tree(it.to_psite());
}
}
- void print_sup_tree()
+ psite lca (psite a, psite b)
{
- psite max = psite(0, 0);
+ return lca_rec(Root, Par_node(a), Par_node(b));
+ }
- for(unsigned int i = 0; i < nodes.domain().len(0); ++i)
- for(unsigned int j = 0; j < nodes.domain().len(1); ++j)
+ psite lca_rec (psite cur, psite a, psite b)
+ {
+ // FIXME : naive implementation, make something better
+
+ if (cur == a)
+ return a;
+
+ if (cur == b)
+ return b;
+
+ if (nodes(cur).children.npoints() == 0)
+ return psite (-1, -1);
+
+ psite tmp, acc = psite(-1, -1);
+ int n = 0;
+ typename p_array<mln_psite(I)>::fwd_piter it(nodes(cur).children);
+ for_all(it)
+ {
+ tmp = lca_rec(it.to_psite(), a, b);
+ if (tmp != psite(-1, -1))
+ {
+ if (tmp == a)
{
- if (nodes(psite(i, j)).area > nodes(max).area)
- max = psite(i, j);
+ acc = tmp;
+ n++;
+ continue;
}
+ if (tmp == b)
+ {
+ acc = tmp;
+ n++;
+ continue;
+ }
+ return tmp;
+ }
+ }
+ if (n == 2)
+ return cur;
+
+ return acc;
+ }
+
+ psite min (p_set<psite>& components)
+ {
+ if (components.npoints() == 0)
+ return psite(-1, -1);
+
+ typename p_set<psite>::fwd_piter it(components);
+ psite min = components[0];
+
+ for_all(it)
+ if (nodes(it.to_point()).level > nodes(min).level)
+ min = it.to_point();
+
+ return min;
+ }
+
+ psite highest_fork (p_set<psite>& components)
+ {
+ if (components.npoints() == 0)
+ return psite(-1, -1);
+
+ psite hfork = components[0], min = hfork;
+ typename p_set<psite>::fwd_piter it(components);
- print_tree(max);
+ for_all(it)
+ hfork = lca(hfork, it.to_point());
+
+ if (nodes(min).level == nodes(hfork).level)
+ return psite(-1, -1);
+
+ return hfork;
}
+ psite w_destructible(psite p)
+ {
+ mln_niter(N) q(nbh, p);
+ p_set<psite> v;
+
+ for_all(q)
+ if (exact(ima)(q) < exact(ima)(p))
+ v.append(Par_node(q));
+
+ if (v.npoints() == 0)
+ return psite(-1, -1);
+
+ psite hf = highest_fork(v);
+
+ if (hf == psite(-1, -1))
+ return min(v);
+
+ if (nodes(hf).level <= exact(ima)(p))
+ return hf;
+
+ return psite(-1, -1);
+ }
+
+ psite m_destructible(psite p)
+ {
+ mln_niter(N) q(nbh, p);
+ p_set<psite> v;
+
+ for_all(q)
+ if (exact(ima)(q) < exact(ima)(p))
+ v.insert(Par_node(q));
+
+ if (v.npoints() == 0)
+ return psite(-1, -1);
+
+ if (nodes(min(v)).children.npoints() != 0)
+ return (psite(-1, -1));
+
+ psite hf = highest_fork(v);
+
+ if (hf == psite(-1, -1))
+ return min(v);
+
+ return psite(-1, -1);
+ }
+
+ void m_watershed ()
+ {
+
+ // FIXME : make a better priority function
+ // typedef
+ // std::priority_queue< psite, std::vector<psite>, util::greater_psite<I> >
+ // ordered_queue_type;
+
+
+ std::priority_queue<psite> l;
+
+ // Clear the marker map
+ level::fill(isproc, false);
+ mln_piter(I) it(exact(ima).domain());
+
+ for_all(it)
+ if (m_destructible(it.to_point()) != psite(-1, -1))
+ {
+ l.push(it.to_point());
+ isproc(it.to_point()) = true;
+ }
+
+ psite p, i;
+ while (!l.empty())
+ {
+ p = l.top();
+ l.pop();
+ isproc(p) = false;
+
+ i = m_destructible(p);
+
+ if (i != psite(-1, -1))
+ {
+ pima(p) = nodes(i).level ;
+ Par_node(p) = i;
+ mln_niter(N) q(nbh, p);
+
+ for_all(q)
+ if (!isproc(q))
+ if (m_destructible(q) != psite(-1, -1))
+ {
+ l.push(q);
+ isproc(q) = true;
+ }
+ }
+ }
+ }
+
+ void w_watershed()
+ {
+ p_array< p_set<psite> > L;
+ // TODO : replace int with the type of value
+ mln_ch_value(I, int) K;
+ mln_ch_value(I, psite) H;
+
+ mln_piter(I) it(exact(ima).domain());
+
+ psite i;
+ for_all(it)
+ {
+ psite p = it.to_point();
+
+ i = w_destructible(p);
+ if (i != psite(-1, -1))
+ {
+ L[nodes(i).level].insert(p);
+ K(p) = nodes(i).level;
+ H(p) = i;
+
+ typename p_array< p_set<psite> >::fwd_piter n(L);
+ for_all(n)
+ {
+ while (!n.empty())
+ {
+ psite p = *n.begin();
+ n.erase(p);
+ // TODO : replace int with the type of value
+ int k = nodes(p).level + 1;
+ if (K(p) == k)
+ {
+ pima(p) = k;
+ Par_node(p) = H(p);
+
+ mln_niter(N) q(nbh, p);
+ for_all(q)
+ if (k < pima(q))
+ {
+ psite j = w_destructible(q);
+ if (j != psite(-1, -1))
+ K(q) = -1;
+ else
+ if (K(q) != nodes(j).level)
+ {
+ n.insert(q);
+ K(q) = i-1;
+ H(q) = j;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ }
+
+
}; // struct basic_najman
}; // namespace morpho
Index: sandbox/abraham/morpho/test.cc
--- sandbox/abraham/morpho/test.cc (revision 1870)
+++ sandbox/abraham/morpho/test.cc (working copy)
@@ -17,21 +17,13 @@
using namespace mln;
using value::int_u8;
- // component_tree< image2d<int_u8> > c;
-
using namespace mln;
using value::int_u8;
image2d<int_u8> input;
io::pgm::load(input, "./images/test_component_tree.pgm");
-
- for(unsigned int i = 0; i < input.domain().len(0); ++i)
- for(unsigned int j = 0; j < input.domain().len(1); ++j)
- input.at(i, j) = 255 - input.at(i, j);
-
-
- morpho::basic_najman< image2d<int_u8>, neighb2d> n(input, c8());
+ morpho::basic_najman< image2d<int_u8>, neighb2d> n(input, c4());
n.image_output(input);
n.go();
n.image_output(n.Par_tree);
@@ -42,7 +34,10 @@
std::cout << " --------------------------- " << std::endl;
n.image_output(n.Rnk_node);
std::cout << " --------------------------- " << std::endl;
- n.print_sup_tree();
+ n.print_tree(n.Root);
+ std::cout << " --------------------------- " << std::endl;
+
+ n.m_watershed();
// image2d<int_u8> output = morpho::topo_wst(input, c4());
// io::pgm::save(output, "out.pgm");
Index: sandbox/abraham/morpho/test_component_tree.cc
--- sandbox/abraham/morpho/test_component_tree.cc (revision 0)
+++ sandbox/abraham/morpho/test_component_tree.cc (revision 0)
@@ -0,0 +1,224 @@
+#include <mln/core/image2d.hh>
+#include <mln/core/window2d.hh>
+#include <mln/core/neighb2d.hh>
+#include <mln/core/p_set.hh>
+
+#include <mln/value/int_u8.hh>
+
+#include <mln/io/pgm/load.hh>
+#include <mln/io/pgm/save.hh>
+
+#include "basic_najman.hh"
+#include <string>
+#include <iostream>
+
+int print_and_exit (std::string s)
+{
+ std::cerr << s << std::endl;
+ return 1;
+}
+
+template <typename T>
+void swap (T& x, T& y)
+{
+ T memo = x;
+ x = y;
+ y = memo;
+}
+
+template <typename T>
+class test_tree;
+
+template <typename T>
+class test_tree
+{
+public:
+
+ test_tree(T pdata) : data(pdata), children(NULL), brother(NULL) { }
+
+ T data;
+ test_tree<T> *children;
+ test_tree<T> *brother;
+
+ test_tree<T>* insert_child(test_tree<T> *n)
+ {
+ test_tree<T> **p = &children;
+ while (*p && (**p).data < n->data)
+ p = &((**p).brother);
+ n->brother = *p;
+ *p = n;
+ return n;
+ }
+
+ test_tree<T>* insert_child(T pdata)
+ {
+ test_tree<T> *n = new test_tree<T>(pdata);
+ return insert_child(n);
+ }
+};
+
+template <typename T>
+bool compare_tree(test_tree<T>* t1, test_tree<T>* t2)
+{
+ if (!t1 && !t2)
+ return true;
+
+ if ((!t1 || !t2) || (t1->data != t2->data))
+ return false;
+
+ return (compare_tree(t1->brother, t2->brother)
+ && compare_tree(t1->children, t2->children));
+}
+
+template <typename T>
+void show_tree (test_tree<T> *t)
+{
+ if (!t)
+ return ;
+
+ if (t->brother)
+ {
+ std::cout << t->data << " - ";
+ show_tree(t->brother);
+ }
+ else
+ std::cout << t->data << std::endl;
+
+ if (t->children)
+ {
+ std::cout << "sons of " << t->data << " : ";
+ show_tree(t->children);
+ }
+}
+
+
+using namespace mln;
+using value::int_u8;
+
+
+test_tree<image2d<int_u8>::psite>* test_convert (morpho::basic_najman<image2d<int_u8>, neighb2d>& ima, image2d<int_u8>::psite root);
+
+test_tree<image2d<int_u8>::psite>* test_convert (morpho::basic_najman<image2d<int_u8>, neighb2d>& ima, image2d<int_u8>::psite root)
+{
+ morpho::basic_najman<image2d<int_u8>, neighb2d>::node& n = ima.nodes(ima.Par_node(root));
+
+ test_tree<image2d<int_u8>::psite> *res = new test_tree<image2d<int_u8>::psite>(ima.Par_node(root));
+
+ p_array<image2d<int_u8>::psite>::fwd_piter it (n.children);
+ for_all(it)
+ res->insert_child(test_convert(ima, it.to_psite()));
+
+ return res;
+}
+
+int main ()
+{
+ typedef image2d<int_u8> image2dint;
+
+ image2dint input, verif;
+ io::pgm::load(input, "./images/test_component_tree.pgm");
+ io::pgm::load(verif, "./images/test_component_mapping.pgm");
+
+ morpho::basic_najman< image2d<int_u8>, neighb2d> n(input, c4());
+ n.go();
+
+ /*
+ Component mapping :
+
+ 3 3 3 3 9 2 2 2 2
+ 1 1 1 9 7 9 2 2 2
+ 1 1 9 7 7 7 9 2 2
+ 1 9 6 9 7 9 5 9 2
+ 1 1 9 1 7 2 7 2 2
+ 1 1 1 1 7 2 2 2 2
+
+
+ Component tree
+
+ 9
+ / \
+ 7 6
+ /|\
+ 3 2 5
+ |
+ 1
+ */
+
+ // Component mapping test
+
+ image2dint::fwd_piter it(input.domain());
+ image2dint::psite c[10];
+ c[1] = n.Par_node(image2dint::psite(1, 0));
+ c[2] = n.Par_node(image2dint::psite(0, 5));
+ c[3] = n.Par_node(image2dint::psite(0, 0));
+ c[5] = n.Par_node(image2dint::psite(3, 6));
+ c[6] = n.Par_node(image2dint::psite(3, 2));
+ c[7] = n.Par_node(image2dint::psite(1, 4));
+ c[9] = n.Par_node(image2dint::psite(0, 4));
+
+ bool id = true;
+
+ for_all(it)
+ id = (c[verif(it.to_point())] == n.Par_node(it.to_point()));
+
+ if (!id)
+ {
+ std::cerr << "Component mapping is fucked up!" << std::endl;
+ return 1;
+ }
+
+ // Component tree test
+
+ test_tree<image2dint::psite> *gen, ref(c[9]), *l1, *l2;
+
+ // Create the ref
+ ref.insert_child(c[6]);
+ l1 = ref.insert_child(c[7]);
+ l1->insert_child(c[2]);
+ l1->insert_child(c[5]);
+ l2 = l1->insert_child(c[3]);
+ l2->insert_child(c[1]);
+
+ // Create the generated tree
+ gen = test_convert(n, n.Par_node(n.Root));
+
+ // Compare the trees
+ if (!compare_tree(gen, &ref))
+ {
+ std::cout << "Your tree :" << std::endl;
+ show_tree(gen);
+
+ std::cout << "Reference tree :" << std::endl;
+ show_tree(&ref);
+
+ std::cerr << "Component tree is fucked up!" << std::endl;
+ return 1;
+ }
+
+ // Test the LCA alorithm
+ image2dint::psite p(0, 0), q(0, 6), r(2, 4);
+ if (n.lca(p, q) != image2dint::psite(2,4))
+ return 1;
+
+ if (n.lca(r, q) != image2dint::psite(2,4))
+ return 1;
+
+ // Test the Highest Fork
+ p_set<image2dint::psite> comp;
+ comp.insert(image2dint::psite(0,0));
+ comp.insert(image2dint::psite(2,4));
+ comp.insert(image2dint::psite(0,6));
+ comp.insert(image2dint::psite(1,0));
+
+ if (n.highest_fork(comp) != image2dint::psite(2, 4))
+ return 1;
+
+ comp.insert(image2dint::psite(3,2));
+
+ if (n.highest_fork(comp) != image2dint::psite(1, 3))
+ return 1;
+
+ std::cout << "Test is successfull" << std::endl;
+
+ return 0;
+}
Index: sandbox/abraham/morpho/images/result_m_watershed.pgm
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: sandbox/abraham/morpho/images/result_m_watershed.pgm
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Index: sandbox/abraham/morpho/images/result_topo_watershed.pgm
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: sandbox/abraham/morpho/images/result_topo_watershed.pgm
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Index: sandbox/abraham/morpho/images/test_watershed.pgm
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: sandbox/abraham/morpho/images/test_watershed.pgm
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Index: sandbox/abraham/morpho/images/test_component_mapping.pgm
--- sandbox/abraham/morpho/images/test_component_mapping.pgm (revision 0)
+++ sandbox/abraham/morpho/images/test_component_mapping.pgm (revision 0)
@@ -0,0 +1,5 @@
+P5
+# CREATOR: GIMP PNM Filter Version 1.1
+9 6
+255
+
\ No newline at end of file
Index: sandbox/abraham/morpho/test_watershed.cc
--- sandbox/abraham/morpho/test_watershed.cc (revision 0)
+++ sandbox/abraham/morpho/test_watershed.cc (revision 0)
@@ -0,0 +1,55 @@
+#include <mln/core/image2d.hh>
+#include <mln/core/window2d.hh>
+#include <mln/core/neighb2d.hh>
+#include <mln/core/p_set.hh>
+
+#include <mln/value/int_u8.hh>
+#include <mln/level/compare.hh>
+
+#include <mln/io/pgm/load.hh>
+#include <mln/io/pgm/save.hh>
+
+#include "basic_najman.hh"
+#include <string>
+#include <iostream>
+
+int print_and_exit (std::string s)
+{
+ std::cerr << s << std::endl;
+ return 1;
+}
+
+int main ()
+{
+ using namespace mln;
+ using value::int_u8;
+
+ typedef image2d<int_u8> image2dint;
+
+ image2dint input, mverif;
+ io::pgm::load(input, "./images/test_watershed.pgm");
+ // io::pgm::load(input, "./images/lena.pgm");
+ io::pgm::load(mverif, "./images/result_m_watershed.pgm");
+
+ morpho::basic_najman< image2d<int_u8>, neighb2d> n(input, c4());
+ n.go();
+ n.m_watershed();
+
+ bool equal = true;
+
+ equal = n.pima == mverif;
+
+ if (!equal)
+ {
+ std::cout << "M-Watershed broken" << std::endl;
+ return 1;
+ }
+ else
+ std::cout << "M-Watershed good as chocolate ice cream" << std::endl;
+
+ // n.w_watershed();
+
+ io::pgm::save(n.pima, "out.pgm");
+
+ return 0;
+}
Index: sandbox/abraham/morpho/Makefile
--- sandbox/abraham/morpho/Makefile (revision 1870)
+++ sandbox/abraham/morpho/Makefile (working copy)
@@ -1,8 +1,16 @@
-SOURCE=test.cc
-OBJECTS=test.o
CXXFLAGS=-Wall -W -I ../../.. -g
-all:${OBJECTS}
- g++ ${FLAGS} ${OBJECTS} -o test
+test: test.o
+ g++ ${CXXFLAGS} test.o -o test
+test_component_tree: test_component_tree.o
+ g++ ${CXXFLAGS} test_component_tree.o -o test_component_tree
+
+test_watershed: test_watershed.o
+ g++ ${CXXFLAGS} test_watershed.o -o test_watershed
+
+all: tree
+
+test_watershed.o: basic_najman.hh
+test_component_tree.o: basic_najman.hh
test.o: basic_najman.hh
\ No newline at end of file
1
0