Olena-patches
Threads by month
- ----- 2025 -----
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- 9625 discussions
URL: https://svn.lrde.epita.fr/svn/scool/trunk
ChangeLog:
2008-03-26 Maxime van Noppen <yabo(a)lrde.epita.fr>
Work on concepts
* src/pp-cxx/CxxFun.str: Pretty-print C++ constructors correctly.
* src/pp-cxx/CxxDecl.str: Fix bug in access blocks pretty-print.
* src/pp-cxx/CxxType.str: Remove useless comment.
* src/scoolt/Concept.str: New.
* src/scoolt/Decl.str: Handle Concept constructor.
pp-cxx/CxxDecl.str | 4 ++--
pp-cxx/CxxFun.str | 11 +++++++++++
pp-cxx/CxxType.str | 2 --
scoolt/Concept.str | 34 ++++++++++++++++++++++++++++++++++
scoolt/Decl.str | 19 +++++++++++++++++--
5 files changed, 64 insertions(+), 6 deletions(-)
Index: trunk/src/pp-cxx/CxxFun.str
===================================================================
--- trunk/src/pp-cxx/CxxFun.str (revision 55)
+++ trunk/src/pp-cxx/CxxFun.str (revision 56)
@@ -16,6 +16,17 @@
]
CxxTopLevelToAbox:
+ CxxFun(params, None(), idf, args) ->
+ V vs=0
+ [
+ ~<CxxParamsToAbox> params
+ H hs=0
+ [
+ H hs=1 [ ~<CxxIdToAbox> idf ] "(" H hs=1 [ ~*<CxxListToAbox(CxxArgDefToAbox|",")> args ] ")" ";"
+ ]
+ ]
+
+ CxxTopLevelToAbox:
CxxFun(params, t, idf, args, body) ->
V vs=0
[
Index: trunk/src/pp-cxx/CxxDecl.str
===================================================================
--- trunk/src/pp-cxx/CxxDecl.str (revision 55)
+++ trunk/src/pp-cxx/CxxDecl.str (revision 56)
@@ -49,7 +49,7 @@
CxxPublic(b) -> V is=2 [ "public:" V [ ~*<map(CxxTopLevelToAbox)> b ] ]
CxxBodyToAbox:
- CxxProtected(b) -> V is=2 [ "private:" V [ ~*<map(CxxTopLevelToAbox)> b ] ]
+ CxxProtected(b) -> V is=2 [ "protected:" V [ ~*<map(CxxTopLevelToAbox)> b ] ]
CxxBodyToAbox:
CxxPrivate(b) -> V is=2 [ "private:" V [ ~*<map(CxxTopLevelToAbox)> b ] ]
@@ -62,7 +62,7 @@
H hs=1 [ "class" ~<CxxIdToAbox> idf ]
~<CxxParentsToAbox> parents
]
- V vs=0 is=2 [ "{" V vs=1 [ ~*<map (CxxBodyToAbox)> body ] ]
+ V vs=0 is=2 [ "{" V vs=0 [ ~*<map (CxxBodyToAbox <+ CxxTopLevelToAbox)> body ] ]
H hs=0 [ "}" ";" ]
]
Index: trunk/src/pp-cxx/CxxType.str
===================================================================
--- trunk/src/pp-cxx/CxxType.str (revision 55)
+++ trunk/src/pp-cxx/CxxType.str (revision 56)
@@ -19,7 +19,5 @@
CxxTypeToAbox:
Typename -> S("typename")
- /* These functions are actually macros */
-
CxxTypeToAbox:
CxxFunCall(idf, args) -> H hs=0 [ ~<CxxIdToAbox>idf "(" H hs=1 [ ~*<CxxListToAbox(CxxTypeToAbox <+ CxxExpToAbox|",")>args ] ")"]
Index: trunk/src/scoolt/Concept.str
===================================================================
--- trunk/src/scoolt/Concept.str (revision 0)
+++ trunk/src/scoolt/Concept.str (revision 56)
@@ -0,0 +1,34 @@
+module Concept
+
+imports libstratego-lib Cxx AsFix Scool
+
+rules
+
+ TypeToStr:
+ Var(t) -> "typedef"
+ where <eq> (t, "type")
+
+ TypeToStr:
+ FunType(_, Var(t)) -> t
+
+ ArgsToStr:
+ FunType([], _) -> ""
+
+ ArgsToStr:
+ FunType([ e | []], _) -> ""
+
+ ArgsToStr:
+ FunType([e | l], _) -> <concat-strings> [ e, ", ", <ArgsToStr> l ]
+
+ ConceptBodyToCxx:
+ ConstDec([], idf, None(), t) -> CxxComment(<concat-strings>[ <TypeToStr> t, " ", idf, ";" ])
+
+ ConceptBodyToCxx:
+ ConstDec(["decl"], idf, None(), t) ->
+ CxxComment(<concat-strings>[ <TypeToStr> t, " ", idf, "(", <ArgsToStr> t, ")", ";"])
+
+ ConceptAddCxxConstructor:
+ idf -> CxxProtected([CxxFun([], None(), idf, [])])
+
+// ConceptAddCxxConstructor(| idf):
+// _ -> CxxProtected([CxxFun([(Typename, "E")], "", <concat-strings>[ idf, "<E>::", idf], [], [])])
Index: trunk/src/scoolt/Decl.str
===================================================================
--- trunk/src/scoolt/Decl.str (revision 55)
+++ trunk/src/scoolt/Decl.str (revision 56)
@@ -1,6 +1,6 @@
module Decl
-imports libstratego-lib Cxx Type Exp Stm Tools AsFix Scool Access
+imports libstratego-lib Cxx Type Exp Stm Tools AsFix Scool Access Concept
rules
@@ -158,7 +158,7 @@
* Grammar: idf ":" "class" "<" parent ";"
*/
DeclToCxx:
- ConstDec([], idf, cs, Class(parent)) -> CxxClassDecl([], idf, [("public", <TypeToCxx> parent)])
+ ConstDec([], idf, cs, Class(Var(parent))) -> CxxClassDecl([], idf, [("public", CxxType(parent))])
where <conc-strings> (idf, "_") => nidf
/*
@@ -189,6 +189,21 @@
DeclToCxx:
BiFunDec(l, idf, params, args, t, ExpStm(body)) -> CxxFun(<map (ParamToCxx)> params, <TypeToCxx> t, idf, <map (ArgDefToCxx)> args, [<StmToCxx> Return(body)])
+
+ /*
+ * Handle concept declarations
+ * Grammar : idf ":" "concept" "{" body "}"
+ */
+ DeclToCxx:
+ Concept(idf, body) -> CxxClassDecl([(Typename, "E")], idf, [],
+ <conc>
+ (
+ [ CxxComment("To be provided by classes that models this concept\n") ],
+ <map (ConceptBodyToCxx)> body,
+ [ <ConceptAddCxxConstructor> idf ]
+ ))
+
+
ParamToCxx:
(idf, Var(t), wclause) ->
<if <eq> (t, "type") then
--
\__/ \__/
(00) Maxime `yabo` van Noppen (00)
___) \ Epita 2009 / (___
(_____/ Président de Prologin \_____)
1
0
URL: https://svn.lrde.epita.fr/svn/scool/trunk
ChangeLog:
2008-03-26 Maxime van Noppen <yabo(a)lrde.epita.fr>
Update some tests
* input/sample_1.scl,
* input/wiki1.scl,
* parser/sample_1.ref,
* parser/wiki1.ref,
* transformer/sample_1.ref,
* transformer/wiki1.ref: Replace int16 by int.
input/sample_1.scl | 4 ++--
input/wiki1.scl | 4 ++--
parser/sample_1.ref | 2 +-
parser/wiki1.ref | 2 +-
transformer/sample_1.ref | 4 ++--
transformer/wiki1.ref | 4 ++--
6 files changed, 10 insertions(+), 10 deletions(-)
Index: trunk/tests/input/sample_1.scl
===================================================================
--- trunk/tests/input/sample_1.scl (revision 54)
+++ trunk/tests/input/sample_1.scl (revision 55)
@@ -1,9 +1,9 @@
f : () -> void =
{
- i : int16 = 3;
+ i : int = 3;
i := 4;
- var j : int16 := 3;
+ var j : int := 3;
j := 4;
}
Index: trunk/tests/input/wiki1.scl
===================================================================
--- trunk/tests/input/wiki1.scl (revision 54)
+++ trunk/tests/input/wiki1.scl (revision 55)
@@ -1,9 +1,9 @@
f : () -> void =
{
- i : int16 = 3;
+ i : int = 3;
i := 4;
- var j : int16 := 3;
+ var j : int := 3;
j := 4;
}
\ No newline at end of file
Index: trunk/tests/transformer/wiki1.ref
===================================================================
--- trunk/tests/transformer/wiki1.ref (revision 54)
+++ trunk/tests/transformer/wiki1.ref (revision 55)
@@ -1,7 +1,7 @@
void f()
{
- const int16 i = 3;
+ const int i = 3;
i = 4;
- int16 j = 3;
+ int j = 3;
j = 4;
}
Index: trunk/tests/transformer/sample_1.ref
===================================================================
--- trunk/tests/transformer/sample_1.ref (revision 54)
+++ trunk/tests/transformer/sample_1.ref (revision 55)
@@ -1,7 +1,7 @@
void f()
{
- const int16 i = 3;
+ const int i = 3;
i = 4;
- int16 j = 3;
+ int j = 3;
j = 4;
}
Index: trunk/tests/parser/wiki1.ref
===================================================================
--- trunk/tests/parser/wiki1.ref (revision 54)
+++ trunk/tests/parser/wiki1.ref (revision 55)
@@ -1 +1 @@
-Program([FunDec([],"f",[],Var("void"),[ConstDec([],"i",Var("int16"),Int("3")),ExpStm(Affect(Var("i"),Int("4"))),VarDec([],"j",Var("int16"),Int("3")),ExpStm(Affect(Var("j"),Int("4")))])])
+Program([FunDec([],"f",[],Var("void"),[ConstDec([],"i",Var("int"),Int("3")),ExpStm(Affect(Var("i"),Int("4"))),VarDec([],"j",Var("int"),Int("3")),ExpStm(Affect(Var("j"),Int("4")))])])
Index: trunk/tests/parser/sample_1.ref
===================================================================
--- trunk/tests/parser/sample_1.ref (revision 54)
+++ trunk/tests/parser/sample_1.ref (revision 55)
@@ -1 +1 @@
-Program([FunDec([],"f",[],Var("void"),[ConstDec([],"i",Var("int16"),Int("3")),ExpStm(Affect(Var("i"),Int("4"))),VarDec([],"j",Var("int16"),Int("3")),ExpStm(Affect(Var("j"),Int("4")))])])
+Program([FunDec([],"f",[],Var("void"),[ConstDec([],"i",Var("int"),Int("3")),ExpStm(Affect(Var("i"),Int("4"))),VarDec([],"j",Var("int"),Int("3")),ExpStm(Affect(Var("j"),Int("4")))])])
--
\__/ \__/
(00) Maxime `yabo` van Noppen (00)
___) \ Epita 2009 / (___
(_____/ Président de Prologin \_____)
1
0
https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Roland Levillain <roland(a)lrde.epita.fr>
Have Meyer's WST depend less on the old code base.
* mln/morpho/meyer_wst.hh: Use labeling::regional_minima instead
of morpho::minima_components.
* mln/morpho/extrema_components.hh,
* mln/morpho/level_components.hh:
Remove.
* mln/canvas/labeling.hh: s/point/psite/.
canvas/labeling.hh | 35 +++++++++++++++++++++++------------
morpho/meyer_wst.hh | 15 ++++++++-------
2 files changed, 31 insertions(+), 19 deletions(-)
Index: mln/morpho/meyer_wst.hh
--- mln/morpho/meyer_wst.hh (revision 1803)
+++ mln/morpho/meyer_wst.hh (working copy)
@@ -43,11 +43,10 @@
# include <mln/trait/ch_value.hh>
+// FIXME: See below.
# include <mln/util/greater_psite.hh>
# include <mln/morpho/includes.hh>
-// FIXME: See below.
-// # include <mln/labeling/regional_minima.hh>
-# include <mln/morpho/extrema_components.hh>
+# include <mln/labeling/regional_minima.hh>
@@ -120,13 +119,15 @@
limitation. As soon as labeling::regional_minima work, get rid of
- mln/morpho/level_components.hh, and
- mln/morpho/extrema_components.hh. */
-// mln_ch_value(I, marker) markers =
-// labeling::regional_minima (input, nbh, nbasins);
mln_ch_value(I, marker) markers =
- minima_components(input, convert::to_window(nbh), nbasins);
+ labeling::regional_minima (input, nbh, nbasins);
- // Ordered queue.
typedef mln_psite(I) psite;
+
+ // Ordered queue.
+ /* FIXME: Milena probably already provides an ordered queue
+ facility via the mln::p_priority_queue class. Try to use it
+ instead, and get rid of mln/util/greater_psite.hh. */
typedef
std::priority_queue< psite, std::vector<psite>, util::greater_psite<I> >
ordered_queue_type;
Index: mln/canvas/labeling.hh
--- mln/canvas/labeling.hh (revision 1803)
+++ mln/canvas/labeling.hh (working copy)
@@ -59,11 +59,11 @@
typedef typename F::S S;
// Local type.
- typedef mln_psite(I) point;
+ typedef mln_psite(I) psite;
// Auxiliary data.
mln_ch_value(I, bool) deja_vu;
- mln_ch_value(I, point) parent;
+ mln_ch_value(I, psite) parent;
// Output.
mln_ch_value(I, L) output;
@@ -82,17 +82,19 @@
// Auxiliary methods.
- void make_set(const point& p);
+ void make_set(const psite& p);
- bool is_root(const point& p) const;
+ bool is_root(const psite& p) const;
- point find_root(const point& x);
+ psite find_root(const psite& x);
- void do_union(const point& n, const point& p);
+ void do_union(const psite& n, const psite& p);
};
+ // Fastest version.
+
template <typename F>
struct labeling_fastest
{
@@ -132,6 +134,10 @@
# ifndef MLN_INCLUDE_ONLY
+ /*-------------------.
+ | canvas::labeling. |
+ `-------------------*/
+
template <typename F>
labeling<F>::labeling(F& f)
: f(f)
@@ -204,7 +210,7 @@
template <typename F>
void
- labeling<F>::make_set(const point& p)
+ labeling<F>::make_set(const psite& p)
{
parent(p) = p;
f.init_attr(p);
@@ -212,14 +218,14 @@
template <typename F>
bool
- labeling<F>::is_root(const point& p) const
+ labeling<F>::is_root(const psite& p) const
{
return parent(p) == p;
}
template <typename F>
- typename labeling<F>::point
- labeling<F>::find_root(const point& x)
+ typename labeling<F>::psite
+ labeling<F>::find_root(const psite& x)
{
if (parent(x) == x)
return x;
@@ -229,9 +235,9 @@
template <typename F>
void
- labeling<F>::do_union(const point& n, const point& p)
+ labeling<F>::do_union(const psite& n, const psite& p)
{
- point r = find_root(n);
+ psite r = find_root(n);
if (r != p)
{
parent(r) = p;
@@ -239,6 +245,11 @@
}
}
+
+ /*---------------------------.
+ | canvas::labeling_fastest. |
+ `---------------------------*/
+
template <typename F>
labeling_fastest<F>::labeling_fastest(F& f)
: f(f)
1
0
1803: Fix validity checks on iterators on graph neighborhoods and windows.
by Roland Levillain 25 Mar '08
by Roland Levillain 25 Mar '08
25 Mar '08
https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Roland Levillain <roland(a)lrde.epita.fr>
Fix validity checks on iterators on graph neighborhoods and windows.
* mln/core/graph_psite.hh
(mln::graph_psite<P>::is_valid_): Set it public.
Rename as...
(mln::graph_psite<P>::is_valid): ...this.
Adjust callers.
* mln/core/graph_neighborhood_piter.hh
(mln::graph_neighborhood_fwd_piter<P>::is_valid):
(mln::graph_neighborhood_bkd_piter<P>::is_valid):
* mln/core/graph_window_piter.hh
(mln::graph_window_fwd_piter<P>::is_valid):
(mln::graph_window_bkd_piter<P>::is_valid):
Use mln::graph_psite<P>::is_valid.
* mln/core/line_graph_psite.hh
(mln::line_graph_psite<P>::is_valid_): Set it public.
Rename as...
(mln::line_graph_psite<P>::is_valid): ...this.
Adjust callers.
* mln/core/line_graph_neighborhood_piter.hh
(mln::line_graph_neighborhood_fwd_piter<P>::is_valid):
(mln::line_graph_neighborhood_bkd_piter<P>::is_valid):
* mln/core/line_graph_window_piter.hh
(mln::line_graph_window_fwd_piter<P>::is_valid):
(mln::line_graph_window_bkd_piter<P>::is_valid):
Use mln::line_graph_psite<P>::is_valid.
graph_neighborhood_piter.hh | 4 ++--
graph_psite.hh | 7 +++----
graph_window_piter.hh | 4 ++--
line_graph_neighborhood_piter.hh | 4 ++--
line_graph_psite.hh | 15 +++++++--------
line_graph_window_piter.hh | 4 ++--
6 files changed, 18 insertions(+), 20 deletions(-)
Index: mln/core/graph_psite.hh
--- mln/core/graph_psite.hh (revision 1802)
+++ mln/core/graph_psite.hh (working copy)
@@ -76,9 +76,8 @@
/// Return the node id of this point site.
util::node_id id() const;
- private:
/// Is this psite valid?
- bool is_valid_() const;
+ bool is_valid() const;
private:
/// The p_graph this point site belongs to.
@@ -137,7 +136,7 @@
template<typename P>
inline
bool
- graph_psite<P>::is_valid_() const
+ graph_psite<P>::is_valid() const
{
return pg_ && id_ < pg_->gr_->nnodes();
}
@@ -163,7 +162,7 @@
mln_coord(P)
graph_psite<P>::operator[](unsigned i) const
{
- mln_assertion(is_valid_());
+ mln_assertion(is_valid());
return to_point()[i];
}
Index: mln/core/graph_neighborhood_piter.hh
--- mln/core/graph_neighborhood_piter.hh (revision 1802)
+++ mln/core/graph_neighborhood_piter.hh (working copy)
@@ -227,7 +227,7 @@
// FIXME: We depend too much on the implementation of util::graph
// here. The util::graph should provide the service to abstract
// these manipulations.
- return id_ < p_ref_.pg().gr_->nnodes();
+ return p_ref_.is_valid() && id_ < p_ref_.pg().gr_->nnodes();
}
template <typename P>
@@ -352,7 +352,7 @@
// FIXME: We depend too much on the implementation of util::graph
// here. The util::graph should provide the service to abstract
// these manipulations.
- return id_ < p_ref_.pg().gr_->nnodes();
+ return p_ref_.is_valid() && id_ < p_ref_.pg().gr_->nnodes();
}
template <typename P>
Index: mln/core/graph_window_piter.hh
--- mln/core/graph_window_piter.hh (revision 1802)
+++ mln/core/graph_window_piter.hh (working copy)
@@ -228,7 +228,7 @@
bool
graph_window_fwd_piter<P>::is_valid() const
{
- return id_ < p_ref_.pg().npoints();
+ return p_ref_.is_valid() && id_ < p_ref_.pg().npoints();
}
template <typename P>
@@ -351,7 +351,7 @@
bool
graph_window_bkd_piter<P>::is_valid() const
{
- return id_ < p_ref_.pg().npoints();
+ return p_ref_.is_valid() && id_ < p_ref_.pg().npoints();
}
template <typename P>
Index: mln/core/line_graph_psite.hh
--- mln/core/line_graph_psite.hh (revision 1802)
+++ mln/core/line_graph_psite.hh (working copy)
@@ -89,9 +89,8 @@
/// Return the id of the second associated vertex.
util::node_id second_id() const;
- private:
/// Is this psite valid?
- bool is_valid_() const;
+ bool is_valid() const;
private:
/// The p_line_graph this point site belongs to.
@@ -179,7 +178,7 @@
template<typename P>
inline
bool
- line_graph_psite<P>::is_valid_() const
+ line_graph_psite<P>::is_valid() const
{
return plg_ && id_ < plg_->gr_->nedges();
}
@@ -206,7 +205,7 @@
mln_coord(P)
line_graph_psite<P>::operator[](unsigned i) const
{
- mln_assertion(is_valid_());
+ mln_assertion(is_valid());
return to_point()[i];
}
@@ -232,7 +231,7 @@
P
line_graph_psite<P>::first() const
{
- mln_assertion(is_valid_());
+ mln_assertion(is_valid());
return plg().gr_->node_data(first_id());
}
@@ -241,7 +240,7 @@
P
line_graph_psite<P>::second() const
{
- mln_assertion(is_valid_());
+ mln_assertion(is_valid());
return plg().gr_->node_data(second_id());
}
@@ -251,7 +250,7 @@
util::node_id
line_graph_psite<P>::first_id() const
{
- mln_assertion(is_valid_());
+ mln_assertion(is_valid());
return plg().gr_->edge(id_).n1();
}
@@ -260,7 +259,7 @@
util::node_id
line_graph_psite<P>::second_id() const
{
- mln_assertion(is_valid_());
+ mln_assertion(is_valid());
return plg().gr_->edge(id_).n2();
}
Index: mln/core/line_graph_neighborhood_piter.hh
--- mln/core/line_graph_neighborhood_piter.hh (revision 1802)
+++ mln/core/line_graph_neighborhood_piter.hh (working copy)
@@ -258,7 +258,7 @@
// FIXME: We depend too much on the implementation of util::graph
// here. The util::graph should provide the service to abstract
// these manipulations.
- return id_ < p_ref_.plg().gr_->nedges();
+ return p_ref_.is_valid() && id_ < p_ref_.plg().gr_->nedges();
}
template <typename P>
@@ -414,7 +414,7 @@
// FIXME: We depend too much on the implementation of util::graph
// here. The util::graph should provide the service to abstract
// these manipulations.
- return id_ < p_ref_.plg().gr_->nedges();
+ return p_ref_.is_valid() && id_ < p_ref_.plg().gr_->nedges();
}
template <typename P>
Index: mln/core/line_graph_window_piter.hh
--- mln/core/line_graph_window_piter.hh (revision 1802)
+++ mln/core/line_graph_window_piter.hh (working copy)
@@ -252,7 +252,7 @@
// FIXME: We depend too much on the implementation of util::graph
// here. The util::graph should provide the service to abstract
// these manipulations.
- return id_ < p_ref_.plg().gr_->nedges();
+ return p_ref_.is_valid() && id_ < p_ref_.plg().gr_->nedges();
}
template <typename P>
@@ -407,7 +407,7 @@
// FIXME: We depend too much on the implementation of util::graph
// here. The util::graph should provide the service to abstract
// these manipulations.
- return id_ < p_ref_.plg().gr_->nedges();
+ return p_ref_.is_valid() && id_ < p_ref_.plg().gr_->nedges();
}
template <typename P>
1
0
1802: Area closing/opening for line graph images based on adjacent vertices.
by Roland Levillain 25 Mar '08
by Roland Levillain 25 Mar '08
25 Mar '08
https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Roland Levillain <roland(a)lrde.epita.fr>
Area closing/opening for line graph images based on adjacent
vertices.
* mln/core/line_graph_psite.hh
(mln::line_graph_psite<P>::first_id)
(mln::line_graph_psite<P>::second_id):
New methods.
Use them to simplify...
(mln::line_graph_psite<P>::first)
(mln::line_graph_psite<P>::second): ...these ones.
* mln/accu/count_adjacent_vertices.hh: New accumulator.
* mln/morpho/closing_area_on_vertices.hh,
* mln/morpho/opening_area_on_vertices.hh:
New filters.
* mln/morpho/closing_area.hh,
* mln/morpho/opening_area.hh,
* mln/morpho/closing_attribute.hh,
* mln/morpho/opening_attribute.hh:
Remove spurious comments.
* tests/morpho/lena_line_graph_image_wst2.cc: Use
morpho::closing_area_on_vertices instead of morpho::closing.
mln/accu/count_adjacent_vertices.hh | 113 +++++++++++++++++------------
mln/core/line_graph_psite.hh | 32 +++++++-
mln/morpho/closing_area.hh | 5 -
mln/morpho/closing_area_on_vertices.hh | 39 ++++------
mln/morpho/closing_attribute.hh | 5 -
mln/morpho/opening_area.hh | 5 -
mln/morpho/opening_area_on_vertices.hh | 38 ++++-----
mln/morpho/opening_attribute.hh | 5 -
tests/morpho/lena_line_graph_image_wst2.cc | 16 +---
9 files changed, 138 insertions(+), 120 deletions(-)
Index: mln/core/line_graph_psite.hh
--- mln/core/line_graph_psite.hh (revision 1801)
+++ mln/core/line_graph_psite.hh (working copy)
@@ -79,11 +79,16 @@
/// Return the edge id of this point site.
util::edge_id id() const;
- /// Return the first associated point (vertex).
+ /// Return the first associated vertex.
P first() const;
- /// Return the second associated point (vertex).
+ /// Return the second associated vertex.
P second() const;
+ /// Return the id of the first associated vertex.
+ util::node_id first_id() const;
+ /// Return the id of the second associated vertex.
+ util::node_id second_id() const;
+
private:
/// Is this psite valid?
bool is_valid_() const;
@@ -228,7 +233,7 @@
line_graph_psite<P>::first() const
{
mln_assertion(is_valid_());
- return plg().gr_->node_data(plg().gr_->edge(id_).n1());
+ return plg().gr_->node_data(first_id());
}
template<typename P>
@@ -237,7 +242,26 @@
line_graph_psite<P>::second() const
{
mln_assertion(is_valid_());
- return plg().gr_->node_data(plg().gr_->edge(id_).n2());
+ return plg().gr_->node_data(second_id());
+ }
+
+
+ template<typename P>
+ inline
+ util::node_id
+ line_graph_psite<P>::first_id() const
+ {
+ mln_assertion(is_valid_());
+ return plg().gr_->edge(id_).n1();
+ }
+
+ template<typename P>
+ inline
+ util::node_id
+ line_graph_psite<P>::second_id() const
+ {
+ mln_assertion(is_valid_());
+ return plg().gr_->edge(id_).n2();
}
Index: mln/accu/count_adjacent_vertices.hh
--- mln/accu/count_adjacent_vertices.hh (revision 1801)
+++ mln/accu/count_adjacent_vertices.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory (LRDE)
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -25,17 +25,17 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-#ifndef MLN_ACCU_COUNT_HH
-# define MLN_ACCU_COUNT_HH
+#ifndef MLN_ACCU_COUNT_ADJACENT_VERTICES_HH
+# define MLN_ACCU_COUNT_ADJACENT_VERTICES_HH
-/*! \file mln/accu/count.hh
- *
- * \brief Define an accumulator that counts.
- */
+/// \file mln/accu/count_adjacent_vertices.hh
+/// \brief Define an accumulator that counts the vertices adjacent to a
+/// set of line graph psite.
# include <mln/accu/internal/base.hh>
# include <mln/core/concept/meta_accumulator.hh>
-
+# include <mln/core/line_graph_image.hh>
+# include <mln/util/pix.hh>
namespace mln
{
@@ -43,96 +43,119 @@
namespace accu
{
-
- /*!
- * \brief Generic counter accumulator class.
- *
- * The parameter \a T is the type to be count.
- */
- template <typename T>
- struct count_ : public mln::accu::internal::base_< std::size_t , count_<T> >
+ /// \brief Accumulator class counting the number of vertices
+ /// adjacent to a set of mln::line_graph_psite (i.e., a set of
+ /// edges).
+ ///
+ /// The type to be count is mln::util::pix< mln::line_graph_image<P, V> >
+ /// where \p P and \p V are the parameters of this class.
+ template <typename P, typename V>
+ struct count_adjacent_vertices_
+ : public mln::accu::internal::base_< std::size_t,
+ count_adjacent_vertices_<P, V> >
{
- typedef T argument;
- typedef std::size_t result; // FIXME: Up in Accumulator.
+ typedef mln::util::pix< mln::line_graph_image<P, V> > argument;
- count_();
+ count_adjacent_vertices_();
+ /// Manipulators.
+ /// \{
void init();
- // FIXME : should we add a take() without argument?
- void take(const argument&);
- void take(const count_<T>& other);
+ void take(const argument& arg);
+ void take(const count_adjacent_vertices_<P, V>& other);
- std::size_t to_result() const;
+ /// Force the value of the counter to \a c.
void set_value(std::size_t c);
+ /// \}
+
+ /// Get the value of the accumulator.
+ std::size_t to_result() const;
protected:
+ /// Update the value of the counter.
+ void update_ ();
+ protected:
+ /// The value of the counter.
std::size_t count__;
+ /// The set of adjacent vertices.
+ std::set<util::node_id> vertices_;
};
- /*!
- * \brief Meta accumulator for count.
- */
- struct count : public Meta_Accumulator< count >
+ /// \brief Meta accumulator for count_adjacent_vertices.
+ struct count_adjacent_vertices
+ : public Meta_Accumulator< count_adjacent_vertices >
{
- template <typename T>
+ template <typename P, typename V>
struct with
{
- typedef count_<T> ret;
+ typedef count_adjacent_vertices_<P, V> ret;
};
};
# ifndef MLN_INCLUDE_ONLY
- template <typename T>
+ template <typename P, typename V>
inline
- count_<T>::count_()
+ count_adjacent_vertices_<P, V>::count_adjacent_vertices_()
{
init();
}
- template <typename T>
+ template <typename P, typename V>
inline
void
- count_<T>::init()
+ count_adjacent_vertices_<P, V>::init()
{
- count__ = 0;
+ vertices_.clear();
+ update_();
}
- template <typename T>
+ template <typename P, typename V>
inline
void
- count_<T>::take(const argument&)
+ count_adjacent_vertices_<P, V>::take(const argument& arg)
{
- ++count__;
+ vertices_.insert(arg.p().first_id());
+ vertices_.insert(arg.p().second_id());
+ update_();
}
- template <typename T>
+ template <typename P, typename V>
inline
void
- count_<T>::take(const count_<T>& other)
+ count_adjacent_vertices_<P, V>::take(const count_adjacent_vertices_<P, V>& other)
{
- count__ += other.count__;
+ vertices_.insert (other.vertices_.begin(), other.vertices_.end());
+ update_();
}
- template <typename T>
+ template <typename P, typename V>
inline
std::size_t
- count_<T>::to_result() const
+ count_adjacent_vertices_<P, V>::to_result() const
{
return count__;
}
- template <typename T>
+ template <typename P, typename V>
inline
void
- count_<T>::set_value(std::size_t c)
+ count_adjacent_vertices_<P, V>::set_value(std::size_t c)
{
count__ = c;
}
+ template <typename P, typename V>
+ inline
+ void
+ count_adjacent_vertices_<P, V>::update_()
+ {
+ count__ = vertices_.size();
+ }
+
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln::accu
@@ -140,4 +163,4 @@
} // end of namespace mln
-#endif // ! MLN_ACCU_COUNT_HH
+#endif // ! MLN_ACCU_COUNT_ADJACENT_VERTICES_HH
Index: mln/morpho/closing_area_on_vertices.hh
--- mln/morpho/closing_area_on_vertices.hh (revision 1801)
+++ mln/morpho/closing_area_on_vertices.hh (working copy)
@@ -25,16 +25,17 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-#ifndef MLN_MORPHO_CLOSING_AREA_HH
-# define MLN_MORPHO_CLOSING_AREA_HH
+#ifndef MLN_MORPHO_CLOSING_AREA_ON_VERTICES_HH
+# define MLN_MORPHO_CLOSING_AREA_ON_VERTICES_HH
-/*! \file mln/morpho/closing_area.hh
- *
- * \brief Morphological area closing.
- */
+/// \file mln/morpho/closing_area.hh
+///
+/// \brief Morphological area closing on a line graph image computing
+/// the area in terms of adjacent vertices.
+# include <mln/core/line_graph_image.hh>
# include <mln/morpho/closing_attribute.hh>
-# include <mln/accu/count.hh>
+# include <mln/accu/count_adjacent_vertices.hh>
namespace mln
@@ -43,28 +44,26 @@
namespace morpho
{
- /* FIXME: The neighborhood shall not be passed as argument, but
- bound to the input image. We can also optionnaly provide a
- version of this function for regular-grid-based images where
- the neighborhood is replaced by a (user-provided) window. */
-
- /// Morphological area closing.
- template <typename I, typename N, typename O>
- void closing_area(const Image<I>& input, const Neighborhood<N>& nbh,
+ /// Morphological area closing on a mln::line_graph_image computing
+ /// the area in terms of adjacent vertices.
+ template <typename P, typename V, typename N, typename O>
+ void closing_area_on_vertices(const line_graph_image<P, V>& input,
+ const Neighborhood<N>& nbh,
std::size_t lambda, Image<O>& output);
# ifndef MLN_INCLUDE_ONLY
- template <typename I, typename N, typename O>
+ template <typename P, typename V, typename N, typename O>
inline
- void closing_area(const Image<I>& input, const Neighborhood<N>& nbh,
+ void closing_area_on_vertices(const line_graph_image<P, V>& input,
+ const Neighborhood<N>& nbh,
std::size_t lambda, Image<O>& output)
{
mln_precondition(exact(output).domain() == exact(input).domain());
- typedef util::pix<I> pix_t;
+ typedef accu::count_adjacent_vertices_<P, V> attribute_t;
// FIXME: Change sig of closing_attribute!
- closing_attribute< accu::count_<pix_t> >(input, nbh, lambda, output);
+ closing_attribute<attribute_t>(input, nbh, lambda, output);
}
# endif // ! MLN_INCLUDE_ONLY
@@ -74,4 +73,4 @@
} // end of namespace mln
-#endif // ! MLN_MORPHO_CLOSING_AREA_HH
+#endif // ! MLN_MORPHO_CLOSING_AREA_ON_VERTICES_HH
Index: mln/morpho/opening_area_on_vertices.hh
--- mln/morpho/opening_area_on_vertices.hh (revision 1801)
+++ mln/morpho/opening_area_on_vertices.hh (working copy)
@@ -25,16 +25,16 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-#ifndef MLN_MORPHO_OPENING_AREA_HH
-# define MLN_MORPHO_OPENING_AREA_HH
+#ifndef MLN_MORPHO_OPENING_AREA_ON_VERTICES_HH
+# define MLN_MORPHO_OPENING_AREA_ON_VERTICES_HH
-/*! \file mln/morpho/opening_area.hh
- *
- * \brief Morphological area opening.
- */
+/// \file mln/morpho/opening_area_on_vertices.hh
+/// \brief Morphological area opening on a line graph image computing
+/// the area in terms of adjacent vertices.
+# include <mln/core/line_graph_image.hh>
# include <mln/morpho/opening_attribute.hh>
-# include <mln/accu/count.hh>
+# include <mln/accu/count_adjacent_vertices.hh>
namespace mln
@@ -43,28 +43,26 @@
namespace morpho
{
- /* FIXME: The neighborhood shall not be passed as argument, but
- bound to the input image. We can also optionnaly provide a
- version of this function for regular-grid-based images where
- the neighborhood is replaced by a (user-provided) window. */
-
- /// Morphological area opening.
- template <typename I, typename N, typename O>
- void opening_area(const Image<I>& input, const Neighborhood<N>& nbh,
+ /// Morphological area opening on a mln::line_graph_image computing
+ /// the area in terms of adjacent vertices.
+ template <typename P, typename V, typename N, typename O>
+ void opening_area_on_vertices(const line_graph_image<P, V>& input,
+ const Neighborhood<N>& nbh,
std::size_t lambda, Image<O>& output);
# ifndef MLN_INCLUDE_ONLY
- template <typename I, typename N, typename O>
+ template <typename P, typename V, typename N, typename O>
inline
- void opening_area(const Image<I>& input, const Neighborhood<N>& nbh,
+ void opening_area_on_vertices(const line_graph_image<P, V>& input,
+ const Neighborhood<N>& nbh,
std::size_t lambda, Image<O>& output)
{
mln_precondition(exact(output).domain() == exact(input).domain());
- typedef util::pix<I> pix_t;
+ typedef accu::count_adjacent_vertices_<P, V> attribute_t;
// FIXME: Change sig of opening_attribute!
- opening_attribute< accu::count_<pix_t> >(input, nbh, lambda, output);
+ opening_attribute<attribute_t>(input, nbh, lambda, output);
}
# endif // ! MLN_INCLUDE_ONLY
@@ -74,4 +72,4 @@
} // end of namespace mln
-#endif // ! MLN_MORPHO_OPENING_AREA_HH
+#endif // ! MLN_MORPHO_OPENING_AREA_ON_VERTICES_HH
Index: mln/morpho/closing_area.hh
--- mln/morpho/closing_area.hh (revision 1801)
+++ mln/morpho/closing_area.hh (working copy)
@@ -43,11 +43,6 @@
namespace morpho
{
- /* FIXME: The neighborhood shall not be passed as argument, but
- bound to the input image. We can also optionnaly provide a
- version of this function for regular-grid-based images where
- the neighborhood is replaced by a (user-provided) window. */
-
/// Morphological area closing.
template <typename I, typename N, typename O>
void closing_area(const Image<I>& input, const Neighborhood<N>& nbh,
Index: mln/morpho/opening_area.hh
--- mln/morpho/opening_area.hh (revision 1801)
+++ mln/morpho/opening_area.hh (working copy)
@@ -43,11 +43,6 @@
namespace morpho
{
- /* FIXME: The neighborhood shall not be passed as argument, but
- bound to the input image. We can also optionnaly provide a
- version of this function for regular-grid-based images where
- the neighborhood is replaced by a (user-provided) window. */
-
/// Morphological area opening.
template <typename I, typename N, typename O>
void opening_area(const Image<I>& input, const Neighborhood<N>& nbh,
Index: mln/morpho/closing_attribute.hh
--- mln/morpho/closing_attribute.hh (revision 1801)
+++ mln/morpho/closing_attribute.hh (working copy)
@@ -45,11 +45,6 @@
namespace morpho
{
- /* FIXME: The neighborhood shall not be passed as argument, but
- bound to the input image. We can also optionnaly provide a
- version of this function for regular-grid-based images where
- the neighborhood is replaced by a (user-provided) window. */
-
/// Morphological attribute closing.
template <typename A,
typename I, typename N, typename O>
Index: mln/morpho/opening_attribute.hh
--- mln/morpho/opening_attribute.hh (revision 1801)
+++ mln/morpho/opening_attribute.hh (working copy)
@@ -45,11 +45,6 @@
namespace morpho
{
- /* FIXME: The neighborhood shall not be passed as argument, but
- bound to the input image. We can also optionnaly provide a
- version of this function for regular-grid-based images where
- the neighborhood is replaced by a (user-provided) window. */
-
/// Morphological attribute opening.
template <typename A,
typename I, typename N, typename O>
Index: tests/morpho/lena_line_graph_image_wst2.cc
--- tests/morpho/lena_line_graph_image_wst2.cc (revision 1801)
+++ tests/morpho/lena_line_graph_image_wst2.cc (working copy)
@@ -42,9 +42,9 @@
between the values on the nodes adjacent to the edge, so as to
create a (norm of the gradient) ``between the pixels'' of the
input image;
- \li (insert an minima-killer pass here, as soon as it works on
- graph-based images);
- \li perform a WST on the line graph image;
+ \li reduce the number of minima using an area opening (computing the
+ area using the vertices, not the edges);
+ \li perform a WST on this simplified line graph image;
\li reduce the quantification of the result of the WST;
\li create an 2-D, color output image with height and width double
the size the original one, and copy the data of the input image
@@ -63,7 +63,7 @@
#include <mln/core/line_graph_neighborhood_piter.hh>
#include <mln/morpho/line_gradient.hh>
-#include <mln/morpho/closing_area.hh>
+#include <mln/morpho/closing_area_on_vertices.hh>
#include <mln/morpho/meyer_wst.hh>
#include <mln/level/stretch.hh>
@@ -114,13 +114,7 @@
nbh_t nbh;
ima_t closed_lg_ima (lg_ima.domain());
- /* FIXME: We should change the attribute closing performed here;
- instead of computing the area using the data on the lines
- (edges), whe should use the data on the pixels (vertices).
-
- The best way is probably to create another attribute-functor and
- use the algebraic_union_find canvas. */
- morpho::closing_area(lg_ima, nbh, 20, closed_lg_ima);
+ morpho::closing_area_on_vertices(lg_ima, nbh, 20, closed_lg_ima);
/*------.
| WST. |
1
0
https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Roland Levillain <roland(a)lrde.epita.fr>
Line gradient computation.
* tests/morpho/lena_line_graph_image_wst1.cc: Fix comments.
* tests/morpho/lena_line_graph_image_wst2.cc: Fix the
initialization of the watershed image.
Reify and move the line gradient computation...
* mln/morpho/line_gradient.hh: ...here (new file).
mln/morpho/line_gradient.hh | 122 +++++++++++++++++++++++++++++
tests/morpho/lena_line_graph_image_wst1.cc | 9 --
tests/morpho/lena_line_graph_image_wst2.cc | 63 +-------------
3 files changed, 133 insertions(+), 61 deletions(-)
Index: tests/morpho/lena_line_graph_image_wst1.cc
--- tests/morpho/lena_line_graph_image_wst1.cc (revision 1800)
+++ tests/morpho/lena_line_graph_image_wst1.cc (working copy)
@@ -90,11 +90,8 @@
image2d<input_val_t> input;
io::pgm::load(input, MLN_IMG_DIR "/tiny.pgm");
- /* FIXME: Don't compute a gradient on the image2d input. Instead,
- have the values of the line graph image /behaves/ as the gradient
- of the input, i.e., edges should hold the absolute difference
- between gray levels.
- */
+ // In this test, the gradient is directly computed on the input
+ // image, not on the edges of the line graph image.
image2d<input_val_t> gradient =
morpho::gradient (input, convert::to_window(c4()));
@@ -126,7 +123,7 @@
g.add_node (p);
node_values.push_back (work(p));
/* FIXME: ``Guessing'' the id of the point just being inserted
- is bad. utill:graph<N,E>::add_node should return this
+ is bad. util:graph<N,E>::add_node should return this
id. */
points[p] = id;
++id;
Index: tests/morpho/lena_line_graph_image_wst2.cc
--- tests/morpho/lena_line_graph_image_wst2.cc (revision 1800)
+++ tests/morpho/lena_line_graph_image_wst2.cc (working copy)
@@ -62,7 +62,7 @@
#include <mln/core/line_graph_elt_neighborhood.hh>
#include <mln/core/line_graph_neighborhood_piter.hh>
-#include <mln/morpho/gradient.hh>
+#include <mln/morpho/line_gradient.hh>
#include <mln/morpho/closing_area.hh>
#include <mln/morpho/meyer_wst.hh>
#include <mln/level/stretch.hh>
@@ -98,57 +98,13 @@
image2d<input_val_t> input;
io::pgm::load(input, MLN_IMG_DIR "/small.pgm");
- /*-------------.
- | Line graph. |
- `-------------*/
-
- // FIXME: Inlined conversion, to be reifed into a routine.
-
- util::graph<point2d> g;
-
- // Points.
- /* FIXME: The need for such a structure during the conversion
- exhibits the lack of a service from util::graph (or a another,
- missing tool) regarding the retrieval of nodes' ids from
- points. */
- std::map<point2d, util::node_id> points;
- util::node_id id = 0;
-
- // Nodes.
- std::vector<input_val_t> node_values;
- mln_fwd_piter_(image2d<input_val_t>) p(input.domain());
- for_all (p)
- {
- g.add_node (p);
- node_values.push_back (input(p));
- /* FIXME: ``Guessing'' the id of the point just being inserted
- is bad. utill:graph<N,E>::add_node should return this
- id. */
- points[p] = id;
- ++id;
- }
-
- // Edges.
- window2d next_c4_win;
- next_c4_win.insert(0, 1).insert(1, 0);
- std::vector<input_val_t> edge_values;
- mln_fwd_qiter_(window2d) q(next_c4_win, p);
- for_all (p)
- for_all (q)
- if (input.has(q))
- {
- g.add_edge(points[p], points[q]);
- // The computed value is a kind of norm of the gradient
- // bewteen P and Q.
- edge_values.push_back(math::abs(input(p) - input(q)));
- }
-
- // Line graph point set.
- p_line_graph<point2d> plg(g);
+ /*----------------.
+ | Line gradient. |
+ `----------------*/
// Line graph image.
typedef line_graph_image<point2d, input_val_t> ima_t;
- ima_t lg_ima(plg, node_values, edge_values);
+ ima_t lg_ima = morpho::line_gradient(input);
/*-----------------.
| Simplification. |
@@ -180,10 +136,8 @@
// Reduce the value set to 8-bit.
typedef int_u8 wst_val_t;
typedef line_graph_image<point2d, wst_val_t> wst_ima_t;
- // FIXME: Initializations should not be that complicated.
- wst_ima_t wshed (plg,
- std::vector<wst_val_t>(node_values.size()),
- std::vector<wst_val_t>(edge_values.size()));
+ wst_ima_t wshed;
+ initialize(wshed, wshed_full);
level::stretch(wshed_full, wshed);
/*---------.
@@ -202,7 +156,7 @@
input.domain().pmax()[1] * 2);
output_t output(box2d(output_pmin, output_pmax));
level::fill(output, literal::black);
- // Reuse the piter on INPUT.
+ mln_fwd_piter_(image2d<input_val_t>) p(input.domain());
for_all(p)
{
// Equivalent of P in OUTPUT.
@@ -214,7 +168,6 @@
}
// Interpolate missing points in OUTPUT.
mln_piter_(output_t) p_out(output.domain());
-// mln_niter_(neighb2d) n_out(c4(), p_out);
for_all(p_out)
{
// Process points on even rows and odd columns
Index: mln/morpho/line_gradient.hh
--- mln/morpho/line_gradient.hh (revision 0)
+++ mln/morpho/line_gradient.hh (revision 0)
@@ -0,0 +1,122 @@
+// 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 MLN_MORPHO_LINE_GRADIENT_HH
+# define MLN_MORPHO_LINE_GRADIENT_HH
+
+/// \file mln/morpho/line_gradient.hh
+/// \brief Conversions to mln::line_graph_image.
+
+# include <map>
+# include <vector>
+
+# include <mln/core/image2d.hh>
+# include <mln/core/line_graph_image.hh>
+
+// FIXME: Generalize to other (input) images as well (image1d,
+// image3d, etc.).
+
+namespace mln
+{
+
+ namespace morpho
+ {
+
+ /// \brief Create a line graph image representing the gradient
+ /// norm of a mln::image2d.
+ /* FIXME: Currently, the adjacency is set to 4-c and cannot be
+ changed. */
+ template <typename T>
+ mln::line_graph_image<mln::point2d, T>
+ line_gradient(const mln::image2d<T>& ima);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename T>
+ mln::line_graph_image<mln::point2d, T>
+ line_gradient(const mln::image2d<T>& ima)
+ {
+ // FIXME: Precondition: Ensure the image is scalar.
+ typedef T value_t;
+
+ util::graph<mln::point2d> g;
+
+ // Points.
+ /* FIXME: The need for such a structure during the conversion
+ exhibits the lack of a service from util::graph (or a another,
+ missing tool) regarding the retrieval of nodes' ids from
+ points. */
+ std::map<mln::point2d, util::node_id> points;
+ util::node_id id = 0;
+
+ // Nodes.
+ std::vector<value_t> node_values;
+ mln_fwd_piter(image2d<value_t>) p(ima.domain());
+ for_all (p)
+ {
+ g.add_node (p);
+ node_values.push_back (ima(p));
+ /* FIXME: ``Guessing'' the id of the point just being inserted
+ is bad. util:graph<N,E>::add_node should return this
+ id. */
+ points[p] = id;
+ ++id;
+ }
+
+ // Edges.
+ // FIXME: The creation of this window should be generic.
+ window2d next_c4_win;
+ next_c4_win.insert(0, 1).insert(1, 0);
+ std::vector<value_t> edge_values;
+ mln_fwd_qiter_(window2d) q(next_c4_win, p);
+ for_all (p)
+ for_all (q)
+ if (ima.has(q))
+ {
+ g.add_edge(points[p], points[q]);
+ // The computed value is a norm of the gradient between P and Q.
+ edge_values.push_back(math::abs(ima(p) - ima(q)));
+ }
+
+ // Line graph point set.
+ p_line_graph<mln::point2d> plg(g);
+
+ // Line graph image.
+ typedef line_graph_image<mln::point2d, value_t> ima_t;
+ ima_t lg_ima(plg, node_values, edge_values);
+ return lg_ima;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::morpho
+
+} // end of namespace mln
+
+
+#endif // ! MLN_MORPHO_LINE_GRADIENT_HH
1
0
25 Mar '08
https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Roland Levillain <roland(a)lrde.epita.fr>
Fix some memory management problems w.r.t. graph-based images.
* mln/core/p_graph.hh (mln::p_graph<P>::gr_): Handle the
underlying graph as a tracked pointer.
(mln::p_graph<P>::p_graph(const graph&))
(mln::p_graph<P>::nnodes)
(mln::p_graph<P>::point_from_id)
(mln::p_graph<P>::node1, mln::p_graph<P>::node2)
(mln::p_graph<P>::has(const psite&))
(mln::p_graph<P>::adjacent_or_equal)
(mln::operator==(const p_graph<P>&, const p_graph<P>&)):
Adjust.
* mln/core/graph_image.hh
(mln::internal::data_< graph_image<P, V> >::pg_): Handle the
p_graph by copy, as the tracked pointer takes care of the
memory management.
(mln::graph_image<P, V>::operator()(const graph_psite<P>&)):
Adjust operators.
* mln/core/graph_psite.hh,
* mln/core/graph_window_piter.hh:
Adjust.
* mln/core/graph_neighborhood_piter.hh: Likewise.
(mln::graph_neighborhood_fwd_piter<P>::adjacent_or_equal_to_p_ref_)
(mln::graph_neighborhood_bkd_piter<P>::adjacent_or_equal_to_p_ref_):
Simplify using mln::p_graph<P>::adjacent_or_equal.
* mln/core/p_line_graph.hh (mln::p_line_graph<P>::gr_): Handle the
underlying graph as a tracked pointer.
(mln::p_line_graph<P>::p_line_graph(const graph&))
(mln::p_line_graph<P>::nnodes, mln::p_line_graph<P>::nedges)
(mln::p_line_graph<P>::has(const psite&))
(mln::operator==(const p_line_graph<P>&, const p_line_graph<P>&)):
Adjust.
* mln/core/line_graph_image.hh
(mln::internal::data_< line_graph_image<P, V> >::plg_): Handle the
p_line_graph by copy, as the tracked pointer takes care of the
memory management.
(mln::line_graph_image<P, V>::operator()(const line_graph_psite<P>&)):
Adjust operators.
* mln/core/line_graph_psite.hh,
* mln/core/line_graph_neighborhood_piter.hh,
* mln/core/line_graph_window_piter.hh:
Adjust.
graph_image.hh | 11 ++-----
graph_neighborhood_piter.hh | 58 ++++-----------------------------------
graph_psite.hh | 2 -
graph_window_piter.hh | 2 -
line_graph_image.hh | 11 ++-----
line_graph_neighborhood_piter.hh | 32 +++++++++++----------
line_graph_psite.hh | 6 ++--
line_graph_window_piter.hh | 32 +++++++++++----------
p_graph.hh | 42 ++++++++++++++++------------
p_line_graph.hh | 30 ++++++++++++--------
10 files changed, 94 insertions(+), 132 deletions(-)
Index: mln/core/p_graph.hh
--- mln/core/p_graph.hh (revision 1799)
+++ mln/core/p_graph.hh (working copy)
@@ -31,6 +31,7 @@
# include <mln/core/concept/point_site.hh>
# include <mln/core/internal/point_set_base.hh>
# include <mln/accu/bbox.hh>
+# include <mln/util/tracked_ptr.hh>
# include <mln/util/graph.hh>
# include <mln/core/graph_psite.hh>
# include <mln/core/p_graph_piter.hh>
@@ -50,8 +51,13 @@
{
typedef util::graph<P> graph;
- /// Construct a graph psite set from a graph of points.
- p_graph (graph& gr);
+ /// \brief Construct a graph psite set from a graph of points.
+ ///
+ /// \param gr The graph upon which the graph psite set is built.
+ ///
+ /// \a gr is \em copied internally, so that the graph psite set is
+ /// still valid after the initial graph has been removed.
+ p_graph (const graph& gr);
/// Point_Site associated type.
typedef graph_psite<P> psite;
@@ -102,7 +108,7 @@
// FIXME: Should be private.
public:
- graph gr_;
+ util::tracked_ptr<graph> gr_;
// FIXME: (Roland) Is it really useful/needed?
/* 2007-12-19: It seems so, since graph_image must implement a method
named bbox(). Now the question is: should each image type have a
@@ -114,8 +120,8 @@
/// \brief Comparison between two mln::p_graph's.
///
- /// Two mln::p_graph's are considered equal if they have the
- /// same address.
+ /// Two mln::p_graph's are considered equal if they share the
+ /// same graph.
template <typename P>
bool
operator==(const p_graph<P>& lhs, const p_graph<P>& rhs);
@@ -125,14 +131,14 @@
template<typename P>
inline
- p_graph<P>::p_graph (util::graph<P>& gr)
- : gr_ (gr)
+ p_graph<P>::p_graph (const util::graph<P>& gr)
+ : gr_ (new util::graph<P>(gr))
{
// FIXME: Warning: if the underlying graph is updated later, this
// won't be taken into account by this p_graph!
accu::bbox<P> a;
for (unsigned i = 0; i < npoints(); ++i)
- a.take(gr_.node_data(i));
+ a.take(gr_->node_data(i));
bb_ = a.to_result();
}
@@ -149,7 +155,7 @@
std::size_t
p_graph<P>::nnodes() const
{
- return this->gr_.nnodes();
+ return this->gr_->nnodes();
}
template<typename P>
@@ -157,7 +163,7 @@
std::size_t
p_graph<P>::nedges() const
{
- return this->gr_.nedges();
+ return this->gr_->nedges();
}
template<typename P>
@@ -177,28 +183,28 @@
// Check whether P is compatible with this psite set.
(&p.pg() == this) &&
// Check that the node id of P belongs to the range of valid node ids.
- (p.id() < gr_.nnodes());
+ (p.id() < gr_->nnodes());
}
template <typename P>
const P&
p_graph<P>::point_from_id(const util::node_id& id) const
{
- return this->gr_.node_data(id);
+ return this->gr_->node_data(id);
}
template <typename P>
P&
p_graph<P>::point_from_id(const util::node_id& id)
{
- return this->gr_.node_data(id);
+ return this->gr_->node_data(id);
}
template <typename P>
const P&
p_graph<P>::node1(const util::edge_id& e) const
{
- util::node_id n1 = this->gr_.edge(e).n1();
+ util::node_id n1 = this->gr_->edge(e).n1();
return this->point_from_id(n1);
}
@@ -206,7 +212,7 @@
const P&
p_graph<P>::node2(const util::edge_id& e) const
{
- util::node_id n2 = this->gr_.edge(e).n2();
+ util::node_id n2 = this->gr_->edge(e).n2();
return this->point_from_id(n2);
}
@@ -225,7 +231,7 @@
p_graph<P>::adjacent_or_equal(const util::node_id& lhs,
const util::node_id& rhs) const
{
- // FIXME: Likewise, this is inefficient.
+ // FIXME: This is inefficient.
assert (lhs < this->npoints());
assert (rhs < this->npoints());
@@ -235,7 +241,7 @@
// Check whether the iterator is among the neighbors of P_REF_.
typedef std::vector<util::node_id> adjacency_type;
- const adjacency_type& lhs_neighbs = gr_.nodes()[lhs]->edges;
+ const adjacency_type& lhs_neighbs = gr_->nodes()[lhs]->edges;
adjacency_type::const_iterator j =
std::find (lhs_neighbs.begin(), lhs_neighbs.end(), rhs);
@@ -264,7 +270,7 @@
bool
operator==(const p_graph<P>& lhs, const p_graph<P>& rhs)
{
- return &lhs == &rhs;
+ return lhs.gr_.ptr_ == rhs.gr_.ptr_;
}
# endif // ! MLN_INCLUDE_ONLY
Index: mln/core/graph_image.hh
--- mln/core/graph_image.hh (revision 1799)
+++ mln/core/graph_image.hh (working copy)
@@ -56,12 +56,7 @@
data_(const p_graph<P>& g, const std::vector<V>& val);
std::vector<V> val_;
- /* The graph point set is handled by address, so that we can
- check the compatibility of images w.r.t. to their point
- sites. We could use a safer (and more complex) facility to
- ensure (memory) equality of line graph point sets, but using
- addresses is simple and efficient enough for the moment. */
- const p_graph<P>& pg_;
+ const p_graph<P> pg_;
};
} // end of namespace mln::internal
@@ -239,7 +234,7 @@
typename graph_image<P, V>::rvalue
graph_image<P, V>::operator()(const graph_psite<P>& p) const
{
- mln_precondition(&p.pg() == &this->data_->pg_);
+ mln_precondition(p.pg() == this->data_->pg_);
mln_precondition(p.id() < this->data_->val_.size());
return this->data_->val_[p.id()];
}
@@ -249,7 +244,7 @@
typename graph_image<P, V>::lvalue
graph_image<P, V>::operator()(const graph_psite<P>& p)
{
- mln_precondition(&p.pg() == &this->data_->pg_);
+ mln_precondition(p.pg() == this->data_->pg_);
mln_precondition(p.id() < this->data_->val_.size());
return this->data_->val_[p.id()];
}
Index: mln/core/graph_psite.hh
--- mln/core/graph_psite.hh (revision 1799)
+++ mln/core/graph_psite.hh (working copy)
@@ -139,7 +139,7 @@
bool
graph_psite<P>::is_valid_() const
{
- return pg_ && id_ < pg_->gr_.nnodes();
+ return pg_ && id_ < pg_->gr_->nnodes();
}
template<typename P>
Index: mln/core/graph_window_piter.hh
--- mln/core/graph_window_piter.hh (revision 1799)
+++ mln/core/graph_window_piter.hh (working copy)
@@ -367,7 +367,7 @@
void
graph_window_bkd_piter<P>::start()
{
- id_ = p_ref_.plg().gr_.nnodes() - 1;
+ id_ = p_ref_.plg().gr_->nnodes() - 1;
if (!adjacent_or_equal_to_p_ref_())
next_();
/* FIXME: This is redundant with the end of next_(), but we might
Index: mln/core/graph_neighborhood_piter.hh
--- mln/core/graph_neighborhood_piter.hh (revision 1799)
+++ mln/core/graph_neighborhood_piter.hh (working copy)
@@ -227,7 +227,7 @@
// FIXME: We depend too much on the implementation of util::graph
// here. The util::graph should provide the service to abstract
// these manipulations.
- return id_ < p_ref_.pg().gr_.nnodes();
+ return id_ < p_ref_.pg().gr_->nnodes();
}
template <typename P>
@@ -277,29 +277,7 @@
bool
graph_neighborhood_fwd_piter<P>::adjacent_or_equal_to_p_ref_() const
{
- // FIXME: Likewise, this is inefficient.
-
- // Check wether the iterator points to P_REF_.
- if (id_ == p_ref_.id())
- return true;
-
- // Check whether the iterator is among the neighbors of P_REF_.
- {
- // Paranoid assertion.
- assert (p_ref_.id() < p_ref_.pg().gr_.nnodes());
- // FIXME: This is too low-level. Yet another service the graph
- // should provide.
- typedef std::vector<util::node_id> adjacency_type;
- const adjacency_type& p_ref_neighbs =
- p_ref_.pg().gr_.nodes()[p_ref_.id()]->edges;
- adjacency_type::const_iterator j =
- std::find (p_ref_neighbs.begin(), p_ref_neighbs.end(), id_);
- if (j != p_ref_neighbs.end())
- return true;
- }
-
- // Otherwise, the iterator is not adjacent to P_REF_.
- return false;
+ return p_ref_.pg().adjacent_or_equal(p_ref_.id(), id_);
}
template <typename P>
@@ -310,7 +288,7 @@
// Update psite_.
psite_ = graph_psite<P>(p_ref_.pg(), id_);
// Update p_.
- p_ = p_ref_.pg().gr_.node_data(id_);
+ p_ = p_ref_.pg().gr_->node_data(id_);
}
template <typename P>
@@ -374,7 +352,7 @@
// FIXME: We depend too much on the implementation of util::graph
// here. The util::graph should provide the service to abstract
// these manipulations.
- return id_ < p_ref_.pg().gr_.nnodes();
+ return id_ < p_ref_.pg().gr_->nnodes();
}
template <typename P>
@@ -390,7 +368,7 @@
void
graph_neighborhood_bkd_piter<P>::start()
{
- id_ = p_ref_.plg().gr_.nnodes() - 1;
+ id_ = p_ref_.plg().gr_->nnodes() - 1;
if (!adjacent_or_equal_to_p_ref_())
next_();
/* FIXME: This is redundant with the end of next_(), but we might
@@ -424,29 +402,7 @@
bool
graph_neighborhood_bkd_piter<P>::adjacent_or_equal_to_p_ref_() const
{
- // FIXME: Likewise, this is inefficient.
-
- // Check wether the iterator points to P_REF_.
- if (id_ == p_ref_.id())
- return true;
-
- // Check whether the iterator is among the neighbors of P_REF_.
- {
- // Paranoid assertion.
- assert (p_ref_.id() < p_ref_.pg().gr_.nnodes());
- // FIXME: This is too low-level. Yet another service the graph
- // should provide.
- typedef std::vector<util::node_id> adjacency_type;
- const adjacency_type& p_ref_neighbs =
- p_ref_.pg().gr_.nodes()[p_ref_.id()]->edges;
- adjacency_type::const_iterator j =
- std::find (p_ref_neighbs.begin(), p_ref_neighbs.end(), id_);
- if (j != p_ref_neighbs.end())
- return true;
- }
-
- // Otherwise, the iterator is not adjacent to P_REF_.
- return false;
+ return p_ref_.pg().adjacent_or_equal(p_ref_.id(), id_);
}
template <typename P>
@@ -457,7 +413,7 @@
// Update psite_.
psite_ = graph_psite<P>(p_ref_.pg(), id_);
// Update p_.
- p_ = p_ref_.pg().gr_.node_data(id_);
+ p_ = p_ref_.pg().gr_->node_data(id_);
}
template <typename P>
Index: mln/core/p_line_graph.hh
--- mln/core/p_line_graph.hh (revision 1799)
+++ mln/core/p_line_graph.hh (working copy)
@@ -32,6 +32,7 @@
# include <mln/core/internal/point_set_base.hh>
# include <mln/accu/bbox.hh>
# include <mln/util/graph.hh>
+# include <mln/util/tracked_ptr.hh>
# include <mln/core/line_graph_psite.hh>
# include <mln/core/p_line_graph_piter.hh>
@@ -54,8 +55,13 @@
{
typedef util::graph<P> graph;
- /// Construct a line graph psite set from a graph of points.
- p_line_graph (graph& gr);
+ /// \brief Construct a line graph psite set from a graph of points.
+ ///
+ /// \param gr The graph upon which the line graph psite set is built.
+ ///
+ /// \a gr is \em copied internally, so that the line graph psite
+ /// set is still valid after the initial graph has been removed.
+ p_line_graph (const graph& gr);
/// Point_Site associated type.
typedef line_graph_psite<P> psite;
@@ -82,7 +88,7 @@
bool has(const psite& p) const;
// FIXME: Should be private.
- graph gr_;
+ util::tracked_ptr<graph> gr_;
// FIXME: (Roland) Is it really useful/needed?
/* 2007-12-19: It seems so, since graph_image must implement a
method named bbox(). Now the question is: should each image
@@ -93,8 +99,8 @@
/// \brief Comparison between two mln::p_line_graph's.
///
- /// Two mln::p_line_graph's are considered equal if they have the
- /// same address.
+ /// Two mln::p_line_graph's are considered equal if they share the
+ /// same graph.
template <typename P>
bool
operator==(const p_line_graph<P>& lhs, const p_line_graph<P>& rhs);
@@ -104,14 +110,14 @@
template<typename P>
inline
- p_line_graph<P>::p_line_graph (util::graph<P>& gr)
- : gr_ (gr)
+ p_line_graph<P>::p_line_graph (const util::graph<P>& gr)
+ : gr_ (new util::graph<P>(gr))
{
// FIXME: Warning: if the underlying graph is updated later, this
// won't be taken into account by this p_line_graph!
accu::bbox<P> a;
for (unsigned i = 0; i < nnodes(); ++i)
- a.take(gr_.node_data(i));
+ a.take(gr_->node_data(i));
bb_ = a.to_result();
}
@@ -128,7 +134,7 @@
std::size_t
p_line_graph<P>::nnodes() const
{
- return this->gr_.nnodes();
+ return this->gr_->nnodes();
}
template<typename P>
@@ -136,7 +142,7 @@
std::size_t
p_line_graph<P>::nedges() const
{
- return this->gr_.nedges();
+ return this->gr_->nedges();
}
template<typename P>
@@ -156,7 +162,7 @@
// Check whether P is compatible with this psite set.
(&p.plg() == this) &&
// Check that the edge id of P belongs to the range of valid edge ids.
- (p.id() < gr_.nedges());
+ (p.id() < gr_->nedges());
}
@@ -164,7 +170,7 @@
bool
operator==(const p_line_graph<P>& lhs, const p_line_graph<P>& rhs)
{
- return &lhs == &rhs;
+ return lhs.gr_.ptr_ == rhs.gr_.ptr_;
}
# endif // ! MLN_INCLUDE_ONLY
Index: mln/core/line_graph_image.hh
--- mln/core/line_graph_image.hh (revision 1799)
+++ mln/core/line_graph_image.hh (working copy)
@@ -72,12 +72,7 @@
std::vector<V> node_val_;
std::vector<V> edge_val_;
- /* The line graph point set is handled by address, so that we
- can check the compatibility of images w.r.t. to their point
- sites. We could use a safer (and more complex) facility to
- ensure (memory) equality of line graph point sets, but using
- addresses is simple and efficient enough for the moment. */
- const p_line_graph<P>& plg_;
+ const p_line_graph<P> plg_;
};
} // end of namespace mln::internal
@@ -273,7 +268,7 @@
typename line_graph_image<P, V>::rvalue
line_graph_image<P, V>::operator()(const line_graph_psite<P>& p) const
{
- mln_precondition(&p.plg() == &this->data_->plg_);
+ mln_precondition(p.plg() == this->data_->plg_);
mln_precondition(p.id() < this->data_->edge_val_.size());
return this->data_->edge_val_[p.id()];
}
@@ -283,7 +278,7 @@
typename line_graph_image<P, V>::lvalue
line_graph_image<P, V>::operator()(const line_graph_psite<P>& p)
{
- mln_precondition(&p.plg() == &this->data_->plg_);
+ mln_precondition(p.plg() == this->data_->plg_);
mln_precondition(p.id() < this->data_->edge_val_.size());
return this->data_->edge_val_[p.id()];
}
Index: mln/core/line_graph_psite.hh
--- mln/core/line_graph_psite.hh (revision 1799)
+++ mln/core/line_graph_psite.hh (working copy)
@@ -176,7 +176,7 @@
bool
line_graph_psite<P>::is_valid_() const
{
- return plg_ && id_ < plg_->gr_.nedges();
+ return plg_ && id_ < plg_->gr_->nedges();
}
template<typename P>
@@ -228,7 +228,7 @@
line_graph_psite<P>::first() const
{
mln_assertion(is_valid_());
- return plg().gr_.node_data(plg().gr_.edge(id_).n1());
+ return plg().gr_->node_data(plg().gr_->edge(id_).n1());
}
template<typename P>
@@ -237,7 +237,7 @@
line_graph_psite<P>::second() const
{
mln_assertion(is_valid_());
- return plg().gr_.node_data(plg().gr_.edge(id_).n2());
+ return plg().gr_->node_data(plg().gr_->edge(id_).n2());
}
Index: mln/core/line_graph_neighborhood_piter.hh
--- mln/core/line_graph_neighborhood_piter.hh (revision 1799)
+++ mln/core/line_graph_neighborhood_piter.hh (working copy)
@@ -258,7 +258,7 @@
// FIXME: We depend too much on the implementation of util::graph
// here. The util::graph should provide the service to abstract
// these manipulations.
- return id_ < p_ref_.plg().gr_.nedges();
+ return id_ < p_ref_.plg().gr_->nedges();
}
template <typename P>
@@ -315,19 +315,20 @@
// Check whether the iterator is among the neighbors of P_REF_.
{
// Paranoid assertion.
- assert (p_ref_.id() < p_ref_.plg().gr_.nedges());
+ assert (p_ref_.id() < p_ref_.plg().gr_->nedges());
/* FIXME: We should have a convenient shortcut for these
repetitive accesses to p_ref_.plg().gr_ (e.g., a method gr()
or g() in this class. */
- const typename p_line_graph<P>::graph& gr = p_ref_.plg().gr_;
+ const util::tracked_ptr<typename p_line_graph<P>::graph>& gr =
+ p_ref_.plg().gr_;
// Check whether the edge this iterator points to is adjacent to
// the one p_ref points to, by comparing their ajacent nodes.
/* FIXME: This is too low-level. Yet another service the graph
// should provide. */
- if (gr.edge(id_).n1() == gr.edge(p_ref_.id()).n1() ||
- gr.edge(id_).n1() == gr.edge(p_ref_.id()).n2() ||
- gr.edge(id_).n2() == gr.edge(p_ref_.id()).n1() ||
- gr.edge(id_).n2() == gr.edge(p_ref_.id()).n2())
+ if (gr->edge(id_).n1() == gr->edge(p_ref_.id()).n1() ||
+ gr->edge(id_).n1() == gr->edge(p_ref_.id()).n2() ||
+ gr->edge(id_).n2() == gr->edge(p_ref_.id()).n1() ||
+ gr->edge(id_).n2() == gr->edge(p_ref_.id()).n2())
return true;
}
@@ -413,7 +414,7 @@
// FIXME: We depend too much on the implementation of util::graph
// here. The util::graph should provide the service to abstract
// these manipulations.
- return id_ < p_ref_.plg().gr_.nedges();
+ return id_ < p_ref_.plg().gr_->nedges();
}
template <typename P>
@@ -429,7 +430,7 @@
void
line_graph_neighborhood_bkd_piter<P>::start()
{
- id_ = p_ref_.plg().gr_.nedges() - 1;
+ id_ = p_ref_.plg().gr_->nedges() - 1;
if (!adjacent_or_equal_to_p_ref_())
next_();
/* FIXME: This is redundant with the end of next_(), but we might
@@ -470,19 +471,20 @@
// Check whether the iterator is among the neighbors of P_REF_.
{
// Paranoid assertion.
- assert (p_ref_.id() < p_ref_.plg().gr_.nedges());
+ assert (p_ref_.id() < p_ref_.plg().gr_->nedges());
/* FIXME: We should have a convenient shortcut for these
repetitive accesses to p_ref_.plg().gr_ (e.g., a method gr()
or g() in this class. */
- const typename p_line_graph<P>::graph& gr = p_ref_.plg().gr_;
+ const util::tracked_ptr<typename p_line_graph<P>::graph>& gr =
+ p_ref_.plg().gr_;
// Check whether the edge this iterator points to is adjacent to
// the one p_ref points to, by comparing their ajacent nodes.
/* FIXME: This is too low-level. Yet another service the graph
// should provide. */
- if (gr.edge(id_).n1() == gr.edge(p_ref_.id()).n1() ||
- gr.edge(id_).n1() == gr.edge(p_ref_.id()).n2() ||
- gr.edge(id_).n2() == gr.edge(p_ref_.id()).n1() ||
- gr.edge(id_).n2() == gr.edge(p_ref_.id()).n2())
+ if (gr->edge(id_).n1() == gr->edge(p_ref_.id()).n1() ||
+ gr->edge(id_).n1() == gr->edge(p_ref_.id()).n2() ||
+ gr->edge(id_).n2() == gr->edge(p_ref_.id()).n1() ||
+ gr->edge(id_).n2() == gr->edge(p_ref_.id()).n2())
return true;
}
Index: mln/core/line_graph_window_piter.hh
--- mln/core/line_graph_window_piter.hh (revision 1799)
+++ mln/core/line_graph_window_piter.hh (working copy)
@@ -252,7 +252,7 @@
// FIXME: We depend too much on the implementation of util::graph
// here. The util::graph should provide the service to abstract
// these manipulations.
- return id_ < p_ref_.plg().gr_.nedges();
+ return id_ < p_ref_.plg().gr_->nedges();
}
template <typename P>
@@ -309,19 +309,20 @@
// Check whether the iterator is among the neighbors of P_REF_.
{
// Paranoid assertion.
- assert (p_ref_.id() < p_ref_.plg().gr_.nedges());
+ assert (p_ref_.id() < p_ref_.plg().gr_->nedges());
/* FIXME: We should have a convenient shortcut for these
repetitive accesses to p_ref_.plg().gr_ (e.g., a method gr()
or g() in this class. */
- const typename p_line_graph<P>::graph& gr = p_ref_.plg().gr_;
+ const util::tracked_ptr<typename p_line_graph<P>::graph>& gr =
+ p_ref_.plg().gr_;
// Check whether the edge this iterator points to is adjacent to
// the one p_ref points to, by comparing their ajacent nodes.
/* FIXME: This is too low-level. Yet another service the graph
// should provide. */
- if (gr.edge(id_).n1() == gr.edge(p_ref_.id()).n1() ||
- gr.edge(id_).n1() == gr.edge(p_ref_.id()).n2() ||
- gr.edge(id_).n2() == gr.edge(p_ref_.id()).n1() ||
- gr.edge(id_).n2() == gr.edge(p_ref_.id()).n2())
+ if (gr->edge(id_).n1() == gr->edge(p_ref_.id()).n1() ||
+ gr->edge(id_).n1() == gr->edge(p_ref_.id()).n2() ||
+ gr->edge(id_).n2() == gr->edge(p_ref_.id()).n1() ||
+ gr->edge(id_).n2() == gr->edge(p_ref_.id()).n2())
return true;
}
@@ -406,7 +407,7 @@
// FIXME: We depend too much on the implementation of util::graph
// here. The util::graph should provide the service to abstract
// these manipulations.
- return id_ < p_ref_.plg().gr_.nedges();
+ return id_ < p_ref_.plg().gr_->nedges();
}
template <typename P>
@@ -422,7 +423,7 @@
void
line_graph_window_bkd_piter<P>::start()
{
- id_ = p_ref_.plg().gr_.nedges() - 1;
+ id_ = p_ref_.plg().gr_->nedges() - 1;
if (!adjacent_or_equal_to_p_ref_())
next_();
/* FIXME: This is redundant with the end of next_(), but we might
@@ -463,19 +464,20 @@
// Check whether the iterator is among the neighbors of P_REF_.
{
// Paranoid assertion.
- assert (p_ref_.id() < p_ref_.plg().gr_.nedges());
+ assert (p_ref_.id() < p_ref_.plg().gr_->nedges());
/* FIXME: We should have a convenient shortcut for these
repetitive accesses to p_ref_.plg().gr_ (e.g., a method gr()
or g() in this class. */
- const typename p_line_graph<P>::graph& gr = p_ref_.plg().gr_;
+ const util::tracked_ptr<typename p_line_graph<P>::graph>& gr =
+ p_ref_.plg().gr_;
// Check whether the edge this iterator points to is adjacent to
// the one p_ref points to, by comparing their ajacent nodes.
/* FIXME: This is too low-level. Yet another service the graph
// should provide. */
- if (gr.edge(id_).n1() == gr.edge(p_ref_.id()).n1() ||
- gr.edge(id_).n1() == gr.edge(p_ref_.id()).n2() ||
- gr.edge(id_).n2() == gr.edge(p_ref_.id()).n1() ||
- gr.edge(id_).n2() == gr.edge(p_ref_.id()).n2())
+ if (gr->edge(id_).n1() == gr->edge(p_ref_.id()).n1() ||
+ gr->edge(id_).n1() == gr->edge(p_ref_.id()).n2() ||
+ gr->edge(id_).n2() == gr->edge(p_ref_.id()).n1() ||
+ gr->edge(id_).n2() == gr->edge(p_ref_.id()).n2())
return true;
}
1
0
URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena
ChangeLog:
2008-03-22 Etienne FOLIO <folio(a)lrde.epita.fr>
Cleanup of the sandbox.
* chamfer_dt.cc: Remove.
* dmap.cc: Remove.
* dt_naive.cc: Remove.
* dt_naive.hh: Remove.
* exercices/heritage_conditionnel.cc: New.
* exercices/heritage_conditionnel.hh: New.
* exercices: New.
* heritage_conditionnel.cc: Remove.
* heritage_conditionnel.hh: Remove.
---
heritage_conditionnel.cc | 7 +++++++
heritage_conditionnel.hh | 46 ++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 53 insertions(+)
Index: trunk/milena/sandbox/folio/chamfer_dt.cc (deleted)
===================================================================
Index: trunk/milena/sandbox/folio/heritage_conditionnel.cc (deleted)
===================================================================
Index: trunk/milena/sandbox/folio/dmap.cc (deleted)
===================================================================
Index: trunk/milena/sandbox/folio/dt_naive.hh (deleted)
===================================================================
Index: trunk/milena/sandbox/folio/heritage_conditionnel.hh (deleted)
===================================================================
Index: trunk/milena/sandbox/folio/dt_naive.cc (deleted)
===================================================================
Index: trunk/milena/sandbox/folio/exercices/heritage_conditionnel.cc
===================================================================
--- trunk/milena/sandbox/folio/exercices/heritage_conditionnel.cc (revision 0)
+++ trunk/milena/sandbox/folio/exercices/heritage_conditionnel.cc (revision 1799)
@@ -0,0 +1,7 @@
+#include "heritage_conditionnel.hh"
+
+int main()
+{
+ new Bottom<1 == 1>();
+ new Bottom<1 == 0>();
+}
Index: trunk/milena/sandbox/folio/exercices/heritage_conditionnel.hh
===================================================================
--- trunk/milena/sandbox/folio/exercices/heritage_conditionnel.hh (revision 0)
+++ trunk/milena/sandbox/folio/exercices/heritage_conditionnel.hh (revision 1799)
@@ -0,0 +1,46 @@
+#ifndef HERITAGE_CONDITIONNEL_HH_
+# define HERITAGE_CONDITIONNEL_HH_
+
+# include <iostream>
+
+class TopLeft
+{
+protected:
+ TopLeft()
+ {
+ std::cout << "top left" << std::endl;
+ }
+};
+
+class TopRight
+{
+protected:
+ TopRight()
+ {
+ std::cout << "top right" << std::endl;
+ }
+};
+
+template<bool C, typename T, typename U>
+struct TraitCond
+{
+ typedef T type;
+};
+
+template<typename T, typename U>
+struct TraitCond<false, T, U>
+{
+ typedef U type;
+};
+
+template<bool B>
+class Bottom: public TraitCond<B, TopLeft, TopRight>::type
+{
+public:
+ Bottom()
+ : TraitCond<B, TopLeft, TopRight>::type()
+ {
+ }
+};
+
+#endif /* !HERITAGE_CONDITIONNEL_HH_ */
1
0
URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena
ChangeLog:
2008-03-22 Etienne FOLIO <folio(a)lrde.epita.fr>
Naive DT rebuilt. Does not compile.
* naive.cc: Uses a given function to calculate the norm.
---
naive.cc | 149 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 149 insertions(+)
Index: trunk/milena/sandbox/folio/naive.cc
===================================================================
--- trunk/milena/sandbox/folio/naive.cc (revision 0)
+++ trunk/milena/sandbox/folio/naive.cc (revision 1798)
@@ -0,0 +1,149 @@
+// 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.
+
+/*! \file TODO
+ *
+ * \brief Defines a function that creates a distance map corresponding to a
+ * given image.
+ */
+
+#ifndef MLN_DT_NAIVE_HH
+# define MLN_DT_NAIVE_HH
+
+# include <mln/core/concept/image.hh>
+# include <mln/literal/zero.hh>
+# include <mln/accu/min.hh>
+
+namespace mln
+{
+
+ namespace dt
+ {
+
+ /*! Calculates the distance map corresponding to a given image
+ *
+ * \param[in] input_ The binary reference image.
+ * \param[in] fun_ The function used for distance aclculus.
+ * \return New distance map image.
+ *
+ * \pre \p input_ has to be initialized.
+ *
+ * \fixme Use instead of R the result type of F::operator().
+ */
+ template <typename I, typename F, typename R>
+ mln_ch_value(I, R)
+ naive(const Image<I>& input_, F& fun_);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ // Facade.
+
+ template <typename I, typename F, typename R>
+ inline
+ mln_ch_value(I, R)
+ naive(const Image<I>& input_, F& fun_)
+ {
+ const I& input = exact(input_);
+ mln_precondition(input.has_data());
+
+ mln_ch_value(I, R) output;
+ initialize(input.domain());
+
+ mln_piter(I) p(input.domain());
+ for_all(p)
+ {
+ if (input(p))
+ output(p) = literal::zero;
+ else
+ {
+ // p is in the background so the distance has to be computed.
+ accu::min_<R> min;
+ min.init();
+
+ mln_piter(I) q(input.domain());
+ for_all(q)
+ if (input(q))
+ {
+ // q is in the object.
+// metal::vec<2, int> vp = p.to_point(), vq = q.to_point();
+// min.take(fun_(vp, vq));
+ min.take(fun_(p, q));
+ }
+ output(p) = min;
+ }
+ }
+
+ return output;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::dt
+
+} // end of namespace mln
+
+#endif // ! MLN_DT_NAIVE_HH
+
+#include <iostream>
+#include <mln/debug/println.hh>
+#include <mln/core/image2d.hh>
+#include <mln/level/fill.hh>
+#include <mln/norm/l2.hh>
+
+struct l2norm
+{
+ template <typename C, typename D>
+ D
+ operator()(C a, C b)
+ {
+ return mln::norm::l2(a, b);
+ }
+};
+
+int main()
+{
+ using namespace mln;
+
+ {
+ image2d<bool> ima(5,5);
+ bool vals[] = { 1, 1, 1, 0, 0,
+ 0, 0, 1, 0, 0,
+ 0, 0, 1, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0 };
+
+ level::fill(ima, vals);
+ debug::println(ima);
+
+ l2norm fun;
+ image2d<float> out = dt::naive(ima, fun);
+
+ std::cerr << "Distance:" << std::endl;
+ debug::println(out);
+ }
+}
1
0
URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena
ChangeLog:
2008-03-22 Etienne FOLIO <folio(a)lrde.epita.fr>
Chamfer DT with nearest point calculus.
* chamfer.cc: Returns a pair containing the two maps.
---
chamfer.cc | 189 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 189 insertions(+)
Index: trunk/milena/sandbox/folio/chamfer.cc
===================================================================
--- trunk/milena/sandbox/folio/chamfer.cc (revision 0)
+++ trunk/milena/sandbox/folio/chamfer.cc (revision 1797)
@@ -0,0 +1,189 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef MLN_DT_CHAMFER_HH
+# define MLN_DT_CHAMFER_HH
+
+# include <mln/core/concept/image.hh>
+# include <mln/make/w_window.hh>
+
+namespace mln
+{
+
+ namespace dt
+ {
+
+ /*! Distance tranform by chamfer application.
+ *
+ * \param[in] input_ The input image.
+ * \param[in] chamfer The chamfer window to use for distance calcul.
+ * \return A pair (distance map, nearest point map).
+ *
+ * \pre \p img has to be initialized.
+ */
+ template<typename I, typename T>
+ std::pair<mln_ch_value(I, T), mln_ch_value(I, mln_point(I))>
+ chamfer(const Image<I>& input_,
+ w_window<mln_dpoint(I), T> chamfer);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace impl
+ {
+
+ /*! Computes a pass of the chamfer DT algorithm.
+ *
+ * \param[in] p Iterator on the input image to use.
+ * \param[in] chamfer The chamfer window to use for distance calcul.
+ * \param[in] input The input image.
+ * \param[out] outputDistance The distance map updated.
+ * \param[out] outputnearest The nearest points map updated.
+ */
+ template<typename Q, typename I, typename T>
+ inline
+ void
+ chamfer_pass(const w_window<mln_dpoint(I), T> chamfer,
+ const I& input,
+ mln_ch_value(I, T)& outputDistance,
+ mln_ch_value(I, mln_point(I))& outputNearest)
+ {
+ typedef w_window<mln_dpoint(I), T> W;
+
+ Q p(input.domain());
+ mln_qiter(W) q(chamfer, p);
+ for_all(p)
+ {
+ std::pair<T, mln_point(I)> min(mln_max(T), p);
+
+ for_all(q)
+ if (input.has(q) && outputDistance(q) != mln_max(T))
+ {
+ T v = outputDistance(q) + q.w();
+
+ if (v < min.first)
+ {
+ min.first = v;
+ min.second = outputNearest(q);
+ }
+ }
+
+ if (min.first < outputDistance(p))
+ {
+ outputDistance(p) = min.first;
+ outputNearest(p) = min.second;
+ }
+ }
+ }
+
+ } // end of namespace mln::dt::impl
+
+
+
+ // Facade.
+
+ template<typename I, typename T>
+ inline
+ std::pair<mln_ch_value(I, T), mln_ch_value(I, mln_point(I))>
+ chamfer(const Image<I>& input_,
+ w_window<mln_dpoint(I), T> chamfer)
+ {
+ typedef w_window<mln_dpoint(I), T> W;
+
+ const I& input = exact(input_);
+ mln_precondition(input.has_data());
+
+ mln_ch_value(I, T) outputDistance;
+ initialize(outputDistance, input);
+
+ mln_ch_value(I, mln_point(I)) outputNearest;
+ initialize(outputNearest, input);
+
+ // Initialization.
+ {
+ mln_fwd_piter(I) p(input.domain());
+ for_all(p)
+ {
+ outputDistance(p) = input(p) ? literal::zero : mln_max(T);
+ outputNearest(p) = p;
+ }
+ }
+
+ // First pass.
+ impl::chamfer_pass<mln_fwd_piter(I)>
+ (chamfer, input, outputDistance, outputNearest);
+
+ chamfer.sym();
+
+ // Second pass.
+ impl::chamfer_pass<mln_bkd_piter(I)>
+ (chamfer, input, outputDistance, outputNearest);
+
+ return std::pair<mln_ch_value(I, T), mln_ch_value(I, mln_point(I))>
+ (outputDistance, outputNearest);
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::dt
+
+} // end of namespace mln
+
+#endif // ! MLN_DT_CHAMFER_HH
+
+#include <iostream>
+#include <mln/debug/println.hh>
+#include <mln/core/image2d.hh>
+#include <mln/make/win_chamfer.hh>
+#include <mln/level/fill.hh>
+
+int main()
+{
+ using namespace mln;
+
+ w_window2d_int chamfer = make::mk_chamfer_3x3_int<3, 4>();
+
+ {
+ image2d<bool> ima(5,5);
+ bool vals[] = { 1, 1, 1, 0, 0,
+ 0, 0, 1, 0, 0,
+ 0, 0, 1, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0 };
+
+ level::fill(ima, vals);
+ debug::println(ima);
+
+ std::pair<image2d<int>, image2d<mln_point_(image2d<bool>)> >
+ out = dt::chamfer(ima, chamfer);
+
+ std::cerr << "Distance:" << std::endl;
+ debug::println(out.first);
+ std::cerr << "PPP:" << std::endl;
+ debug::println(out.second);
+ }
+}
1
0