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
March 2009
- 9 participants
- 202 discussions
02 Mar '09
* mln/geom/bbox.hh,
* mln/geom/max_col.hh,
* mln/geom/max_ind.hh,
* mln/geom/max_row.hh,
* mln/geom/max_sli.hh,
* mln/geom/min_col.hh,
* mln/geom/min_ind.hh,
* mln/geom/min_row.hh,
* mln/geom/min_sli.hh,
* mln/geom/ncols.hh,
* mln/geom/ninds.hh,
* mln/geom/nrows.hh,
* mln/geom/nslis.hh: add missing traces.
---
milena/ChangeLog | 18 ++++++++++++++++++
milena/mln/geom/bbox.hh | 18 ++++++++++++++++--
milena/mln/geom/max_col.hh | 16 +++++++++++++---
milena/mln/geom/max_ind.hh | 9 +++++++--
milena/mln/geom/max_row.hh | 16 +++++++++++++---
milena/mln/geom/max_sli.hh | 9 +++++++--
milena/mln/geom/min_col.hh | 16 +++++++++++++---
milena/mln/geom/min_ind.hh | 9 +++++++--
milena/mln/geom/min_row.hh | 16 +++++++++++++---
milena/mln/geom/min_sli.hh | 9 +++++++--
milena/mln/geom/ncols.hh | 23 ++++++++++++++++-------
milena/mln/geom/ninds.hh | 9 +++++++--
milena/mln/geom/nrows.hh | 23 ++++++++++++++++-------
milena/mln/geom/nslis.hh | 16 ++++++++++------
14 files changed, 163 insertions(+), 44 deletions(-)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 438bfe2..9de7f13 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,5 +1,23 @@
2009-03-02 Guillaume Lazzara <lazzara(a)lrde.epita.fr>
+ Add missing traces in basic routines in geom/* (ticket #49).
+
+ * mln/geom/bbox.hh,
+ * mln/geom/max_col.hh,
+ * mln/geom/max_ind.hh,
+ * mln/geom/max_row.hh,
+ * mln/geom/max_sli.hh,
+ * mln/geom/min_col.hh,
+ * mln/geom/min_ind.hh,
+ * mln/geom/min_row.hh,
+ * mln/geom/min_sli.hh,
+ * mln/geom/ncols.hh,
+ * mln/geom/ninds.hh,
+ * mln/geom/nrows.hh,
+ * mln/geom/nslis.hh: add missing traces.
+
+2009-03-02 Guillaume Lazzara <lazzara(a)lrde.epita.fr>
+
Cleanup scribo sandbox.
* sandbox/scribo/Makefile: add new rules.
diff --git a/milena/mln/geom/bbox.hh b/milena/mln/geom/bbox.hh
index 9a7d5bc..32d8377 100644
--- a/milena/mln/geom/bbox.hh
+++ b/milena/mln/geom/bbox.hh
@@ -135,27 +135,41 @@ namespace mln
template <typename I>
box<mln_site(I)> bbox(const Image<I>& ima_)
{
+ trace::entering("geom::bbox");
+
const I& ima = exact(ima_);
mln_precondition(ima.is_valid());
- return geom::bbox(ima.domain());
+ box<mln_site(I)> b = geom::bbox(ima.domain());
+
+ trace::exiting("geom::bbox");
+ return b;
}
template <typename W>
box<mln_psite(W)> bbox(const Window<W>& win)
{
+ trace::entering("geom::bbox");
+
typedef mln_psite(W) P;
accu::bbox<P> b;
P O = literal::origin;
mln_qiter(W) q(exact(win), O);
for_all(q)
b.take(q);
+
+ trace::exiting("geom::bbox");
return b;
}
template <typename W>
box<mln_psite(W)> bbox(const Weighted_Window<W>& win)
{
- return bbox(exact(win).win());
+ trace::entering("geom::bbox");
+
+ box<mln_psite(W)> b = bbox(exact(win).win());
+
+ trace::exiting("geom::bbox");
+ return b;
}
diff --git a/milena/mln/geom/max_col.hh b/milena/mln/geom/max_col.hh
index 6152e5d..561810e 100644
--- a/milena/mln/geom/max_col.hh
+++ b/milena/mln/geom/max_col.hh
@@ -1,4 +1,4 @@
-// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2008, 2009 EPITA Research and Development Laboratory
// (LRDE)
//
// This file is part of the Olena Library. This library is free
@@ -57,8 +57,13 @@ namespace mln
inline
mln_deduce(I, site, coord) max_col(const Image<I>& ima)
{
+ trace::entering("mln::geom::max_col");
+
mln_precondition(exact(ima).is_valid());
- return geom::bbox(ima).pmax().col();
+ mln_deduce(I, site, coord) maxcol = geom::bbox(ima).pmax().col();
+
+ trace::exiting("mln::geom::max_col");
+ return maxcol;
}
@@ -66,8 +71,13 @@ namespace mln
inline
mln_deduce(B, point, coord) max_col(const Box<B>& b)
{
+ trace::entering("mln::geom::max_col");
+
metal::not_<metal::equal<metal::int_<B::dim>, metal::int_<1> > >::check();
- return exact(b).pmax().col();
+ mln_deduce(B, point, coord) maxcol = exact(b).pmax().col();
+
+ trace::exiting("mln::geom::max_col");
+ return maxcol;
}
# endif // ! MLN_INCLUDE_ONLY
diff --git a/milena/mln/geom/max_ind.hh b/milena/mln/geom/max_ind.hh
index 6d5baf0..15bcc86 100644
--- a/milena/mln/geom/max_ind.hh
+++ b/milena/mln/geom/max_ind.hh
@@ -1,4 +1,4 @@
-// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2008, 2009 EPITA Research and Development Laboratory
// (LRDE)
//
// This file is part of the Olena Library. This library is free
@@ -53,8 +53,13 @@ namespace mln
inline
mln_deduce(I, site, coord) max_ind(const Image<I>& ima)
{
+ trace::entering("mln::geom::max_ind");
+
mln_precondition(exact(ima).is_valid());
- return exact(ima).bbox().pmax().ind();
+ mln_deduce(I, site, coord) maxind = exact(ima).bbox().pmax().ind();
+
+ trace::exiting("mln::geom::max_ind");
+ return maxind;
}
# endif // ! MLN_INCLUDE_ONLY
diff --git a/milena/mln/geom/max_row.hh b/milena/mln/geom/max_row.hh
index cf33984..db49bb9 100644
--- a/milena/mln/geom/max_row.hh
+++ b/milena/mln/geom/max_row.hh
@@ -1,4 +1,4 @@
-// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2008, 2009 EPITA Research and Development Laboratory
// (LRDE)
//
// This file is part of the Olena Library. This library is free
@@ -58,8 +58,13 @@ namespace mln
inline
mln_deduce(I, site, coord) max_row(const Image<I>& ima)
{
+ trace::entering("mln::geom::max_row");
+
mln_precondition(exact(ima).is_valid());
- return geom::bbox(ima).pmax().row();
+ mln_deduce(I, site, coord) maxrow = geom::bbox(ima).pmax().row();
+
+ trace::exiting("mln::geom::max_row");
+ return maxrow;
}
@@ -67,8 +72,13 @@ namespace mln
inline
mln_deduce(B, point, coord) max_row(const Box<B>& b)
{
+ trace::entering("mln::geom::max_row");
+
metal::not_<metal::equal<metal::int_<B::dim>, metal::int_<1> > >::check();
- return exact(b).pmax().row();
+ mln_deduce(B, point, coord) maxrow = exact(b).pmax().row();
+
+ trace::exiting("mln::geom::max_row");
+ return maxrow;
}
# endif // ! MLN_INCLUDE_ONLY
diff --git a/milena/mln/geom/max_sli.hh b/milena/mln/geom/max_sli.hh
index 07920d6..18f9aad 100644
--- a/milena/mln/geom/max_sli.hh
+++ b/milena/mln/geom/max_sli.hh
@@ -1,4 +1,4 @@
-// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2008, 2009 EPITA Research and Development Laboratory
// (LRDE)
//
// This file is part of the Olena Library. This library is free
@@ -53,8 +53,13 @@ namespace mln
inline
mln_deduce(I, site, coord) max_sli(const Image<I>& ima)
{
+ trace::entering("mln::geom::max_sli");
+
mln_precondition(exact(ima).is_valid());
- return exact(ima).bbox().pmax().sli();
+ mln_deduce(I, site, coord) maxsli = exact(ima).bbox().pmax().sli();
+
+ trace::exiting("mln::geom::max_sli");
+ return maxsli;
}
# endif // ! MLN_INCLUDE_ONLY
diff --git a/milena/mln/geom/min_col.hh b/milena/mln/geom/min_col.hh
index cf66a3d..631d989 100644
--- a/milena/mln/geom/min_col.hh
+++ b/milena/mln/geom/min_col.hh
@@ -1,4 +1,4 @@
-// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2008, 2009 EPITA Research and Development Laboratory
// (LRDE)
//
// This file is part of the Olena Library. This library is free
@@ -58,8 +58,13 @@ namespace mln
inline
mln_deduce(I, site, coord) min_col(const Image<I>& ima)
{
+ trace::entering("mln::geom::min_col");
+
mln_precondition(exact(ima).is_valid());
- return geom::bbox(ima).pmin().col();
+ mln_deduce(I, site, coord) mincol = geom::bbox(ima).pmin().col();
+
+ trace::exiting("mln::geom::min_col");
+ return mincol;
}
@@ -67,8 +72,13 @@ namespace mln
inline
mln_deduce(B, point, coord) min_col(const Box<B>& b)
{
+ trace::entering("mln::geom::min_col");
+
metal::not_<metal::equal<metal::int_<B::dim>, metal::int_<1> > >::check();
- return exact(b).pmin().col();
+ mln_deduce(B, point, coord) mincol = exact(b).pmin().col();
+
+ trace::exiting("mln::geom::min_col");
+ return mincol;
}
# endif // ! MLN_INCLUDE_ONLY
diff --git a/milena/mln/geom/min_ind.hh b/milena/mln/geom/min_ind.hh
index 892b2fc..65e5721 100644
--- a/milena/mln/geom/min_ind.hh
+++ b/milena/mln/geom/min_ind.hh
@@ -1,4 +1,4 @@
-// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2008, 2009 EPITA Research and Development Laboratory
// (LRDE)
//
// This file is part of the Olena Library. This library is free
@@ -53,8 +53,13 @@ namespace mln
inline
mln_deduce(I, site, coord) min_ind(const Image<I>& ima)
{
+ trace::entering("mln::geom::min_ind");
+
mln_precondition(exact(ima).is_valid());
- return exact(ima).bbox().pmin().ind();
+ mln_deduce(I, site, coord) minind = exact(ima).bbox().pmin().ind();
+
+ trace::exiting("mln::geom::min_ind");
+ return minind;
}
# endif // ! MLN_INCLUDE_ONLY
diff --git a/milena/mln/geom/min_row.hh b/milena/mln/geom/min_row.hh
index 0d991ca..05ee4cb 100644
--- a/milena/mln/geom/min_row.hh
+++ b/milena/mln/geom/min_row.hh
@@ -1,4 +1,4 @@
-// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2008, 2009 EPITA Research and Development Laboratory
// (LRDE)
//
// This file is part of the Olena Library. This library is free
@@ -61,8 +61,13 @@ namespace mln
inline
mln_deduce(I, site, coord) min_row(const Image<I>& ima)
{
+ trace::entering("mln::geom::min_row");
+
mln_precondition(exact(ima).is_valid());
- return geom::bbox(ima).pmin().row();
+ mln_deduce(I, site, coord) minrow = geom::bbox(ima).pmin().row();
+
+ trace::exiting("mln::geom::min_row");
+ return minrow;
}
@@ -70,8 +75,13 @@ namespace mln
inline
mln_deduce(B, point, coord) min_row(const Box<B>& b)
{
+ trace::entering("mln::geom::min_row");
+
metal::not_<metal::equal<metal::int_<B::dim>, metal::int_<1> > >::check();
- return exact(b).pmin().row();
+ mln_deduce(B, point, coord) minrow = exact(b).pmin().row();
+
+ trace::exiting("mln::geom::min_row");
+ return minrow;
}
# endif // ! MLN_INCLUDE_ONLY
diff --git a/milena/mln/geom/min_sli.hh b/milena/mln/geom/min_sli.hh
index 9d186fe..182fe15 100644
--- a/milena/mln/geom/min_sli.hh
+++ b/milena/mln/geom/min_sli.hh
@@ -1,4 +1,4 @@
-// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2008, 2009 EPITA Research and Development Laboratory
// (LRDE)
//
// This file is part of the Olena Library. This library is free
@@ -53,8 +53,13 @@ namespace mln
inline
mln_deduce(I, site, coord) min_sli(const Image<I>& ima)
{
+ trace::entering("mln::geom::min_sli");
+
mln_precondition(exact(ima).is_valid());
- return exact(ima).bbox().pmin().sli();
+ mln_deduce(I, site, coord) minsli = exact(ima).bbox().pmin().sli();
+
+ trace::exiting("mln::geom::min_sli");
+ return minsli;
}
# endif // ! MLN_INCLUDE_ONLY
diff --git a/milena/mln/geom/ncols.hh b/milena/mln/geom/ncols.hh
index 76c2d5a..6aa3742 100644
--- a/milena/mln/geom/ncols.hh
+++ b/milena/mln/geom/ncols.hh
@@ -1,4 +1,4 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2009 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
@@ -28,10 +28,9 @@
#ifndef MLN_GEOM_NCOLS_HH
# define MLN_GEOM_NCOLS_HH
-/*! \file mln/geom/ncols.hh
- *
- * \brief Give the number of columns of an image.
- */
+/// \file mln/geom/ncols.hh
+///
+/// Give the number of columns of an image.
# include <mln/geom/min_col.hh>
# include <mln/geom/max_col.hh>
@@ -58,16 +57,26 @@ namespace mln
inline
unsigned ncols(const Image<I>& ima)
{
+ trace::entering("mln::geom::ncols");
+
mln_precondition(exact(ima).is_valid());
- return geom::max_col(ima) - geom::min_col(ima) + 1;
+ unsigned ncols = geom::max_col(ima) - geom::min_col(ima) + 1;
+
+ trace::exiting("mln::geom::ncols");
+ return ncols;
}
template <typename B>
unsigned ncols(const Box<B>& b)
{
+ trace::entering("mln::geom::ncols");
+
metal::not_<metal::equal<metal::int_<B::dim>, metal::int_<1> > >::check();
- return geom::max_col(b) - geom::min_col(b) + 1;
+ unsigned ncols = geom::max_col(b) - geom::min_col(b) + 1;
+
+ trace::exiting("mln::geom::ncols");
+ return ncols;
}
# endif // ! MLN_INCLUDE_ONLY
diff --git a/milena/mln/geom/ninds.hh b/milena/mln/geom/ninds.hh
index a331748..47026ed 100644
--- a/milena/mln/geom/ninds.hh
+++ b/milena/mln/geom/ninds.hh
@@ -1,4 +1,4 @@
-// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2008, 2009 EPITA Research and Development Laboratory
// (LRDE)
//
// This file is part of the Olena Library. This library is free
@@ -54,8 +54,13 @@ namespace mln
inline
unsigned ninds(const Image<I>& ima)
{
+ trace::entering("mln::geom::ninds");
+
mln_precondition(exact(ima).is_valid());
- return geom::max_ind(ima) - geom::min_ind(ima) + 1;
+ unsigned ninds = geom::max_ind(ima) - geom::min_ind(ima) + 1;
+
+ trace::exiting("mln::geom::ninds");
+ return ninds;
}
# endif // ! MLN_INCLUDE_ONLY
diff --git a/milena/mln/geom/nrows.hh b/milena/mln/geom/nrows.hh
index c7f3e9a..01e9969 100644
--- a/milena/mln/geom/nrows.hh
+++ b/milena/mln/geom/nrows.hh
@@ -1,4 +1,4 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2009 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
@@ -28,10 +28,9 @@
#ifndef MLN_GEOM_NROWS_HH
# define MLN_GEOM_NROWS_HH
-/*! \file mln/geom/nrows.hh
- *
- * \brief Give the number of rows of an image.
- */
+/// \file mln/geom/nrows.hh
+///
+/// Give the number of rows of an image.
# include <mln/geom/min_row.hh>
# include <mln/geom/max_row.hh>
@@ -58,15 +57,25 @@ namespace mln
inline
unsigned nrows(const Image<I>& ima)
{
+ trace::entering("mln::geom::nrows");
+
mln_precondition(exact(ima).is_valid());
- return geom::max_row(ima) - geom::min_row(ima) + 1;
+ unsigned nrows = geom::max_row(ima) - geom::min_row(ima) + 1;
+
+ trace::exiting("mln::geom::nrows");
+ return nrows;
}
template <typename B>
unsigned nrows(const Box<B>& b)
{
+ trace::entering("mln::geom::nrows");
+
metal::not_<metal::equal<metal::int_<B::dim>, metal::int_<1> > >::check();
- return geom::max_row(b) - geom::min_row(b) + 1;
+ unsigned nrows = geom::max_row(b) - geom::min_row(b) + 1;
+
+ trace::exiting("mln::geom::nrows");
+ return nrows;
}
# endif // ! MLN_INCLUDE_ONLY
diff --git a/milena/mln/geom/nslis.hh b/milena/mln/geom/nslis.hh
index 3e6aa77..5ce4e6b 100644
--- a/milena/mln/geom/nslis.hh
+++ b/milena/mln/geom/nslis.hh
@@ -1,4 +1,4 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2009 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
@@ -28,10 +28,9 @@
#ifndef MLN_GEOM_NSLIS_HH
# define MLN_GEOM_NSLIS_HH
-/*! \file mln/geom/nslis.hh
- *
- * \brief Give the number of slices of an image.
- */
+/// \file mln/geom/nslis.hh
+///
+/// Give the number of slices of an image.
# include <mln/geom/min_sli.hh>
# include <mln/geom/max_sli.hh>
@@ -54,8 +53,13 @@ namespace mln
inline
unsigned nslis(const Image<I>& ima)
{
+ trace::entering("mln::geom::nslis");
+
mln_precondition(exact(ima).is_valid());
- return geom::max_sli(ima) - geom::min_sli(ima) + 1;
+ unsigned nslis = geom::max_sli(ima) - geom::min_sli(ima) + 1;
+
+ trace::exiting("mln::geom::nslis");
+ return nslis;
}
# endif // ! MLN_INCLUDE_ONLY
--
1.5.6.5
1
0
Re: [Olena-patches] [Olena] #30: Result images missing in reference documentation
by Olena Trac 02 Mar '09
by Olena Trac 02 Mar '09
02 Mar '09
#30: Result images missing in reference documentation
-----------------------+----------------------------------------------------
Reporter: levill_r | Owner: Olena Team
Type: defect | Status: closed
Priority: major | Milestone: Olena 0.11.1
Component: other | Version: 0.11
Resolution: wontfix | Keywords: ref doc doxygen images
-----------------------+----------------------------------------------------
Changes (by lazzara):
* status: new => closed
* resolution: => wontfix
Comment:
This task is obsolete.
New documentation for Olena 1.0 does include all generated images.
--
Ticket URL: <https://trac.lrde.org/olena/ticket/30#comment:3>
Olena <http://olena.lrde.epita.fr>
Olena, a generic and efficient C++ image processing library.
1
0
Re: [Olena-patches] [Olena] #3: Migrate Olena 0.11 (and previous revisions) from PRCS to Subversion
by Olena Trac 02 Mar '09
by Olena Trac 02 Mar '09
02 Mar '09
#3: Migrate Olena 0.11 (and previous revisions) from PRCS to Subversion
--------------------------+-------------------------------------------------
Reporter: levill_r | Owner: levill_r
Type: enhancement | Status: closed
Priority: blocker | Milestone: Olena 0.11.1
Component: other | Version: 0.11
Resolution: wontfix | Keywords: prcs subversion svn
--------------------------+-------------------------------------------------
Changes (by lazzara):
* status: assigned => closed
* resolution: => wontfix
Comment:
This task is obsolete.
--
Ticket URL: <https://trac.lrde.org/olena/ticket/3#comment:7>
Olena <http://olena.lrde.epita.fr>
Olena, a generic and efficient C++ image processing library.
1
0
* sandbox/scribo/Makefile: add new rules.
* sandbox/scribo/demat.hh: add more documentation.
* sandbox/scribo/demat31Oct2008.hh,
* sandbox/scribo/demat_v2.hh: remove.
---
milena/ChangeLog | 11 +
milena/sandbox/scribo/Makefile | 14 +-
milena/sandbox/scribo/demat.hh | 137 +++++++--
milena/sandbox/scribo/demat31Oct2008.hh | 559 -------------------------------
milena/sandbox/scribo/demat_v2.hh | 134 --------
5 files changed, 138 insertions(+), 717 deletions(-)
delete mode 100644 milena/sandbox/scribo/demat31Oct2008.hh
delete mode 100644 milena/sandbox/scribo/demat_v2.hh
diff --git a/milena/ChangeLog b/milena/ChangeLog
index e894701..438bfe2 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,5 +1,16 @@
2009-03-02 Guillaume Lazzara <lazzara(a)lrde.epita.fr>
+ Cleanup scribo sandbox.
+
+ * sandbox/scribo/Makefile: add new rules.
+
+ * sandbox/scribo/demat.hh: add more documentation.
+
+ * sandbox/scribo/demat31Oct2008.hh,
+ * sandbox/scribo/demat_v2.hh: remove.
+
+2009-03-02 Guillaume Lazzara <lazzara(a)lrde.epita.fr>
+
Small fixes.
* headers.mk: update dist headers.
diff --git a/milena/sandbox/scribo/Makefile b/milena/sandbox/scribo/Makefile
index 2a58b92..730d8c2 100644
--- a/milena/sandbox/scribo/Makefile
+++ b/milena/sandbox/scribo/Makefile
@@ -1,5 +1,13 @@
-all:
- g++ -I../.. -I$(HOME)/local/include -O1 -DNDEBUG table.cc $(HOME)/local/lib/libtesseract_full.a -lpthread
+all: table photo
+
+table: demat.hh
+ g++ -I../.. -I$(HOME)/local/include -O1 -DNDEBUG table.cc $(HOME)/local/lib/libtesseract_full.a -lpthread -o table
+
+photo: demat.hh
+ g++ -I../.. -I$(HOME)/local/include -O1 -DNDEBUG photo.cc $(HOME)/local/lib/libtesseract_full.a -lpthread -o photo
clean:
- rm -f a.out
+ rm *.ppm *.pgm *.pbm
+
+dist-clean: clean
+ rm -f table photo
diff --git a/milena/sandbox/scribo/demat.hh b/milena/sandbox/scribo/demat.hh
index 0bc72ef..8872afc 100644
--- a/milena/sandbox/scribo/demat.hh
+++ b/milena/sandbox/scribo/demat.hh
@@ -1,4 +1,5 @@
-// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory
+// (LRDE)
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -48,9 +49,10 @@
# include <mln/transform/influence_zone_geodesic.hh>
# include <mln/debug/draw_graph.hh>
# include <mln/make/graph.hh>
+# include <mln/make/region_adjacency_graph.hh>
# include <mln/util/graph.hh>
# include <mln/util/line_graph.hh>
-# include <mln/opt/at.hh>
+# include <mln/io/txt/save.hh>
# include <mln/canvas/browsing/depth_first_search.hh>
@@ -109,9 +111,13 @@ namespace scribo
std::ostringstream os;
os << "./"
- << file_id++
- << "_"
<< input_file
+ << "_";
+
+ if (file_id < 10)
+ os << "0";
+
+ os << file_id++
<< "_"
<< name;
return os.str();
@@ -185,7 +191,7 @@ namespace scribo
//-*****************************************
/// \{
- /// Passes the text bboxes to Tesseract and store the result an image of
+ /// Passes the text bboxes to Tesseract and store the result in an image of
/// char.
/// \param[in] in image from where the text bboxes are extracted.
/// \param[in] lbl labeled image.
@@ -258,6 +264,22 @@ namespace scribo
** 4 | | | {2} |
** 5 |- - | | {2} |
** 6 | | | {2} |
+ **
+ ** \p hboxes contains all the table lines bboxes. Each bbox is
+ ** associated with an id, its location in the array.
+ **
+ ** For each bbox, its id is marked in a vector. The location is defined,
+ ** according to the given parameter \p dim, either by the row or the col
+ ** value of the pmin site.
+ **
+ ** Ids are then propagated in the vector according a small delta value.
+ ** if bbox ids are at the same location in the vector, their related bboxes
+ ** are likely to be on the same line.
+ **
+ ** Finally, iterate over the vector until all bboxes have been treated.
+ ** For each iteration, the set with a specific number of elements is found
+ ** and all bboxes referenced in this set are aligned on the same row or col.
+ **
*/
util::array<int>
align_lines(unsigned nsites,
@@ -296,6 +318,9 @@ namespace scribo
max_nelts = lines[i].nelements();
// Aligning lines
+ // FIXME: not optimal... Make it faster!
+ // We may do too much iterations (while loop) and some of them may
+ // be done for nothing...
util::array<int> newlines;
while (max_nelts > 0)
{
@@ -327,7 +352,7 @@ namespace scribo
- /// Connect lines if they are close to each other.
+ /// Connect vertical and horizontal lines if they are close to each other.
void
connect_lines(const util::array<int>& aligned_lines,
util::array<box2d>& boxes,
@@ -353,6 +378,49 @@ namespace scribo
}
}
+// void
+// connect_lines2(const util::array<int>& aligned_lines,
+// util::array<box2d>& boxes,
+// unsigned dim,
+// unsigned dim_size)
+// {
+// image1d<int> l(dim_size);
+// data::fill(l, -1);
+//
+// for_all_components(i, boxes)
+// {
+// opt::at(l, boxes[i].pmin()[dim]) = i;
+// opt::at(l, boxes[i].pmax()[dim]) = i;
+// }
+//
+// for (unsigned i = 0; i < settings.max_dist_lines; ++i)
+// l = morpho::elementary::dilation(l, c2());
+//
+// for_all_components(i, boxes)
+// {
+// std::pair<point2d, point2d> cp = central_sites(boxes[i], dim);
+//
+// win::segment1d seg(11);
+// {
+// mln_qiter_(win::segment1d) q(seg, point1d(cp.first[dim]));
+// for_all(q)
+// if (opt::at(l, q[0]) != -1)
+// {
+// boxes[i].pmin()[dim] = boxes[opt::at(l, q[0])].pmin()[dim];
+// break;
+// }
+// }
+// {
+// mln_qiter_(win::segment1d) q(seg, point1d(cp.second[dim]));
+// for_all(q)
+// if (opt::at(l, q[0]) != -1)
+// {
+// boxes[i].pmax()[dim] = boxes[opt::at(l, q[0])].pmax()[dim];
+// break;
+// }
+// }
+// }
+// }
/// Align line bboxes vertically and horizontally. Then, try to join
@@ -372,7 +440,7 @@ namespace scribo
1);
# ifndef NOUT
image2d<rgb8> out2(in.domain());
- level::fill(out2, literal::black);
+ data::fill(out2, literal::black);
for_all_components(i, tblboxes.first)
draw::box(out2, tblboxes.first[i], literal::red);
for_all_components(i, tblboxes.second)
@@ -380,6 +448,12 @@ namespace scribo
io::ppm::save(out2, output_file("after-alignment.ppm"));
# endif
+ // FIXME: Rebuild incomplete lines if possible.
+ // ----- --- => ----------
+// connect_lines2(tblboxes.first, 0, in.nrows());
+// connect_lines2(rows, tblboxes.second, 0, in.nrows());
+
+ // Connect vertical lines with horizontal lines.
connect_lines(rows, tblboxes.first, 0, in.nrows());
connect_lines(cols, tblboxes.second, 1, in.ncols());
@@ -481,7 +555,7 @@ namespace scribo
/// Find table bboxes and remove them from the image.
std::pair<util::array<box2d>,
- util::array<box2d> >
+ util::array<box2d> >
extract_tables(image2d<bool>& in)
{
typedef image2d<label_16> I;
@@ -489,7 +563,7 @@ namespace scribo
typedef util::array<mln_result_(A)> boxes_t;
- // Lignes verticales
+ // Vertical lines
std::cout << "Removing vertical lines" << std::endl;
win::vline2d vline(settings.ero_line_width);
image2d<bool> vfilter = morpho::rank_filter(in, vline, settings.rank_filter);
@@ -500,7 +574,7 @@ namespace scribo
boxes_t vboxes = component_boxes(vfilter);
- // Lignes horizontales
+ // Horizontal lines.
std::cout << "Removing horizontal lines" << std::endl;
win::hline2d hline(settings.ero_line_width);
image2d<bool> hfilter = morpho::rank_filter(in, hline, settings.rank_filter);
@@ -596,12 +670,15 @@ namespace scribo
if (settings.treat_tables)
{
+ // Remove components which are too small
typedef util::array<accu_count_res_t> nsitecomp_t;
nsitecomp_t nsitecomp = labeling::compute(accu_count_t(), lbl, nlabels);
remove_small_comps<accu_count_res_t> fl2b(nsitecomp);
labeling::relabel_inplace(lbl, nlabels, fl2b);
} else
{
+ // Remove components which have too much or not enough sites and which are
+ // too heigh.
typedef util::array<accu_pair_res_t> nsitecomp_t;
nsitecomp_t nsitecomp = labeling::compute(accu_pair_t(), lbl, nlabels);
remove_smallandlarge_comps<accu_pair_res_t> fl2b(nsitecomp);
@@ -609,6 +686,9 @@ namespace scribo
}
}
+
+ /// Functor to be passed to depth_first_search.
+ /// Map each component vertex with its representative vertex id.
struct make_relabel_fun_t
{
template <typename G>
@@ -640,6 +720,10 @@ namespace scribo
fun::l2l::relabel<label_16> l2l;
};
+
+
+ /// Functor to be passed to depth_first_search.
+ /// Computes the number of vertices per graph component.
struct comp_size_t
{
template <typename G>
@@ -654,6 +738,7 @@ namespace scribo
void next()
{
unsigned compsize = comp_vertices.nelements();
+ std::cout << "compsize = " << compsize << std::endl;
for (unsigned i = 0; i < comp_vertices.nelements(); ++i)
treated[comp_vertices[i]] = compsize;
comp_vertices.clear();
@@ -663,7 +748,11 @@ namespace scribo
{ comp_vertices.insert(id); }
void update_queued(unsigned id)
- { update_treated(id); }
+ {
+ std::cout << "update_queued_before " << comp_vertices << std::endl;
+ update_treated(id);
+ std::cout << "update_queued_after " << comp_vertices << std::endl;
+ }
bool to_be_treated(unsigned id)
{ return treated[id] == mln_max(label_16); }
@@ -675,6 +764,8 @@ namespace scribo
util::array<unsigned> treated;
};
+
+
/// Merge bboxes according to their left box neighbor.
util::array<box2d>
group_bboxes(const util::graph& g, image2d<label_16>& lbl,
@@ -710,6 +801,7 @@ namespace scribo
comp_size_t comp_size;
canvas::browsing::depth_first_search(g, comp_size);
+ std::cout << g << std::endl;
for_all_ncomponents(i, nlabels)
if (tboxes[i].is_valid())
if (comp_size.treated[i] < 3)
@@ -750,7 +842,7 @@ namespace scribo
int dmax = midcol + settings.bbox_distance;
point2d c = cboxes[i].center();
/// First site on the right of the central site
- point2d p(c.row(), c.col() + 1);
+ point2d p = c + right;
// FIXME: Lemmings with a condition on the distance => write a special version?
while (lbl.domain().has(p) && (lbl(p) == 0u || lbl(p) == i)
@@ -793,21 +885,24 @@ namespace scribo
return tboxes;
}
+
+
+
+ /// Function mapping value to sites of a line graph image.
template <typename P>
struct lg_vertex_values : public mln::Function_p2v< lg_vertex_values<P> >
{
typedef float result;
+ // Compute the angle between P and (0,1)
float operator()(const P& p) const
{
- mln::algebra::vec<2,float> v;
+ mln::algebra::vec<2,float> v, pv;
v[0] = 0;
v[1] = 1;
- float norm = mln::math::sqrt(std::pow(p.to_vec()[0], 2)
- + std::pow(p.to_vec()[1], 2));
- // FIXME: missing proxy_impl for point and line2d?
- float res = (v * p.to_vec()) / norm;
- return res;
+ pv = p.to_vec().normalize();
+
+ return v * pv;
}
};
@@ -848,7 +943,7 @@ namespace scribo
#endif
typedef util::graph G;
- G g = make::graph(iz | (pw::value(iz) != pw::cst(0u)), nlabels);
+ G g = make::graph(iz | (pw::value(iz) != pw::cst(0u)), c8(), nlabels);
// Compute the component centers and use them as vertex.
//FIXME: Add fun::vertex2p
@@ -857,8 +952,6 @@ namespace scribo
for_all_components(i, tboxes)
fv2p(i) = tboxes[i].center();
-// util::array<point2d> centers = labeling::compute(accu::center<point2d>(), iz, nlabels);
-// fv2p_t fv2p = convert::to<fv2p_t>(centers);
// Create a p_vertices.
p_vertices<G, fv2p_t> pv(g, fv2p);
@@ -935,6 +1028,8 @@ namespace scribo
internal::settings.max_comp_size = in.ncols() * in.nrows() * 0.05;
+ // tblboxes.first = vertical lines.
+ // tblboxes.second = horizontal lines.
std::pair<util::array<box2d>,
util::array<box2d> > tblboxes = internal::extract_tables(in);
image2d<bool> table = internal::rebuild_table(in, tblboxes);
diff --git a/milena/sandbox/scribo/demat31Oct2008.hh b/milena/sandbox/scribo/demat31Oct2008.hh
deleted file mode 100644
index e482326..0000000
--- a/milena/sandbox/scribo/demat31Oct2008.hh
+++ /dev/null
@@ -1,559 +0,0 @@
-// 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.
-
-# ifndef DEMAT_HH_
-# define DEMAT_HH_
-
-# include <libgen.h>
-# include <sstream>
-
-# include <mln/core/image/image2d.hh>
-# include <mln/core/image/image1d.hh>
-
-# include <mln/core/concept/function.hh>
-# include <mln/core/image/image_if.hh>
-# include <mln/core/image/sub_image.hh>
-# include <mln/core/image/cast_image.hh>
-# include <mln/core/alias/neighb2d.hh>
-# include <mln/core/var.hh>
-# include <mln/core/routine/clone.hh>
-# include <mln/core/routine/ops.hh>
-# include <mln/core/site_set/p_vaccess.hh>
-# include <mln/core/site_set/p_set.hh>
-
-# include <mln/accu/bbox.hh>
-# include <mln/accu/count.hh>
-
-# include <mln/border/fill.hh>
-
-# include <mln/convert/to.hh>
-# include <mln/convert/to_fun.hh>
-
-# include <mln/debug/println.hh>
-# include <mln/debug/colorize.hh>
-
-# include <mln/draw/box.hh>
-
-# include <mln/fun/i2v/array.hh>
-
-# include <mln/io/pbm/load.hh>
-# include <mln/io/pbm/save.hh>
-# include <mln/io/ppm/save.hh>
-# include <mln/io/pgm/save.hh>
-
-# include <mln/labeling/blobs.hh>
-# include <mln/labeling/compute.hh>
-
-# include <mln/level/convert.hh>
-# include <mln/level/compute.hh>
-# include <mln/level/fill.hh>
-# include <mln/level/paste.hh>
-# include <mln/level/apply.hh>
-# include <mln/level/transform.hh>
-
-# include <mln/literal/all.hh>
-
-# include <mln/logical/not.hh>
-
-# include <mln/morpho/hit_or_miss.hh>
-# include <mln/morpho/erosion.hh>
-# include <mln/morpho/top_hat.hh>
-
-# include <mln/pw/all.hh>
-
-# include <mln/util/array.hh>
-
-# include <mln/value/int_u16.hh>
-# include <mln/value/rgb8.hh>
-
-# include <mln/win/hline2d.hh>
-# include <mln/win/vline2d.hh>
-
-namespace scribo
-{
-
- namespace internal
- {
-
- using namespace mln;
- using value::int_u16;
- using value::rgb8;
-
- char *input_file = 0;
- int dbg_file_id = 0;
-
- std::string output_file(const char *name, unsigned file_id)
- {
- std::ostringstream os;
- os << "./"
- << file_id
- << "_"
- << input_file
- << "_"
- << name;
- return os.str();
- }
-
- void draw_component_boxes(image2d<rgb8>& output, const util::array<box2d>& boxes)
- {
- for (unsigned i = 1; i < boxes.nelements(); ++i)
- if (boxes[i].is_valid())
- {
- output(boxes[i].center()) = literal::red;
- draw::box(output, boxes[i], literal::red);
- }
- }
-
- template <typename V>
- void save_lbl_image(const image2d<V>& lbl, unsigned nlabels,
- const char *filename, unsigned file_id)
- {
- image2d<rgb8> output = debug::colorize<image2d<rgb8>, image2d<V> >(lbl, nlabels);
- io::ppm::save(output, output_file(filename, file_id));
- }
-
-
- /// Functions related to the matrix extraction
- /// \{
-
- void draw_hline(image2d<rgb8>& ima,
- const box2d& box,
- const rgb8& v)
- {
- unsigned ncols = box.pmax().col() - box.pmin().col();
- point2d p1 = box.center();
- p1.col() -= ncols / 2;
- point2d p2 = box.center();
- p2.col() += ncols / 2;
-
- draw::line(ima, p1, p2, v);
- }
-
- void draw_vline(image2d<rgb8>& ima,
- const box2d& box,
- const rgb8& v)
- {
- unsigned nrows = box.pmax().row() - box.pmin().row();
- point2d p1 = box.center();
- p1.row() -= nrows / 2;
- point2d p2 = box.center();
- p2.row() += nrows / 2;
-
- draw::line(ima, p1, p2, v);
- }
-
- void draw_row(image2d<rgb8>& ima,
- unsigned line,
- const rgb8& v)
- {
- draw::line(ima, point2d(line, 0), point2d(line, ima.ncols()), v);
- }
-
- void draw_col(image2d<rgb8>& ima,
- unsigned line,
- const rgb8& v)
- {
- draw::line(ima, point2d(0, line), point2d(ima.nrows(), line), v);
- }
-
- void
- extract_matrix(const image2d<bool>& in,
- std::pair<util::array<box2d>, util::array<box2d> > tboxes)
- {
- std::cout << "Extracting matrix..." << std::endl;
-
- image1d<unsigned> hend(in.ncols()),
- hrow(in.nrows()),
- vend(in.nrows()),
- vcol(in.ncols());
-
- level::fill(hend, 0);
- level::fill(hrow, 0);
- level::fill(vend, 0);
- level::fill(vcol, 0);
-
- for (unsigned i = 1; i < tboxes.first.nelements(); ++i)
- {
- ++vend.at(tboxes.first[i].pmin().row());
- ++vend.at(tboxes.first[i].pmax().row());
- ++vcol.at(tboxes.first[i].center().col());
- }
-
- for (unsigned i = 1; i < tboxes.second.nelements(); ++i)
- {
- ++hend.at(tboxes.second[i].pmin().col());
- ++hend.at(tboxes.second[i].pmax().col());
- ++hrow.at(tboxes.second[i].center().row());
- }
-
-#ifndef NOUT
- image2d<rgb8> tmp(in.domain());
- level::fill(tmp, literal::black);
-
- for (unsigned i = 1; i < in.ncols(); ++i)
- {
- if (hend.at(i) > 0)
- draw_col(tmp, i, literal::dark_orange);
- if (vcol.at(i) > 0)
- draw_col(tmp, i, literal::dark_orange);
- }
-
- for (unsigned i = 1; i < in.nrows(); ++i)
- {
- if (hrow.at(i) > 0)
- draw_row(tmp, i, literal::dark_red);
- if (vend.at(i) > 0)
- draw_row(tmp, i, literal::dark_red);
- }
-
- for (unsigned i = 1; i < tboxes.first.nelements(); ++i)
- draw_vline(tmp, tboxes.first[i], literal::green);
-
- for (unsigned i = 1; i < tboxes.second.nelements(); ++i)
- draw_hline(tmp, tboxes.second[i], literal::red);
-
- io::ppm::save(tmp, output_file("matrix.ppm", 4));
-#endif
-
- }
-
- /// \}
-
-
-
- /// Functions related to the table removal
- /// \{
-
-
- /// Extract the components bboxes.
- util::array<box2d>
- component_boxes(const image2d<bool>& filter)
- {
- std::cout << "component boxes" << std::endl;
- int_u16 nlabels = 0;
- image2d<int_u16> lbl = labeling::blobs(filter, c8(), nlabels);
-
- return labeling::compute(accu::meta::bbox(), lbl, nlabels);
- }
-
- /// Remove table bboxes from an image.
- void erase_table_boxes(image2d<bool>& output,
- util::array<box2d>& boxes,
- unsigned bbox_enlarge, unsigned dim)
- {
- for (unsigned i = 1; i < boxes.nelements(); ++i)
- {
- boxes[i].enlarge(dim, bbox_enlarge + 1);
- boxes[i].crop_wrt(output.domain());
- level::paste((pw::cst(false) | boxes[i] |
- (pw::value(output) == pw::cst(true))), output);
- }
- }
-
-
- /// Find table bboxes and remove them from the image.
- std::pair<util::array<box2d>,
- util::array<box2d> >
- extract_tables(image2d<bool>& in,
- image2d<rgb8>& output,
- unsigned l)
- {
- typedef image2d<int_u16> I;
- typedef accu::bbox<mln_psite_(I)> A;
- typedef util::array<mln_result_(A)> boxes_t;
-
-
- // Lignes verticales
- std::cout << "Removing vertical lines" << std::endl;
- win::vline2d vline(l);
- image2d<bool> vfilter = morpho::erosion(in, vline);
-
-#ifndef NOUT
- io::pbm::save(vfilter, output_file("table-vfilter.pbm", 1));
-#endif
-
- boxes_t vboxes = component_boxes(vfilter);
- erase_table_boxes(in, vboxes, (l / 2), 0);
-
-
- // Lignes horizontales
- std::cout << "Removing horizontal lines" << std::endl;
- win::hline2d hline(l);
- image2d<bool> hfilter = morpho::erosion(in, hline);
-
-#ifndef NOUT
- io::pbm::save(hfilter, output_file("table-hfilter.pbm", 2));
-#endif
-
- boxes_t hboxes = component_boxes(hfilter);
- erase_table_boxes(in, hboxes, (l / 2), 1);
-
-
-#ifndef NOUT
- image2d<rgb8> tmp = clone(output);
- draw_component_boxes(tmp, vboxes);
- draw_component_boxes(tmp, hboxes);
- io::ppm::save(tmp, output_file("table-filtered.ppm", 3));
-#endif
-
- return std::make_pair(vboxes, hboxes);
- }
-
- /// \}
- /// End of functions related to the table removal.
-
-
- /// Function related to text extraction
- /// \{
-
- inline
- int_u16
- most_left(const fun::i2v::array<int_u16>& left_link, unsigned i)
- {
- while (left_link(i) != i)
- i = left_link(i);
- return i;
- }
-
- inline
- int_u16
- uncurri_left_link(fun::i2v::array<int_u16>& left_link, unsigned i)
- {
- if (left_link(i) != i)
- left_link(i) = uncurri_left_link(left_link, left_link(i));
- return left_link(i);
- }
-
- template <typename V>
- void
- remove_small_comps_i2v(image2d<V>& lbl,
- V& nlabels,
- unsigned min_comp_size)
- {
- std::cout << "Removing small components smaller than "
- << min_comp_size << " sites among " << nlabels
- << " components" << std::endl;
-
- typedef accu::count<mln_psite(image2d<V>)> accu_count_t;
-
- util::array<mln_result(accu_count_t)> nsitecomp
- = labeling::compute(accu_count_t(), lbl, nlabels);
-
- V ncomp = 0;
-
- fun::i2v::array<V> f(nsitecomp.nelements());
- f(0) = 0;
-
- for (unsigned i = 1; i <= nlabels; ++i)
- {
- if (nsitecomp[i] < min_comp_size)
- f(i) = 0;
- else
- f(i) = ++ncomp;
- }
-
- lbl = level::transform(lbl, f);
- nlabels = ncomp;
-
-#ifndef NOUT
- save_lbl_image(lbl, nlabels, "lbl-small-comps-removed.pgm", 6);
-#endif
- }
-
-
- /// Merge bboxes according to their left box neighbor.
- util::array< box2d >
- group_bboxes(fun::i2v::array<int_u16>& left_link, image2d<int_u16>& lbl,
- util::array<box2d>& cboxes, unsigned ncomp)
- {
- // Currify left_link lookup table and compute text area bboxes.
- util::array< accu::bbox<point2d> > tboxes;
- tboxes.resize(ncomp + 1);
- for (unsigned i = 1; i <= ncomp; ++i)
- tboxes[uncurri_left_link(left_link, i)].take(cboxes[i]);
-
- //Update labels
- lbl = level::transform(lbl, left_link);
-
-#ifndef NOUT
- save_lbl_image(lbl, ncomp, "lbl-grouped-boxes.pgm", 7);
-#endif
-
- util::array<box2d> result;
- for (unsigned i = 1; i <= ncomp; ++i)
- if (tboxes[i].is_valid())
- result.append(tboxes[i].to_result());
-
- return result;
- }
-
-
- /// Update the lookup table \p left if a neighbor is found on the right of
- /// the current bbox.
- void update_link(fun::i2v::array<int_u16>& left_link, image2d<int_u16>& lbl,
- const point2d& p, const point2d& c,
- unsigned i, int dmax)
- {
- if (lbl.domain().has(p) && lbl(p) != 0u && lbl(p) != i
- && (math::abs(p.col() - c.col())) < dmax)
- {
- if (left_link(lbl(p)) == lbl(p) && most_left(left_link, i) != lbl(p))
- left_link(lbl(p)) = i;
-// else
-// left_link(lbl(p)) = 0;//FIXME: should be uncommented?
- }
- }
-
-
-
- /// Map each character bbox to its left bbox neighbor if possible.
- /// Iterate to the right but link boxes to the left.
- fun::i2v::array<int_u16>
- link_character_bboxes(image2d<int_u16>& lbl,
- const util::array<box2d>& cboxes,
- unsigned ncomp,
- unsigned bbox_distance)
- {
- fun::i2v::array<int_u16> left_link;
- left_link.resize(ncomp + 1);
-
- for (unsigned i = 0; i <= ncomp; ++i)
- left_link(i) = i;
-
- for (unsigned i = 1; i <= ncomp; ++i)
- {
- unsigned midcol = (cboxes[i].pmax().col() - cboxes[i].pmin().col()) / 2;
- int dmax = midcol + bbox_distance;
- point2d c = cboxes[i].center();
- /// First site on the right of the central site
- point2d p(c.row(), c.col() + 1);
-
- // FIXME: Lemmings with a condition on the distance => write a special version?
- while (lbl.domain().has(p) && (lbl(p) == 0u || lbl(p) == i)
- && math::abs(p.col() - c.col()) < dmax)
- ++p.col();
-
- update_link(left_link, lbl, p, c, i, dmax);
- }
-
- return left_link;
- }
-
- util::array<box2d>
- extract_text(image2d<bool>& in_,
- image2d<rgb8>& output,
- unsigned bbox_distance,
- unsigned min_comp_size)
- {
- std::cout << "extracting text..." << std::endl;
-
- typedef int_u16 V;
- typedef image2d<V> I;
- typedef util::array<box2d> boxes_t;
-
- // Extract edges.
- win::rectangle2d l(3, 3);
- image2d<bool> in = morpho::top_hat_white(in_, l);
- io::pbm::save(in, output_file("top_hat.ppm", 9));
-
- // Find character bboxes.
- V nlabels;
- image2d<V> lbl = labeling::blobs(in, c8(), nlabels);
-
- //Remove small components.
- remove_small_comps_i2v(lbl, nlabels, min_comp_size);
-
- boxes_t cboxes = labeling::compute(accu::meta::bbox(), lbl, nlabels);
-
-#ifndef NOUT
- image2d<rgb8> tmp = clone(output);
- draw_component_boxes(tmp, cboxes);
- io::ppm::save(tmp, output_file("character-bboxes.ppm", 5));
-#endif
-
- //merge_bboxes(cboxes, lbl, nlabels);
-
- //Link character bboxes to their left neighboor if possible.
- fun::i2v::array<int_u16> left =
- link_character_bboxes(lbl, cboxes, nlabels, bbox_distance);
-
- //Merge character bboxes according to their left neighbor.
- util::array<box2d> tboxes = group_bboxes(left, lbl, cboxes, nlabels);
-
- return tboxes;
- }
-
- /// \}
- /// End of functions related to text extraction
-
- } // end of namespace scribo::internal
-
-
- // Facade
- void demat(char *argv[], bool treat_tables)
- {
- using namespace mln;
- using value::rgb8;
-
- border::thickness = 3;
- trace::quiet = true;
-
- //Useful debug variables
- internal::input_file = basename(argv[1]);
- unsigned l = 101;
- unsigned bbox_distance = 25;
- unsigned min_comp_size = 5;
-
- //Load image
- image2d<bool> in;
- io::pbm::load(in, argv[1]);
- in = logical::not_(in);
-
- image2d<rgb8> output = level::convert(rgb8(), in);
-
- std::pair<util::array<box2d>,
- util::array<box2d> > tblboxes;
- if (treat_tables)
- {
- tblboxes = internal::extract_tables(in, output, l);
- internal::extract_matrix(in, tblboxes);
- }
-
- util::array<box2d> tboxes =
- internal::extract_text(in, output, bbox_distance, min_comp_size);
-
- internal::draw_component_boxes(output, tboxes);
- io::ppm::save(output, internal::output_file("out.ppm", 8));
-
- /// Use txt bboxes here with Tesseract
- /// for (i = 1; i < tboxes.nelements(); ++i)
- /// tesseract(in | tboxes[i])
- }
-
-} // end of namespace scribo
-
-# endif // ! DEMAT_HH
diff --git a/milena/sandbox/scribo/demat_v2.hh b/milena/sandbox/scribo/demat_v2.hh
deleted file mode 100644
index 2295c2f..0000000
--- a/milena/sandbox/scribo/demat_v2.hh
+++ /dev/null
@@ -1,134 +0,0 @@
-// 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.
-
-#ifndef DEMAT_HH_
-# define DEMAT_HH_
-
-# include <mln/core/image/image2d.hh>
-
-# include <mln/core/image/image_if.hh>
-# include <mln/core/image/sub_image.hh>
-# include <mln/core/alias/neighb2d.hh>
-# include <mln/core/var.hh>
-# include <mln/core/site_set/p_vaccess.hh>
-
-# include <mln/binarization/threshold.hh>
-# include <mln/morpho/hit_or_miss.hh>
-# include <mln/level/fill.hh>
-# include <mln/border/fill.hh>
-# include <mln/io/pbm/load.hh>
-# include <mln/io/pgm/load.hh>
-# include <mln/io/pbm/save.hh>
-# include <mln/io/pgm/save.hh>
-# include <mln/debug/println.hh>
-# include <mln/morpho/opening.hh>
-# include <mln/trait/value_.hh>
-# include <mln/value/int_u8.hh>
-# include <mln/value/int_u16.hh>
-# include <mln/level/paste.hh>
-# include <mln/labeling/blobs.hh>
-# include <mln/level/fill.hh>
-# include <mln/pw/all.hh>
-# include <mln/convert/to_fun.hh>
-# include <mln/geom/bbox.hh>
-
-# include <mln/labeling/compute.hh>
-# include <mln/accu/bbox.hh>
-
-namespace scribo
-{
-
- namespace internal
- {
-
- void filter_image(mln::image2d<bool>& ima,
- const mln::image2d<bool>& filter,
- unsigned bbox_larger)
- {
- using namespace mln;
- using value::int_u16;
-
- typedef image2d<int_u16> I;
- typedef mln_accu_with_(accu::meta::bbox, mln_psite_(I)) A;
- typedef util::array<A::result> boxes_t;
-
- int_u16 nlabels;
- I lbl = labeling::blobs(filter, c4(), nlabels);
-
- boxes_t boxes = labeling::compute(accu::meta::bbox(), lbl, nlabels);
-
- for (unsigned i = 1; i <= nlabels; ++i)
- level::paste(pw::cst(false)
- | boxes[i].to_larger(bbox_larger),
- ima);
- }
-
- void remove_tables(mln::image2d<bool>& in, unsigned h, unsigned w, unsigned n)
- {
- using namespace mln;
-
- // Lignes verticales
- win::rectangle2d vwin(h, w);
- image2d<bool> vfilter = morpho::opening(in, vwin);
- io::pbm::save(vfilter, "./table-vfilter.pbm");
- filter_image(in, vfilter, n);
-
-
- // Lignes horizontales
- win::rectangle2d hwin(w, h);
- image2d<bool> hfilter = morpho::opening(in, hwin);
- io::pbm::save(hfilter, "./table-hfilter.pbm");
- filter_image(in, hfilter, n);
- }
-
- } // end of namespace scribo::internal
-
-
-
- // Facade
- void demat(char *argv[])
- {
- using namespace mln;
- using value::int_u8;
-
- //Useful debug variables
- unsigned h = atoi(argv[2]);
- unsigned w = atoi(argv[3]);
- unsigned n = atoi(argv[4]);
-
- //Load image
- image2d<bool> in;
- io::pbm::load(in, argv[1]);
-
- internal::remove_tables(in, h, w, n);
-
- io::pbm::save(in, "./table-filtered.pbm");
- }
-
-} // end of namespace scribo
-
-# endif // ! DEMAT_HH
--
1.5.6.5
1
0
* headers.mk: update dist headers.
* mln/canvas/morpho/all.hh: remove non existing included headers.
* mln/morpho/tree/compute_attribute_image.hh,
* mln/canvas/morpho/attribute_filter.hh: add missing include.
* tests/core/image/plain.cc
* mln/level/compare.hh,
* mln/core/pixter2d.hh: add more preconditions.
* mln/io/dicom/load.hh: update doc.
* mln/morpho/essential.hh,
* mln/morpho/all.hh,
* mln/morpho/closing/algebraic.hh: revamp.
* mln/morpho/closing/all.hh,
* mln/morpho/closing/essential.hh,
* mln/morpho/opening/all.hh,
* mln/morpho/opening/essential.hh: new files.
* tests/unit_test/unit-tests.mk: update test list.
---
milena/ChangeLog | 28 ++++++++
milena/headers.mk | 37 ++++++----
milena/mln/canvas/morpho/all.hh | 4 +-
milena/mln/canvas/morpho/attribute_filter.hh | 2 +
milena/mln/core/pixter2d.hh | 3 +
milena/mln/io/dicom/load.hh | 24 +++----
milena/mln/level/compare.hh | 2 +
milena/mln/morpho/all.hh | 4 +-
milena/mln/morpho/closing/algebraic.hh | 57 +++++++++-------
.../mln/{canvas/morpho => morpho/closing}/all.hh | 37 ++++------
.../morpho/all.hh => morpho/closing/essential.hh} | 36 +++------
milena/mln/morpho/essential.hh | 4 +-
.../mln/{canvas/morpho => morpho/opening}/all.hh | 37 ++++------
.../morpho/all.hh => morpho/opening/essential.hh} | 36 +++------
milena/mln/morpho/tree/compute_attribute_image.hh | 8 ++-
milena/tests/core/image/plain.cc | 2 +
milena/tests/unit_test/unit-tests.mk | 74 ++++++++++++--------
17 files changed, 208 insertions(+), 187 deletions(-)
copy milena/mln/{canvas/morpho => morpho/closing}/all.hh (67%)
copy milena/mln/{canvas/morpho/all.hh => morpho/closing/essential.hh} (67%)
copy milena/mln/{canvas/morpho => morpho/opening}/all.hh (67%)
copy milena/mln/{canvas/morpho/all.hh => morpho/opening/essential.hh} (67%)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 39e6faa..e894701 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,3 +1,31 @@
+2009-03-02 Guillaume Lazzara <lazzara(a)lrde.epita.fr>
+
+ Small fixes.
+
+ * headers.mk: update dist headers.
+
+ * mln/canvas/morpho/all.hh: remove non existing included headers.
+
+ * mln/morpho/tree/compute_attribute_image.hh,
+ * mln/canvas/morpho/attribute_filter.hh: add missing include.
+
+ * tests/core/image/plain.cc
+ * mln/level/compare.hh,
+ * mln/core/pixter2d.hh: add more preconditions.
+
+ * mln/io/dicom/load.hh: update doc.
+
+ * mln/morpho/essential.hh,
+ * mln/morpho/all.hh,
+ * mln/morpho/closing/algebraic.hh: revamp.
+
+ * mln/morpho/closing/all.hh,
+ * mln/morpho/closing/essential.hh,
+ * mln/morpho/opening/all.hh,
+ * mln/morpho/opening/essential.hh: new files.
+
+ * tests/unit_test/unit-tests.mk: update test list.
+
2009-03-01 Edwin Carlinet <carlinet(a)lrde.epita.fr>
Make area_on_vertices work with new algebraic code [POST-RUSH].
diff --git a/milena/headers.mk b/milena/headers.mk
index 6460d8f..e37427e 100644
--- a/milena/headers.mk
+++ b/milena/headers.mk
@@ -359,6 +359,7 @@ mln/value/int_s.hh \
mln/value/rgb8.hh \
mln/value/int_s32.hh \
mln/value/float01_.hh \
+mln/value/int_u12.hh \
mln/value/rgb16.hh \
mln/value/int_u32.hh \
mln/value/gl8.hh \
@@ -534,9 +535,7 @@ mln/canvas/all.hh \
mln/canvas/distance_front.hh \
mln/canvas/morpho/internal/find_root.hh \
mln/canvas/morpho/all.hh \
-mln/canvas/morpho/connected_filter.hh \
-mln/canvas/morpho/algebraic_filter.hh \
-mln/canvas/morpho/algebraic_union_find.hh \
+mln/canvas/morpho/attribute_filter.hh \
mln/canvas/morpho/essential.hh \
mln/canvas/essential.hh \
mln/metal/is_const.hh \
@@ -623,29 +622,39 @@ mln/morpho/skeleton_constrained.hh \
mln/morpho/complementation.hh \
mln/morpho/line_gradient.hh \
mln/morpho/hit_or_miss.hh \
-mln/morpho/closing_height.hh \
mln/morpho/plus.hh \
mln/morpho/general.hh \
mln/morpho/internal/elementary.hh \
mln/morpho/contrast.hh \
-mln/morpho/opening_area.hh \
-mln/morpho/opening_height.hh \
mln/morpho/thickening.hh \
mln/morpho/dilation.hh \
+mln/morpho/closing/all.hh \
+mln/morpho/closing/algebraic.hh \
+mln/morpho/closing/leveling.hh \
+mln/morpho/closing/area_on_vertices.hh \
+mln/morpho/closing/area.hh \
+mln/morpho/closing/volume.hh \
+mln/morpho/closing/height.hh \
+mln/morpho/closing/essential.hh \
mln/morpho/laplacian.hh \
mln/morpho/all.hh \
-mln/morpho/opening_algebraic.hh \
-mln/morpho/opening_attribute.hh \
-mln/morpho/opening_volume.hh \
-mln/morpho/closing_algebraic.hh \
mln/morpho/watershed/flooding.hh \
mln/morpho/watershed/all.hh \
-mln/morpho/closing_area_on_vertices.hh \
-mln/morpho/closing_volume.hh \
+mln/morpho/opening/all.hh \
+mln/morpho/opening/algebraic.hh \
+mln/morpho/opening/leveling.hh \
+mln/morpho/opening/area_on_vertices.hh \
+mln/morpho/opening/area.hh \
+mln/morpho/opening/volume.hh \
+mln/morpho/opening/height.hh \
+mln/morpho/opening/essential.hh \
mln/morpho/attribute/all.hh \
mln/morpho/attribute/volume.hh \
mln/morpho/attribute/sum.hh \
+mln/morpho/attribute/height.hh \
+mln/morpho/attribute/sharpness.hh \
mln/morpho/attribute/card.hh \
+mln/morpho/attribute/count_adjacent_vertices.hh \
mln/morpho/minus.hh \
mln/morpho/gradient.hh \
mln/morpho/tree/max.hh \
@@ -654,16 +663,16 @@ mln/morpho/tree/all.hh \
mln/morpho/tree/utils.hh \
mln/morpho/tree/data.hh \
mln/morpho/tree/compute_attribute_image.hh \
-mln/morpho/opening_area_on_vertices.hh \
mln/morpho/general.spe.hh \
mln/morpho/min.hh \
mln/morpho/closing.hh \
mln/morpho/top_hat.hh \
mln/morpho/erosion.hh \
+mln/morpho/leveling_filter.hh \
mln/morpho/closing_sum.hh \
mln/morpho/Rd.hh \
-mln/morpho/closing_area.hh \
mln/morpho/thick_miss.hh \
+mln/morpho/algebraic_filter.hh \
mln/morpho/closing_attribute.hh \
mln/morpho/rank_filter.hh \
mln/morpho/essential.hh \
diff --git a/milena/mln/canvas/morpho/all.hh b/milena/mln/canvas/morpho/all.hh
index 5720829..2cd3dd0 100644
--- a/milena/mln/canvas/morpho/all.hh
+++ b/milena/mln/canvas/morpho/all.hh
@@ -47,9 +47,7 @@ namespace mln
# include <mln/canvas/morpho/internal/find_root.hh>
-# include <mln/canvas/morpho/algebraic_filter.hh>
-# include <mln/canvas/morpho/algebraic_union_find.hh>
-//# include <mln/canvas/morpho/connected_filter.hh>
+# include <mln/canvas/morpho/attribute_filter.hh>
#endif // ! MLN_CANVAS_MORPHO_ALL_HH
diff --git a/milena/mln/canvas/morpho/attribute_filter.hh b/milena/mln/canvas/morpho/attribute_filter.hh
index 8365271..e605f18 100644
--- a/milena/mln/canvas/morpho/attribute_filter.hh
+++ b/milena/mln/canvas/morpho/attribute_filter.hh
@@ -38,6 +38,8 @@
# include <mln/core/concept/neighborhood.hh>
# include <mln/core/concept/accumulator.hh>
+# include <mln/level/sort_offsets.hh>
+
# include <mln/trait/accumulators.hh>
# include <mln/util/pix.hh>
diff --git a/milena/mln/core/pixter2d.hh b/milena/mln/core/pixter2d.hh
index 93e43d8..32ea19e 100644
--- a/milena/mln/core/pixter2d.hh
+++ b/milena/mln/core/pixter2d.hh
@@ -136,6 +136,8 @@ namespace mln
row_offset_(image.bbox().ncols() + border_x2_)
{
mln_precondition(image.is_valid());
+ mln_precondition(image_.is_valid());
+ mln_precondition(image_.buffer() == image.buffer());
}
template <typename I>
@@ -156,6 +158,7 @@ namespace mln
void
fwd_pixter2d<I>::start_()
{
+ mln_precondition(image_.is_valid());
eor_ = & opt::at(image_, geom::min_row(image_), geom::max_col(image_)) + 1;
}
diff --git a/milena/mln/io/dicom/load.hh b/milena/mln/io/dicom/load.hh
index 491e207..b41eddb 100644
--- a/milena/mln/io/dicom/load.hh
+++ b/milena/mln/io/dicom/load.hh
@@ -1,4 +1,4 @@
-// Copyright (C) 2009 EPITA Research and Development Laboratory
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -28,13 +28,10 @@
#ifndef MLN_IO_DICOM_LOAD_HH
# define MLN_IO_DICOM_LOAD_HH
-/*!
- * \file mln/io/magick/load.hh
- *
- * \brief Define a function which loads an image of kind magick with
- * given path.
- *
- */
+/// \file mln/io/magick/load.hh
+///
+/// \brief Define a function which loads an image of kind magick with
+/// given path.
# include <mln/core/image/image2d.hh>
# include <mln/core/image/image3d.hh>
@@ -57,12 +54,11 @@ namespace mln
namespace dicom
{
- /*! Load a dicom image in a Milena image.
- *
- * \param[out] ima A reference to the image which will receive
- * data.
- * \param[in] filename The source.
- */
+ /// Load a dicom image in a Milena image.
+ ///
+ /// \param[out] ima A reference to the image which will receive
+ /// data.
+ /// \param[in] filename The source.
template <typename I>
void load(Image<I>& ima,
const std::string& filename);
diff --git a/milena/mln/level/compare.hh b/milena/mln/level/compare.hh
index 44f4202..f9390ab 100644
--- a/milena/mln/level/compare.hh
+++ b/milena/mln/level/compare.hh
@@ -90,6 +90,8 @@ namespace mln
const L& lhs = exact(lhs_);
const R& rhs = exact(rhs_);
+ mln_precondition(lhs.is_valid());
+ mln_precondition(rhs.is_valid());
mln_precondition(lhs.domain() == rhs.domain());
return test::predicate(lhs_, rhs_, F());
diff --git a/milena/mln/morpho/all.hh b/milena/mln/morpho/all.hh
index 5db9619..11ec6b3 100644
--- a/milena/mln/morpho/all.hh
+++ b/milena/mln/morpho/all.hh
@@ -57,7 +57,6 @@ namespace mln
# include <mln/morpho/closing.hh>
-# include <mln/morpho/closing/all.hh>
# include <mln/morpho/complementation.hh>
# include <mln/morpho/contrast.hh>
# include <mln/morpho/dilation.hh>
@@ -71,7 +70,6 @@ namespace mln
# include <mln/morpho/min.hh>
# include <mln/morpho/minus.hh>
# include <mln/morpho/opening.hh>
-# include <mln/morpho/opening/all.hh>
# include <mln/morpho/plus.hh>
# include <mln/morpho/Rd.hh>
# include <mln/morpho/rank_filter.hh>
@@ -85,7 +83,9 @@ namespace mln
// Sub-directories.
# include <mln/morpho/attribute/all.hh>
+# include <mln/morpho/closing/all.hh>
# include <mln/morpho/elementary/all.hh>
+# include <mln/morpho/opening/all.hh>
# include <mln/morpho/tree/all.hh>
# include <mln/morpho/watershed/all.hh>
diff --git a/milena/mln/morpho/closing/algebraic.hh b/milena/mln/morpho/closing/algebraic.hh
index 2b6258b..eb7e9d2 100644
--- a/milena/mln/morpho/closing/algebraic.hh
+++ b/milena/mln/morpho/closing/algebraic.hh
@@ -37,15 +37,20 @@
# include <mln/morpho/algebraic_filter.hh>
-namespace mln {
- namespace morpho {
- namespace closing {
+namespace mln
+{
- /// Morphological algebraic closing.
- template <typename I, typename N, typename A>
- mln_concrete(I)
- algebraic(const Image<I>& input, const Neighborhood<N>& nbh,
- const Accumulator<A>& accu, const mln_result(A)& lambda);
+ namespace morpho
+ {
+
+ namespace closing
+ {
+
+ /// Morphological algebraic closing.
+ template <typename I, typename N, typename A>
+ mln_concrete(I)
+ algebraic(const Image<I>& input, const Neighborhood<N>& nbh,
+ const Accumulator<A>& accu, const mln_result(A)& lambda);
@@ -53,33 +58,35 @@ namespace mln {
# ifndef MLN_INCLUDE_ONLY
- template <typename I, typename N, typename A>
- inline
- mln_concrete(I)
- algebraic(const Image<I>& input, const Neighborhood<N>& nbh,
- const Accumulator<A>& accu, const mln_result(A)& lambda)
- {
- trace::entering("morpho::closing::algebraic");
+ template <typename I, typename N, typename A>
+ inline
+ mln_concrete(I)
+ algebraic(const Image<I>& input, const Neighborhood<N>& nbh,
+ const Accumulator<A>& accu, const mln_result(A)& lambda)
+ {
+ trace::entering("morpho::closing::algebraic");
- mln_precondition(exact(input).is_valid());
- mln_precondition(mlc_not_equal(mln_trait_accumulator_when_pix(A),
- trait::accumulator::when_pix::not_ok)::value);
+ mln_precondition(exact(input).is_valid());
+ mln_precondition(mlc_not_equal(mln_trait_accumulator_when_pix(A),
+ trait::accumulator::when_pix::not_ok)::value);
- mln_concrete(I) output;
- output = algebraic_filter(input, nbh, accu, lambda,
- /* increasing = */ true);
+ mln_concrete(I) output;
+ output = algebraic_filter(input, nbh, accu, lambda,
+ /* increasing = */ true);
- mln_postcondition(output >= input);
+ mln_postcondition(output >= input);
- trace::exiting("morpho::closing::algebraic");
- return output;
- }
+ trace::exiting("morpho::closing::algebraic");
+ return output;
+ }
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln::morpho::closing
+
} // end of namespace mln::morpho
+
} // end of namespace mln
diff --git a/milena/mln/canvas/morpho/all.hh b/milena/mln/morpho/closing/all.hh
similarity index 67%
copy from milena/mln/canvas/morpho/all.hh
copy to milena/mln/morpho/closing/all.hh
index 5720829..8378d17 100644
--- a/milena/mln/canvas/morpho/all.hh
+++ b/milena/mln/morpho/closing/all.hh
@@ -1,5 +1,5 @@
-// Copyright (C) 2007, 2008, 2009 EPITA Research and Development
-// Laboratory (LRDE)
+// Copyright (C) 2009 EPITA Research and Development Laboratory
+// (LRDE)
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -26,30 +26,19 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-#ifndef MLN_CANVAS_MORPHO_ALL_HH
-# define MLN_CANVAS_MORPHO_ALL_HH
+#ifndef MLN_MORPHO_CLOSING_ALL_HH
+# define MLN_MORPHO_CLOSING_ALL_HH
-/// \file mln/canvas/morpho/all.hh
+/// \file mln/morpho/closing/all.hh
///
-/// File that includes morphological canvas-related routines.
+/// File that includes all closing attributes.
+#include <mln/morpho/closing/algebraic.hh>
+#include <mln/morpho/closing/leveling.hh>
+#include <mln/morpho/closing/area_on_vertices.hh>
+#include <mln/morpho/closing/area.hh>
+#include <mln/morpho/closing/volume.hh>
+#include <mln/morpho/closing/height.hh>
-namespace mln
-{
- namespace canvas
- {
+#endif // ! MLN_MORPHO_CLOSING_ALL_HH
- /// Namespace of morphological canvas.
- namespace morpho {}
-
- }
-}
-
-
-# include <mln/canvas/morpho/internal/find_root.hh>
-# include <mln/canvas/morpho/algebraic_filter.hh>
-# include <mln/canvas/morpho/algebraic_union_find.hh>
-//# include <mln/canvas/morpho/connected_filter.hh>
-
-
-#endif // ! MLN_CANVAS_MORPHO_ALL_HH
diff --git a/milena/mln/canvas/morpho/all.hh b/milena/mln/morpho/closing/essential.hh
similarity index 67%
copy from milena/mln/canvas/morpho/all.hh
copy to milena/mln/morpho/closing/essential.hh
index 5720829..a478a2c 100644
--- a/milena/mln/canvas/morpho/all.hh
+++ b/milena/mln/morpho/closing/essential.hh
@@ -1,5 +1,5 @@
-// Copyright (C) 2007, 2008, 2009 EPITA Research and Development
-// Laboratory (LRDE)
+// Copyright (C) 2009 EPITA Research and Development Laboratory
+// (LRDE)
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -26,30 +26,18 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-#ifndef MLN_CANVAS_MORPHO_ALL_HH
-# define MLN_CANVAS_MORPHO_ALL_HH
+#ifndef MLN_MORPHO_CLOSING_ESSENTIAL_HH
+# define MLN_MORPHO_CLOSING_ESSENTIAL_HH
-/// \file mln/canvas/morpho/all.hh
+/// \file mln/morpho/closing/all.hh
///
-/// File that includes morphological canvas-related routines.
+/// File that includes essential closing attributes.
+#include <mln/morpho/closing/algebraic.hh>
+#include <mln/morpho/closing/leveling.hh>
+#include <mln/morpho/closing/area.hh>
+#include <mln/morpho/closing/volume.hh>
+#include <mln/morpho/closing/height.hh>
-namespace mln
-{
- namespace canvas
- {
+#endif // ! MLN_MORPHO_CLOSING_ESSENTIAL_HH
- /// Namespace of morphological canvas.
- namespace morpho {}
-
- }
-}
-
-
-# include <mln/canvas/morpho/internal/find_root.hh>
-# include <mln/canvas/morpho/algebraic_filter.hh>
-# include <mln/canvas/morpho/algebraic_union_find.hh>
-//# include <mln/canvas/morpho/connected_filter.hh>
-
-
-#endif // ! MLN_CANVAS_MORPHO_ALL_HH
diff --git a/milena/mln/morpho/essential.hh b/milena/mln/morpho/essential.hh
index 6c45cc0..d16fcce 100644
--- a/milena/mln/morpho/essential.hh
+++ b/milena/mln/morpho/essential.hh
@@ -41,12 +41,12 @@
# include <mln/morpho/includes.hh>
# include <mln/morpho/laplacian.hh>
# include <mln/morpho/meyer_wst.hh>
-# include <mln/morpho/opening/area.hh>
-# include <mln/morpho/opening/attribute.hh>
# include <mln/morpho/opening.hh>
# include <mln/morpho/rank_filter.hh>
# include <mln/morpho/top_hat.hh>
+# include <mln/morpho/opening/essential.hh>
+# include <mln/morpho/closing/essential.hh>
# include <mln/morpho/elementary/essential.hh>
diff --git a/milena/mln/canvas/morpho/all.hh b/milena/mln/morpho/opening/all.hh
similarity index 67%
copy from milena/mln/canvas/morpho/all.hh
copy to milena/mln/morpho/opening/all.hh
index 5720829..ee35281 100644
--- a/milena/mln/canvas/morpho/all.hh
+++ b/milena/mln/morpho/opening/all.hh
@@ -1,5 +1,5 @@
-// Copyright (C) 2007, 2008, 2009 EPITA Research and Development
-// Laboratory (LRDE)
+// Copyright (C) 2009 EPITA Research and Development Laboratory
+// (LRDE)
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -26,30 +26,19 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-#ifndef MLN_CANVAS_MORPHO_ALL_HH
-# define MLN_CANVAS_MORPHO_ALL_HH
+#ifndef MLN_MORPHO_OPENING_ALL_HH
+# define MLN_MORPHO_OPENING_ALL_HH
-/// \file mln/canvas/morpho/all.hh
+/// \file mln/morpho/opening/all.hh
///
-/// File that includes morphological canvas-related routines.
+/// File that includes all opening attributes.
+#include <mln/morpho/opening/algebraic.hh>
+#include <mln/morpho/opening/leveling.hh>
+#include <mln/morpho/opening/area_on_vertices.hh>
+#include <mln/morpho/opening/area.hh>
+#include <mln/morpho/opening/volume.hh>
+#include <mln/morpho/opening/height.hh>
-namespace mln
-{
- namespace canvas
- {
+#endif // ! MLN_MORPHO_OPENING_ALL_HH
- /// Namespace of morphological canvas.
- namespace morpho {}
-
- }
-}
-
-
-# include <mln/canvas/morpho/internal/find_root.hh>
-# include <mln/canvas/morpho/algebraic_filter.hh>
-# include <mln/canvas/morpho/algebraic_union_find.hh>
-//# include <mln/canvas/morpho/connected_filter.hh>
-
-
-#endif // ! MLN_CANVAS_MORPHO_ALL_HH
diff --git a/milena/mln/canvas/morpho/all.hh b/milena/mln/morpho/opening/essential.hh
similarity index 67%
copy from milena/mln/canvas/morpho/all.hh
copy to milena/mln/morpho/opening/essential.hh
index 5720829..45fbdae 100644
--- a/milena/mln/canvas/morpho/all.hh
+++ b/milena/mln/morpho/opening/essential.hh
@@ -1,5 +1,5 @@
-// Copyright (C) 2007, 2008, 2009 EPITA Research and Development
-// Laboratory (LRDE)
+// Copyright (C) 2009 EPITA Research and Development Laboratory
+// (LRDE)
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -26,30 +26,18 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-#ifndef MLN_CANVAS_MORPHO_ALL_HH
-# define MLN_CANVAS_MORPHO_ALL_HH
+#ifndef MLN_MORPHO_OPENING_ESSENTIAL_HH
+# define MLN_MORPHO_OPENING_ESSENTIAL_HH
-/// \file mln/canvas/morpho/all.hh
+/// \file mln/morpho/opening/all.hh
///
-/// File that includes morphological canvas-related routines.
+/// File that includes essential opening attributes.
+#include <mln/morpho/opening/algebraic.hh>
+#include <mln/morpho/opening/leveling.hh>
+#include <mln/morpho/opening/area.hh>
+#include <mln/morpho/opening/volume.hh>
+#include <mln/morpho/opening/height.hh>
-namespace mln
-{
- namespace canvas
- {
+#endif // ! MLN_MORPHO_OPENING_ESSENTIAL_HH
- /// Namespace of morphological canvas.
- namespace morpho {}
-
- }
-}
-
-
-# include <mln/canvas/morpho/internal/find_root.hh>
-# include <mln/canvas/morpho/algebraic_filter.hh>
-# include <mln/canvas/morpho/algebraic_union_find.hh>
-//# include <mln/canvas/morpho/connected_filter.hh>
-
-
-#endif // ! MLN_CANVAS_MORPHO_ALL_HH
diff --git a/milena/mln/morpho/tree/compute_attribute_image.hh b/milena/mln/morpho/tree/compute_attribute_image.hh
index a877cb8..0514fef 100644
--- a/milena/mln/morpho/tree/compute_attribute_image.hh
+++ b/milena/mln/morpho/tree/compute_attribute_image.hh
@@ -1,4 +1,5 @@
-// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory
+// (LRDE)
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -35,6 +36,7 @@
/// \todo Specialize for low quant (and try fastest).
# include <mln/core/concept/image.hh>
+# include <mln/trait/accumulators.hh>
# include <mln/util/pix.hh>
# include <mln/data/fill.hh>
@@ -67,7 +69,7 @@ namespace mln
template <typename A, typename T>
mln_ch_value(typename T::function, mln_result(A))
- compute_attribute_image(const Accumulator<A>& a, const T& t);
+ compute_attribute_image(const Accumulator<A>& a, const T& t);
@@ -118,7 +120,7 @@ namespace mln
template <typename A, typename T>
inline
mln_ch_value(typename T::function, mln_result(A))
- compute_attribute_image(const Accumulator<A>& a_, const T& t)
+ compute_attribute_image(const Accumulator<A>& a_, const T& t)
{
trace::entering("morpho::tree::compute_attribute_image");
diff --git a/milena/tests/core/image/plain.cc b/milena/tests/core/image/plain.cc
index 087362f..b963b1b 100644
--- a/milena/tests/core/image/plain.cc
+++ b/milena/tests/core/image/plain.cc
@@ -62,6 +62,8 @@ int main()
ima(point2d(0,0)) = 124;
+ mln_assertion(exact(ima).is_valid());
+ mln_assertion(exact(lena).is_valid());
mln_assertion(ima != lena);
ima2 = lena;
diff --git a/milena/tests/unit_test/unit-tests.mk b/milena/tests/unit_test/unit-tests.mk
index 055ede1..53cd03f 100644
--- a/milena/tests/unit_test/unit-tests.mk
+++ b/milena/tests/unit_test/unit-tests.mk
@@ -354,6 +354,7 @@ mln_value_int_s \
mln_value_rgb8 \
mln_value_int_s32 \
mln_value_float01_ \
+mln_value_int_u12 \
mln_value_rgb16 \
mln_value_int_u32 \
mln_value_gl8 \
@@ -527,9 +528,7 @@ mln_canvas_all \
mln_canvas_distance_front \
mln_canvas_morpho_internal_find_root \
mln_canvas_morpho_all \
-mln_canvas_morpho_connected_filter \
-mln_canvas_morpho_algebraic_filter \
-mln_canvas_morpho_algebraic_union_find \
+mln_canvas_morpho_attribute_filter \
mln_canvas_morpho_essential \
mln_canvas_essential \
mln_metal_is_const \
@@ -616,29 +615,39 @@ mln_morpho_skeleton_constrained \
mln_morpho_complementation \
mln_morpho_line_gradient \
mln_morpho_hit_or_miss \
-mln_morpho_closing_height \
mln_morpho_plus \
mln_morpho_general \
mln_morpho_internal_elementary \
mln_morpho_contrast \
-mln_morpho_opening_area \
-mln_morpho_opening_height \
mln_morpho_thickening \
mln_morpho_dilation \
+mln_morpho_closing_all \
+mln_morpho_closing_algebraic \
+mln_morpho_closing_leveling \
+mln_morpho_closing_area_on_vertices \
+mln_morpho_closing_area \
+mln_morpho_closing_volume \
+mln_morpho_closing_height \
+mln_morpho_closing_essential \
mln_morpho_laplacian \
mln_morpho_all \
-mln_morpho_opening_algebraic \
-mln_morpho_opening_attribute \
-mln_morpho_opening_volume \
-mln_morpho_closing_algebraic \
mln_morpho_watershed_flooding \
mln_morpho_watershed_all \
-mln_morpho_closing_area_on_vertices \
-mln_morpho_closing_volume \
+mln_morpho_opening_all \
+mln_morpho_opening_algebraic \
+mln_morpho_opening_leveling \
+mln_morpho_opening_area_on_vertices \
+mln_morpho_opening_area \
+mln_morpho_opening_volume \
+mln_morpho_opening_height \
+mln_morpho_opening_essential \
mln_morpho_attribute_all \
mln_morpho_attribute_volume \
mln_morpho_attribute_sum \
+mln_morpho_attribute_height \
+mln_morpho_attribute_sharpness \
mln_morpho_attribute_card \
+mln_morpho_attribute_count_adjacent_vertices \
mln_morpho_minus \
mln_morpho_gradient \
mln_morpho_tree_max \
@@ -647,15 +656,15 @@ mln_morpho_tree_all \
mln_morpho_tree_utils \
mln_morpho_tree_data \
mln_morpho_tree_compute_attribute_image \
-mln_morpho_opening_area_on_vertices \
mln_morpho_min \
mln_morpho_closing \
mln_morpho_top_hat \
mln_morpho_erosion \
+mln_morpho_leveling_filter \
mln_morpho_closing_sum \
mln_morpho_Rd \
-mln_morpho_closing_area \
mln_morpho_thick_miss \
+mln_morpho_algebraic_filter \
mln_morpho_closing_attribute \
mln_morpho_rank_filter \
mln_morpho_essential \
@@ -1429,6 +1438,7 @@ mln_value_int_s_SOURCES = mln_value_int_s.cc
mln_value_rgb8_SOURCES = mln_value_rgb8.cc
mln_value_int_s32_SOURCES = mln_value_int_s32.cc
mln_value_float01__SOURCES = mln_value_float01_.cc
+mln_value_int_u12_SOURCES = mln_value_int_u12.cc
mln_value_rgb16_SOURCES = mln_value_rgb16.cc
mln_value_int_u32_SOURCES = mln_value_int_u32.cc
mln_value_gl8_SOURCES = mln_value_gl8.cc
@@ -1602,9 +1612,7 @@ mln_canvas_all_SOURCES = mln_canvas_all.cc
mln_canvas_distance_front_SOURCES = mln_canvas_distance_front.cc
mln_canvas_morpho_internal_find_root_SOURCES = mln_canvas_morpho_internal_find_root.cc
mln_canvas_morpho_all_SOURCES = mln_canvas_morpho_all.cc
-mln_canvas_morpho_connected_filter_SOURCES = mln_canvas_morpho_connected_filter.cc
-mln_canvas_morpho_algebraic_filter_SOURCES = mln_canvas_morpho_algebraic_filter.cc
-mln_canvas_morpho_algebraic_union_find_SOURCES = mln_canvas_morpho_algebraic_union_find.cc
+mln_canvas_morpho_attribute_filter_SOURCES = mln_canvas_morpho_attribute_filter.cc
mln_canvas_morpho_essential_SOURCES = mln_canvas_morpho_essential.cc
mln_canvas_essential_SOURCES = mln_canvas_essential.cc
mln_metal_is_const_SOURCES = mln_metal_is_const.cc
@@ -1691,29 +1699,39 @@ mln_morpho_skeleton_constrained_SOURCES = mln_morpho_skeleton_constrained.cc
mln_morpho_complementation_SOURCES = mln_morpho_complementation.cc
mln_morpho_line_gradient_SOURCES = mln_morpho_line_gradient.cc
mln_morpho_hit_or_miss_SOURCES = mln_morpho_hit_or_miss.cc
-mln_morpho_closing_height_SOURCES = mln_morpho_closing_height.cc
mln_morpho_plus_SOURCES = mln_morpho_plus.cc
mln_morpho_general_SOURCES = mln_morpho_general.cc
mln_morpho_internal_elementary_SOURCES = mln_morpho_internal_elementary.cc
mln_morpho_contrast_SOURCES = mln_morpho_contrast.cc
-mln_morpho_opening_area_SOURCES = mln_morpho_opening_area.cc
-mln_morpho_opening_height_SOURCES = mln_morpho_opening_height.cc
mln_morpho_thickening_SOURCES = mln_morpho_thickening.cc
mln_morpho_dilation_SOURCES = mln_morpho_dilation.cc
+mln_morpho_closing_all_SOURCES = mln_morpho_closing_all.cc
+mln_morpho_closing_algebraic_SOURCES = mln_morpho_closing_algebraic.cc
+mln_morpho_closing_leveling_SOURCES = mln_morpho_closing_leveling.cc
+mln_morpho_closing_area_on_vertices_SOURCES = mln_morpho_closing_area_on_vertices.cc
+mln_morpho_closing_area_SOURCES = mln_morpho_closing_area.cc
+mln_morpho_closing_volume_SOURCES = mln_morpho_closing_volume.cc
+mln_morpho_closing_height_SOURCES = mln_morpho_closing_height.cc
+mln_morpho_closing_essential_SOURCES = mln_morpho_closing_essential.cc
mln_morpho_laplacian_SOURCES = mln_morpho_laplacian.cc
mln_morpho_all_SOURCES = mln_morpho_all.cc
-mln_morpho_opening_algebraic_SOURCES = mln_morpho_opening_algebraic.cc
-mln_morpho_opening_attribute_SOURCES = mln_morpho_opening_attribute.cc
-mln_morpho_opening_volume_SOURCES = mln_morpho_opening_volume.cc
-mln_morpho_closing_algebraic_SOURCES = mln_morpho_closing_algebraic.cc
mln_morpho_watershed_flooding_SOURCES = mln_morpho_watershed_flooding.cc
mln_morpho_watershed_all_SOURCES = mln_morpho_watershed_all.cc
-mln_morpho_closing_area_on_vertices_SOURCES = mln_morpho_closing_area_on_vertices.cc
-mln_morpho_closing_volume_SOURCES = mln_morpho_closing_volume.cc
+mln_morpho_opening_all_SOURCES = mln_morpho_opening_all.cc
+mln_morpho_opening_algebraic_SOURCES = mln_morpho_opening_algebraic.cc
+mln_morpho_opening_leveling_SOURCES = mln_morpho_opening_leveling.cc
+mln_morpho_opening_area_on_vertices_SOURCES = mln_morpho_opening_area_on_vertices.cc
+mln_morpho_opening_area_SOURCES = mln_morpho_opening_area.cc
+mln_morpho_opening_volume_SOURCES = mln_morpho_opening_volume.cc
+mln_morpho_opening_height_SOURCES = mln_morpho_opening_height.cc
+mln_morpho_opening_essential_SOURCES = mln_morpho_opening_essential.cc
mln_morpho_attribute_all_SOURCES = mln_morpho_attribute_all.cc
mln_morpho_attribute_volume_SOURCES = mln_morpho_attribute_volume.cc
mln_morpho_attribute_sum_SOURCES = mln_morpho_attribute_sum.cc
+mln_morpho_attribute_height_SOURCES = mln_morpho_attribute_height.cc
+mln_morpho_attribute_sharpness_SOURCES = mln_morpho_attribute_sharpness.cc
mln_morpho_attribute_card_SOURCES = mln_morpho_attribute_card.cc
+mln_morpho_attribute_count_adjacent_vertices_SOURCES = mln_morpho_attribute_count_adjacent_vertices.cc
mln_morpho_minus_SOURCES = mln_morpho_minus.cc
mln_morpho_gradient_SOURCES = mln_morpho_gradient.cc
mln_morpho_tree_max_SOURCES = mln_morpho_tree_max.cc
@@ -1722,15 +1740,15 @@ mln_morpho_tree_all_SOURCES = mln_morpho_tree_all.cc
mln_morpho_tree_utils_SOURCES = mln_morpho_tree_utils.cc
mln_morpho_tree_data_SOURCES = mln_morpho_tree_data.cc
mln_morpho_tree_compute_attribute_image_SOURCES = mln_morpho_tree_compute_attribute_image.cc
-mln_morpho_opening_area_on_vertices_SOURCES = mln_morpho_opening_area_on_vertices.cc
mln_morpho_min_SOURCES = mln_morpho_min.cc
mln_morpho_closing_SOURCES = mln_morpho_closing.cc
mln_morpho_top_hat_SOURCES = mln_morpho_top_hat.cc
mln_morpho_erosion_SOURCES = mln_morpho_erosion.cc
+mln_morpho_leveling_filter_SOURCES = mln_morpho_leveling_filter.cc
mln_morpho_closing_sum_SOURCES = mln_morpho_closing_sum.cc
mln_morpho_Rd_SOURCES = mln_morpho_Rd.cc
-mln_morpho_closing_area_SOURCES = mln_morpho_closing_area.cc
mln_morpho_thick_miss_SOURCES = mln_morpho_thick_miss.cc
+mln_morpho_algebraic_filter_SOURCES = mln_morpho_algebraic_filter.cc
mln_morpho_closing_attribute_SOURCES = mln_morpho_closing_attribute.cc
mln_morpho_rank_filter_SOURCES = mln_morpho_rank_filter.cc
mln_morpho_essential_SOURCES = mln_morpho_essential.cc
--
1.5.6.5
1
0
01 Mar '09
URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox
ChangeLog:
2009-03-01 Frederic Bour <bour(a)lrde.epita.fr>
Add exo3 "assignable" functions part, correct other parts.
* rush/exo3/Makefile: Added assignable target.
* rush/exo3/assignable.cc: New.
* rush/exo3/assignable.cc: New.
* rush/exo3/exo3_1.cc: Renamed to...
* rush/exo3/exo3_fun_area.cc: New.
* rush/exo3/exo3_2.cc: Renamed to...
* rush/exo3/exo3_fun_generator.cc: New.
---
Makefile | 10 -
assignable.cc | 251 ++++++++++++++++++++++++++++++++++
exo3_fun_area.cc | 313 ++++++++++++++++++++++++++++++++++++++++++
exo3_fun_generator.cc | 366 ++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 935 insertions(+), 5 deletions(-)
Index: trunk/milena/sandbox/theo/rush/exo3/exo3_1.cc (deleted)
===================================================================
Index: trunk/milena/sandbox/theo/rush/exo3/exo3_2.cc (deleted)
===================================================================
Index: trunk/milena/sandbox/theo/rush/exo3/exo3_fun_generator.cc
===================================================================
--- trunk/milena/sandbox/theo/rush/exo3/exo3_fun_generator.cc (revision 0)
+++ trunk/milena/sandbox/theo/rush/exo3/exo3_fun_generator.cc (revision 3452)
@@ -0,0 +1,366 @@
+#include <mln/core/image/image2d.hh>
+#include <mln/core/concept/function.hh>
+#include <mln/core/alias/neighb2d.hh>
+#include <mln/core/var.hh>
+#include <mln/value/int_u8.hh>
+#include <mln/pw/all.hh>
+#include <mln/io/pgm/all.hh>
+#include <mln/io/pbm/all.hh>
+#include <mln/trait/all.hh>
+#include <mln/fun/internal/resolve.hh>
+#include <mln/morpho/attribute/card.hh>
+#include <mln/morpho/attribute/sharpness.hh>
+#include <mln/level/sort_offsets.hh>
+#include <mln/canvas/morpho/attribute_filter.hh>
+#include <mln/canvas/morpho/internal/find_root.hh>
+
+namespace exo3
+{
+ // Se code est un peu ... sale, et tente de répondre aux problèmes
+ // techniques apparus lors de la présentation (bonus ?).
+
+ // mln::trait::solve se spécialise pour des template <class T>
+ // en premier paramètre.
+ // Afin de transmettre plusieurs types, on passe par
+ // T = couple<TExact, TAux>. On 'hérite' de la catégorie de TExact.
+ // Utiliser pour le générateur de (méta)fonctions.
+ template <typename TExact, typename TAux>
+ struct couple
+ {
+ typedef TExact Exact;
+ typedef typename mln::category<Exact>::ret category;
+
+ typedef TAux Aux;
+ };
+
+ // Crée un type unique vide pour un type donné, évite une instantation ?!
+ // (inutile probablement, dans le doute...).
+ template <typename U>
+ struct uniq
+ {
+ };
+
+ // Get attribute from attribute "E" exact.
+ template <typename E>
+ typename E::result
+ get_attribute(uniq<E>, const E& exact)
+ {
+ return exact.to_result();
+ }
+
+ // area
+ template <typename I, typename E>
+ unsigned get_attribute(uniq< mln::morpho::attribute::card<I> >, const E& exact)
+ {
+ return exact.area();
+ }
+
+ // volume
+ template <typename I, typename E>
+ unsigned get_attribute(uniq< mln::morpho::attribute::volume<I> >, const E& exact)
+ {
+ return exact.volume();
+ }
+}
+
+namespace mln
+{
+ namespace fun
+ {
+ namespace v2v
+ {
+ template <typename T> struct from_accu_t;
+ template <typename T> struct solve_from_accu;
+ }
+
+ namespace meta
+ {
+ template <template <class> class A>
+ struct from_accu
+ {
+ template <typename T>
+ typename fun::v2v::from_accu_t< exo3::couple<T, A<T> > >::result
+ operator()(const T& t1) const
+ {
+ fun::v2v::from_accu_t< exo3::couple<T, A<T> > > f;
+ return f(t1);
+ }
+
+ template <typename T>
+ struct with
+ {
+ typedef fun::v2v::from_accu_t< exo3::couple<T, A<T> > > ret;
+ };
+ };
+ }
+ }
+
+ namespace trait
+ {
+ template <typename TE, typename TA>
+ struct set_unary_< fun::v2v::from_accu_t, Accumulator, exo3::couple<TE, TA> >
+ {
+ typedef set_unary_< fun::v2v::from_accu_t, Accumulator, exo3::couple<TE, TA> > ret;
+ typedef unsigned result;
+
+ static
+ result
+ exec(const TE& t1)
+ {
+ return exo3::get_attribute(exo3::uniq<TA>(), t1);
+ }
+ };
+
+ } // mln::trait
+
+ namespace fun
+ {
+ namespace v2v
+ {
+ template <typename T>
+ struct from_accu_t;
+
+ template <typename TE, typename TA>
+ struct from_accu_t< exo3::couple<TE, TA> > : mln::Function_v2v< from_accu_t< exo3::couple<TE, TA> > >
+ {
+ typedef mln_fun_internal_resolve(from_accu_t) impl;
+ typedef typename impl::result result;
+
+ result
+ operator()(const TE& t1) const
+ {
+ return impl::exec(t1);
+ }
+ };
+
+ template <typename A>
+ struct solve_from_accu
+ {
+ // FIXME: Not sure whether inheritance is the right way...
+ // But templated typedef are not currently available.
+ template <typename E>
+ struct ret : from_accu_t< exo3::couple< E, A > >
+ {
+ };
+ };
+ }
+ }
+
+}
+
+namespace exo3
+{
+ template <typename F, typename G>
+ struct functors_compose_
+ : mln::Function_p2v< functors_compose_<F, G> >
+ {
+ typedef typename F::result result;
+
+ functors_compose_() {}
+ functors_compose_(const F& f, const G& g)
+ : f_(f), g_(g)
+ {
+ }
+
+ template <typename T>
+ result
+ operator()(const T& p) const
+ {
+ return f_(g_(p));
+ }
+
+ protected:
+ F f_;
+ G g_;
+ };
+
+}
+
+namespace mln
+{
+
+ namespace trait
+ {
+
+ template <typename TG, typename TA>
+ struct set_unary_<fun::v2v::from_accu_t, mln::Function_p2v, exo3::couple<TG, TA> >
+ {
+ typedef set_unary_<fun::v2v::from_accu_t, mln::Function_p2v, exo3::couple<TG, TA> > ret;
+ typedef exo3::functors_compose_<fun::v2v::from_accu_t< exo3::couple<typename TG::result, TA> >, TG> result;
+
+ static
+ result
+ exec(const TG& g)
+ {
+ return exo3::functors_compose_<fun::v2v::from_accu_t< exo3::couple<typename TG::result, TA> >, TG>
+ (fun::v2v::from_accu_t<exo3::couple<typename TG::result, TA> >(), g);
+ }
+ };
+ }
+
+}
+
+// Modified copy of mln::canvas::morpho::attribute_filter
+namespace exo3_filter
+{
+ using namespace mln;
+
+ template <typename I, typename N, typename S, typename A>
+ mln_ch_value(I, A)
+ attribute_filter (const Image<I>& input_,
+ const Neighborhood<N>& nbh_,
+ const Site_Set<S>& s_,
+ const Accumulator<A>& a_,
+ const typename A::result& lambda)
+ {
+ const I& input = exact(input_);
+ const N& nbh = exact(nbh_);
+ const S& s = exact(s_);
+ (void)a_; // To avoid warning at compilation
+
+ // Local type.
+ typedef mln_psite(I) P;
+
+ mln_ch_value(I, bool) deja_vu;
+ mln_ch_value(I, bool) activity;
+ mln_ch_value(I, P) parent;
+ mln_ch_value(I, A) data;
+
+ {
+ initialize(deja_vu, input);
+ data::fill(deja_vu, false);
+ initialize(activity, input);
+ data::fill(activity, true);
+ initialize(parent, input);
+ initialize(data, input);
+ }
+ {
+ mln_fwd_piter(S) p(s);
+ mln_niter(N) n(nbh, p);
+
+ for_all(p)
+ {
+ {
+ parent(p) = p;
+ mln::canvas::morpho::impl::take_as_init (data(p), input, p);
+ }
+
+ for_all(n)
+ if (input.domain().has(n) && deja_vu(n))
+ {
+ P r = mln::canvas::morpho::impl::generic::find_root(parent, n);
+ if (r != p)
+ {
+ if (input(r) == input(p) || (activity(r) && (data(r) < lambda)))
+ {
+ data(p).take(data(r));
+ parent(r) = p;
+ if (activity(r) == false)
+ activity(p) = false;
+ }
+ else
+ {
+ activity(p) = false;
+ }
+ }
+ }
+ deja_vu(p) = true;
+ }
+ }
+ // Second pass.
+ {
+ mln_bkd_piter(S) p(s);
+ for_all(p)
+ if (parent(p) != p)
+ data(p) = data(parent(p));
+ }
+ return data;
+ }
+
+ // Surcharger les operateurs uniquement pour les builtins...
+ // l'idée est de provoquer une sfinae. J'ai pas trouvé mieux :(
+ // (pas vu d'opérateurs <, >, ... pour les fonctions utilisant mln::trait::solve)
+
+ // C is Category, R is return type
+ template <typename C, typename R>
+ struct ret_builtin;
+ template <typename T, typename R>
+ struct ret_builtin< value::Built_In< T > , R>
+ {
+ typedef R ret;
+ };
+
+} // end of namespace exo3_filter
+
+#define templatize(...) __VA_ARGS__
+
+#define op_for_cst(name, op) \
+ template <typename F, typename C> \
+ mln_trait_op_##name( \
+ F, \
+ templatize(typename exo3_filter::ret_builtin< typename mln::category< C >::ret, mln::pw::cst_<C> >::ret) \
+ ) \
+ operator op (const mln::Function_p2v<F>& f, const C& c) \
+ { \
+ return exact(f) op mln::pw::cst(c); \
+ } \
+ \
+ template <typename F, typename C> \
+ mln_trait_op_##name( \
+ templatize(typename exo3_filter::ret_builtin< typename mln::category< C >::ret, mln::pw::cst_<C> >::ret), \
+ F \
+ ) \
+ operator op (const C& c, const mln::Function_p2v<F>& f) \
+ { \
+ return mln::pw::cst(c) or exact(f); \
+ }
+
+op_for_cst(less, <)
+op_for_cst(greater, >)
+op_for_cst(leq, <=)
+op_for_cst(geq, >=)
+op_for_cst(eq, ==)
+op_for_cst(neq, !=)
+
+#undef op_for_cst
+
+void usage(char* argv[])
+{
+ std::cerr << "usage: " << argv[0] << " input.pgm sharpness minvol minarea (inclusive or)"
+ << std::endl;
+ abort();
+}
+
+int main(int argc, char **argv)
+{
+ using namespace mln;
+ using value::int_u8;
+
+ typedef image2d<int_u8> I;
+
+ float l_sharpness;
+ unsigned l_minvol;
+ unsigned l_minarea;
+ I input;
+
+ if (argc < 5)
+ usage(argv);
+
+ io::pgm::load(input, argv[1]);
+
+ l_sharpness = atof(argv[2]);
+ l_minvol = atoi(argv[3]);
+ l_minarea = atoi(argv[4]);
+
+ mln_VAR(sharp, exo3_filter::attribute_filter(input, c4(),
+ level::sort_psites_decreasing(input),
+ morpho::attribute::sharpness<I>(), l_sharpness));
+
+ mln_VAR(s, pw::value(sharp));
+
+ mln::fun::meta::from_accu< mln::morpho::attribute::volume > vol;
+ mln::fun::meta::from_accu< mln::morpho::attribute::card > area;
+
+ io::pbm::save((vol(s) > l_minvol || area(s) > l_minarea) | input.domain(), "out.pbm");
+
+}
\ No newline at end of file
Index: trunk/milena/sandbox/theo/rush/exo3/exo3_fun_area.cc
===================================================================
--- trunk/milena/sandbox/theo/rush/exo3/exo3_fun_area.cc (revision 0)
+++ trunk/milena/sandbox/theo/rush/exo3/exo3_fun_area.cc (revision 3452)
@@ -0,0 +1,313 @@
+#include <mln/core/image/image2d.hh>
+#include <mln/core/concept/function.hh>
+#include <mln/core/alias/neighb2d.hh>
+#include <mln/core/var.hh>
+#include <mln/value/int_u8.hh>
+#include <mln/pw/all.hh>
+#include <mln/io/pgm/all.hh>
+#include <mln/io/pbm/all.hh>
+#include <mln/trait/all.hh>
+#include <mln/fun/internal/resolve.hh>
+#include <mln/morpho/attribute/card.hh>
+#include <mln/morpho/attribute/sharpness.hh>
+#include <mln/level/sort_offsets.hh>
+#include <mln/canvas/morpho/attribute_filter.hh>
+#include <mln/canvas/morpho/internal/find_root.hh>
+
+namespace mln
+{
+ namespace fun
+ {
+ namespace v2v
+ {
+ template <typename T> struct area;
+ }
+
+ /// Meta function for area calculation
+ namespace meta
+ {
+
+ struct area
+ {
+ template <typename T>
+ typename fun::v2v::area<T>::result
+ operator()(const T& t1) const
+ {
+ fun::v2v::area<T> f;
+ return f(t1);
+ }
+
+ template <typename T>
+ struct with
+ {
+ typedef fun::v2v::area<T> ret;
+ };
+ };
+
+ } // end of namespace mln::fun::meta
+
+ /// Function for area calculation
+ namespace v2v
+ {
+
+ template <typename T>
+ struct area : mln::Function_v2v< area<T> >
+ {
+ typedef mln_fun_internal_resolve(area) impl;
+ typedef typename impl::result result;
+
+ result
+ operator()(const T& t1) const
+ {
+ return impl::exec(t1);
+ }
+ };
+
+ } // end of namespace mln::fun::v2v
+
+ /// Function_p2v composition
+ namespace p2v
+ {
+ template <typename F, typename G>
+ struct composition_t
+ : mln::Function_p2v< composition_t<F, G> >
+ {
+ typedef typename F::result result;
+
+ composition_t() {}
+ composition_t(const F& f, const G& g)
+ : f_(f), g_(g)
+ {
+ }
+
+ template <typename T>
+ result
+ operator()(const T& p) const
+ {
+ return f_(g_(p));
+ }
+
+ protected:
+ F f_;
+ G g_;
+ };
+
+ } // end of namespace mln::fun::p2v
+
+ } // end of namespace mln::fun
+
+ /// fun::v2v::area trait for composition
+ namespace trait
+ {
+ template <typename T>
+ struct set_unary_< fun::v2v::area, Accumulator, T >
+ {
+ typedef set_unary_< fun::v2v::area, Accumulator, T > ret;
+ typedef unsigned result;
+
+ static
+ result
+ exec(const T& t1)
+ {
+ return t1.area();
+ }
+ };
+
+ template <typename I>
+ struct set_precise_unary_< fun::v2v::area, mln::morpho::attribute::card<I> >
+ {
+ typedef set_precise_unary_< fun::v2v::area, mln::morpho::attribute::card<I> > ret;
+ typedef unsigned result;
+
+ static
+ result
+ exec(const mln::morpho::attribute::card<I>& t1)
+ {
+ return t1.to_result();
+ }
+ };
+
+ template <typename G>
+ struct set_unary_<fun::v2v::area, mln::Function_p2v, G>
+ {
+ typedef set_unary_<fun::v2v::area, mln::Function_p2v, G> ret;
+ typedef fun::p2v::composition_t<fun::v2v::area<typename G::result>, G> result;
+
+ static
+ result
+ exec(const G& g)
+ {
+ return fun::p2v::composition_t<fun::v2v::area<typename G::result>, G>
+ (fun::v2v::area<typename G::result>(), g);
+ }
+ };
+ }
+
+}
+
+// Modified copy of mln::canvas::morpho::attribute_filter
+// for purpose of testing.
+namespace exo3_filter
+{
+ using namespace mln;
+
+ template <typename I, typename N, typename S, typename A>
+ mln_ch_value(I, A)
+ attribute_filter (const Image<I>& input_,
+ const Neighborhood<N>& nbh_,
+ const Site_Set<S>& s_,
+ const Accumulator<A>& a_,
+ const typename A::result& lambda)
+ {
+ const I& input = exact(input_);
+ const N& nbh = exact(nbh_);
+ const S& s = exact(s_);
+ (void)a_; // To avoid warning at compilation
+
+ // Local type.
+ typedef mln_psite(I) P;
+
+ mln_ch_value(I, bool) deja_vu;
+ mln_ch_value(I, bool) activity;
+ mln_ch_value(I, P) parent;
+ mln_ch_value(I, A) data;
+
+ {
+ initialize(deja_vu, input);
+ data::fill(deja_vu, false);
+ initialize(activity, input);
+ data::fill(activity, true);
+ initialize(parent, input);
+ initialize(data, input);
+ }
+ {
+ mln_fwd_piter(S) p(s);
+ mln_niter(N) n(nbh, p);
+
+ for_all(p)
+ {
+ {
+ parent(p) = p;
+ mln::canvas::morpho::impl::take_as_init (data(p), input, p);
+ }
+
+ for_all(n)
+ if (input.domain().has(n) && deja_vu(n))
+ {
+ P r = mln::canvas::morpho::impl::generic::find_root(parent, n);
+ if (r != p)
+ {
+ if (input(r) == input(p) || (activity(r) && (data(r) < lambda)))
+ {
+ data(p).take(data(r));
+ parent(r) = p;
+ if (activity(r) == false)
+ activity(p) = false;
+ }
+ else
+ {
+ activity(p) = false;
+ }
+ }
+ }
+ deja_vu(p) = true;
+ }
+ }
+ // Second pass.
+ {
+ mln_bkd_piter(S) p(s);
+ for_all(p)
+ if (parent(p) != p)
+ data(p) = data(parent(p));
+ }
+ return data;
+ }
+} // end of namespace exo3_filter
+
+namespace exo3_filter
+{
+ // Le but est de surcharger les operateurs uniquement pour les Built_In<>...
+ // l'idée est de provoquer une sfinae. J'ai pas trouvé mieux :(
+ // (pas vu d'opérateurs <, >, ... pour les Function<> utilisant mln::trait::solve)
+
+ // C is Category, R is return type
+ template <typename C, typename R>
+ struct ret_builtin;
+
+ template <typename T, typename R>
+ struct ret_builtin< value::Built_In< T > , R>
+ {
+ typedef R ret;
+ };
+
+} // end of namespace exo3_filter
+
+#define templatize(...) __VA_ARGS__
+
+#define op_for_cst(name, op) \
+ template <typename F, typename C> \
+ mln_trait_op_##name( \
+ F, \
+ templatize(typename exo3_filter::ret_builtin< typename mln::category< C >::ret, mln::pw::cst_<C> >::ret) \
+ ) \
+ operator op (const mln::Function_p2v<F>& f, const C& c) \
+ { \
+ return exact(f) op mln::pw::cst(c); \
+ } \
+ \
+ template <typename F, typename C> \
+ mln_trait_op_##name( \
+ templatize(typename exo3_filter::ret_builtin< typename mln::category< C >::ret, mln::pw::cst_<C> >::ret), \
+ F \
+ ) \
+ operator op (const C& c, const mln::Function_p2v<F>& f) \
+ { \
+ return mln::pw::cst(c) or exact(f); \
+ }
+
+op_for_cst(less, <)
+op_for_cst(greater, >)
+op_for_cst(leq, <=)
+op_for_cst(geq, >=)
+op_for_cst(eq, ==)
+op_for_cst(neq, !=)
+
+#undef op_for_cst
+
+void usage(char* argv[])
+{
+ std::cerr << "usage: " << argv[0] << " input.pgm sharpness minarea maxarea"
+ << std::endl;
+ abort();
+}
+
+int main(int argc, char **argv)
+{
+ using namespace mln;
+ using value::int_u8;
+
+ typedef image2d<int_u8> I;
+
+ float l_sharpness;
+ unsigned l_minarea;
+ unsigned l_maxarea;
+ I input;
+
+ if (argc < 5)
+ usage(argv);
+
+ io::pgm::load(input, argv[1]);
+
+ l_sharpness = atof(argv[2]);
+ l_minarea = atoi(argv[3]);
+ l_maxarea = atoi(argv[4]);
+
+ mln_VAR(sharp, exo3_filter::attribute_filter(input, c4(),
+ level::sort_psites_decreasing(input),
+ morpho::attribute::sharpness<I>(), l_sharpness));
+
+ mln_VAR(s, pw::value(sharp));
+
+ mln::fun::meta::area area;
+ io::pbm::save((area(s) > l_minarea && area(s) < l_maxarea) | input.domain(), "out.pbm");
+}
\ No newline at end of file
Index: trunk/milena/sandbox/theo/rush/exo3/assignable.cc
===================================================================
--- trunk/milena/sandbox/theo/rush/exo3/assignable.cc (revision 0)
+++ trunk/milena/sandbox/theo/rush/exo3/assignable.cc (revision 3452)
@@ -0,0 +1,251 @@
+#include <mln/core/concept/all.hh>
+#include <mln/fun/all.hh>
+#include <mln/trait/all.hh>
+#include <mln/fun/meta/green.hh>
+#include <mln/fun/v2w2v/cos.hh>
+#include <mln/fun/v2w_w2v/norm.hh>
+
+// Main definition, use solve_unary to find "implementation"
+// Usage: assignable< mln::fun::v2w2v::cos<double > cos;
+template <typename F>
+struct assignable : mln::trait::solve_unary<assignable, F>::ret
+{
+};
+
+// Meta for assignable
+// Usage: meta::assignable< mln::fun::v2w2v::cos > meta_cos;
+namespace meta
+{
+ template <template <class> class T>
+ struct assignable
+ {
+ template <typename V>
+ struct with
+ {
+ typedef ::assignable< T<V> > ret;
+ };
+
+ template <typename V>
+ typename with<V>::ret::result
+ operator() (const V& value) const
+ {
+ return typename with<V>::ret()(value);
+ }
+
+ template <typename V>
+ typename with<V>::ret::lresult
+ operator() (V& value) const
+ {
+ return typename with<V>::ret()(value);
+ }
+ };
+
+ template <template <class, class> class T>
+ struct assignable_bin
+ {
+ template <typename V, typename R>
+ struct with
+ {
+ typedef ::assignable< T<V, R> > ret;
+ };
+ };
+};
+
+// Tricks to play with templates
+namespace tricky
+{
+ // Disgusting: used to subsitute only according to certain condition (sfinae)
+ template <typename C1, typename C2 = void,
+ typename C3 = void, typename C4 = void>
+ struct subst_test
+ {
+ typedef void ret;
+ };
+
+ // Reinstantiate a template with another parameter
+ template <typename Tmpl, typename E>
+ struct reinstantiate;
+
+ template <template <class> class Tmpl, typename T, typename E>
+ struct reinstantiate<Tmpl<T>, E>
+ {
+ typedef Tmpl<E> ret;
+ };
+
+ template <typename T, template <class> class>
+ struct if_is_templated;
+
+ template <template <class> class Tmpl, typename M>
+ struct if_is_templated< Tmpl<M>, Tmpl >
+ {
+ };
+}
+
+// Internal namespace for assignable functor
+namespace internal
+{
+ namespace assignable
+ {
+ //
+ template <typename F, typename X, typename V>
+ void
+ compute_inv(const mln::Function_v2w_w2v<F>& f, X& x, const V& v)
+ {
+ x = mln::exact(f).f_1(v, x);
+ };
+
+ template <typename F, typename X, typename V>
+ void
+ compute_inv(const mln::Function_v2w2v<F>& f, X& x, const V& v)
+ {
+ x = mln::exact(f).f_1(v);
+ };
+
+ template <typename F, typename X>
+ struct modifier
+ {
+ modifier(X& x, const F& f)
+ : x_(&x), f_(&f)
+ {
+ }
+
+ operator const X& () const
+ { return *x_; };
+
+ operator X& ()
+ { return *x_; };
+
+ template <typename V>
+ const V& operator= (const V& v)
+ {
+ compute_inv(*f_, *x_, v);
+ return v;
+ }
+
+ private:
+ X *x_;
+ const F* f_;
+ };
+
+ // Solve modifiable type: do we need a modifier or can we directly set thru lvalue ?
+ template <typename F, typename V>
+ struct solve_value
+ {
+ typedef typename F::result ret;
+ };
+
+ template <typename F>
+ struct solve_value<F, typename tricky::subst_test< typename F::value >::ret >
+ {
+ typedef typename F::value ret;
+ };
+
+ // Solve modifiable type: do we need a modifier or can we directly set thru lvalue ?
+ template <typename F, typename Dummy>
+ struct solve_lresult
+ {
+ typedef modifier<F, typename F::result> ret;
+
+ template <typename V>
+ static inline
+ ret
+ modify(V& value, const F& thru)
+ {
+ return ret(value, thru);
+ }
+ };
+
+ template <typename F>
+ struct solve_lresult<F, typename tricky::subst_test< tricky::if_is_templated<typename F::F, mln::function> >::ret >
+ {
+ typedef typename F::lresult ret;
+
+ template <typename X>
+ static inline
+ ret
+ modify(X& value, const F& thru)
+ {
+ (void)thru;
+ return mln::function<F>().write(value);
+ }
+ };
+
+ template <typename F>
+ struct function_assign : public tricky::reinstantiate<typename F::category, function_assign<F> >::ret
+ {
+ typedef F function;
+ typedef typename function::result result;
+ typedef typename solve_value<function, void>::ret value;
+ typedef solve_lresult<function, void> lresult_solve;
+ typedef typename lresult_solve::ret lresult;
+
+ inline
+ result
+ operator() (const value& t) const
+ {
+ return f_.read(t);
+ }
+
+ inline
+ lresult
+ operator() (value& t)
+ {
+ return lresult_solve::modify(t, f_);
+ }
+
+ protected:
+ F f_;
+ };
+ }
+}
+
+namespace mln
+{
+
+ namespace trait
+ {
+
+ template <typename F>
+ struct set_unary_< ::assignable, Function_v2w2v, F >
+ {
+ typedef ::internal::assignable::function_assign<F> ret;
+ };
+
+ template <typename F>
+ struct set_unary_< ::assignable, Function_v2w_w2v, F >
+ {
+ typedef ::internal::assignable::function_assign<F> ret;
+ };
+
+ };
+
+};
+
+#define print_dbg(expr) std::cout << #expr "\t\t == " << (expr) << std::endl
+int main()
+{
+ mln::value::rgb8 p;
+ double x;
+
+ assignable< mln::fun::v2w2v::cos<double> > cos;
+ assignable< mln::meta::red<mln::value::rgb8> > red;
+ assignable< mln::meta::green<mln::value::rgb8> > green;
+ assignable< mln::meta::blue<mln::value::rgb8> > blue;
+
+ meta::assignable< mln::fun::v2w2v::cos > meta_cos;
+ meta::assignable< mln::meta::green > meta_green;
+
+ print_dbg(cos(x) = 0);
+ print_dbg(x);
+ print_dbg(meta_cos(x) = 1);
+ print_dbg(x);
+
+ print_dbg(red(p) = 0);
+ print_dbg(green(p) = 127);
+ print_dbg(blue(p) = 255);
+ print_dbg(p);
+
+ print_dbg(meta_green(p) = 0);
+ print_dbg(p);
+
+};
\ No newline at end of file
Index: trunk/milena/sandbox/theo/rush/exo3/Makefile
===================================================================
--- trunk/milena/sandbox/theo/rush/exo3/Makefile (revision 3451)
+++ trunk/milena/sandbox/theo/rush/exo3/Makefile (revision 3452)
@@ -1,9 +1,9 @@
-TARGETS=exo3_1 exo3_2 inverse
+TARGETS=exo3_fun_area exo3_fun_generator assignable
OLENADIR=../../../../..
MILENADIR=$(OLENADIR)/milena
-CXXFLAGS=-I$(MILENADIR) -I./ -W -Wall -O2
+CXXFLAGS+=-I$(MILENADIR) -I./ -W -Wall -O2
CXX=g++
LD=g++
LDFLAGS=
@@ -11,9 +11,9 @@
all: $(TARGETS)
-exo3_1: exo3_1.o
-exo3_2: exo3_2.o
-inverse: inverse.o
+exo3_fun_area: exo3_fun_area.o
+exo3_fun_generator: exo3_fun_generator.o
+assignable: assignable.o
$(TARGETS):
$(LD) $(LDFLAGS) -o $@ $<
1
0
milena r3451: Make area_on_vertices work with new algebraic code [POST-RUSH]
by Edwin Carlinet 01 Mar '09
by Edwin Carlinet 01 Mar '09
01 Mar '09
URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena
Area_on_vertices was the last file using old code, so we can now
delete old implementation.
ChangeLog:
2009-03-01 Edwin Carlinet <carlinet(a)lrde.epita.fr>
Make area_on_vertices work with new algebraic code [POST-RUSH].
* mln/morpho/attribute/count_adjacent_vertices.hh,
* mln/morpho/closing/area_on_vertices.hh,
* mln/morpho/opening/area_on_vertices.hh:
Make area_on_vertices work with new algebraic code, and
adapt count_adjacent_vertices accumulator as a morpho attribute.
* mln/morpho/closing_area_on_vertices.hh,
* mln/morpho/closing_attribute.hh,
* mln/morpho/opening_area_on_vertices.hh,
* mln/morpho/opening_attribute.hh:
Delete old implementations.
* tests/morpho/artificial_line_graph_image_wst.cc,
* tests/morpho/lena_line_graph_image_wst2.cc:
Update test files using area_on_vertices.
---
mln/morpho/attribute/count_adjacent_vertices.hh | 197 ++++++++++++++++++++++++
mln/morpho/closing/area_on_vertices.hh | 91 +++++++++++
mln/morpho/opening/area_on_vertices.hh | 91 +++++++++++
tests/morpho/artificial_line_graph_image_wst.cc | 2
tests/morpho/lena_line_graph_image_wst2.cc | 4
5 files changed, 382 insertions(+), 3 deletions(-)
Index: trunk/milena/tests/morpho/artificial_line_graph_image_wst.cc
===================================================================
--- trunk/milena/tests/morpho/artificial_line_graph_image_wst.cc (revision 3450)
+++ trunk/milena/tests/morpho/artificial_line_graph_image_wst.cc (revision 3451)
@@ -62,7 +62,7 @@
#include <mln/util/graph.hh>
#include <mln/morpho/line_gradient.hh>
-#include <mln/morpho/closing_area_on_vertices.hh>
+#include <mln/morpho/closing/area_on_vertices.hh>
#include <mln/morpho/meyer_wst.hh>
#include <mln/level/stretch.hh>
Index: trunk/milena/tests/morpho/lena_line_graph_image_wst2.cc
===================================================================
--- trunk/milena/tests/morpho/lena_line_graph_image_wst2.cc (revision 3450)
+++ trunk/milena/tests/morpho/lena_line_graph_image_wst2.cc (revision 3451)
@@ -64,7 +64,7 @@
#include <mln/util/graph.hh>
#include <mln/morpho/line_gradient.hh>
-#include <mln/morpho/closing_area_on_vertices.hh>
+#include <mln/morpho/closing/area_on_vertices.hh>
#include <mln/morpho/meyer_wst.hh>
#include <mln/level/stretch.hh>
@@ -115,7 +115,7 @@
typedef line_graph_elt_neighborhood<util::graph, lg_ima_t::pset::fun_t> nbh_t;
nbh_t nbh;
- lg_ima_t closed_lg_ima = morpho::closing_area_on_vertices(lg_ima, nbh, 20);
+ lg_ima_t closed_lg_ima = morpho::closing::area_on_vertices(lg_ima, nbh, 20);
/*------.
| WST. |
Index: trunk/milena/mln/morpho/opening_area_on_vertices.hh (deleted)
===================================================================
Index: trunk/milena/mln/morpho/closing_attribute.hh (deleted)
===================================================================
Index: trunk/milena/mln/morpho/opening_attribute.hh (deleted)
===================================================================
Index: trunk/milena/mln/morpho/closing_area_on_vertices.hh (deleted)
===================================================================
Index: trunk/milena/mln/morpho/closing/area_on_vertices.hh
===================================================================
--- trunk/milena/mln/morpho/closing/area_on_vertices.hh (revision 0)
+++ trunk/milena/mln/morpho/closing/area_on_vertices.hh (revision 3451)
@@ -0,0 +1,91 @@
+// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
+// (LRDE)
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef MLN_MORPHO_CLOSING_AREA_ON_VERTICES_HH
+# define MLN_MORPHO_CLOSING_AREA_ON_VERTICES_HH
+
+/// \file mln/morpho/closing/area_on_vertices.hh
+///
+/// Morphological area closing on a line graph image computing
+/// the area in terms of adjacent vertices.
+
+# include <mln/pw/image.hh>
+# include <mln/core/site_set/p_edges.hh>
+# include <mln/morpho/closing/algebraic.hh>
+# include <mln/morpho/attribute/count_adjacent_vertices.hh>
+
+
+namespace mln
+{
+
+ namespace morpho
+ {
+
+ namespace closing
+ {
+
+ /// Morphological area closing on a mln::line_graph_image computing
+ /// the area in terms of adjacent vertices.
+ template <typename P2V, typename G, typename V2P, typename N>
+ pw::image<P2V, p_edges<G, V2P> >
+ area_on_vertices(const pw::image<P2V, p_edges<G, V2P> >& input,
+ const Neighborhood<N>& nbh,
+ unsigned lambda);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename P2V, typename G, typename V2P, typename N>
+ inline
+ pw::image<P2V, p_edges<G, V2P> >
+ area_on_vertices(const pw::image<P2V, p_edges<G, V2P> >& input,
+ const Neighborhood<N>& nbh,
+ unsigned lambda)
+ {
+ trace::entering("morpho::closing::area_on_vertices");
+ mln_precondition(exact(input).is_valid());
+
+ typedef p_edges<G, V2P> pe_t;
+ typedef attribute::count_adjacent_vertices< pw::image<P2V, pe_t> > attribute_t;
+
+ pw::image<P2V, p_edges<G, V2P> > output;
+ output = closing::algebraic(input, nbh, attribute_t(), lambda);
+
+ trace::exiting("morpho::closing::area_on_vertices");
+ return output;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+ } // end of namespace mln::morpho::closing
+
+ } // end of namespace mln::morpho
+
+} // end of namespace mln
+
+
+#endif // ! MLN_MORPHO_CLOSING_AREA_ON_VERTICES_HH
Index: trunk/milena/mln/morpho/attribute/count_adjacent_vertices.hh
===================================================================
--- trunk/milena/mln/morpho/attribute/count_adjacent_vertices.hh (revision 0)
+++ trunk/milena/mln/morpho/attribute/count_adjacent_vertices.hh (revision 3451)
@@ -0,0 +1,197 @@
+// Copyright (C) 2007, 2008, 2009 EPITA Research and Development Laboratory
+// (LRDE)
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// 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_MORPHO_ATTRIBUTE_COUNT_ADJACENT_VERTICES_HH_
+# define MLN_MORPHO_ATTRIBUTE_COUNT_ADJACENT_VERTICES_HH_
+
+/// \file mln/accu/count_adjacent_vertices.hh
+///
+/// Define an accumulator that counts the vertices adjacent to a
+/// set of p_edges psites.
+
+# include <mln/accu/internal/base.hh>
+# include <mln/pw/image.hh>
+# include <mln/util/pix.hh>
+
+namespace mln
+{
+
+ // Forward declaration.
+ namespace morpho {
+ namespace attribute {
+ template <typename I>
+ struct count_adjacent_vertices;
+ }
+ }
+
+
+ // Traits.
+
+ namespace trait
+ {
+
+ template <typename I>
+ struct accumulator_< morpho::attribute::count_adjacent_vertices<I> >
+ {
+ typedef accumulator::has_untake::no has_untake;
+ typedef accumulator::has_set_value::no has_set_value;
+ typedef accumulator::has_stop::no has_stop;
+ typedef accumulator::when_pix::use_p when_pix;
+ };
+
+ } // end of namespace mln::trait
+
+
+ namespace morpho
+ {
+
+ namespace attribute
+ {
+
+ /// Count_Adjacent_Vertices accumulator class.
+ ///
+ /// The parameter \p I is the image type on which the accumulator
+ /// of pixels is built.
+
+ template <typename F, typename S>
+ struct count_adjacent_vertices< pw::image<F, S> >
+ : public accu::internal::base< unsigned , count_adjacent_vertices< pw::image<F, S> > >
+ {
+ typedef pw::image<F, S> I;
+ typedef mln_psite(I) argument;
+
+ count_adjacent_vertices();
+
+ /// Manipulators.
+ /// \{
+ void init();
+
+ void take(const argument& px);
+ void take(const count_adjacent_vertices<I>& other);
+
+ void take_as_init(const argument& px);
+ /// \}
+
+ /// Get the value of the accumulator.
+ unsigned to_result() const;
+
+ /// Check whether this accu is able to return a result.
+ bool is_valid() const;
+
+
+ protected:
+ /// Update the value of the counter.
+ void update_ ();
+
+ /// The value of the counter.
+ unsigned count__;
+ /// The set of adjacent vertices.
+ std::set<unsigned> vertices_;
+ };
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename F, typename S>
+ inline
+ count_adjacent_vertices< pw::image<F, S> >::count_adjacent_vertices()
+ {
+ init();
+ }
+
+ template <typename F, typename S>
+ inline
+ void
+ count_adjacent_vertices< pw::image<F, S> >::init()
+ {
+ vertices_.clear();
+ update_();
+ }
+
+ template <typename F, typename S>
+ inline
+ void
+ count_adjacent_vertices< pw::image<F,S> >::take(const argument& p)
+ {
+ vertices_.insert(p.v1());
+ vertices_.insert(p.v2());
+ update_();
+ }
+
+ template <typename F, typename S>
+ inline
+ void
+ count_adjacent_vertices< pw::image<F,S> >::take(const count_adjacent_vertices< pw::image <F,S> >& other)
+ {
+ vertices_.insert (other.vertices_.begin(), other.vertices_.end());
+ update_();
+ }
+
+ template <typename F, typename S>
+ inline
+ void
+ count_adjacent_vertices< pw::image<F,S> >::take_as_init(const argument& px)
+ {
+ vertices_.clear();
+ take(px);
+ }
+
+ template <typename F, typename S>
+ inline
+ unsigned
+ count_adjacent_vertices< pw::image<F,S> >::to_result() const
+ {
+ return count__;
+ }
+
+ template <typename F, typename S>
+ inline
+ void
+ count_adjacent_vertices< pw::image<F,S> >::update_()
+ {
+ count__ = vertices_.size();
+ }
+
+ template <typename F, typename S>
+ inline
+ bool
+ count_adjacent_vertices< pw::image<F,S> >::is_valid() const
+ {
+ return true;
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::morpho::attribute
+
+ } // end of namespace mln::morpho
+
+} // end of namespace mln
+
+#endif /* !MLN_MORPHO_ATTRIBUTE_COUNT_ADJACENT_VERTICES_HH_ */
Index: trunk/milena/mln/morpho/opening/area_on_vertices.hh
===================================================================
--- trunk/milena/mln/morpho/opening/area_on_vertices.hh (revision 0)
+++ trunk/milena/mln/morpho/opening/area_on_vertices.hh (revision 3451)
@@ -0,0 +1,91 @@
+// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
+// (LRDE)
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef MLN_MORPHO_OPENING_AREA_ON_VERTICES_HH
+# define MLN_MORPHO_OPENING_AREA_ON_VERTICES_HH
+
+/// \file mln/morpho/opening/area_on_vertices.hh
+///
+/// Morphological area opening on a line graph image computing
+/// the area in terms of adjacent vertices.
+
+# include <mln/pw/image.hh>
+# include <mln/core/site_set/p_edges.hh>
+# include <mln/morpho/opening/algebraic.hh>
+# include <mln/morpho/attribute/count_adjacent_vertices.hh>
+
+
+namespace mln
+{
+
+ namespace morpho
+ {
+
+ namespace opening
+ {
+
+ /// Morphological area opening on a mln::line_graph_image computing
+ /// the area in terms of adjacent vertices.
+ template <typename P2V, typename G, typename V2P, typename N>
+ pw::image<P2V, p_edges<G, V2P> >
+ area_on_vertices(const pw::image<P2V, p_edges<G, V2P> >& input,
+ const Neighborhood<N>& nbh,
+ unsigned lambda);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename P2V, typename G, typename V2P, typename N>
+ inline
+ pw::image<P2V, p_edges<G, V2P> >
+ area_on_vertices(const pw::image<P2V, p_edges<G, V2P> >& input,
+ const Neighborhood<N>& nbh,
+ unsigned lambda)
+ {
+ trace::entering("morpho::opening::area_on_vertices");
+ mln_precondition(exact(input).is_valid());
+
+ typedef p_edges<G, V2P> pe_t;
+ typedef attribute::count_adjacent_vertices< pw::image<P2V, pe_t> > attribute_t;
+
+ pw::image<P2V, p_edges<G, V2P> > output;
+ output = opening::algebraic(input, nbh, attribute_t(), lambda);
+
+ trace::exiting("morpho::opening::area_on_vertices");
+ return output;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+ } // end of namespace mln::morpho::opening
+
+ } // end of namespace mln::morpho
+
+} // end of namespace mln
+
+
+#endif // ! MLN_MORPHO_OPENING_AREA_ON_VERTICES_HH
1
0
URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena
ChangeLog:
2009-03-01 Edwin Carlinet <carlinet(a)lrde.epita.fr>
[EXO2] Add shell script for exo2.
* sandbox/theo/rush/exo2/Makefile
* sandbox/theo/rush/exo2/exo2.cc
* sandbox/theo/rush/exo2/exo2.sh: Shell script for exo2.
---
Makefile | 4 ++++
exo2.cc | 35 ++++++++++++++++++++++++++---------
exo2.sh | 16 ++++++++++++++++
3 files changed, 46 insertions(+), 9 deletions(-)
Index: trunk/milena/sandbox/theo/rush/exo2/exo2.cc
===================================================================
--- trunk/milena/sandbox/theo/rush/exo2/exo2.cc (revision 3449)
+++ trunk/milena/sandbox/theo/rush/exo2/exo2.cc (revision 3450)
@@ -18,28 +18,36 @@
#include <mln/morpho/attribute/card.hh>
#include <mln/morpho/attribute/sharpness.hh>
+#include <string>
+
#include "propagate.hh"
namespace mln
{
+ /// Structure to simplify filtering using min tree.
template <typename I>
struct treefilter
{
typedef p_array< mln_site(I) > S;
typedef morpho::tree::data<I,S> tree_t;
+ /// Constructor: Make the min tree based on the image \p f_, then
+ /// performs calculus using \p a_ attribute. To finish, it filters
+ /// tree's nodes which values are in [lambda1, lambda2] set.
template <typename A>
treefilter(Image<I>& f_,
Accumulator<A> a_,
double lambda1 = mln_min(double),
double lambda2 = mln_max(double));
+ /// Get the min tree performed.
tree_t& tree() { return tree_; };
+
+ /// Get the boolean image got after filtering.
mln_ch_value(I, bool)& img() {return img_; };
private:
-
S sorted_sites_;
tree_t tree_;
mln_ch_value(I, bool) img_;
@@ -68,7 +76,7 @@
void usage(char* argv[])
{
- std::cerr << "usage: " << argv[0] << " input.pgm lambda1 lamda2"
+ std::cerr << "usage: " << argv[0] << " input.pgm accumulator lambda1 [lambda2]"
<< std::endl;
abort();
}
@@ -85,17 +93,26 @@
float lambda2;
I input;
- if (argc < 3)
+ if (argc < 4)
usage(argv);
io::pgm::load(input, argv[1]);
- lambda1 = atof(argv[2]);
- lambda2 = (argc == 4) ? atof(argv[3]) : mln_max(float);
- treefilter<I> f(input, morpho::attribute::sharpness<I>(), lambda1, lambda2);
+ lambda1 = atof(argv[3]);
+ lambda2 = (argc == 5) ? atof(argv[4]) : mln_max(float);
+
+ std::string s(argv[2]);
+ treefilter<I>* f = 0;
+ if (s == "card")
+ f = new treefilter<I>(input, morpho::attribute::card<I>(), lambda1, lambda2);
+ else if (s == "sharpness")
+ f = new treefilter<I>(input, morpho::attribute::sharpness<I>(), lambda1, lambda2);
+ else
+ usage(argv);
- back_propagate_subbranch(f.tree(), f.img() ,true);
- back_propagate_level(f.tree(), f.img());
+ back_propagate_subbranch(f->tree(), f->img() ,true);
+ back_propagate_level(f->tree(), f->img());
- io::pbm::save(f.img(), "out.pbm");
+ io::pbm::save(f->img(), "out.pbm");
+ delete f;
}
Index: trunk/milena/sandbox/theo/rush/exo2/exo2.sh
===================================================================
--- trunk/milena/sandbox/theo/rush/exo2/exo2.sh (revision 0)
+++ trunk/milena/sandbox/theo/rush/exo2/exo2.sh (revision 3450)
@@ -0,0 +1,16 @@
+#! /bin/bash
+
+if [ ! -f affiche2.pgm ]; then
+ echo "affiche2.pgm introuvable"
+ exit 1
+fi
+
+convert -geometry 10% affiche2.pgm temp.bmp
+convert temp.bmp affiche2_10p.pgm
+./exo2 affiche2_10p.pgm card -1 21
+mv out.pbm card_10p.pbm
+./exo2 affiche2.pgm card 2100 3000
+mv out.pbm card.pbm
+./exo2 affiche2.pgm sharpness 0.8 1
+mv out.pbm sharpness.pbm
+rm temp.bmp
\ No newline at end of file
Property changes on: trunk/milena/sandbox/theo/rush/exo2/exo2.sh
___________________________________________________________________
Name: svn:executable
+ *
Index: trunk/milena/sandbox/theo/rush/exo2/Makefile
===================================================================
--- trunk/milena/sandbox/theo/rush/exo2/Makefile (revision 3449)
+++ trunk/milena/sandbox/theo/rush/exo2/Makefile (revision 3450)
@@ -14,6 +14,8 @@
LDFLAGS=
all: clean $(TARGET)
+ chmod +x exo2.sh
+ ./exo2.sh
$(TARGET): $(OBJS) $(SRC)
$(LD) $(LDFLAGS) -o $@ $(OBJS)
@@ -30,3 +32,5 @@
clean:
rm -f *.o $(REF) $(TARGET)
+ rm -f *.pbm
+ find -name "*.pgm" \! -regex ".*/affiche2?.pgm" -delete
\ No newline at end of file
1
0
URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox
ChangeLog:
2009-03-01 Frederic Bour <bour(a)lrde.epita.fr>
Mistake in previous commit..
* inverse.cc: Remove. Test file.
---
0 files changed
Index: trunk/milena/sandbox/theo/rush/exo3/inverse.cc (deleted)
===================================================================
1
0
URL: https://svn.lrde.epita.fr/svn/oln/trunk
ChangeLog:
2009-03-01 Frederic Bour <bour(a)lrde.epita.fr>
Add rush/exo3.
* milena/mln/canvas/morpho/attribute_filter.hh: Add one missing include.
* milena/sandbox/theo/rush/exo3/Makefile: New.
* milena/sandbox/theo/rush/exo3/exo3_1.cc: New.
* milena/sandbox/theo/rush/exo3/exo3_2.cc: New.
* milena/sandbox/theo/rush/exo3/inverse.cc: New.
* milena/sandbox/theo/rush/exo3: New.
---
mln/canvas/morpho/attribute_filter.hh | 7
sandbox/theo/rush/exo3/Makefile | 28 ++
sandbox/theo/rush/exo3/exo3_1.cc | 296 +++++++++++++++++++++++++++++
sandbox/theo/rush/exo3/exo3_2.cc | 346 ++++++++++++++++++++++++++++++++++
sandbox/theo/rush/exo3/inverse.cc | 84 ++++++++
5 files changed, 755 insertions(+), 6 deletions(-)
Index: trunk/milena/mln/canvas/morpho/attribute_filter.hh
===================================================================
--- trunk/milena/mln/canvas/morpho/attribute_filter.hh (revision 3447)
+++ trunk/milena/mln/canvas/morpho/attribute_filter.hh (revision 3448)
@@ -43,6 +43,7 @@
# include <mln/util/pix.hh>
# include <mln/data/fill.hh>
+# include <mln/level/sort_psites.hh>
namespace mln {
namespace canvas {
@@ -55,12 +56,6 @@
const Accumulator<A>& a, const typename A::result& lambda,
bool increasing);
- template <typename I, typename N, typename A>
- mln_concrete(I)
- algebraic_filter(const Image<I>& input, const Neighborhood<N>& nbh,
- const Accumulator<A>& a, const typename A::result& lambda,
- bool increasing);
-
# ifndef MLN_INCLUDE_ONLY
namespace impl {
Index: trunk/milena/sandbox/theo/rush/exo3/inverse.cc
===================================================================
--- trunk/milena/sandbox/theo/rush/exo3/inverse.cc (revision 0)
+++ trunk/milena/sandbox/theo/rush/exo3/inverse.cc (revision 3448)
@@ -0,0 +1,84 @@
+#include <mln/fun/all.hh>
+
+// Some definitions
+struct not_found {};
+struct impossible {};
+
+namespace inverse
+{
+ template <typename F>
+ struct solve_inverse
+ {
+ typedef not_found ret;
+ typedef not_found inversekind;
+ };
+
+ struct FInvKind_
+ {
+ struct lazy
+ {
+ };
+
+ struct computed
+ {
+ };
+
+ struct computed_w
+ {
+ };
+
+ };
+
+ namespace decompose
+ {
+ template <typename Class, typename Member>
+ struct Functor;
+
+ template <typename Class, typename Res, typename Arg>
+ struct Functor<Class, Result (Class::*)(Arg)>
+ {
+ typedef Res fun_result;
+ typedef Arg fun_argument;
+ };
+
+ template <typename T>
+ struct Dec
+ {
+ typedef Functor<T, &(const T)::operator() > const_tool;
+ typedef Functor<T, &T::operator() > mutab_tool;
+
+ typedef tool::fun_result result;
+ typedef tool::fun_argument argument;
+
+ T inst_;
+
+ result
+ operator() (argument a) const
+ {
+ return inst_(a);
+ };
+
+ result
+ operator() (argument a)
+ {
+ return inst_(a);
+ };
+ };
+
+ }
+
+ template <typename F, typename F_1 = typename solve_inverse<F>::ret,
+ typename InvKind = typename solve_inverse<F>::InvKind>
+ struct invertible : typename solve_kind<InvKind, invertible>::ret
+ {
+
+ typedef invertible<F_1, F> inverse;
+ };
+}
+
+int main()
+{
+ using namespace mln;
+
+
+};
\ No newline at end of file
Index: trunk/milena/sandbox/theo/rush/exo3/exo3_1.cc
===================================================================
--- trunk/milena/sandbox/theo/rush/exo3/exo3_1.cc (revision 0)
+++ trunk/milena/sandbox/theo/rush/exo3/exo3_1.cc (revision 3448)
@@ -0,0 +1,296 @@
+#include <mln/core/image/image2d.hh>
+#include <mln/morpho/attribute/sharpness.hh>
+#include <mln/pw/all.hh>
+#include <mln/io/pgm/all.hh>
+#include <mln/io/pbm/all.hh>
+#include <mln/core/var.hh>
+#include <mln/value/int_u8.hh>
+#include <mln/core/alias/neighb2d.hh>
+#include <mln/trait/all.hh>
+#include <mln/core/concept/function.hh>
+#include <mln/fun/internal/resolve.hh>
+#include <mln/morpho/attribute/card.hh>
+#include <mln/level/sort_offsets.hh>
+#include <mln/canvas/morpho/attribute_filter.hh>
+#include <mln/canvas/morpho/internal/find_root.hh>
+#include <mln/trait/op/all.hh>
+
+namespace mln
+{
+ namespace fun
+ {
+ namespace v2v
+ {
+ template <typename T> struct area;
+ }
+
+ /// Meta function for area calculation
+ namespace meta
+ {
+
+ struct area
+ {
+ template <typename T>
+ typename fun::v2v::area<T>::result
+ operator()(const T& t1) const
+ {
+ fun::v2v::area<T> f;
+ return f(t1);
+ }
+
+ template <typename T>
+ struct with
+ {
+ typedef fun::v2v::area<T> ret;
+ };
+ };
+
+ } // end of namespace mln::fun::meta
+
+ /// Function for area calculation
+ namespace v2v
+ {
+
+ template <typename T>
+ struct area : mln::Function_v2v< area<T> >
+ {
+ typedef mln_fun_internal_resolve(area) impl;
+ typedef typename impl::result result;
+
+ result
+ operator()(const T& t1) const
+ {
+ return impl::exec(t1);
+ }
+ };
+
+ } // end of namespace mln::fun::v2v
+
+ /// Function_p2v composition
+ namespace p2v
+ {
+ template <typename F, typename G>
+ struct composition_t
+ : mln::Function_p2v< composition_t<F, G> >
+ {
+ typedef typename F::result result;
+
+ composition_t() {}
+ composition_t(const F& f, const G& g)
+ : f_(f), g_(g)
+ {
+ }
+
+ template <typename T>
+ result
+ operator()(const T& p) const
+ {
+ return f_(g_(p));
+ }
+
+ protected:
+ F f_;
+ G g_;
+ };
+
+ } // end of namespace mln::fun::p2v
+
+ } // end of namespace mln::fun
+
+ /// fun::v2v::area trait for composition
+ namespace trait
+ {
+ template <typename T>
+ struct set_unary_< fun::v2v::area, Accumulator, T >
+ {
+ typedef set_unary_< fun::v2v::area, Accumulator, T > ret;
+ typedef unsigned result;
+
+ static
+ result
+ exec(const T& t1)
+ {
+ return t1.area();
+ }
+ };
+
+ template <typename I>
+ struct set_precise_unary_< fun::v2v::area, mln::morpho::attribute::card<I> >
+ {
+ typedef set_precise_unary_< fun::v2v::area, mln::morpho::attribute::card<I> > ret;
+ typedef unsigned result;
+
+ static
+ result
+ exec(const mln::morpho::attribute::card<I>& t1)
+ {
+ return t1.to_result();
+ }
+ };
+
+ template <typename G>
+ struct set_unary_<fun::v2v::area, mln::Function_p2v, G>
+ {
+ typedef set_unary_<fun::v2v::area, mln::Function_p2v, G> ret;
+ typedef fun::p2v::composition_t<fun::v2v::area<typename G::result>, G> result;
+
+ static
+ result
+ exec(const G& g)
+ {
+ return fun::p2v::composition_t<fun::v2v::area<typename G::result>, G>
+ (fun::v2v::area<typename G::result>(), g);
+ }
+ };
+ }
+
+}
+
+// Modified copy of mln::canvas::morpho::attribute_filter
+// for purpose of testing.
+namespace exo3_filter
+{
+ using namespace mln;
+
+ template <typename I, typename N, typename S, typename A>
+ mln_ch_value(I, A)
+ attribute_filter (const Image<I>& input_,
+ const Neighborhood<N>& nbh_,
+ const Site_Set<S>& s_,
+ const Accumulator<A>& a_,
+ const typename A::result& lambda)
+ {
+ const I& input = exact(input_);
+ const N& nbh = exact(nbh_);
+ const S& s = exact(s_);
+ (void)a_; // To avoid warning at compilation
+
+ // Local type.
+ typedef mln_psite(I) P;
+
+ mln_ch_value(I, bool) deja_vu;
+ mln_ch_value(I, bool) activity;
+ mln_ch_value(I, P) parent;
+ mln_ch_value(I, A) data;
+
+ {
+ initialize(deja_vu, input);
+ data::fill(deja_vu, false);
+ initialize(activity, input);
+ data::fill(activity, true);
+ initialize(parent, input);
+ initialize(data, input);
+ }
+ {
+ mln_fwd_piter(S) p(s);
+ mln_niter(N) n(nbh, p);
+
+ for_all(p)
+ {
+ {
+ parent(p) = p;
+ mln::canvas::morpho::impl::take_as_init (data(p), input, p);
+ }
+
+ for_all(n)
+ if (input.domain().has(n) && deja_vu(n))
+ {
+ P r = mln::canvas::morpho::impl::generic::find_root(parent, n);
+ if (r != p)
+ {
+ if (input(r) == input(p) || (activity(r) && (data(r) < lambda)))
+ {
+ data(p).take(data(r));
+ parent(r) = p;
+ if (activity(r) == false)
+ activity(p) = false;
+ }
+ else
+ {
+ activity(p) = false;
+ }
+ }
+ }
+ deja_vu(p) = true;
+ }
+ }
+ // Second pass.
+ {
+ mln_bkd_piter(S) p(s);
+ for_all(p)
+ if (parent(p) != p)
+ data(p) = data(parent(p));
+ }
+ return data;
+ }
+} // end of namespace exo3_filter
+
+namespace exo3_filter
+{
+ // Le but est de surcharger les operateurs uniquement pour les Built_In<>...
+ // l'idée est de provoquer une sfinae. J'ai pas trouvé mieux :(
+ // (pas vu d'opérateurs <, >, ... pour les Function<> utilisant mln::trait::solve)
+
+ // C is Category, R is return type
+ template <typename C, typename R>
+ struct ret_builtin;
+
+ template <typename T, typename R>
+ struct ret_builtin< value::Built_In< T > , R>
+ {
+ typedef R ret;
+ };
+
+} // end of namespace exo3_filter
+
+#define templatize(...) __VA_ARGS__
+
+#define op_for_cst(name, op) \
+ template <typename F, typename C> \
+ mln_trait_op_##name( \
+ F, \
+ templatize(typename exo3_filter::ret_builtin< typename mln::category< C >::ret, mln::pw::cst_<C> >::ret) \
+ ) \
+ operator op (const mln::Function_p2v<F>& f, const C& c) \
+ { \
+ return exact(f) op mln::pw::cst(c); \
+ } \
+ \
+ template <typename F, typename C> \
+ mln_trait_op_##name( \
+ templatize(typename exo3_filter::ret_builtin< typename mln::category< C >::ret, mln::pw::cst_<C> >::ret), \
+ F \
+ ) \
+ operator op (const C& c, const mln::Function_p2v<F>& f) \
+ { \
+ return mln::pw::cst(c) or exact(f); \
+ }
+
+op_for_cst(less, <)
+op_for_cst(greater, >)
+op_for_cst(leq, <=)
+op_for_cst(geq, >=)
+op_for_cst(eq, ==)
+op_for_cst(neq, !=)
+
+#undef op_for_cst
+
+int main()
+{
+ using namespace mln;
+
+ typedef image2d<value::int_u8> I;
+
+ I lena;
+ io::pgm::load(lena, "./affiche2.pgm");
+
+ mln_VAR(sharp, exo3_filter::attribute_filter(lena, c4(),
+ level::sort_psites_decreasing(lena),
+ morpho::attribute::sharpness<I>(), 0.2));
+
+ mln_VAR(s, pw::value(sharp));
+
+ mln::fun::meta::area area;
+ io::pbm::save((area(s) > 1500U && area(s) < 2000U) | lena.domain(), "out.pbm");
+
+}
\ No newline at end of file
Index: trunk/milena/sandbox/theo/rush/exo3/exo3_2.cc
===================================================================
--- trunk/milena/sandbox/theo/rush/exo3/exo3_2.cc (revision 0)
+++ trunk/milena/sandbox/theo/rush/exo3/exo3_2.cc (revision 3448)
@@ -0,0 +1,346 @@
+#include <mln/core/image/image2d.hh>
+#include <mln/morpho/attribute/sharpness.hh>
+#include <mln/pw/all.hh>
+#include <mln/io/pgm/all.hh>
+#include <mln/io/pbm/all.hh>
+#include <mln/core/var.hh>
+#include <mln/value/int_u8.hh>
+#include <mln/core/alias/neighb2d.hh>
+#include <mln/trait/all.hh>
+#include <mln/core/concept/function.hh>
+#include <mln/fun/internal/resolve.hh>
+#include <mln/morpho/attribute/card.hh>
+#include <mln/level/sort_offsets.hh>
+#include <mln/canvas/morpho/attribute_filter.hh>
+#include <mln/canvas/morpho/internal/find_root.hh>
+#include <mln/trait/op/all.hh>
+
+namespace exo3
+{
+ // Se code est un peu ... sale, et tente de répondre aux problèmes
+ // techniques apparus lors de la présentation (bonus ?).
+
+ // mln::trait::solve se spécialise pour des template <class T>
+ // en premier paramètre.
+ // Afin de transmettre plusieurs types, on passe par
+ // T = couple<TExact, TAux>. On 'hérite' de la catégorie de TExact.
+ // Utiliser pour le générateur de (méta)fonctions.
+ template <typename TExact, typename TAux>
+ struct couple
+ {
+ typedef TExact Exact;
+ typedef typename mln::category<Exact>::ret category;
+
+ typedef TAux Aux;
+ };
+
+ // Crée un type unique vide pour un type donné, évite une instantation ?!
+ // (inutile probablement, dans le doute...).
+ template <typename U>
+ struct uniq
+ {
+ };
+
+ // Get attribute from attribute "E" exact.
+ template <typename E>
+ typename E::result
+ get_attribute(uniq<E>, const E& exact)
+ {
+ return exact.to_result();
+ }
+
+ // area
+ template <typename I, typename E>
+ unsigned get_attribute(uniq< mln::morpho::attribute::card<I> >, const E& exact)
+ {
+ return exact.area();
+ }
+
+ // volume
+ template <typename I, typename E>
+ unsigned get_attribute(uniq< mln::morpho::attribute::volume<I> >, const E& exact)
+ {
+ return exact.volume();
+ }
+}
+
+namespace mln
+{
+ namespace fun
+ {
+ namespace v2v
+ {
+ template <typename T> struct from_accu_t;
+ template <typename T> struct solve_from_accu;
+ }
+
+ namespace meta
+ {
+ template <template <class> class A>
+ struct from_accu
+ {
+ template <typename T>
+ typename fun::v2v::from_accu_t< exo3::couple<T, A<T> > >::result
+ operator()(const T& t1) const
+ {
+ fun::v2v::from_accu_t< exo3::couple<T, A<T> > > f;
+ return f(t1);
+ }
+
+ template <typename T>
+ struct with
+ {
+ typedef fun::v2v::from_accu_t< exo3::couple<T, A<T> > > ret;
+ };
+ };
+ }
+ }
+
+ namespace trait
+ {
+ template <typename TE, typename TA>
+ struct set_unary_< fun::v2v::from_accu_t, Accumulator, exo3::couple<TE, TA> >
+ {
+ typedef set_unary_< fun::v2v::from_accu_t, Accumulator, exo3::couple<TE, TA> > ret;
+ typedef unsigned result;
+
+ static
+ result
+ exec(const TE& t1)
+ {
+ return exo3::get_attribute(exo3::uniq<TA>(), t1);
+ }
+ };
+
+ } // mln::trait
+
+ namespace fun
+ {
+ namespace v2v
+ {
+ template <typename T>
+ struct from_accu_t;
+
+ template <typename TE, typename TA>
+ struct from_accu_t< exo3::couple<TE, TA> > : mln::Function_v2v< from_accu_t< exo3::couple<TE, TA> > >
+ {
+ typedef mln_fun_internal_resolve(from_accu_t) impl;
+ typedef typename impl::result result;
+
+ result
+ operator()(const TE& t1) const
+ {
+ return impl::exec(t1);
+ }
+ };
+
+ template <typename A>
+ struct solve_from_accu
+ {
+ // FIXME: Not sure whether inheritance is the right way...
+ // But templated typedef are not currently available.
+ template <typename E>
+ struct ret : from_accu_t< exo3::couple< E, A > >
+ {
+ };
+ };
+ }
+ }
+
+}
+
+namespace exo3
+{
+ template <typename F, typename G>
+ struct functors_compose_
+ : mln::Function_p2v< functors_compose_<F, G> >
+ {
+ typedef typename F::result result;
+
+ functors_compose_() {}
+ functors_compose_(const F& f, const G& g)
+ : f_(f), g_(g)
+ {
+ }
+
+ template <typename T>
+ result
+ operator()(const T& p) const
+ {
+ return f_(g_(p));
+ }
+
+ protected:
+ F f_;
+ G g_;
+ };
+
+}
+
+namespace mln
+{
+
+ namespace trait
+ {
+
+ template <typename TG, typename TA>
+ struct set_unary_<fun::v2v::from_accu_t, mln::Function_p2v, exo3::couple<TG, TA> >
+ {
+ typedef set_unary_<fun::v2v::from_accu_t, mln::Function_p2v, exo3::couple<TG, TA> > ret;
+ typedef exo3::functors_compose_<fun::v2v::from_accu_t< exo3::couple<typename TG::result, TA> >, TG> result;
+
+ static
+ result
+ exec(const TG& g)
+ {
+ return exo3::functors_compose_<fun::v2v::from_accu_t< exo3::couple<typename TG::result, TA> >, TG>
+ (fun::v2v::from_accu_t<exo3::couple<typename TG::result, TA> >(), g);
+ }
+ };
+ }
+
+}
+
+// Modified copy of mln::canvas::morpho::attribute_filter
+namespace exo3_filter
+{
+ using namespace mln;
+
+ template <typename I, typename N, typename S, typename A>
+ mln_ch_value(I, A)
+ attribute_filter (const Image<I>& input_,
+ const Neighborhood<N>& nbh_,
+ const Site_Set<S>& s_,
+ const Accumulator<A>& a_,
+ const typename A::result& lambda)
+ {
+ const I& input = exact(input_);
+ const N& nbh = exact(nbh_);
+ const S& s = exact(s_);
+ (void)a_; // To avoid warning at compilation
+
+ // Local type.
+ typedef mln_psite(I) P;
+
+ mln_ch_value(I, bool) deja_vu;
+ mln_ch_value(I, bool) activity;
+ mln_ch_value(I, P) parent;
+ mln_ch_value(I, A) data;
+
+ {
+ initialize(deja_vu, input);
+ data::fill(deja_vu, false);
+ initialize(activity, input);
+ data::fill(activity, true);
+ initialize(parent, input);
+ initialize(data, input);
+ }
+ {
+ mln_fwd_piter(S) p(s);
+ mln_niter(N) n(nbh, p);
+
+ for_all(p)
+ {
+ {
+ parent(p) = p;
+ mln::canvas::morpho::impl::take_as_init (data(p), input, p);
+ }
+
+ for_all(n)
+ if (input.domain().has(n) && deja_vu(n))
+ {
+ P r = mln::canvas::morpho::impl::generic::find_root(parent, n);
+ if (r != p)
+ {
+ if (input(r) == input(p) || (activity(r) && (data(r) < lambda)))
+ {
+ data(p).take(data(r));
+ parent(r) = p;
+ if (activity(r) == false)
+ activity(p) = false;
+ }
+ else
+ {
+ activity(p) = false;
+ }
+ }
+ }
+ deja_vu(p) = true;
+ }
+ }
+ // Second pass.
+ {
+ mln_bkd_piter(S) p(s);
+ for_all(p)
+ if (parent(p) != p)
+ data(p) = data(parent(p));
+ }
+ return data;
+ }
+
+ // Surcharger les operateurs uniquement pour les builtins...
+ // l'idée est de provoquer une sfinae. J'ai pas trouvé mieux :(
+ // (pas vu d'opérateurs <, >, ... pour les fonctions utilisant mln::trait::solve)
+
+ // C is Category, R is return type
+ template <typename C, typename R>
+ struct ret_builtin;
+ template <typename T, typename R>
+ struct ret_builtin< value::Built_In< T > , R>
+ {
+ typedef R ret;
+ };
+
+} // end of namespace exo3_filter
+
+#define templatize(...) __VA_ARGS__
+
+#define op_for_cst(name, op) \
+ template <typename F, typename C> \
+ mln_trait_op_##name( \
+ F, \
+ templatize(typename exo3_filter::ret_builtin< typename mln::category< C >::ret, mln::pw::cst_<C> >::ret) \
+ ) \
+ operator op (const mln::Function_p2v<F>& f, const C& c) \
+ { \
+ return exact(f) op mln::pw::cst(c); \
+ } \
+ \
+ template <typename F, typename C> \
+ mln_trait_op_##name( \
+ templatize(typename exo3_filter::ret_builtin< typename mln::category< C >::ret, mln::pw::cst_<C> >::ret), \
+ F \
+ ) \
+ operator op (const C& c, const mln::Function_p2v<F>& f) \
+ { \
+ return mln::pw::cst(c) or exact(f); \
+ }
+
+op_for_cst(less, <)
+op_for_cst(greater, >)
+op_for_cst(leq, <=)
+op_for_cst(geq, >=)
+op_for_cst(eq, ==)
+op_for_cst(neq, !=)
+
+#undef op_for_cst
+
+int main()
+{
+ using namespace mln;
+
+ typedef image2d<value::int_u8> I;
+
+ I lena;
+ io::pgm::load(lena, "/home/defre/affiche2.pgm");
+
+ mln_VAR(sharp, exo3_filter::attribute_filter(lena, c4(),
+ level::sort_psites_decreasing(lena),
+ morpho::attribute::sharpness<I>(), 0.2));
+
+ mln_VAR(s, pw::value(sharp));
+
+ mln::fun::meta::from_accu< mln::morpho::attribute::volume > vol;
+ io::pbm::save((vol(s) > 1500U && vol(s) < 2000U) | lena.domain(), "out.pbm");
+
+}
\ No newline at end of file
Index: trunk/milena/sandbox/theo/rush/exo3/Makefile
===================================================================
--- trunk/milena/sandbox/theo/rush/exo3/Makefile (revision 0)
+++ trunk/milena/sandbox/theo/rush/exo3/Makefile (revision 3448)
@@ -0,0 +1,28 @@
+TARGETS=exo3_1 exo3_2 inverse
+
+OLENADIR=../../../../..
+MILENADIR=$(OLENADIR)/milena
+
+CXXFLAGS=-I$(MILENADIR) -I./ -W -Wall -O2
+CXX=g++
+LD=g++
+LDFLAGS=
+RM=rm
+
+all: $(TARGETS)
+
+exo3_1: exo3_1.o
+exo3_2: exo3_2.o
+inverse: inverse.o
+
+$(TARGETS):
+ $(LD) $(LDFLAGS) -o $@ $<
+
+%.o: %.cc
+ $(CXX) $(CXXFLAGS) -c $<
+
+%.o: %.hh
+ $(CXX) $(CXXFLAGS) -c $<
+
+clean:
+ $(RM) -f $(TARGETS) *.o *~
1
0