Olena-patches
Threads by month
- ----- 2025 -----
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
November 2008
- 14 participants
- 266 discussions
* mln/labeling/compute.hh: Check if the image is a labeled image and
fix a wrong dispatch.
---
milena/ChangeLog | 7 +++++++
milena/mln/labeling/compute.hh | 7 ++++---
2 files changed, 11 insertions(+), 3 deletions(-)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 4e2cfcb..959337a 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,5 +1,12 @@
2008-11-25 Guillaume Lazzara <z(a)lrde.epita.fr>
+ Fix labeling::compute tests.
+
+ * mln/labeling/compute.hh: Check if the image is a labeled image and
+ fix a wrong dispatch.
+
+2008-11-25 Guillaume Lazzara <z(a)lrde.epita.fr>
+
Fix tutorial generation.
* doc/tutorial/Makefile.am
diff --git a/milena/mln/labeling/compute.hh b/milena/mln/labeling/compute.hh
index dfc95f1..ececa18 100644
--- a/milena/mln/labeling/compute.hh
+++ b/milena/mln/labeling/compute.hh
@@ -127,6 +127,7 @@ namespace mln
const mln_value(L)& nlabels)
{
mln_precondition(exact(label).has_data());
+ mlc_is_a(mln_value(L), mln::value::Symbolic)::check();
(void) a;
(void) label;
(void) nlabels;
@@ -143,7 +144,7 @@ namespace mln
{
mln_precondition(exact(input).has_data());
mln_precondition(exact(label).has_data());
-
+ mlc_is_a(mln_value(L), mln::value::Symbolic)::check();
(void) a;
(void) input;
(void) label;
@@ -276,7 +277,7 @@ namespace mln
typedef mln_accu_with(A, mln_value(I)) A_;
A_ a_ = accu::unmeta(exact(a), mln_value(I)());
- return internal::compute_dispatch(a_, input, label, nlabels);
+ return compute(a_, input, label, nlabels);
}
@@ -309,7 +310,7 @@ namespace mln
typedef mln_accu_with(A, mln_psite(L)) A_;
A_ a_ = accu::unmeta(exact(a), mln_psite(L)());
- return internal::compute_dispatch(a_, label, nlabels);
+ return compute(a_, label, nlabels);
}
--
1.5.6.5
1
0
* doc/tutorial/Makefile.am
* doc/Makefile.am: fix wrong variable names.
* doc/tutorial/samples/fill-part-2.cc,
* doc/tutorial/samples/fill-part-3.cc,
* doc/tutorial/samples/ima2d-decl-2-blobs-full.cc,
* doc/tutorial/samples/ima2d-decl-2-blobs.cc,
* doc/tutorial/samples/labeling-compute-full.cc: Use label8 instead of
int_u8.
* doc/tutorial/samples/graph-data-full.cc: Add new example.
---
milena/ChangeLog | 16 ++++
milena/doc/Makefile.am | 10 +-
milena/doc/tutorial/Makefile.am | 10 +-
milena/doc/tutorial/samples/fill-part-2.cc | 7 +-
milena/doc/tutorial/samples/fill-part-3.cc | 7 +-
milena/doc/tutorial/samples/graph-data-full.cc | 82 ++++++++++++++++++++
.../tutorial/samples/ima2d-decl-2-blobs-full.cc | 6 +-
milena/doc/tutorial/samples/ima2d-decl-2-blobs.cc | 4 +-
.../doc/tutorial/samples/labeling-compute-full.cc | 5 +-
9 files changed, 122 insertions(+), 25 deletions(-)
create mode 100644 milena/doc/tutorial/samples/graph-data-full.cc
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 82e1f97..4e2cfcb 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,3 +1,19 @@
+2008-11-25 Guillaume Lazzara <z(a)lrde.epita.fr>
+
+ Fix tutorial generation.
+
+ * doc/tutorial/Makefile.am
+ * doc/Makefile.am: fix wrong variable names.
+
+ * doc/tutorial/samples/fill-part-2.cc,
+ * doc/tutorial/samples/fill-part-3.cc,
+ * doc/tutorial/samples/ima2d-decl-2-blobs-full.cc,
+ * doc/tutorial/samples/ima2d-decl-2-blobs.cc,
+ * doc/tutorial/samples/labeling-compute-full.cc: Use label8 instead of
+ int_u8.
+
+ * doc/tutorial/samples/graph-data-full.cc: Add new example.
+
2008-11-25 Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Add a morpho tree data structure based on parenthood.
diff --git a/milena/doc/Makefile.am b/milena/doc/Makefile.am
index 039f5dc..bb717f6 100644
--- a/milena/doc/Makefile.am
+++ b/milena/doc/Makefile.am
@@ -14,24 +14,24 @@ complete-doc: html_complete
user-doc: html_user tutorial
-html_complete: tuto_html figures Doxyfile
+html_complete: figures Doxyfile tuto_html
$(DOXYGEN) Doxyfile_complete
-html_user: tuto_html figures Doxyfile
+html_user: figures Doxyfile tuto_html
$(DOXYGEN) Doxyfile_user
figures: all
@failcom='exit 1'; \
- list='${wildcard $(FIGURES_DIR)/*.p*m}'; for img in $$list; do \
+ list='${wildcard $(FIGURES_BUILDDIR)/*.p*m}'; for img in $$list; do \
echo "Converting $$img to png"; \
- convert $$img $(FIGURES_DIR)/`basename $$img .ppm`.png \
+ convert $$img $(FIGURES_BUILDDIR)/`basename $$img .ppm`.png \
|| eval $$failcom; \
done;
tuto_html:
$(MAKE) -C tutorial tuto_html
-tuto: all
+tuto: all figures
$(MAKE) -C tutorial tuto
edit = sed -e "s|@ID@|$$Id|" \
diff --git a/milena/doc/tutorial/Makefile.am b/milena/doc/tutorial/Makefile.am
index 0b70c3e..9bc00e6 100644
--- a/milena/doc/tutorial/Makefile.am
+++ b/milena/doc/tutorial/Makefile.am
@@ -2,15 +2,15 @@ SUBDIRS = samples
.PHONY: tuto
-TUTO_DIR = "milena/doc/tutorial"
-TEXINPUTS = $(top_srcdir)/$(TUTO_DIR):$(top_builddir)/$(TUTO_DIR):
+include $(top_srcdir)/milena/doc/doc.mk
+TEXINPUTS = $(TUTORIAL_SRCDIR):$(TUTORIAL_BUILDDIR):
tuto:
- TEXINPUTS=$(TEXINPUTS) pdflatex $(top_srcdir)/$(TUTO_DIR)/tutorial.tex
+ TEXINPUTS=$(TEXINPUTS) pdflatex $(TUTORIAL_SRCDIR)/tutorial.tex
tuto_html:
- chmod u+x $(top_srcdir)/$(TUTO_DIR)/todoxygen.sh
- $(top_srcdir)/$(TUTO_DIR)/todoxygen.sh $(top_srcdir)/$(TUTO_DIR)/tutorial.tex $(top_builddir)/$(TUTO_DIR)
+ chmod u+x $(TUTORIAL_SRCDIR)/todoxygen.sh
+ $(TUTORIAL_SRCDIR)/todoxygen.sh $(TUTORIAL_SRCDIR)/tutorial.tex $(TUTORIAL_BUILDDIR)
clean-local:
rm -f *.aux *.toc *.log *.bbl *blg *.lot *.out *~
diff --git a/milena/doc/tutorial/samples/fill-part-2.cc b/milena/doc/tutorial/samples/fill-part-2.cc
index 4f69cbc..17335d2 100644
--- a/milena/doc/tutorial/samples/fill-part-2.cc
+++ b/milena/doc/tutorial/samples/fill-part-2.cc
@@ -1,10 +1,9 @@
using namespace mln;
-using value::int_u8;
-using value::rgb8;
+using value::label8;
// Find and label the different components.
-int_u8 nlabels;
-image2d<int_u8> lab = labeling::blobs(ima, c4(), nlabels);
+label8 nlabels;
+image2d<label8> lab = labeling::blobs(ima, c4(), nlabels);
// Store a boolean image. True if the site is part of
// component 2, false otherwise.
diff --git a/milena/doc/tutorial/samples/fill-part-3.cc b/milena/doc/tutorial/samples/fill-part-3.cc
index 29c112a..9082430 100644
--- a/milena/doc/tutorial/samples/fill-part-3.cc
+++ b/milena/doc/tutorial/samples/fill-part-3.cc
@@ -1,10 +1,9 @@
using namespace mln;
-using value::int_u8;
-using value::rgb8;
+using value::label8;
// Find and label the different components.
-int_u8 nlabels;
-image2d<int_u8> lab = labeling::blobs(ima, c4(), nlabels);
+label8 nlabels;
+image2d<label8> lab = labeling::blobs(ima, c4(), nlabels);
// Fill the sites of component 2 with red.
fill(lab.domain(2).rw(), color::red);
diff --git a/milena/doc/tutorial/samples/graph-data-full.cc b/milena/doc/tutorial/samples/graph-data-full.cc
new file mode 100644
index 0000000..60792a3
--- /dev/null
+++ b/milena/doc/tutorial/samples/graph-data-full.cc
@@ -0,0 +1,82 @@
+#include <mln/essential/2d.hh>
+#include <mln/util/graph.hh>
+
+// Part of graph-data.cc
+// \{
+template <typename S>
+struct viota_t : public mln::Function_p2v< viota_t<S> >
+{
+ typedef unsigned result;
+
+ viota_t(unsigned size)
+ {
+ v_.resize(size);
+ for(unsigned i = 0; i < size; ++i)
+ v_[i] = 10 + i;
+ }
+
+ unsigned
+ operator()(const mln_psite(S)& p) const
+ {
+ return v_[p.v().id()];
+ }
+
+ protected:
+ std::vector<result> v_;
+};
+// \}
+
+int main()
+{
+ using namespace mln;
+
+ // Part of graph-add-vertec.cc
+ // \{
+ util::graph g;
+
+ for (unsigned i = 0; i < 5; ++i)
+ g.add_vertex(); // Add vertex 'i';
+ // \}
+
+ // Part of graph-add-edges.cc
+ // \{
+ g.add_edge(0, 1); // Associated to edge 0.
+ g.add_edge(1, 2); // Associated to edge 1.
+ g.add_edge(1, 3); // Associated to edge 2.
+ g.add_edge(3, 4); // Associated to edge 3.
+ g.add_edge(4, 2); // Associated to edge 4.
+ // \}
+
+ // Part of graph-i2v-vertex.cc
+ // \{
+ typedef fun::i2v::array<point2d> F;
+ F f(5); // We need to map 5 vertices.
+ f(0) = point2d(0, 0);
+ f(1) = point2d(2, 2);
+ f(2) = point2d(0, 4);
+ f(3) = point2d(4, 3);
+ f(4) = point2d(4, 4);
+ // \}
+
+ // Part of graph-p-vertices.cc
+ // \{
+ typedef p_vertices<util::graph, F> pv_t;
+ pv_t pv(g, f);
+ // \}
+
+ // Part of graph-data.cc
+ // \{
+
+ // Constructs an image
+ viota_t<pv_t> viota(pv.nsites());
+ mln_VAR(graph_vertices_ima, viota | pv);
+
+ //Prints each vertex and its associated data.
+ mln_piter_(graph_vertices_ima_t) p(graph_vertices_ima.domain());
+ for_all(p)
+ std::cout << "graph_vertices_ima(" << p << ") = "
+ << graph_vertices_ima(p) << std::endl;
+
+ // \}
+}
+
diff --git a/milena/doc/tutorial/samples/ima2d-decl-2-blobs-full.cc b/milena/doc/tutorial/samples/ima2d-decl-2-blobs-full.cc
index 9728ac7..da6fa2b 100644
--- a/milena/doc/tutorial/samples/ima2d-decl-2-blobs-full.cc
+++ b/milena/doc/tutorial/samples/ima2d-decl-2-blobs-full.cc
@@ -2,7 +2,7 @@
int main()
{
using namespace mln;
- using value::int_u8;
+ using value::label8;
bool vals[6][5] = {
{0, 1, 1, 0, 0},
@@ -14,8 +14,8 @@ int main()
};
image2d<bool> ima = make::image(vals);
- int_u8 nlabels;
- image2d<int_u8> lbl = labeling::blobs(ima, c4(), nlabels);
+ label8 nlabels;
+ image2d<label8> lbl = labeling::blobs(ima, c4(), nlabels);
debug::println(lbl);
}
diff --git a/milena/doc/tutorial/samples/ima2d-decl-2-blobs.cc b/milena/doc/tutorial/samples/ima2d-decl-2-blobs.cc
index 6699982..f69c8c0 100644
--- a/milena/doc/tutorial/samples/ima2d-decl-2-blobs.cc
+++ b/milena/doc/tutorial/samples/ima2d-decl-2-blobs.cc
@@ -1,2 +1,2 @@
-int_u8 nlabels;
-image2d<int_u8> lbl = labeling::blobs(ima, c4(), nlabels);
+label8 nlabels;
+image2d<label8> lbl = labeling::blobs(ima, c4(), nlabels);
diff --git a/milena/doc/tutorial/samples/labeling-compute-full.cc b/milena/doc/tutorial/samples/labeling-compute-full.cc
index fa378ca..4996a99 100644
--- a/milena/doc/tutorial/samples/labeling-compute-full.cc
+++ b/milena/doc/tutorial/samples/labeling-compute-full.cc
@@ -3,6 +3,7 @@ int main()
{
using namespace mln;
using value::int_u8;
+ using value::label8;
bool vals[6][5] = {
{0, 1, 1, 0, 0},
@@ -14,8 +15,8 @@ int main()
};
image2d<bool> ima = make::image(vals);
- int_u8 nlabels;
- image2d<int_u8> lbl = labeling::blobs(ima, c4(), nlabels);
+ label8 nlabels;
+ image2d<label8> lbl = labeling::blobs(ima, c4(), nlabels);
util::array<box2d> boxes =
labeling::compute(accu::meta::bbox(),
--
1.5.6.5
1
0
https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Add a morpho tree data structure based on parenthood.
* mln/morpho/tree/data.hh: New.
* mln/morpho/tree/all.hh: Update.
* tests/morpho/tree/data.cc: New.
* tests/morpho/tree/Makefile.am: Update.
* mln/morpho/tree/utils.hh (todo): New.
* mln/core/image/safe.hh (init_): New precondition.
Upgrade doc style.
mln/core/image/safe.hh | 17 ++-
mln/morpho/tree/all.hh | 1
mln/morpho/tree/data.hh | 187 ++++++++++++++++++++++++++++++++++++++++++
mln/morpho/tree/utils.hh | 2
tests/morpho/tree/Makefile.am | 6 -
tests/morpho/tree/data.cc | 86 +++++++++++++++++++
6 files changed, 289 insertions(+), 10 deletions(-)
Index: tests/morpho/tree/Makefile.am
--- tests/morpho/tree/Makefile.am (revision 2945)
+++ tests/morpho/tree/Makefile.am (working copy)
@@ -4,9 +4,11 @@
check_PROGRAMS = \
compute_tree \
+ data \
max
-compute_tree_SOURCES = compute_tree_.cc
-max_SOURCES = max_.cc
+compute_tree_SOURCES = compute_tree.cc
+data_SOURCES = data.cc
+max_SOURCES = max.cc
TESTS = $(check_PROGRAMS)
Index: tests/morpho/tree/data.cc
--- tests/morpho/tree/data.cc (revision 0)
+++ tests/morpho/tree/data.cc (revision 0)
@@ -0,0 +1,86 @@
+// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+/// \file tests/morpho/tree/parent.cc
+///
+/// Tests on mln::morpho::tree::parent.
+
+#include <mln/core/image/image2d.hh>
+#include <mln/core/alias/neighb2d.hh>
+#include <mln/pw/image.hh>
+
+#include <mln/debug/println.hh>
+#include <mln/debug/iota.hh>
+#include <mln/morpho/elementary/dilation.hh>
+
+#include <mln/core/site_set/p_array.hh>
+#include <mln/level/sort_psites.hh>
+
+#include <mln/morpho/tree/data.hh>
+
+
+int main()
+{
+ using namespace mln;
+
+ typedef image2d<unsigned> I;
+ I ima(3, 3);
+ debug::iota(ima);
+
+ ima = morpho::elementary::dilation(ima, c8());
+ debug::println("ima = ", ima);
+
+ typedef p_array<point2d> S;
+ S s = level::sort_psites_increasing(ima);
+
+ typedef morpho::tree::data<I,S> tree_t;
+ tree_t t(ima, s, c4());
+
+ debug::println( "parent = ", t.parent_image() | t.domain() );
+ debug::println( "on node = ", t.parent_image() | t.nodes() );
+
+ {
+ std::cout << "nodes = ";
+ tree_t::nodes_t::piter p(t.nodes());
+ for_all(p)
+ std::cout << p << ' ';
+ std::cout << std::endl
+ << std::endl;
+ }
+
+
+ {
+ image2d<unsigned> area(ima.domain());
+ level::fill(area, 1);
+ tree_t::piter p(t.domain());
+ for_all(p)
+ if (! t.is_root(p))
+ area(t.parent(p)) += area(p);
+ debug::println("area = ", area | t.nodes());
+ }
+
+}
Index: mln/core/image/safe.hh
--- mln/core/image/safe.hh (revision 2945)
+++ mln/core/image/safe.hh (working copy)
@@ -1,4 +1,5 @@
// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
+// (LRDE)
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -28,14 +29,13 @@
#ifndef MLN_CORE_IMAGE_SAFE_HH
# define MLN_CORE_IMAGE_SAFE_HH
-/*!
- * \file mln/core/image/safe.hh
- *
- * \brief Definition of a morpher that makes image become accessible
- * at undefined location.
- *
- * \todo Use 'instant' as the routine safe returns.
- */
+///
+/// \file mln/core/image/safe.hh
+///
+/// \brief Definition of a morpher that makes image become accessible
+/// at undefined location.
+///
+/// \todo Use 'instant' as the routine safe returns.
# include <mln/core/internal/image_identity.hh>
@@ -162,6 +162,7 @@
void
safe_image<I>::init_(I& ima, const mln_value(I)& default_value)
{
+ mln_precondition(! this->has_data());
mln_precondition(ima.has_data());
this->data_ = new internal::data< safe_image<I> >(ima, default_value);
}
Index: mln/morpho/tree/all.hh
--- mln/morpho/tree/all.hh (revision 2945)
+++ mln/morpho/tree/all.hh (working copy)
@@ -47,6 +47,7 @@
# include <mln/morpho/tree/compute_parent.hh>
+# include <mln/morpho/tree/data.hh>
# include <mln/morpho/tree/max.hh>
# include <mln/morpho/tree/utils.hh>
Index: mln/morpho/tree/data.hh
--- mln/morpho/tree/data.hh (revision 0)
+++ mln/morpho/tree/data.hh (revision 0)
@@ -0,0 +1,187 @@
+// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef MLN_MORPHO_TREE_DATA_HH
+# define MLN_MORPHO_TREE_DATA_HH
+
+/// \file mln/morpho/tree/data.hh
+///
+/// FIXME: First Attempt.
+
+# include <mln/morpho/tree/compute_parent.hh>
+# include <mln/core/image/sub_image.hh>
+
+
+
+namespace mln
+{
+
+ namespace morpho
+ {
+
+ namespace tree
+ {
+
+ // FIXME: Doc!
+
+ template <typename I, typename S>
+ class data
+ {
+ public:
+
+
+ /// Ctor.
+ template <typename N>
+ data(const Image<I>& f, const Site_Set<S>& s, const Neighborhood<N>& nbh);
+
+
+
+ /// \{ Parent-related materials.
+
+ typedef mln_ch_value(I, mln_psite(I)) parent_t;
+
+ const mln_psite(I)& parent(const mln_psite(I)& p) const
+ {
+ mln_precondition(is_valid());
+ mln_precondition(parent_.domain().has(p));
+ return parent_(p);
+ }
+
+ const parent_t& parent_image() const
+ {
+ mln_precondition(is_valid());
+ return parent_;
+ }
+
+ /// \}
+
+
+ /// \{ Tests.
+
+ bool is_valid() const
+ {
+ return parent_.has_data(); // FIXME: and... (?)
+ }
+
+ bool is_root(const mln_psite(I)& p) const
+ {
+ mln_precondition(is_valid());
+ mln_precondition(parent_.domain().has(p));
+ return parent_(p) == p;
+ }
+
+ bool is_a_node(const mln_psite(I)& p) const
+ {
+ mln_precondition(is_valid());
+ mln_precondition(parent_.domain().has(p));
+ return parent_(p) == p || f_(parent_(p)) != f_(p);
+ }
+
+ /// \}
+
+
+ /// \{ Nodes-related materials.
+
+ typedef p_array<mln_psite(I)> nodes_t;
+
+ const p_array<mln_psite(I)>& nodes() const
+ {
+ mln_precondition(is_valid());
+ return nodes_;
+ }
+
+ /// \}
+
+
+ /// \{ How-to iterate on all sites.
+
+ typedef mln_bkd_piter(S) piter;
+ typedef mln_bkd_piter(S) fwd_piter;
+ typedef mln_fwd_piter(S) bkd_piter;
+
+ const S& domain() const
+ {
+ return s_;
+ }
+
+ /// \}
+
+ unsigned nroots() const
+ {
+ return nroots_;
+ }
+
+ protected:
+
+ const I& f_;
+ const S& s_;
+ mln_ch_value(I, mln_psite(I)) parent_;
+ p_array<mln_psite(I)> nodes_;
+ unsigned nroots_;
+ };
+
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename I, typename S>
+ template <typename N>
+ inline
+ data<I,S>::data(const Image<I>& f, const Site_Set<S>& s, const Neighborhood<N>& nbh)
+ : f_(exact(f)),
+ s_(exact(s))
+ {
+ const N& nbh_ = exact(nbh);
+
+ // Compute parent image.
+ parent_ = morpho::tree::compute_parent(f_, nbh_, s_);
+
+ // Store tree nodes.
+ nroots_ = 0;
+ mln_bkd_piter(S) p(s_);
+ for_all(p)
+ if (f_(parent_(p)) != f_(p))
+ nodes_.insert(p);
+ else
+ if (parent_(p) == p)
+ {
+ nodes_.insert(p);
+ ++nroots_;
+ }
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::morpho::tree
+
+ } // end of namespace mln::morpho
+
+} // end of namespace mln
+
+
+#endif // ! MLN_MORPHO_TREE_DATA_HH
Index: mln/morpho/tree/utils.hh
--- mln/morpho/tree/utils.hh (revision 2945)
+++ mln/morpho/tree/utils.hh (working copy)
@@ -31,6 +31,8 @@
/// \file mln/morpho/tree/utils.hh
///
/// Utilities.
+///
+/// \todo Remove this file after ./data.hh is completed!
# include <mln/core/concept/image.hh>
# include <mln/core/site_set/p_array.hh>
1
0
24 Nov '08
* scribo/demat.hh:
- cleanup and refactor.
- Remove too large/small components.
- use a graph to store the text bboxes relationship.
---
milena/sandbox/ChangeLog | 9 +
milena/sandbox/scribo/demat.hh | 402 ++++++++++++++++++++++++++--------------
2 files changed, 269 insertions(+), 142 deletions(-)
diff --git a/milena/sandbox/ChangeLog b/milena/sandbox/ChangeLog
index 000b312..162aafe 100644
--- a/milena/sandbox/ChangeLog
+++ b/milena/sandbox/ChangeLog
@@ -1,3 +1,12 @@
+2008-11-24 Guillaume Lazzara <z(a)lrde.epita.fr>
+
+ [Scribo] Cleanup and improve removal of unwanted components.
+
+ * scribo/demat.hh:
+ - cleanup and refactor.
+ - Remove too large/small components.
+ - use a graph to store the text bboxes relationship.
+
2008-11-24 Ugo Jardonnet <ugo.jardonnet(a)lrde.epita.fr>
Start /filtering to n components/ procedure.
diff --git a/milena/sandbox/scribo/demat.hh b/milena/sandbox/scribo/demat.hh
index 87e8008..8b59a11 100644
--- a/milena/sandbox/scribo/demat.hh
+++ b/milena/sandbox/scribo/demat.hh
@@ -39,14 +39,13 @@
# include <libgen.h>
# include <sstream>
+# include <queue>
# include <mln/essential/1d.hh>
# include <mln/essential/2d.hh>
# include <mln/morpho/elementary/dilation.hh>
# include <mln/labeling/background.hh>
-# include <mln/transform/influence_zone_geodesic.hh>
-
#include <tesseract/baseapi.h>
namespace scribo
@@ -56,28 +55,42 @@ namespace scribo
{
using namespace mln;
- using value::int_u16;
+ using value::label16;
using value::rgb8;
+
+
struct settings_t
{
settings_t()
{
- bbox_enlarge = 1;
ero_line_width = 51;
- bbox_distance = 25;
+ rank_filter = 6;
+ bbox_enlarge = 1 + ero_line_width / 2 - rank_filter;
+ bbox_distance = 20;
min_comp_size = 5;
+ max_comp_size = 1000;
+ max_dist_lines = 10;
+ max_txt_box_height = 100;
}
unsigned bbox_enlarge;
unsigned ero_line_width;
unsigned bbox_distance;
unsigned min_comp_size;
+ unsigned max_comp_size;
+ unsigned max_dist_lines;
+ int max_txt_box_height;
+ unsigned rank_filter;
};
+
+
settings_t settings;
char *input_file = 0;
+
+
/// Returns a formated output file name.
std::string output_file(const char *name)
{
@@ -126,6 +139,8 @@ namespace scribo
return std::make_pair(p1, p2);
}
+
+
/// Draw a list of bboxes and their center in a RGB8 image.
void draw_component_boxes(image2d<rgb8>& output, const util::array<box2d>& boxes)
{
@@ -137,6 +152,8 @@ namespace scribo
}
}
+
+
/// Colorize and save a labeled image.
template <typename V>
void save_lbl_image(const image2d<V>& lbl, unsigned nlabels,
@@ -147,7 +164,14 @@ namespace scribo
}
+
+
+
+
+
+ //-*****************************************
/// Functions related to Text Recognition.
+ //-*****************************************
/// \{
/// Passes the text bboxes to Tesseract and store the result an image of
@@ -158,7 +182,7 @@ namespace scribo
///
/// FIXME: For each text bbox, we create a new image. We may like to avoid that.
void
- text_recognition(const image2d<bool>& in, const image2d<int_u16>& lbl,
+ text_recognition(const image2d<bool>& in, const image2d<label16>& lbl,
const util::array<box2d>& tboxes)
{
/// Use txt bboxes here with Tesseract
@@ -195,10 +219,18 @@ namespace scribo
io::txt::save(txt, "out.txt");
}
-
/// \}
+ //--------------------------------------------------
+ /// End of functions related to Text Recognition.
+ //--------------------------------------------------
- /// Functions related to the matrix extraction
+
+
+
+
+ //-*********************************************
+ /// Functions related to the table extraction
+ //-*********************************************
/// \{
/// Align table lines bboxes according to a given dimension.
@@ -259,7 +291,7 @@ namespace scribo
for_all_elements(i, lines)
if (lines[i].nelements() == max_nelts)
{
- accu::mean<int_u16> mean;
+ accu::mean<unsigned> mean;
for_all_elements(j, lines[i])
if (box2line[lines[i][j]] == -1)
mean.take(hboxes[lines[i][j]].center()[dim]);
@@ -282,11 +314,45 @@ namespace scribo
return newlines;
}
+
+
+ /// Connect lines if they are close to each other.
+ void
+ connect_lines(const image2d<bool>& in,
+ const util::array<int>& aligned_lines,
+ util::array<box2d>& boxes,
+ unsigned dim)
+ {
+ image1d<int> l(in.nrows());
+ level::fill(l, -1);
+
+ for_all_elements(i, aligned_lines)
+ l.at(aligned_lines[i]) = 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);
+ if (l.at(cp.first[dim]) != -1)
+ boxes[i].pmin()[dim] = aligned_lines[l.at(cp.first[dim])];
+ if (l.at(cp.second[dim]) != -1)
+ boxes[i].pmax()[dim] = aligned_lines[l.at(cp.second[dim])];
+ }
+ }
+
+
+
+ /// Align line bboxes vertically and horizontally. Then, try to join
+ /// vertical and horizontal lines in order to rebuild the table.
image2d<bool>
rebuild_table(const image2d<bool>& in,
std::pair<util::array<box2d>,
util::array<box2d> >& tblboxes)
{
+ std::cout << "Rebuild table" << std::endl;
+
util::array<int> rows = align_lines(in.nrows(), geom::min_row(in),
geom::max_row(in), tblboxes.second,
0);
@@ -294,43 +360,8 @@ namespace scribo
geom::max_col(in), tblboxes.first,
1);
- image1d<int> v(in.nrows());
- image1d<int> h(in.ncols());
- level::fill(v, -1);
- level::fill(h, -1);
-
- for_all_elements(i, rows)
- v.at(rows[i]) = i;
- for_all_elements(i, cols)
- h.at(cols[i]) = i;
-
- for (int i = 0; i < 10; ++i)
- {
- v = morpho::elementary::dilation(v, c2());
- h = morpho::elementary::dilation(h, c2());
- }
-
- util::array<box2d>& vb = tblboxes.first;
- for_all_components(i, vb)
- {
- std::pair<point2d, point2d> cp = central_sites(vb[i], 0);
- if (v.at(cp.first.row()) != -1)
- vb[i].pmin().row() = rows[v.at(cp.first.row())];
- if (v.at(cp.second.row()) != -1)
- vb[i].pmax().row() = rows[v.at(cp.second.row())];
-
- cp = central_sites(vb[i], 0);
- }
-
- util::array<box2d>& hb = tblboxes.second;
- for_all_components(i, hb)
- {
- std::pair<point2d, point2d> cp = central_sites(hb[i], 1);
- if (h.at(cp.first.col()) != -1)
- hb[i].pmin().col() = cols[h.at(cp.first.col())];
- if (h.at(cp.second.col()) != -1)
- hb[i].pmax().col() = cols[h.at(cp.second.col())];
- }
+ connect_lines(in, rows, tblboxes.first, 0);
+ connect_lines(in, cols, tblboxes.second, 1);
image2d<bool> res;
initialize(res, in);
@@ -349,10 +380,12 @@ namespace scribo
draw::box(out, tblboxes.second[i], literal::red);
io::ppm::save(out, output_file("table.ppm"));
# endif
+
return res;
}
+
void draw_line(image2d<rgb8>& ima,
unsigned dim,
const box2d& box,
@@ -363,6 +396,8 @@ namespace scribo
draw::line(ima, cp.first, cp.second, v);
}
+
+
void draw_row(image2d<rgb8>& ima,
unsigned line,
const rgb8& v)
@@ -370,6 +405,8 @@ namespace scribo
draw::line(ima, point2d(line, 0), point2d(line, ima.ncols()), v);
}
+
+
void draw_col(image2d<rgb8>& ima,
unsigned line,
const rgb8& v)
@@ -377,6 +414,7 @@ namespace scribo
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)
@@ -437,34 +475,44 @@ namespace scribo
#endif
}
-
+*/
/// \}
+ //-****************************************************
+ /// End of functions related to the table extraction
+ //-****************************************************
+
+
+ //-*****************************************
/// 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);
+ label16 nlabels = 0;
+ image2d<label16> 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)
+ unsigned dim)
{
for_all_components(i, boxes)
{
- boxes[i].enlarge(dim, bbox_enlarge + settings.bbox_enlarge);
+ boxes[i].enlarge(dim, settings.bbox_enlarge);
boxes[i].crop_wrt(output.domain());
level::paste((pw::cst(false) | boxes[i] |
(pw::value(output) == pw::cst(true))), output);
@@ -472,13 +520,13 @@ namespace scribo
}
+
/// 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)
+ extract_tables(image2d<bool>& in)
{
- typedef image2d<int_u16> I;
+ typedef image2d<label16> I;
typedef accu::bbox<mln_psite_(I)> A;
typedef util::array<mln_result_(A)> boxes_t;
@@ -486,7 +534,7 @@ namespace scribo
// Lignes verticales
std::cout << "Removing vertical lines" << std::endl;
win::vline2d vline(settings.ero_line_width);
- image2d<bool> vfilter = morpho::erosion(in, vline);
+ image2d<bool> vfilter = morpho::rank_filter(in, win_c4p(), settings.rank_filter);
#ifndef NOUT
io::pbm::save(vfilter, output_file("vertical-erosion.pbm"));
@@ -497,7 +545,7 @@ namespace scribo
// Lignes horizontales
std::cout << "Removing horizontal lines" << std::endl;
win::hline2d hline(settings.ero_line_width);
- image2d<bool> hfilter = morpho::erosion(in, hline);
+ image2d<bool> hfilter = morpho::rank_filter(in, hline, settings.rank_filter);
#ifndef NOUT
io::pbm::save(hfilter, output_file("horizontal-erosion.pbm"));
@@ -505,11 +553,11 @@ namespace scribo
boxes_t hboxes = component_boxes(hfilter);
- erase_table_boxes(in, vboxes, (settings.ero_line_width / 2), 0);
- erase_table_boxes(in, hboxes, (settings.ero_line_width / 2), 1);
+ erase_table_boxes(in, vboxes, 0);
+ erase_table_boxes(in, hboxes, 1);
#ifndef NOUT
- image2d<rgb8> tmp = clone(output);
+ image2d<rgb8> tmp = level::convert(rgb8(), in);
draw_component_boxes(tmp, vboxes);
draw_component_boxes(tmp, hboxes);
io::ppm::save(tmp, output_file("vertical-and-horizontal-erosion.ppm"));
@@ -519,79 +567,133 @@ namespace scribo
}
/// \}
+ //--------------------------------------------------
/// 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)
+ fun::i2v::array<label16>
+ make_relabel_fun(const util::graph& g)
{
- while (left_link(i) != i)
- i = left_link(i);
- return i;
- }
+ fun::i2v::array<label16> fun(g.v_nmax(), mln_max(label16));
- 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);
+ mln_vertex_iter_(util::graph) v(g);
+ for_all(v)
+ if (fun(v.id()) == mln_max(label16))
+ {
+ std::queue<unsigned> queue;
+ queue.push(v.id());
+ fun(v.id()) = v.id();
+ while (!queue.empty())
+ {
+ util::vertex<util::graph> current_v = g.vertex(queue.front());
+ queue.pop();
+ for (unsigned nv = 0; nv < current_v.nmax_nbh_vertices(); ++nv)
+ if (fun(current_v.ith_nbh_vertex(nv)) == mln_max(label16))
+ {
+ fun(current_v.ith_nbh_vertex(nv)) = v.id();
+ queue.push(current_v.ith_nbh_vertex(nv));
+ }
+ }
+ }
+
+ return fun;
}
- template <typename V>
- void
- remove_small_comps_i2v(image2d<V>& lbl,
- V& nlabels)
+
+
+ template <typename R>
+ struct remove_small_comps
+ : Function_l2b< remove_small_comps<R> >
{
- std::cout << "Removing small components smaller than "
- << settings.min_comp_size << " sites among " << nlabels
- << " components" << std::endl;
+ remove_small_comps(const util::array<R>& nsitecomp)
+ : nsitecomp_(nsitecomp)
+ {
+ }
- typedef accu::count<mln_psite(image2d<V>)> accu_count_t;
+ /// Return false if the components is smaller than a given size.
+ bool operator()(const label16& l) const
+ {
+ return nsitecomp_[l].first >= settings.min_comp_size;
+ }
- util::array<mln_result(accu_count_t)> nsitecomp
- = labeling::compute(accu_count_t(), lbl, nlabels);
+ const util::array<R>& nsitecomp_;
+ };
- V ncomp = 0;
- fun::i2v::array<V> f(nsitecomp.nelements());
- f(0) = 0;
- for_all_ncomponents(i, nlabels)
+ template <typename R>
+ struct remove_smallandlarge_comps
+ : Function_l2b< remove_smallandlarge_comps<R> >
+ {
+ remove_smallandlarge_comps(const util::array<R>& nsitecomp)
+ : nsitecomp_(nsitecomp)
{
- if (nsitecomp[i] < settings.min_comp_size)
- f(i) = 0;
- else
- f(i) = ++ncomp;
}
- lbl = level::transform(lbl, f);
- nlabels = ncomp;
+ /// Return false if the components is smaller than a given size.
+ bool operator()(const label16& l) const
+ {
+ return nsitecomp_[l].first >= settings.min_comp_size
+ && nsitecomp_[l].first < settings.max_comp_size
+ && math::abs(nsitecomp_[l].second.pmax().row()
+ - nsitecomp_[l].second.pmin().row())
+ <= settings.max_txt_box_height;
+ }
-#ifndef NOUT
- save_lbl_image(lbl, nlabels, "lbl-small-comps-removed.pgm");
-#endif
+ const util::array<R>& nsitecomp_;
+ };
+
+
+
+ void
+ cleanup_components(image2d<label16>& lbl,
+ label16& nlabels, bool treat_tables)
+ {
+ std::cout << "Cleanup components..." << std::endl;
+
+ typedef accu::count<mln_psite_(image2d<label16>)> accu_count_t;
+ typedef accu::bbox<mln_psite_(image2d<label16>)> accu_bbox_t;
+ typedef accu::pair<accu_count_t, accu_bbox_t> accu_pair_t;
+ typedef mln_result_(accu_pair_t) accu_res_t;
+ typedef util::array<accu_res_t> nsitecomp_t;
+
+ nsitecomp_t nsitecomp = labeling::compute(accu_pair_t(), lbl, nlabels);
+ if (treat_tables)
+ {
+ remove_small_comps<accu_res_t> fl2b(nsitecomp);
+ labeling::relabel_inplace(lbl, nlabels, fl2b);
+ } else
+ {
+ remove_smallandlarge_comps<accu_res_t> fl2b(nsitecomp);
+ labeling::relabel_inplace(lbl, nlabels, fl2b);
+ }
}
+
/// Merge bboxes according to their left box neighbor.
util::array< box2d >
- group_bboxes(fun::i2v::array<int_u16>& left_link, image2d<int_u16>& lbl,
+ group_bboxes(const util::graph& g, image2d<label16>& lbl,
util::array<box2d>& cboxes, unsigned ncomp)
{
- // Currify left_link lookup table and compute text area bboxes.
+ fun::i2v::array<label16> relabel_fun = make_relabel_fun(g);
+
util::array< accu::bbox<point2d> > tboxes;
tboxes.resize(ncomp + 1);
for_all_ncomponents(i, ncomp)
- tboxes[uncurri_left_link(left_link, i)].take(cboxes[i]);
+ tboxes[relabel_fun(i)].take(cboxes[i]);
//Update labels
- lbl = level::transform(lbl, left_link);
+ level::transform_inplace(lbl, relabel_fun);
#ifndef NOUT
save_lbl_image(lbl, ncomp, "lbl-grouped-boxes.pgm");
@@ -606,36 +708,28 @@ namespace scribo
}
+
/// 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,
+ void update_link(util::graph& g, image2d<label16>& 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? VERY bad results otherwise.
- }
+ g.add_edge(lbl(p), i);
}
/// 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,
+ util::graph
+ link_character_bboxes(image2d<label16>& lbl,
const util::array<box2d>& cboxes,
unsigned ncomp)
{
- fun::i2v::array<int_u16> left_link;
- left_link.resize(ncomp + 1);
-
- for (unsigned i = 0; i <= ncomp; ++i)
- left_link(i) = i;
+ util::graph g(ncomp + 1);
for_all_ncomponents(i, ncomp)
{
@@ -650,33 +744,29 @@ namespace scribo
&& math::abs(p.col() - c.col()) < dmax)
++p.col();
- update_link(left_link, lbl, p, c, i, dmax);
+ update_link(g, lbl, p, c, i, dmax);
}
- return left_link;
+ return g;
}
+
+
util::array<box2d>
extract_text(image2d<bool>& in,
- image2d<int_u16>& lbl,
- image2d<rgb8>& output)
+ image2d<label16>& lbl,
+ const label16& nlabels)
{
+ std::cout << "extract text" << std::endl;
- typedef int_u16 V;
+ typedef label16 V;
typedef image2d<V> I;
typedef util::array<box2d> boxes_t;
- // Find character bboxes.
- V nlabels;
- lbl = labeling::blobs(in, c8(), nlabels);
-
- //Remove small components.
- remove_small_comps_i2v(lbl, nlabels);
-
boxes_t cboxes = labeling::compute(accu::meta::bbox(), lbl, nlabels);
#ifndef NOUT
- image2d<rgb8> tmp = clone(output);
+ image2d<rgb8> tmp = level::convert(rgb8(), in);
draw_component_boxes(tmp, cboxes);
io::ppm::save(tmp, output_file("character-bboxes.ppm"));
#endif
@@ -684,48 +774,57 @@ namespace scribo
//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);
+ util::graph g = link_character_bboxes(lbl, cboxes, nlabels);
//Merge character bboxes according to their left neighbor.
- util::array<box2d> tboxes = group_bboxes(left, lbl, cboxes, nlabels);
+ util::array<box2d> tboxes = group_bboxes(g, lbl, cboxes, nlabels);
return tboxes;
}
+
+
void maptext_to_cells(const image2d<bool>& in, const image2d<bool>& table, const util::array<box2d>& tboxes)
{
- int_u16 nlabels;
- image2d<int_u16> tblelbl = labeling::background(table, c8(), nlabels);
- image2d<rgb8> color = debug::colorize<image2d<rgb8>, image2d<int_u16> >(tblelbl, nlabels);
+ std::cout << "map text to cells" << std::endl;
+ label16 nlabels;
+ image2d<label16> tblelbl = labeling::background(table, c8(), nlabels);
+ image2d<rgb8> color = debug::colorize<image2d<rgb8>, image2d<label16> >(tblelbl, nlabels);
# ifndef NOUT
io::ppm::save(color, output_file("cells-labels.ppm"));
-# endif
image2d<rgb8> dbg = level::convert(rgb8(), logical::not_(table));
for_all_elements(i, tboxes)
if (tboxes[i].is_valid())
- {
level::paste(pw::cst(color(tboxes[i].center())) | (tboxes[i] | pw::value(in) == pw::cst(true)),
dbg);
- }
-# ifndef NOUT
io::ppm::save(dbg, output_file("text2cell.ppm"));
# endif
}
+
/// \}
+ //-----------------------------------------------
/// 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;
- using value::int_u16;
+ using value::label16;
border::thickness = 3;
trace::quiet = true;
@@ -738,7 +837,16 @@ namespace scribo
io::pbm::load(in, argv[1]);
logical::not_inplace(in);
- image2d<rgb8> output = level::convert(rgb8(), in);
+#ifndef NOUT
+ image2d<bool> in_bak = clone(in);
+#endif
+
+ internal::settings.max_comp_size = in.ncols() * in.nrows() * 0.05;
+
+ //Label and remove small components.
+ label16 nlabels;
+ image2d<label16> lbl = labeling::blobs(in, c8(), nlabels);
+ internal::cleanup_components(lbl, nlabels, treat_tables);
std::pair<util::array<box2d>,
util::array<box2d> > tblboxes;
@@ -746,20 +854,30 @@ namespace scribo
image2d<bool> table;
if (treat_tables)
{
- tblboxes = internal::extract_tables(in, output);
+ tblboxes = internal::extract_tables(in);
// internal::extract_matrix(in, tblboxes);
table = internal::rebuild_table(in, tblboxes);
+
+ lbl = labeling::blobs(in, c8(), nlabels);
+ internal::cleanup_components(lbl, nlabels, treat_tables);
+
+#ifndef NOUT
+ internal::save_lbl_image(lbl, nlabels, "lbl-small-comps-removed.pgm");
+#endif
}
- image2d<value::int_u16> lbl;
util::array<box2d> tboxes =
- internal::extract_text(in, lbl, output);
+ internal::extract_text(in, lbl, nlabels);
if (treat_tables)
internal::maptext_to_cells(in, table, tboxes);
+#ifndef NOUT
+ std::cout << "Saving output" << std::endl;
+ image2d<rgb8> output = level::convert(rgb8(), in_bak);
internal::draw_component_boxes(output, tboxes);
io::ppm::save(output, internal::output_file("out.ppm"));
+#endif
internal::text_recognition(in, lbl, tboxes);
}
--
1.5.6.5
1
0
* mln/fun/l2l/all.hh
* mln/fun/l2l/essential.hh: new headers.
* mln/value/all.hh,
* mln/accu/bbox.hh: Fix comments.
* mln/fun/i2v/array.hh: add missing constructor implementation.
* mln/value/essential.hh,
* mln/value/aliases.hh,
* mln/level/essential.hh,
* mln/labeling/essential.hh: update includes.
* mln/make/relabelfun.hh: Fix a bug. New component ids were not set
correclty.
* mln/value/label.hh: Fix a duplicate attribute.
* mln/labeling/compute.hh,
* mln/debug/colorize.hh: use label::next() instead of operator '+' to
get the next label.
---
milena/ChangeLog | 26 ++++++++++++++++
milena/mln/accu/bbox.hh | 6 ++--
milena/mln/debug/colorize.hh | 9 ++++--
milena/mln/fun/i2v/array.hh | 7 ++++
milena/mln/{value/aliases.hh => fun/l2l/all.hh} | 34 ++++++++++++++-------
milena/mln/{labeling => fun/l2l}/essential.hh | 18 +++++------
milena/mln/labeling/compute.hh | 6 ++-
milena/mln/labeling/essential.hh | 10 +++---
milena/mln/level/essential.hh | 1 +
milena/mln/make/relabelfun.hh | 3 +-
milena/mln/value/aliases.hh | 19 +++++++++---
milena/mln/value/all.hh | 9 ++---
milena/mln/value/essential.hh | 12 ++++---
milena/mln/value/label.hh | 36 +++++++----------------
14 files changed, 120 insertions(+), 76 deletions(-)
copy milena/mln/{value/aliases.hh => fun/l2l/all.hh} (75%)
copy milena/mln/{labeling => fun/l2l}/essential.hh (78%)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index d149788..404e42b 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,5 +1,31 @@
2008-11-24 Guillaume Lazzara <z(a)lrde.epita.fr>
+ Various small fixes.
+
+ * mln/fun/l2l/all.hh
+ * mln/fun/l2l/essential.hh: new headers.
+
+ * mln/value/all.hh,
+ * mln/accu/bbox.hh: Fix comments.
+
+ * mln/fun/i2v/array.hh: add missing constructor implementation.
+
+ * mln/value/essential.hh,
+ * mln/value/aliases.hh,
+ * mln/level/essential.hh,
+ * mln/labeling/essential.hh: update includes.
+
+ * mln/make/relabelfun.hh: Fix a bug. New component ids were not set
+ correclty.
+
+ * mln/value/label.hh: Fix a duplicate attribute.
+
+ * mln/labeling/compute.hh,
+ * mln/debug/colorize.hh: use label::next() instead of operator '+' to
+ get the next label.
+
+2008-11-24 Guillaume Lazzara <z(a)lrde.epita.fr>
+
Update rank_filter.
* mln/accu/rank_bool.hh: Add untake() and remove unnecessary
diff --git a/milena/mln/accu/bbox.hh b/milena/mln/accu/bbox.hh
index 90c2e5d..7c3e35f 100644
--- a/milena/mln/accu/bbox.hh
+++ b/milena/mln/accu/bbox.hh
@@ -45,9 +45,9 @@ namespace mln
/// Generic bbox accumulator class.
- /*!
- * The parameter \c P is the type of points.
- */
+ ///
+ /// The parameter \c P is the type of points.
+ ///
template <typename P>
struct bbox : public mln::accu::internal::base< const box<P>& , bbox<P> >
{
diff --git a/milena/mln/debug/colorize.hh b/milena/mln/debug/colorize.hh
index f764278..cf99383 100644
--- a/milena/mln/debug/colorize.hh
+++ b/milena/mln/debug/colorize.hh
@@ -100,12 +100,15 @@ namespace mln
{
trace::entering("debug::colorize");
mln_precondition(exact(input).has_data());
+ // FIXME: we want to be sure that this is a label.
+ mlc_is_a(mln_value(L), mln::value::Symbolic)::check();
+ unsigned label_count = nlabels.next();
static fun::i2v::array<mln_value(I)> f(0);
- int diff_size = f.size() - (nlabels + 1);
+ int diff_size = f.size() - label_count;
if (diff_size < 0)
{
- f.resize(nlabels + 1);
+ f.resize(label_count);
unsigned i = f.size() + diff_size;
// We want to treat comp 0 differently since it is the background.
if (i == 0)
@@ -116,7 +119,7 @@ namespace mln
for (; i < f.size(); ++i)
f(i) = internal::random_color();
}
- mln_precondition(f.size() == (nlabels + 1));
+ mln_precondition(f.size() == (label_count));
mln_concrete(I) output = level::transform(input, f);
trace::exiting("debug::colorize");
diff --git a/milena/mln/fun/i2v/array.hh b/milena/mln/fun/i2v/array.hh
index ee9b1bb..630675e 100644
--- a/milena/mln/fun/i2v/array.hh
+++ b/milena/mln/fun/i2v/array.hh
@@ -166,6 +166,13 @@ namespace mln
template <typename T>
inline
+ array<T>::array(unsigned n, const T& val)
+ : super_base_(n, val)
+ {
+ }
+
+ template <typename T>
+ inline
array<T>::array(const util::array<T>& from)
: super_base_(from)
{
diff --git a/milena/mln/value/aliases.hh b/milena/mln/fun/l2l/all.hh
similarity index 75%
copy from milena/mln/value/aliases.hh
copy to milena/mln/fun/l2l/all.hh
index c3790b8..c763ca7 100644
--- a/milena/mln/value/aliases.hh
+++ b/milena/mln/fun/l2l/all.hh
@@ -1,4 +1,4 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE)
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -25,19 +25,31 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-#ifndef MLN_VALUE_ALIASES_HH
-# define MLN_VALUE_ALIASES_HH
+#ifndef MLN_FUN_L2L_ALL_HH
+# define MLN_FUN_L2L_ALL_HH
-/*! \file mln/value/aliases.hh
- *
- * \brief File that includes all aliases of value types.
- */
+/// \file mln/fun/l2l/all.hh
+///
+/// File that includes all functions from index to value.
-# include <mln/value/int_u8.hh>
-# include <mln/value/int_u16.hh>
+namespace mln
+{
-# include <mln/value/int_s8.hh>
+ namespace fun
+ {
+ /// Namespace of functions from label to label.
+ namespace l2l
+ {
+ }
+ }
-#endif // ! MLN_VALUE_ALIASES_HH
+}
+
+
+# include <mln/fun/l2l/relabel.hh>
+
+
+
+#endif // ! MLN_FUN_L2L_ALL_HH
diff --git a/milena/mln/labeling/essential.hh b/milena/mln/fun/l2l/essential.hh
similarity index 78%
copy from milena/mln/labeling/essential.hh
copy to milena/mln/fun/l2l/essential.hh
index 940f2c2..6ca53c0 100644
--- a/milena/mln/labeling/essential.hh
+++ b/milena/mln/fun/l2l/essential.hh
@@ -1,4 +1,4 @@
-// Copyright (C) 2008 EPITA Research and Development Laboratory
+// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE)
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -25,15 +25,13 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-#ifndef MLN_LABELING_ESSENTIAL_HH
-# define MLN_LABELING_ESSENTIAL_HH
+#ifndef MLN_FUN_L2L_ESSENTIAL_HH
+# define MLN_FUN_L2L_ESSENTIAL_HH
-/*! \file mln/labeling/essential.hh
- *
- * \brief File that includes essential labeling routines.
- */
+/// \file mln/fun/l2l/essential.hh
+///
+/// File that includes essential functions from label to label.
-# include <mln/labeling/blobs.hh>
-# include <mln/labeling/compute.hh>
+# include <mln/fun/l2l/all.hh>
-#endif // ! MLN_LABELING_ESSENTIAL_HH
+#endif // ! MLN_FUN_L2L_ESSENTIAL_HH
diff --git a/milena/mln/labeling/compute.hh b/milena/mln/labeling/compute.hh
index 6233979..dfc95f1 100644
--- a/milena/mln/labeling/compute.hh
+++ b/milena/mln/labeling/compute.hh
@@ -32,6 +32,8 @@
///
/// Compute accumulators onto sites/values of each labeled component
/// of an image.
+///
+/// \todo write fastest version.
# include <mln/core/concept/image.hh>
# include <mln/core/concept/accumulator.hh>
@@ -171,7 +173,7 @@ namespace mln
const A& a = exact(a_);
const L& label = exact(label_);
- util::array<A> accus(nlabels + 1, a);
+ util::array<A> accus(nlabels.next(), a);
mln_piter(L) p(label.domain());
for_all(p)
@@ -197,7 +199,7 @@ namespace mln
const I& input = exact(input_);
const L& label = exact(label_);
- util::array<A> accus (nlabels + 1, a);
+ util::array<A> accus (nlabels.next(), a);
mln_piter(I) p(input.domain());
for_all(p)
diff --git a/milena/mln/labeling/essential.hh b/milena/mln/labeling/essential.hh
index 940f2c2..3a5544d 100644
--- a/milena/mln/labeling/essential.hh
+++ b/milena/mln/labeling/essential.hh
@@ -1,4 +1,4 @@
-// Copyright (C) 2008 EPITA Research and Development Laboratory
+// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE)
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -28,12 +28,12 @@
#ifndef MLN_LABELING_ESSENTIAL_HH
# define MLN_LABELING_ESSENTIAL_HH
-/*! \file mln/labeling/essential.hh
- *
- * \brief File that includes essential labeling routines.
- */
+/// \file mln/labeling/essential.hh
+///
+/// File that includes essential labeling routines.
# include <mln/labeling/blobs.hh>
# include <mln/labeling/compute.hh>
+# include <mln/labeling/relabel.hh>
#endif // ! MLN_LABELING_ESSENTIAL_HH
diff --git a/milena/mln/level/essential.hh b/milena/mln/level/essential.hh
index f545c0e..e89031e 100644
--- a/milena/mln/level/essential.hh
+++ b/milena/mln/level/essential.hh
@@ -47,6 +47,7 @@
# include <mln/level/replace.hh>
# include <mln/level/saturate.hh>
# include <mln/level/transform.hh>
+# include <mln/level/transform_inplace.hh>
# include <mln/level/update.hh>
# include <mln/level/approx/essential.hh>
diff --git a/milena/mln/make/relabelfun.hh b/milena/mln/make/relabelfun.hh
index d02dd88..abbba80 100644
--- a/milena/mln/make/relabelfun.hh
+++ b/milena/mln/make/relabelfun.hh
@@ -75,8 +75,7 @@ namespace mln
for (label_t i = 1; i <= nlabels; ++i)
if (fl2b(i))
{
- fl2l(i) = i;
- ++tmp_nlabels;
+ fl2l(i) = ++tmp_nlabels;
}
new_nlabels = tmp_nlabels;
trace::exiting("mln::make::relabelfun");
diff --git a/milena/mln/value/aliases.hh b/milena/mln/value/aliases.hh
index c3790b8..8fe2485 100644
--- a/milena/mln/value/aliases.hh
+++ b/milena/mln/value/aliases.hh
@@ -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
@@ -28,16 +28,25 @@
#ifndef MLN_VALUE_ALIASES_HH
# define MLN_VALUE_ALIASES_HH
-/*! \file mln/value/aliases.hh
- *
- * \brief File that includes all aliases of value types.
- */
+/// \file mln/value/aliases.hh
+///
+/// File that includes all aliases of value types.
+# include <mln/value/float01_8.hh>
+# include <mln/value/float01_16.hh>
# include <mln/value/int_u8.hh>
# include <mln/value/int_u16.hh>
+# include <mln/value/int_u32.hh>
# include <mln/value/int_s8.hh>
+# include <mln/value/int_s16.hh>
+# include <mln/value/int_s32.hh>
+# include <mln/value/label_8.hh>
+# include <mln/value/label_16.hh>
+
+# include <mln/value/rgb8.hh>
+# include <mln/value/rgb16.hh>
#endif // ! MLN_VALUE_ALIASES_HH
diff --git a/milena/mln/value/all.hh b/milena/mln/value/all.hh
index 2620f21..27ef955 100644
--- a/milena/mln/value/all.hh
+++ b/milena/mln/value/all.hh
@@ -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
@@ -28,10 +28,9 @@
#ifndef MLN_VALUE_ALL_HH
# define MLN_VALUE_ALL_HH
-/*! \file mln/value/all.hh
- *
- * \brief File that includes all "value types"-related materials.
- */
+/// \file mln/value/all.hh
+///
+/// File that includes all "value types"-related materials.
namespace mln
diff --git a/milena/mln/value/essential.hh b/milena/mln/value/essential.hh
index e537eff..4d0b97b 100644
--- a/milena/mln/value/essential.hh
+++ b/milena/mln/value/essential.hh
@@ -1,4 +1,4 @@
-// Copyright (C) 2008 EPITA Research and Development Laboratory
+// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE)
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -28,10 +28,9 @@
#ifndef MLN_VALUE_ESSENTIAL_HH
# define MLN_VALUE_ESSENTIAL_HH
-/*! \file mln/value/essential.hh
- *
- * \brief File that includes essential "value types"-related materials.
- */
+/// \file mln/value/essential.hh
+///
+/// File that includes essential "value types"-related materials.
# include <mln/value/concept/essential.hh>
# include <mln/value/builtin/essential.hh>
@@ -50,6 +49,9 @@
# include <mln/value/int_u16.hh>
# include <mln/value/int_u32.hh>
+# include <mln/value/label_8.hh>
+# include <mln/value/label_16.hh>
+
# include <mln/value/rgb8.hh>
# include <mln/value/rgb16.hh>
diff --git a/milena/mln/value/label.hh b/milena/mln/value/label.hh
index 02eec94..8421133 100644
--- a/milena/mln/value/label.hh
+++ b/milena/mln/value/label.hh
@@ -129,12 +129,6 @@ namespace mln
/// Return the next value.
label<n> next() const;
- /// Conversion to unsigned.
- const enc& to_enc() const;
-
- protected:
-
- enc v_;
};
@@ -165,21 +159,21 @@ namespace mln
inline
label<n>::label(unsigned i)
{
- v_ = enc(i);
+ this->v_ = enc(i);
}
template <unsigned n>
inline
label<n>::label(const literal::zero_t&)
{
- v_ = 0;
+ this->v_ = 0;
}
template <unsigned n>
inline
label<n>::operator unsigned() const
{
- return to_enc();
+ return this->to_enc();
}
template <unsigned n>
@@ -188,7 +182,7 @@ namespace mln
label<n>::operator=(unsigned i)
{
mln_precondition(i <= mln_max(enc));
- v_ = enc(i);
+ this->v_ = enc(i);
return *this;
}
@@ -197,7 +191,7 @@ namespace mln
label<n>&
label<n>::operator=(const literal::zero_t&)
{
- v_ = 0;
+ this->v_ = 0;
return *this;
}
@@ -206,8 +200,8 @@ namespace mln
label<n>&
label<n>::operator++()
{
- mln_precondition(v_ < mln_max(enc));
- ++v_;
+ mln_precondition(this->v_ < mln_max(enc));
+ ++this->v_;
return *this;
}
@@ -216,8 +210,8 @@ namespace mln
label<n>&
label<n>::operator--()
{
- mln_precondition(v_ != 0);
- --v_;
+ mln_precondition(this->v_ != 0);
+ --this->v_;
return *this;
}
@@ -226,22 +220,14 @@ namespace mln
label<n>
label<n>::next() const
{
- return label<n>(v_ + 1);
- }
-
- template <unsigned n>
- inline
- const mln_enc(label<n>)&
- label<n>::to_enc() const
- {
- return v_;
+ return label<n>(this->v_ + 1);
}
template <unsigned n>
inline
std::ostream& operator<<(std::ostream& ostr, const label<n>& i)
{
- return ostr << i.to_enc();
+ return ostr << debug::format(i.to_equiv());
}
# endif // ! MLN_INCLUDE_ONLY
--
1.5.6.5
1
0
* mln/accu/rank_bool.hh: Add untake() and remove unnecessary
attributes.
* mln/morpho/rank_filter.hh: Add rank_filter_directional. It is used
with win::line.
* mln/morpho/rank_filter.hh: Add rank_filter_directional. It is used
with win::line.
* mln/accu/rank.hh: update constructor and add untake(accu::rank).
* tests/accu/rank.cc,
* tests/morpho/rank_filter.cc: fix tests.
* tests/morpho/Makefile.am: add rank_filter test.
---
milena/ChangeLog | 17 +++++
milena/mln/accu/rank.hh | 60 ++++++++++++-------
milena/mln/accu/rank_bool.hh | 43 ++++++++++----
milena/mln/morpho/rank_filter.hh | 115 ++++++++++++++++++++++++++++--------
milena/tests/accu/rank.cc | 22 ++++----
milena/tests/morpho/Makefile.am | 3 +
milena/tests/morpho/rank_filter.cc | 19 ++----
7 files changed, 197 insertions(+), 82 deletions(-)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 2170ada..d149788 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,3 +1,20 @@
+2008-11-24 Guillaume Lazzara <z(a)lrde.epita.fr>
+
+ Update rank_filter.
+
+ * mln/accu/rank_bool.hh: Add untake() and remove unnecessary
+ attributes.
+
+ * mln/morpho/rank_filter.hh: Add rank_filter_directional. It is used
+ with win::line.
+
+ * mln/accu/rank.hh: update constructor and add untake(accu::rank).
+
+ * tests/accu/rank.cc,
+ * tests/morpho/rank_filter.cc: fix tests.
+
+ * tests/morpho/Makefile.am: add rank_filter test.
+
2008-11-21 Guillaume Lazzara <z(a)lrde.epita.fr>
Add reference files for example outputs used in the tutorial.
diff --git a/milena/mln/accu/rank.hh b/milena/mln/accu/rank.hh
index bdd4df0..bd1999d 100644
--- a/milena/mln/accu/rank.hh
+++ b/milena/mln/accu/rank.hh
@@ -51,16 +51,16 @@ namespace mln
/// Generic rank accumulator class.
- /*!
- * The parameter \c T is the type of values.
- */
+ ///
+ /// The parameter \c T is the type of values.
template <typename T>
struct rank : public mln::accu::internal::base< const T&, rank<T> >
{
typedef T argument;
typedef mln::value::set<T> S;
- rank(unsigned k, unsigned n);
+ rank();
+ explicit rank(unsigned k);
/// Manipulators.
/// \{
@@ -68,6 +68,7 @@ namespace mln
void take(const argument& t);
void take(const rank<T>& other);
void untake(const argument& t);
+ void untake(const rank<T>& other);
/// \}
unsigned card() const { return h_.sum(); }
@@ -82,13 +83,9 @@ namespace mln
/// Give the rank.
unsigned k() const;
- /// Give the total number of elements.
- unsigned n() const;
-
protected:
unsigned k_; // 0 <= k_ < n
- unsigned n_;
mutable accu::histo<T> h_;
const S& s_; // derived from h_
@@ -97,7 +94,7 @@ namespace mln
mutable bool valid_;
mutable unsigned i_; // the median index
- mutable argument t_; // the median value
+ mutable argument t_; // the median value
// Auxiliary methods
void update_() const;
@@ -116,7 +113,7 @@ namespace mln
struct rank : public Meta_Accumulator< rank >
{
- rank(unsigned k_, unsigned n_) : k(k_), n(n_) {}
+ rank(unsigned k_) : k(k_) {}
template <typename T>
struct with
@@ -125,7 +122,6 @@ namespace mln
};
unsigned k;
- unsigned n;
};
} // end of namespace mln::accu::meta
@@ -134,7 +130,7 @@ namespace mln
template <typename T>
rank<T> unmeta(const meta::rank& m, T)
{
- rank<T> a(m.k, m.n);
+ rank<T> a(m.k);
return a;
}
@@ -143,32 +139,32 @@ namespace mln
# ifndef MLN_INCLUDE_ONLY
+
template <typename T>
inline
- rank<T>::rank(unsigned k, unsigned n)
- : k_(k),
- n_(n),
- h_(),
+ rank<T>::rank()
+ : h_(),
s_(h_.vset())
{
- mln_assertion(k_ < n_);
init();
}
template <typename T>
inline
- unsigned
- rank<T>::k() const
+ rank<T>::rank(unsigned k)
+ : k_(k),
+ h_(),
+ s_(h_.vset())
{
- return k_;
+ init();
}
template <typename T>
inline
unsigned
- rank<T>::n() const
+ rank<T>::k() const
{
- return n_;
+ return k_;
}
template <typename T>
@@ -227,6 +223,26 @@ namespace mln
template <typename T>
inline
void
+ rank<T>::untake(const rank<T>& other)
+ {
+ // h_
+ h_.untake(other.h_);
+
+ // sum_minus_
+ for (unsigned i = 0; i < i_; ++i)
+ sum_minus_ -= other.h_[i];
+
+ // sum_plus_
+ for (unsigned i = i_ + 1; i < h_.nvalues(); ++i)
+ sum_plus_ -= other.h_[i];
+
+ if (valid_)
+ valid_ = false;
+ }
+
+ template <typename T>
+ inline
+ void
rank<T>::update_() const
{
valid_ = true;
diff --git a/milena/mln/accu/rank_bool.hh b/milena/mln/accu/rank_bool.hh
index f5e9b07..597e078 100644
--- a/milena/mln/accu/rank_bool.hh
+++ b/milena/mln/accu/rank_bool.hh
@@ -56,7 +56,8 @@ namespace mln
{
typedef bool argument;
- rank(unsigned k, unsigned n);
+ rank();
+ rank(unsigned k);
/// Manipulators.
/// \{
@@ -64,6 +65,8 @@ namespace mln
void take_as_init(const argument& t);
void take(const argument& t);
void take(const rank<bool>& other);
+ void untake(const argument& t);
+ void untake(const rank<bool>& other);
/// \}
/// Get the value of the accumulator.
@@ -75,22 +78,24 @@ namespace mln
protected:
unsigned nfalse_;
- unsigned k_; // 0 <= k_ < n
- unsigned n_;
+ unsigned k_; // 0 <= k_
};
# ifndef MLN_INCLUDE_ONLY
inline
- rank<bool>::rank(unsigned k, unsigned n)
- : k_(k),
- n_(n)
+ rank<bool>::rank()
{
- mln_assertion(k_ < n_);
init();
}
+ inline
+ rank<bool>::rank(unsigned k)
+ : k_(k)
+ {
+ init();
+ }
inline
void
@@ -99,20 +104,28 @@ namespace mln
nfalse_ = 0;
}
-
inline
void rank<bool>::take_as_init(const argument& t)
{
nfalse_ = t ? 0 : 1;
}
-
inline
void rank<bool>::take(const argument& t)
{
- nfalse_ += !t;
+ if (t == false)
+ ++nfalse_;
}
+ inline
+ void rank<bool>::untake(const argument& t)
+ {
+ if (t == false)
+ {
+ mln_assertion(nfalse_ > 0);
+ --nfalse_;
+ }
+ }
inline
void
@@ -121,12 +134,18 @@ namespace mln
nfalse_ += other.nfalse_;
}
+ inline
+ void
+ rank<bool>::untake(const rank<bool>& other)
+ {
+ mln_precondition(other.nfalse_ <= nfalse_);
+ nfalse_ -= other.nfalse_;
+ }
inline
bool
rank<bool>::to_result() const
{
- mln_assertion(nfalse_ <= n_);
return k_ >= nfalse_;
}
@@ -134,7 +153,7 @@ namespace mln
bool
rank<bool>::is_valid() const
{
- return nfalse_ <= n_;
+ return true;
}
# endif // ! MLN_INCLUDE_ONLY
diff --git a/milena/mln/morpho/rank_filter.hh b/milena/mln/morpho/rank_filter.hh
index 94a0a27..eb24567 100644
--- a/milena/mln/morpho/rank_filter.hh
+++ b/milena/mln/morpho/rank_filter.hh
@@ -1,4 +1,4 @@
-// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory (LRDE)
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -28,10 +28,9 @@
#ifndef MLN_MORPHO_RANK_FILTER_HH
# define MLN_MORPHO_RANK_FILTER_HH
-/*! \file mln/morpho/rank_filter.hh
- *
- * \brief Morphological rank_filter.
- */
+/// \file mln/morpho/rank_filter.hh
+///
+/// Morphological rank_filter.
# include <mln/morpho/includes.hh>
# include <mln/convert/to_p_array.hh>
@@ -42,8 +41,7 @@ namespace mln
namespace morpho
{
- /*! Morphological rank_filter.
- */
+ /// Morphological rank_filter.
template <typename I, typename W>
mln_concrete(I)
rank_filter(const Image<I>& input, const Window<W>& win);
@@ -51,47 +49,116 @@ namespace mln
# ifndef MLN_INCLUDE_ONLY
+
+
+ namespace internal
+ {
+
+ template <typename I, typename W>
+ inline
+ void
+ rank_filter_tests(const Image<I>& input_, const Window<W>& win_, unsigned k)
+ {
+ const I& input = exact(input_);
+ const W& win = exact(win_);
+
+ mln_precondition(input.has_data());
+ mln_precondition(! win.is_empty());
+ (void) input;
+ (void) win;
+ (void) k;
+ }
+
+ } // end of namespace mln::morpho::internal
+
+
namespace impl
{
namespace generic
{
- // On function.
-
template <typename I, typename W>
inline
mln_concrete(I)
- rank_filter_(const I& input, const W& win, unsigned k)
+ rank_filter(const Image<I>& input_, const Window<W>& win_, unsigned k)
{
- trace::entering("morpho::impl::generic::rank_filter_");
+ trace::entering("morpho::impl::generic::rank_filter");
+
+ internal::rank_filter_tests(input_, win_, k);
+
+ const I& input = exact(input_);
+ const W& win = exact(win_);
mln_concrete(I) output;
initialize(output, input);
- accu::rank<mln_value(I)> accu(k, convert::to_p_array(win, mln_psite(I)()).nsites());
+ accu::rank<mln_value(I)> accu(k);
+ extension::adjust_fill(input, geom::delta(win) + 1, accu);
mln_piter(I) p(input.domain());
mln_qiter(W) q(win, p);
for_all(p)
- {
- accu.init();
- for_all(q)
- if (input.has(q))
- accu.take(input(q));
-// else
-// accu.take(mln_value(I)(literal::zero));
- output(p) = accu;
- }
-
- trace::exiting("morpho::impl::generic::rank_filter_");
+ {
+ accu.init();
+ for_all(q)
+ if (input.has(q))
+ accu.take(input(q));
+ //else
+ // accu.take(mln_value(I)(literal::zero));
+ output(p) = accu;
+ }
+
+ trace::exiting("morpho::impl::generic::rank_filter");
return output;
}
} // end of namespace mln::morpho::impl::generic
+
+ template <typename I, typename W>
+ inline
+ mln_concrete(I)
+ rank_filter_directional(const Image<I>& input, const Window<W>& win, unsigned k, unsigned dir)
+ {
+ trace::entering("morpho::impl::generic::rank_filter_directional");
+
+ internal::rank_filter_tests(input, win, k);
+
+ accu::rank<mln_value(I)> accu(k);
+ extension::adjust_fill(input, geom::delta(win) + 1, accu);
+ mln_concrete(I) output = accu::transform_directional(accu, input, win, dir);
+
+ trace::exiting("morpho::impl::generic::rank_filter_directional");
+ return output;
+ }
+
} // end of namespace mln::morpho::impl
+ namespace internal
+ {
+
+ template <typename I, typename M, unsigned i, typename C>
+ inline
+ mln_concrete(I)
+ rank_filter_dispatch(const Image<I>& input, const win::line<M, i, C> & win, unsigned k)
+ {
+ return impl::rank_filter_directional(input, win, k, i);
+ }
+
+
+
+ template <typename I, typename W>
+ inline
+ mln_concrete(I)
+ rank_filter_dispatch(const Image<I>& input, const Window<W>& win, unsigned k)
+ {
+ return impl::generic::rank_filter(input, win, k);
+ }
+
+ } // end of namespace mln::morpho::internal
+
+
// Facades.
@@ -104,7 +171,7 @@ namespace mln
mln_precondition(exact(input).has_data());
mln_precondition(! exact(win).is_empty());
- mln_concrete(I) output = impl::generic::rank_filter_(exact(input), exact(win), k);
+ mln_concrete(I) output = internal::rank_filter_dispatch(exact(input), exact(win), k);
trace::exiting("morpho::rank_filter");
return output;
diff --git a/milena/tests/accu/rank.cc b/milena/tests/accu/rank.cc
index 9c334a9..0e9b6c8 100644
--- a/milena/tests/accu/rank.cc
+++ b/milena/tests/accu/rank.cc
@@ -55,55 +55,55 @@ int main()
using value::int_u8;
{
- accu::meta::rank r(4, 9);
+ accu::meta::rank r(4);
accu::rank<int_u8> a = accu::unmeta(r, int_u8());
- mln_assertion(a.k() == 4 && a.n() == 9);
+ mln_assertion(a.k() == 4);
// Meta_Accumulator<accu::meta::rank>& R = r;
// accu::unmeta(R, int_u8());
}
{
- accu::rank<int_u8> accu(0, 8);
+ accu::rank<int_u8> accu(0);
fill(accu);
mln_assertion(accu.to_result() == 1u);
}
{
- accu::rank<int_u8> accu(1, 8);
+ accu::rank<int_u8> accu(1);
fill(accu);
mln_assertion(accu.to_result() == 2u);
}
{
- accu::rank<int_u8> accu(2, 8);
+ accu::rank<int_u8> accu(2);
fill(accu);
mln_assertion(accu.to_result() == 2u);
}
{
- accu::rank<int_u8> accu(3, 8);
+ accu::rank<int_u8> accu(3);
fill(accu);
mln_assertion(accu.to_result() == 3u);
}
{
- accu::rank<int_u8> accu(4, 8);
+ accu::rank<int_u8> accu(4);
fill(accu);
mln_assertion(accu.to_result() == 4u);
}
{
- accu::rank<int_u8> accu(5, 8);
+ accu::rank<int_u8> accu(5);
fill(accu);
mln_assertion(accu.to_result() == 5u);
}
{
- accu::rank<int_u8> accu(6, 8);
+ accu::rank<int_u8> accu(6);
fill(accu);
mln_assertion(accu.to_result() == 5u);
}
{
- accu::rank<int_u8> accu(7, 8);
+ accu::rank<int_u8> accu(7);
fill(accu);
mln_assertion(accu.to_result() == 5u);
}
{
- accu::rank<bool> accu_bool(1, 5);
+ accu::rank<bool> accu_bool(1);
accu_bool.take(true);
accu_bool.take(true);
accu_bool.take(true);
diff --git a/milena/tests/morpho/Makefile.am b/milena/tests/morpho/Makefile.am
index 734aef5..fd5cc00 100644
--- a/milena/tests/morpho/Makefile.am
+++ b/milena/tests/morpho/Makefile.am
@@ -33,6 +33,7 @@ check_PROGRAMS = \
opening_area \
opening_height \
opening_volume \
+ rank_filter \
skeleton_constrained \
thinning
@@ -70,6 +71,8 @@ complex_image_wst_SOURCES = complex_image_wst.cc
meyer_wst_SOURCES = meyer_wst.cc
+rank_filter_SOURCES = rank_filter.cc
+
skeleton_constrained_SOURCES = skeleton_constrained.cc
combined_SOURCES = combined.cc
diff --git a/milena/tests/morpho/rank_filter.cc b/milena/tests/morpho/rank_filter.cc
index 597dccd..9550876 100644
--- a/milena/tests/morpho/rank_filter.cc
+++ b/milena/tests/morpho/rank_filter.cc
@@ -25,16 +25,12 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-/*! \file tests/morpho/rank_filter.cc
- *
- * \brief Test on mln::morpho::rank_filter.
- */
+/// \file tests/morpho/rank_filter.cc
+///
+/// Test on mln::morpho::rank_filter.
#include <mln/core/image/image2d.hh>
#include <mln/win/rectangle2d.hh>
-#include <mln/win/octagon2d.hh>
-#include <mln/win/diag2d.hh>
-#include <mln/win/backdiag2d.hh>
#include <mln/core/alias/window2d.hh>
#include <mln/io/pgm/load.hh>
@@ -52,9 +48,6 @@
#include <mln/pw/cst.hh>
#include <mln/fun/ops.hh>
-#include <mln/convert/to_p_array.hh>
-#include <mln/convert/to_window.hh>
-
#include "tests/data.hh"
@@ -70,23 +63,23 @@ int main()
io::pgm::load(lena, MLN_IMG_DIR "/small.pgm");
{
- win::octagon2d oct(31);
image2d<int_u8> out;
out = morpho::rank_filter(lena, rec, 0);
image2d<int_u8> ref(lena.domain());
ref = morpho::erosion(lena, rec);
+
mln_assertion(ref == out);
}
{
- win::octagon2d oct(31);
image2d<int_u8> out;
- out = morpho::rank_filter(lena, rec, 21 * 21 - 1);
+ out = morpho::rank_filter(lena, rec, 21 * 21);
image2d<int_u8> ref(lena.domain());
ref = morpho::dilation(lena, rec);
+
mln_assertion(ref == out);
}
--
1.5.6.5
1
0
https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox
Index: ChangeLog
from Ugo Jardonnet <ugo.jardonnet(a)lrde.epita.fr>
Start /filtering to n components/ procedure.
* jardonnet/n_cmpt/Makefile (all,debug): New.
* jardonnet/n_cmpt: New.
* jardonnet/n_cmpt/n_cmpt.cc: New. Lauch procedure.
* jardonnet/n_cmpt/check: New.
* jardonnet/n_cmpt/check/tiny.pgm: New test image.
* jardonnet/n_cmpt/check/mg_ima.pgm: New test image.
* jardonnet/n_cmpt/n_cmpt.hh: Modified version of algebraic unionfind.
* jardonnet/igr/check/check: New check script.
igr/Makefile | 24 ++++---
igr/check/check | 10 +++
n_cmpt/Makefile | 5 +
n_cmpt/n_cmpt.cc | 43 +++++++++++++
n_cmpt/n_cmpt.hh | 174 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 247 insertions(+), 9 deletions(-)
Index: jardonnet/n_cmpt/n_cmpt.cc
--- jardonnet/n_cmpt/n_cmpt.cc (revision 0)
+++ jardonnet/n_cmpt/n_cmpt.cc (revision 0)
@@ -0,0 +1,43 @@
+
+#include <iostream>
+
+#include <mln/core/image/image2d.hh>
+#include <mln/core/alias/neighb2d.hh>
+#include <mln/value/int_u8.hh>
+#include <mln/io/pgm/load.hh>
+#include <mln/io/pgm/save.hh>
+
+#include <mln/accu/volume.hh>
+
+#include "n_cmpt.hh"
+
+using namespace mln;
+using namespace mln::value;
+
+bool usage(int argc, char ** argv)
+{
+ if (argc != 3)
+ {
+ std::cout << argv[0] << " ima.pgm lambda" << std::endl;
+ return false;
+ }
+ return true;
+}
+
+int main(int argc, char ** argv)
+{
+ if (not usage(argc,argv))
+ return 1;
+
+ image2d<int_u8> ima;
+ io::pgm::load(ima, argv[1]);
+
+ int lambda = atoi(argv[2]);
+
+ image2d<int_u8> out(ima.domain());
+
+ n_cmpt::algebraic_union_find(ima, c4(), lambda, out);
+
+ io::pgm::save(out, "out.pgm");
+}
+
Index: jardonnet/n_cmpt/Makefile
--- jardonnet/n_cmpt/Makefile (revision 0)
+++ jardonnet/n_cmpt/Makefile (revision 0)
@@ -0,0 +1,5 @@
+n_cmpt: n_cmpt.hh n_cmpt.cc
+ g++ -I../../.. n_cmpt.cc -DNDEBUG -O1 -o n_cmpt
+
+debug: n_cmpt.hh n_cmpt.cc
+ g++ -I../../.. n_cmpt.cc -g -g3 -DNDEBUG -O1 -o n_cmpt
Index: jardonnet/n_cmpt/check/tiny.pgm
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: jardonnet/n_cmpt/check/tiny.pgm
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Index: jardonnet/n_cmpt/check/mg_ima.pgm
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: jardonnet/n_cmpt/check/mg_ima.pgm
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Index: jardonnet/n_cmpt/n_cmpt.hh
--- jardonnet/n_cmpt/n_cmpt.hh (revision 0)
+++ jardonnet/n_cmpt/n_cmpt.hh (revision 0)
@@ -0,0 +1,174 @@
+// 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__N_CMPT_HH
+# define MLN__N_CMPT_HH
+
+# include <mln/core/concept/image.hh>
+# include <mln/core/concept/neighborhood.hh>
+# include <mln/level/fill.hh>
+# include <mln/util/pix.hh>
+# include <mln/level/sort_psites.hh>
+
+namespace mln
+{
+
+ namespace n_cmpt
+ {
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ template <typename I>
+ inline
+ mln_psite(I)
+ find_root(I& parent,
+ const mln_psite(I)& x)
+ {
+ if (parent(x) == x)
+ return x;
+ else
+ return parent(x) = find_root(parent, parent(x));
+ }
+
+ template <typename I, typename N, typename O>
+ void
+ algebraic_union_find(const Image<I>& input_,
+ const Neighborhood<N>& nbh_,
+ unsigned limit,
+ Image<O>& output_)
+ {
+ trace::entering("canvas::morpho::algebraic_union_find");
+
+ std::cout << "limit = " << limit << std::endl;
+
+
+ const I& input = exact(input_);
+ const N& nbh = exact(nbh_);
+ O& output = exact(output_);
+
+ mln_precondition(output.domain() == input.domain());
+
+ // Local type.
+ typedef mln_psite(I) P;
+
+ typedef accu::volume<I> A;
+ typedef mln_psite(I) P;
+ typedef p_array<P> S;
+
+ const S s(level::sort_psites_increasing(input));
+
+ // Auxiliary data.
+ mln_ch_value(O, bool) deja_vu;
+ mln_ch_value(O, P) parent;
+
+ int n_cmpt = input.domain().nsites();
+ int lambda = 10;
+ std::cout << "trying lambda = 10" << std::endl;
+
+ // init
+ {
+ initialize(deja_vu, input);
+ initialize(parent, input);
+ }
+
+ // first pass
+ {
+
+ do {
+ mln_ch_value(O, A) data;
+ initialize(data, input);
+
+ mln::level::fill(deja_vu, false);
+
+ {
+ mln_fwd_piter(S) p(s);
+ for_all(p)
+ parent(p) = p;
+ }
+
+ mln_fwd_piter(S) p(s); // s required.
+ mln_niter(N) n(nbh, p);
+ for_all(p)
+ {
+ // Make set.
+ {
+ data(p).take_as_init(make::pix(input, p)); // FIXME: algebraic so p!
+ }
+
+ for_all(n)
+ if (input.domain().has(n) && deja_vu(n))
+ {
+ //do_union(n, p);
+ P r = find_root(parent, n);
+ if (r != p)
+ {
+ if (input(r) == input(p) || (data(p).to_result() < lambda))
+ // Either a flat zone or the component of r is still growing.
+ {
+ data(p).take(data(r));
+ parent(r) = p;
+ if(--n_cmpt <= limit)
+ {
+ std::cout << "limit reached at " << n_cmpt << std::endl;
+ goto step2;
+ }
+ }
+ else
+ data(p).set_value(lambda);
+ }
+ }
+ deja_vu(p) = true;
+ }
+ n_cmpt = input.domain().nsites();
+ lambda *= 1.1;
+ std::cout << "trying lambda = " << lambda << std::endl;
+ }while (1);
+ }
+
+ step2:
+ // second pass
+ {
+ mln_bkd_piter(S) p(s);
+ for_all(p)
+ if (parent(p) == p) // p is root.
+ output(p) = input(p);
+ else
+ output(p) = output(parent(p));
+ }
+
+ trace::exiting("canvas::morpho::algebraic_union_find");
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::n_cmpt
+
+} // end of namespace mln
+
+#endif /* MLN__N_CMPT_HH */
+
Index: jardonnet/igr/Makefile
--- jardonnet/igr/Makefile (revision 2941)
+++ jardonnet/igr/Makefile (working copy)
@@ -2,18 +2,20 @@
## Author: ugo.jardonnet(a)lrde.epita.fr
## Version: $Id: Makefile,v 0.0 2008/11/19 11:40:34 jardonnet Exp $
-## Keywords:
-## X-URL:
+## Keywords: IGR OLENA LRDE RECONSTRUCTION
+
+
+CXXC?=g++
+LFLAGS=-I../../abraham/ -I../../../
+CFLAGS=-W -Wall -Wextra -O1 -DNDEBUG
PROJ=igr-reco
SRC=src/igr.cc
BIN=igr
-LFLAGS=-I../../abraham/ -I../../../
-CFLAGS=-W -Wall -Wextra -O1 -DNDEBUG
FILES=src configure check README
$(BIN): Makefile
- g++ $(CFLAGS) $(LFLAGS) $(SRC) -o $(BIN)
+ $(CXXC) $(CFLAGS) $(LFLAGS) $(SRC) -o $(BIN)
check:
cd check && ./check
@@ -23,7 +25,7 @@
rm -f .deps .depsr
rm -f *.ppm
-dist: clean todo AUTHORS svn_check
+dist: clean AUTHORS TODO svn_check
rm -rf $(PROJ)
mkdir $(PROJ)
cp -r Makefile AUTHORS TODO $(FILES) $(PROJ)
@@ -34,21 +36,25 @@
rm -rf $(PROJ)
chmod 644 $(PROJ).tar.bz2
+AUTHORS:
+ echo $(USER) > AUTHORS
+
svn_check:
@svn st | grep \? ; [ $$? = "1" ] \
|| (echo "----------------------------------------------"\
&& echo "SOME FILES ARE MISSING FROM THE SVN REPOSITORY"\
&& echo "----------------------------------------------");
-todo:
- grep "FIXME" -r . --exclude="Makefile" > TODO
+TODO:
+ grep "FIXME" -r . --exclude="Makefile" --exclude-dir=".svn" \
+ --exclude="TODO" > TODO
.deps:
g++ $(LFLAGS) -MM $(SRC) > $@
@sed -ir s/igr.cc// .deps
@sed -ir s/igr.o/igr/ .deps
-.PHONY: doc check .deps
+.PHONY: doc check .deps AUTHORS TODO
include .deps
Index: jardonnet/igr/check/check
--- jardonnet/igr/check/check (revision 0)
+++ jardonnet/igr/check/check (revision 0)
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+
+for i in `seq 10000 1000 50000`
+do
+ ../igr ./tiny.ppm $i
+ mv out.ppm out/$i.ppm
+done
+
+rm g_ima.ppm mg_ima.ppm o_ima.ppm
\ No newline at end of file
Property changes on: jardonnet/igr/check/check
___________________________________________________________________
Name: svn:executable
+ *
1
0
21 Nov '08
* doc/doc.mk: add new path variables.
* doc/tutorial/figures/ima2d-rot-1.ppm
* doc/tutorial/figures/ima2d-rot-2.ppm
* doc/tutorial/outputs/borderthickness.txt
* doc/tutorial/outputs/dpoint-1.txt
* doc/tutorial/outputs/graph-data-full.txt
* doc/tutorial/outputs/ima-has.txt
* doc/tutorial/outputs/ima-size.txt
* doc/tutorial/outputs/ima2d-1.txt
* doc/tutorial/outputs/ima2d-decl-2-blobs-full.txt
* doc/tutorial/outputs/ima2d-rot.txt
* doc/tutorial/outputs/labeling-compute-full.txt
* doc/tutorial/outputs/logical-not.txt
* doc/tutorial/outputs/paste-call-1.txt
* doc/tutorial/outputs/point-1.txt: reference files.
* doc/tutorial/samples/Makefile.am: diff the generated files to their
reference.
---
milena/ChangeLog | 24 ++++++++
milena/doc/doc.mk | 10 +++-
milena/doc/tutorial/figures/ima2d-rot-1.ppm | Bin 0 -> 235320 bytes
milena/doc/tutorial/figures/ima2d-rot-2.ppm | Bin 0 -> 235320 bytes
milena/doc/tutorial/outputs/borderthickness.txt | 16 ++++++
milena/doc/tutorial/outputs/dpoint-1.txt | 1 +
milena/doc/tutorial/outputs/graph-data-full.txt | 5 ++
milena/doc/tutorial/outputs/ima-has.txt | 7 +++
milena/doc/tutorial/outputs/ima-size.txt | 1 +
milena/doc/tutorial/outputs/ima2d-1.txt | 2 +
.../tutorial/outputs/ima2d-decl-2-blobs-full.txt | 7 +++
.../doc/tutorial/outputs/labeling-compute-full.txt | 3 +
milena/doc/tutorial/outputs/logical-not.txt | 18 ++++++
milena/doc/tutorial/outputs/paste-call-1.txt | 4 ++
milena/doc/tutorial/outputs/point-1.txt | 2 +
milena/doc/tutorial/samples/Makefile.am | 58 +++++++++++++++++---
16 files changed, 147 insertions(+), 11 deletions(-)
create mode 100644 milena/doc/tutorial/figures/ima2d-rot-1.ppm
create mode 100644 milena/doc/tutorial/figures/ima2d-rot-2.ppm
create mode 100644 milena/doc/tutorial/outputs/borderthickness.txt
create mode 100644 milena/doc/tutorial/outputs/dpoint-1.txt
create mode 100644 milena/doc/tutorial/outputs/graph-data-full.txt
create mode 100644 milena/doc/tutorial/outputs/ima-has.txt
create mode 100644 milena/doc/tutorial/outputs/ima-size.txt
create mode 100644 milena/doc/tutorial/outputs/ima2d-1.txt
create mode 100644 milena/doc/tutorial/outputs/ima2d-decl-2-blobs-full.txt
create mode 100644 milena/doc/tutorial/outputs/ima2d-rot.txt
create mode 100644 milena/doc/tutorial/outputs/labeling-compute-full.txt
create mode 100644 milena/doc/tutorial/outputs/logical-not.txt
create mode 100644 milena/doc/tutorial/outputs/paste-call-1.txt
create mode 100644 milena/doc/tutorial/outputs/point-1.txt
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 7669b73..2170ada 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,3 +1,27 @@
+2008-11-21 Guillaume Lazzara <z(a)lrde.epita.fr>
+
+ Add reference files for example outputs used in the tutorial.
+
+ * doc/doc.mk: add new path variables.
+
+ * doc/tutorial/figures/ima2d-rot-1.ppm
+ * doc/tutorial/figures/ima2d-rot-2.ppm
+ * doc/tutorial/outputs/borderthickness.txt
+ * doc/tutorial/outputs/dpoint-1.txt
+ * doc/tutorial/outputs/graph-data-full.txt
+ * doc/tutorial/outputs/ima-has.txt
+ * doc/tutorial/outputs/ima-size.txt
+ * doc/tutorial/outputs/ima2d-1.txt
+ * doc/tutorial/outputs/ima2d-decl-2-blobs-full.txt
+ * doc/tutorial/outputs/ima2d-rot.txt
+ * doc/tutorial/outputs/labeling-compute-full.txt
+ * doc/tutorial/outputs/logical-not.txt
+ * doc/tutorial/outputs/paste-call-1.txt
+ * doc/tutorial/outputs/point-1.txt: reference files.
+
+ * doc/tutorial/samples/Makefile.am: diff the generated files to their
+ reference.
+
2008-11-21 Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Add some reference code in morpho tree.
diff --git a/milena/doc/doc.mk b/milena/doc/doc.mk
index d911d86..3311139 100644
--- a/milena/doc/doc.mk
+++ b/milena/doc/doc.mk
@@ -2,6 +2,12 @@
include $(top_srcdir)/milena/tests/tests.mk
-OUTPUTS_DIR = $(top_builddir)/milena/doc/tutorial/outputs
-FIGURES_DIR = $(top_builddir)/milena/doc/tutorial/figures
+TUTORIAL_SRCDIR = $(top_srcdir)/milena/doc/tutorial
+OUTPUTS_SRCDIR = $(TUTORIAL_SRCDIR)/outputs
+FIGURES_SRCDIR = $(TUTORIAL_SRCDIR)/figures
+
+TUTORIAL_BUILDDIR = $(top_builddir)/milena/doc/tutorial
+OUTPUTS_BUILDDIR = $(TUTORIAL_BUILDDIR)/outputs
+FIGURES_BUILDDIR = $(TUTORIAL_BUILDDIR)/figures
+
diff --git a/milena/doc/tutorial/figures/ima2d-rot-1.ppm b/milena/doc/tutorial/figures/ima2d-rot-1.ppm
new file mode 100644
index 0000000000000000000000000000000000000000..512ff99db8f5f207b30561a082499c471cd8116d
GIT binary patch
literal 235320
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
X5FkK+009C72oNAZfB*pk|3lzEi5B~u
literal 0
HcmV?d00001
diff --git a/milena/doc/tutorial/figures/ima2d-rot-2.ppm b/milena/doc/tutorial/figures/ima2d-rot-2.ppm
new file mode 100644
index 0000000000000000000000000000000000000000..c46713d24fdf6898ab821f6945fcab91780063de
GIT binary patch
literal 235320
zcmeI5+iDy~6h-~)uNcTn@*+D1hmf~`O$az(OnyL)C)nV~MiBvjy;JIzW=7+gzEqv6
zI=gCt0%J$&KE2LfwMUARy#DF&cbng~SKI5$o9(;J+b^3xK78C>U2cB7c)HoVzq$GR
z%abRcZhz<E<Mq4k#rE@uo6C#8uftcpeEs{Mzi!@a|J`0*|Mh-zdG&7dV*B6r<EPL6
zY_D!MuP)zy3K#u!{blq0t2ZxR{_yzO&rdhuugA}xKY#r7>mxoO009U<00Izz00bZa
z0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z
z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=
z5P$##AOHafKmY;|fB*y_a7*A39}sXxK=J>sGI+%Q6$S!M2;3g*vL1!uHK$i3&dgH;
z@CXwjkWN6@qi{U%?oRT}#MHr_9_cDqz@sYIxoKkrv^}Dd=p!El@Tjqak;kb*K;9!N
z$;W|QCB1%b+KflxLHtl<lHLfk;1QKXCDkU-l1EfhZ!O^Gc^mPFN~(Pz`-yawNgDHr
zN~)3~ZrYAVR1%d`k3dr%p;EmdbzVt$)Oi4Sd=mn#c|;{qNi_)Ik;!qyMLH+Yphr|v
zjRP5vB&kpTA)w*kOA1Fs=gZ~sixFtEkEkTc!!fK)^`mW%s3hHFYE9m(M^uvR*{)^K
zIBoMDQAvuil$*I_kEkRnsT6_6Jwl~YL6U0_+kx@OmM2&1lR*0(QAt!%egb&Z=lRJ~
z+Y;!)BPuEXfovN~xvO>MQFvIn1u?J$fnGeKlBlGd1bXv`N|HF<<%aCYBPuE9fh?DN
z+krduh)S}J5LXKX`tpcMqLT6u=*}Zl$`ho{TM3Uk4*-vELZC;Fs3a=MngAY|97kNF
za{`@uL?u}t$ao}4H2n|w@ZS`YTzohIJ%04tM^uu_K>E~Vb}Bpy1ZFAm2@sej(6vWY
z5|v~`0FQ17P)SB{nm)7}{=2<<L?vO61pz#|rAQ@NWU1l0nSC@o!lT)c@Cma7@aXO&
zrjn?n1Oj+;=ux0Cd-CuJ5crk=9_<eyDrwImeACFs3Icev&&%Kum4rbN1n_9@5kI(l
zz+%N|91*<6z66gRWQR(6fCH7562PP5;P742F_EQNYOG>bJq{inr-n*8CW1%v1n}rY
zYN(_WQ0B9=>Hu%-lkw<uWKiie7i>CB0FO@R1&>a1Ih~@$$|d4)@aSw_Q0XihY&s@@
zM`yz_cog_VoKAd6Zv^n@tViL<p^~QP9G}U(xpVlucr=w1Drt%i9_<O>(M(dPq!~c_
zEFGTDy}ibxnV3*XGl1~umH-~j$An6nXVkk*c(f=ZsI&-Ezc%5~qJZGhB20Ls_I+Up
zcHyO=QfcCa7o2oE`e<o7@MtNiq(BxwA8n?^qZR2ur4_Jj@~NT~9<7MR;87r^vRvjY
zMgWgicodFUDrp_BURnu{*5!gqTE`2IidACNjVivkqLNVQ8v^vvH%R8Zrjk}8YrmE7
zC?*tCQVg}0ZNj6-M4(b6xHfIVqsTbmQ6xA#n)}9~B%u)FlD9i~FI1|(gOiJ?@SF5e
zd=~I1o?V5gXFYlGC@Bl5l!UJxoA4+p2!ls~Vb-&bi~A>lM@b%q1C>fjCD=kM;ZbS|
zsH9YacvP=%UA>c{lDb!kJ~D^^m1F=>yOr?BCIVEF4M$a*@W^ccsAPsx&n7%FTRt9{
zp~Rz7KY0kDbqE`kJZ_~#Q0ODe&Et_J%@X;yI*#$kc=M=a3{=A=JThMU;8CDzb<lAg
z2?BUz>`^#AsU&-*-dhQe>~~Hj*)zqXJhklneG`?`nM(9gmW5MES+M$TB|OTta4IPm
zS&ug1QO0efQbxGGY{H|AtHz^@aPi3ECl4W_zCfOt2bDDTlo}@bDDR%}C@<gC{GU1g
zR$ms6vhNv{vLjv{dn<i**TJLgOCCH5oOjH5(H;Rj%I;A(EUBatlxwyU9+lWIl~jT<
z9<A?rxpzraQqwBYM}^i)B^3f)r<L%i+<K{`a;!_+ghxepi%Latm$M0viY^w9isHtj
zxt~0QK$e4KdM{K`-P}~*=%dnG#iP>1r}A%gMB-6}t)fx|=y`3zqY5h>JPPEk4nwX}
zod6zH@F*OOR8k%8xmpR2>g<zBs>2<R9#(e)?}@0ShE$@Dsx6aBs)pXamGG$MGO47R
z^et_|qsp5^rOFGiu?deVuMv+bF944o{^Y@iM~!QulD<mxQT-j_QT-jHp2B$KVuz^Y
zVh!;&;gO344jzSF)OcGNA0DRN5x^rC9)&DZNnSP)bFko%m+etWUN(V8yPDN}K_zLb
zG`^RRoW05KB&Z~{Eba{w4W#JUvu_y&l{DLQ_Su^HguOxIV~GY*bnGQjLM7j=bZihF
zElG9x&%q<F9-TG_kIFl;@Q$eDOr<G<@MvMG%YPakdGcspqL7fVvhq1ezoY2b%O4z-
z9OQD5LE}zE11UQ8N{_-GHIKRF&*}6tR~UpxPIq{(4wY1+l2#jpM+zQMN%zM}_H9KP
zgh$yolN<pmsYoRy8H7h79#Kij=h4)r4I~Pe7yU+7bnK~po(T(;l&z9%3>tST8c5Nx
zBRm?<I(~3xYLlfwcodiF@?S+I*-2z?5FV8`BKnS~l&n%NgYYOi)#bksj}kn}YY-ll
z*CFMOs1&7A35mj5!*)`ZTkC5@$4<dDcog=fxv-QckNny~2948+u0?e0$VA+$GpKa`
zi^OZS{N+Ur!XvpT4IWWR6DLUpgYZbsqcAX)bmsezY6jtvtVdMRVI@^I2#*v!3Nuql
z2bJVPqH!sTaSB;d9NTJURQekB@9C$_qJb108;>lGKVJroI~5J2=-5^sh3f<Y{r$5f
zj|Sn9VXDhtYVfEZmHZlnN9DtBd&fR1>CPbM??9Z7cP@CMW1oARxZfW<YP*uW*U)Zp
zqJb10dxzcX#h_A?Kf9DMXk4XeAVtTv(r0&_!K211Nz5QT+NDwYMMIS&X%HSs>vK4~
zzDmLd;n86frC%$1bZ1a_1oagt&aaN$oVlh-@-?*Eqi7&S$KGK#f1&14I|hxb6b+>4
z*yj2iUQk4()(pa<!w@#`dhjTu)a`c~Z5o6}4Y+gk2wp3xWrOhOD1;6C(qARr8RWMl
zjoMrE0Y%3ypz5HKQ8-e^ZNG+gghT@=I`$5Gz88Z>A;5K2>d2sRm6dtNZd-KheEJ+-
zc~B{q?BRuCUUz5E2uU=MqGQJdGfIdWDs^fQ9u-S<`5Tq>sB44psC>Lj-m!>EcLwqH
zK$L*!*ll@44ekGIt!N-c$1dqnxL2T*=LdHfv^Qwnsc0ZY$FAX#tx6blY!Dt5PIZ;r
z*;Nt-oi+%Mssy|6O$Uz>D+z<948o(rk*;;Sgi5+Ih<DMmyAwquI`-^3a(u$zQA8zC
zL-RGX+m~n{MaSM@FZ^OqY55<Fz@QZdjjI$5r0Cd%^*OxVGL<lBwLy4v7_;VI&v}GF
zkp|&W^X?oy;2D)LD9Io^I*M8IzdYp;5*bJok`ve}=0|kw>ZlJ?!XV4!iw073Y#$zB
zkflN6PDKMLI(BuB!T_Mlu?118qGRXSAlLLjKs1n|V|&;*Gvpv38c5Nxb8L`ndLSSg
zNYSx9Y@8W#5D*Qd=-4?n$Td9>5Dld0*d8{{3^@ph22ynF92?}C9temAQgmz&8)t?b
z1VjTVI(Ci?a!n5eL<1>0wug-~Lk<F>ffOA(#|F8k2Lhsj6dl{c#+e}p0ntE;j-6wJ
zT+;&q(Ljoh?P250kb{6|AVtT{u|clsfq-ZrMaTBAac0OtKs1n|W9Qf)*YrR@G?1cW
zd)PQL<RBm#NYSx#Y>;buARrn@(Xl;joEdTu5Dld0*f}=HH9Zgz4W#JU9yZPlIS7ab
zQgrMb8|0cE2#5w!bZieBXNDXEL<1>0c8(2lO%DV_0~yBV0|KrHc+i;{AOHafKmY;|
zfB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<
z00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa
b0SG_<0uX=z1Rwwb2tWV=5P$##91!>)W)sP>
literal 0
HcmV?d00001
diff --git a/milena/doc/tutorial/outputs/borderthickness.txt b/milena/doc/tutorial/outputs/borderthickness.txt
new file mode 100644
index 0000000..94f4df7
--- /dev/null
+++ b/milena/doc/tutorial/outputs/borderthickness.txt
@@ -0,0 +1,16 @@
+- - - - - - - - -
+- - - - - - - - -
+- - - - - - - - -
+- - - - | | - - -
+- - - | - - - - -
+- - - | | - - - -
+- - - - - - - - -
+- - - - - - - - -
+- - - - - - - - -
+
+===========
+
+- | |
+| - -
+| | -
+
diff --git a/milena/doc/tutorial/outputs/dpoint-1.txt b/milena/doc/tutorial/outputs/dpoint-1.txt
new file mode 100644
index 0000000..8982f0f
--- /dev/null
+++ b/milena/doc/tutorial/outputs/dpoint-1.txt
@@ -0,0 +1 @@
+(0, 1)
diff --git a/milena/doc/tutorial/outputs/graph-data-full.txt b/milena/doc/tutorial/outputs/graph-data-full.txt
new file mode 100644
index 0000000..6bfffae
--- /dev/null
+++ b/milena/doc/tutorial/outputs/graph-data-full.txt
@@ -0,0 +1,5 @@
+graph_vertices_ima((0, 0)) = 10
+graph_vertices_ima((2, 2)) = 11
+graph_vertices_ima((0, 4)) = 12
+graph_vertices_ima((4, 3)) = 13
+graph_vertices_ima((4, 4)) = 14
diff --git a/milena/doc/tutorial/outputs/ima-has.txt b/milena/doc/tutorial/outputs/ima-has.txt
new file mode 100644
index 0000000..598cd04
--- /dev/null
+++ b/milena/doc/tutorial/outputs/ima-has.txt
@@ -0,0 +1,7 @@
+ima1.has(0, 0) : 1
+ima1.has(-3, 0) : 1
+ima1.has(2, 5) : 1
+=========
+ima2.has(0, 0) : 1
+ima2.has(-3, 0) : 0
+ima2.has(2, 5) : 0
diff --git a/milena/doc/tutorial/outputs/ima-size.txt b/milena/doc/tutorial/outputs/ima-size.txt
new file mode 100644
index 0000000..333c6f9
--- /dev/null
+++ b/milena/doc/tutorial/outputs/ima-size.txt
@@ -0,0 +1 @@
+nrows = 11 - ncols = 13
diff --git a/milena/doc/tutorial/outputs/ima2d-1.txt b/milena/doc/tutorial/outputs/ima2d-1.txt
new file mode 100644
index 0000000..2a65d2f
--- /dev/null
+++ b/milena/doc/tutorial/outputs/ima2d-1.txt
@@ -0,0 +1,2 @@
+b = [(-2, -3)..(3, 5)]
+domain = [(-2, -3)..(3, 5)]
diff --git a/milena/doc/tutorial/outputs/ima2d-decl-2-blobs-full.txt b/milena/doc/tutorial/outputs/ima2d-decl-2-blobs-full.txt
new file mode 100644
index 0000000..b48c715
--- /dev/null
+++ b/milena/doc/tutorial/outputs/ima2d-decl-2-blobs-full.txt
@@ -0,0 +1,7 @@
+0 1 1 0 0
+0 1 1 0 0
+0 0 0 0 0
+2 2 0 3 0
+2 0 3 3 3
+2 0 0 0 0
+
diff --git a/milena/doc/tutorial/outputs/ima2d-rot.txt b/milena/doc/tutorial/outputs/ima2d-rot.txt
new file mode 100644
index 0000000..e69de29
diff --git a/milena/doc/tutorial/outputs/labeling-compute-full.txt b/milena/doc/tutorial/outputs/labeling-compute-full.txt
new file mode 100644
index 0000000..174807d
--- /dev/null
+++ b/milena/doc/tutorial/outputs/labeling-compute-full.txt
@@ -0,0 +1,3 @@
+[(0, 1)..(1, 2)]
+[(3, 0)..(5, 1)]
+[(3, 2)..(4, 4)]
diff --git a/milena/doc/tutorial/outputs/logical-not.txt b/milena/doc/tutorial/outputs/logical-not.txt
new file mode 100644
index 0000000..42391a7
--- /dev/null
+++ b/milena/doc/tutorial/outputs/logical-not.txt
@@ -0,0 +1,18 @@
+ima:
+| -
+- |
+
+----
+ima_neg:
+- |
+| -
+
+ima:
+| -
+- |
+
+----
+not_inplace(ima)
+- |
+| -
+
diff --git a/milena/doc/tutorial/outputs/paste-call-1.txt b/milena/doc/tutorial/outputs/paste-call-1.txt
new file mode 100644
index 0000000..a09b521
--- /dev/null
+++ b/milena/doc/tutorial/outputs/paste-call-1.txt
@@ -0,0 +1,4 @@
+b b b b
+b b b b
+b b b b
+
diff --git a/milena/doc/tutorial/outputs/point-1.txt b/milena/doc/tutorial/outputs/point-1.txt
new file mode 100644
index 0000000..39f77d0
--- /dev/null
+++ b/milena/doc/tutorial/outputs/point-1.txt
@@ -0,0 +1,2 @@
+has(p1)? false
+has(p2)? true
diff --git a/milena/doc/tutorial/samples/Makefile.am b/milena/doc/tutorial/samples/Makefile.am
index dcbf13c..43a5877 100644
--- a/milena/doc/tutorial/samples/Makefile.am
+++ b/milena/doc/tutorial/samples/Makefile.am
@@ -5,6 +5,7 @@ include $(top_srcdir)/milena/doc/doc.mk
bin_PROGRAMS = \
borderthickness \
dpoint-1 \
+ graph-data-full \
ima-has \
ima-size \
ima2d-1 \
@@ -17,6 +18,7 @@ bin_PROGRAMS = \
borderthickness_SOURCES = borderthickness.cc
dpoint_1_SOURCES = dpoint-1.cc
+graph_data_full_SOURCES = graph-data-full.cc
ima_has_SOURCES = ima-has.cc
ima_size_SOURCES = ima-size.cc
ima2d_1_SOURCES = ima2d-1.cc
@@ -27,15 +29,53 @@ logical_not_SOURCES = logical-not.cc
paste_call_1_SOURCES = paste-call-1.cc
point_1_SOURCES = point-1.cc
-all:
- mkdir -p $(OUTPUTS_DIR)
- mkdir -p $(FIGURES_DIR)
- @failcom='exit 1'; \
- list='$(bin_PROGRAMS)'; for bin in $$list; do \
- echo "Running $$bin"; \
- ./$$bin > $(OUTPUTS_DIR)/$$bin.txt || eval $$failcom; \
- done;
+all: clean-png-figures
+ mkdir -p $(OUTPUTS_BUILDDIR)
+ mkdir -p $(FIGURES_BUILDDIR)
+ @failcom='exit 1'; \
+ list='$(bin_PROGRAMS)'; for bin in $$list; do \
+ echo "Running $$bin"; \
+ ./$$bin > $(OUTPUTS_BUILDDIR)/$$bin.txt || eval $$failcom; \
+ done; \
+ has_txt_diff=""; \
+ txtlist="$(OUTPUTS_BUILDDIR)/*"; for txt in $$txtlist; do \
+ echo "Diff `basename $$txt`"; \
+ diff $$txt $(OUTPUTS_SRCDIR)/`basename $$txt` >/dev/null 2>&1 \
+ || has_txt_diff+=" `basename $$txt`"; \
+ done; \
+ has_fig_diff=""; \
+ figlist="$(FIGURES_BUILDDIR)/*"; for fig in $$figlist; do \
+ echo "Diff `basename $$fig`"; \
+ diff $$fig $(FIGURES_SRCDIR)/`basename $$fig` >/dev/null 2>&1 \
+ || has_fig_diff=" `basename $$fig`"; \
+ done; \
+ (test -z "$$has_txt_diff" && test -z "$$has_fig_diff") \
+ || (echo "--------"; \
+ echo "ERROR: please check if the tutorial needs an update.";\
+ echo " The following files differ from their \
+reference or their reference file does not exist:"; \
+ echo "--------"; \
+ echo "* Outputs:"; \
+ echo ""; \
+ echo "$$has_txt_diff"; \
+ echo ""; \
+ echo "--------"; \
+ echo "* Figures:"; \
+ echo ""; \
+ echo "$$has_fig_diff"; \
+ echo ""; \
+ echo "--------"; \
+ echo "* Please update the reference files located in:"; \
+ echo ""; \
+ echo " $(OUTPUTS_SRCDIR)"; \
+ echo " $(FIGURES_SRCDIR)"; \
+ echo ""; \
+ eval $$failcom);
+
clean-local:
- rm -Rf $(OUTPUTS_DIR) $(FIGURES_DIR)
+ rm -Rf $(OUTPUTS_BUILDDIR) $(FIGURES_BUILDDIR)
+## Clean up converted images. (*.p*m -> *.png)
+clean-png-figures:
+ rm -f $(FIGURES_BUILDDIR)/*.png
--
1.5.6.5
1
0
* bootstrap: Add missings functions.
---
ChangeLog | 6 ++++++
bootstrap | 28 +++++++++++++++++++++++++---
milena/ChangeLog | 2 +-
3 files changed, 32 insertions(+), 4 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index e385329..dc72c90 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
2008-11-20 Guillaume Lazzara <z(a)lrde.epita.fr>
+ Fix bootstrap.
+
+ * bootstrap: Add missings functions.
+
+2008-11-20 Guillaume Lazzara <z(a)lrde.epita.fr>
+
Generate unit test files on bootstrap.
* bootstrap: generate unit test files.
diff --git a/bootstrap b/bootstrap
index 75befde..575c158 100755
--- a/bootstrap
+++ b/bootstrap
@@ -7,6 +7,11 @@ fatal ()
exit 1
}
+stderr ()
+{
+ echo >&2 "$0: $@"
+}
+
awk_strverscmp='
# Use only awk features that work with 7th edition Unix awk (1978).
# My, what an old awk you have, Mr. Solaris!
@@ -87,6 +92,23 @@ require ()
esac
}
+# run DIRECTORY COMMAND-LINE
+# --------------------------
+# "set -e" doesn't work for subshells!
+run ()
+{
+ (
+ stderr "$@"
+ cd "$1"
+ shift
+ if ! "$@"; then
+ fatal "unexpected failure: $@"
+ exit 1
+ fi
+ )
+}
+
+
# Failures do matter.
set -e
@@ -94,11 +116,11 @@ set -e
require autoconf 2.59
require automake 1.9.4
+# Generate unit test files.
+run milena/tests/unit_test ./build_unit_test.sh
+
# Tell what's going on.
set -x
-# Generate unit test files.
-run milena/tests/unit_tests build_unit_test.sh
-
# Install the GNU Build System.
autoreconf -f -v -i
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 2c59824..7669b73 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -23,7 +23,7 @@
* tests/morpho/Makefile.am: Update.
* mln/canvas/morpho/all.hh: Upgrade doc style.
-2008-11-20 Guillaume Lazzara <z(a)lrde.epita.fr>
+2008-11-21 Guillaume Lazzara <z(a)lrde.epita.fr>
Add new from_to overloads.
--
1.5.6.5
1
0
https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Add some reference code in morpho tree.
* mln/morpho/tree/compute_parent.hh: Add doc.
* mln/morpho/tree/max.hh: New.
* mln/morpho/tree/all.hh: New.
* mln/morpho/tree/utils.hh: New.
* mln/morpho/all.hh: Update.
* tests/morpho/tree/max.cc: New.
* tests/morpho/tree/Makefile.am: Update.
mln/morpho/all.hh | 12 ++-
mln/morpho/tree/all.hh | 55 ++++++++++++++
mln/morpho/tree/compute_parent.hh | 18 ++++
mln/morpho/tree/max.hh | 91 ++++++++++++++++++++++++
mln/morpho/tree/utils.hh | 141 ++++++++++++++++++++++++++++++++++++++
tests/morpho/tree/Makefile.am | 5 -
tests/morpho/tree/max.cc | 73 +++++++++++++++++++
7 files changed, 386 insertions(+), 9 deletions(-)
Index: tests/morpho/tree/Makefile.am
--- tests/morpho/tree/Makefile.am (revision 2938)
+++ tests/morpho/tree/Makefile.am (working copy)
@@ -3,9 +3,10 @@
include $(top_srcdir)/milena/tests/tests.mk
check_PROGRAMS = \
- compute_tree
-
+ compute_tree \
+ max
compute_tree_SOURCES = compute_tree_.cc
+max_SOURCES = max_.cc
TESTS = $(check_PROGRAMS)
Index: tests/morpho/tree/max.cc
--- tests/morpho/tree/max.cc (revision 0)
+++ tests/morpho/tree/max.cc (revision 0)
@@ -0,0 +1,73 @@
+// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+/// \file tests/morpho/tree/max.cc
+///
+/// Tests on mln::morpho::tree::max.
+
+#include <mln/core/image/image2d.hh>
+#include <mln/core/alias/neighb2d.hh>
+#include <mln/pw/image.hh>
+
+#include <mln/debug/println.hh>
+#include <mln/debug/iota.hh>
+#include <mln/morpho/elementary/dilation.hh>
+
+#include <mln/morpho/tree/utils.hh>
+#include <mln/morpho/tree/max.hh>
+
+
+int main()
+{
+ using namespace mln;
+
+ image2d<unsigned> ima(3, 3);
+ debug::iota(ima);
+
+ ima = morpho::elementary::dilation(ima, c8());
+ debug::println(ima);
+
+ image2d<point2d> par = morpho::tree::max(ima, c4());
+ debug::println(par);
+
+
+// using morpho::tree::is_root;
+// using morpho::tree::is_a_node;
+
+// mln_piter_(box2d) p(ima.domain());
+// for_all(p)
+// if (is_root(par, p, ima))
+// std::cout << "R ";
+// else if (is_a_node(par, p, ima))
+// std::cout << "n ";
+// else
+// std::cout << ". ";
+// std::cout << std::endl;
+
+ p_array<point2d> s = level::sort_psites_increasing(ima);
+ std::cout << morpho::tree::nodes(par, ima, s) << std::endl;
+}
Index: mln/morpho/tree/compute_parent.hh
--- mln/morpho/tree/compute_parent.hh (revision 2938)
+++ mln/morpho/tree/compute_parent.hh (working copy)
@@ -49,9 +49,21 @@
namespace tree
{
- // Remember:
- // p is root iff parent(p) == p
- // p is node iff either p is root or f(parent(p)) != f(p)
+ /// Compute a tree with a parent relationship between sites.
+ ///
+ /// Warning: \p s translates the ordering related to the
+ /// "natural" childhood relationship. The parenthood is thus
+ /// inverted w.r.t. to \p s.
+ ///
+ /// It is very convenient since all processing upon the parent
+ /// tree are performed following \p s (in the default "forward"
+ /// way).
+ ///
+ /// FIXME: Put it more clearly...
+ ///
+ /// The parent result image verifies: \n
+ /// - p is root iff parent(p) == p \n
+ /// - p is a node iff either p is root or f(parent(p)) != f(p).
template <typename I, typename N, typename S>
mln_ch_value(I, mln_psite(I))
Index: mln/morpho/tree/max.hh
--- mln/morpho/tree/max.hh (revision 0)
+++ mln/morpho/tree/max.hh (revision 0)
@@ -0,0 +1,91 @@
+// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef MLN_MORPHO_TREE_MAX_HH
+# define MLN_MORPHO_TREE_MAX_HH
+
+/// \file mln/morpho/tree/max.hh
+///
+/// Compute a canonized (parenthood) max-tree from an image.
+
+# include <mln/morpho/tree/compute_parent.hh>
+# include <mln/level/sort_psites.hh>
+
+
+namespace mln
+{
+
+ namespace morpho
+ {
+
+ namespace tree
+ {
+
+ // Remember:
+ // p is root iff parent(p) == p
+ // p is node iff either p is root or f(parent(p)) != f(p)
+
+ template <typename I, typename N>
+ mln_ch_value(I, mln_psite(I))
+ max(const Image<I>& f, const Neighborhood<N>& nbh);
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ template <typename I, typename N>
+ inline
+ mln_ch_value(I, mln_psite(I))
+ max(const Image<I>& f_, const Neighborhood<N>& nbh_)
+ {
+ trace::entering("morpho::tree::max");
+
+ const I& f = exact(f_);
+ const N& nbh = exact(nbh_);
+
+ mln_precondition(f.has_data());
+ // mln_precondition(nbh.is_valid());
+
+ // For the max-tree, childhood maps "increasing level":
+ p_array<mln_psite(I)> s = level::sort_psites_increasing(f);
+ mln_ch_value(I, mln_psite(I)) output = compute_parent(f, nbh, s);
+
+ trace::exiting("morpho::tree::max");
+ return output;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::morpho::tree
+
+ } // end of namespace mln::morpho
+
+} // end of namespace mln
+
+
+#endif // ! MLN_MORPHO_TREE_MAX_HH
Index: mln/morpho/tree/all.hh
--- mln/morpho/tree/all.hh (revision 0)
+++ mln/morpho/tree/all.hh (revision 0)
@@ -0,0 +1,55 @@
+// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef MLN_MORPHO_TREE_ALL_HH
+# define MLN_MORPHO_TREE_ALL_HH
+
+/// \file mln/morpho/tree/all.hh
+///
+/// File that includes all morphological tree-related routines.
+
+
+namespace mln
+{
+ namespace morpho
+ {
+
+ /// Namespace of morphological tree-related routines.
+ namespace tree
+ {}
+
+ }
+}
+
+
+# include <mln/morpho/tree/compute_parent.hh>
+# include <mln/morpho/tree/max.hh>
+# include <mln/morpho/tree/utils.hh>
+
+
+
+#endif // ! MLN_MORPHO_TREE_ALL_HH
Index: mln/morpho/tree/utils.hh
--- mln/morpho/tree/utils.hh (revision 0)
+++ mln/morpho/tree/utils.hh (revision 0)
@@ -0,0 +1,141 @@
+// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef MLN_MORPHO_TREE_UTILS_HH
+# define MLN_MORPHO_TREE_UTILS_HH
+
+/// \file mln/morpho/tree/utils.hh
+///
+/// Utilities.
+
+# include <mln/core/concept/image.hh>
+# include <mln/core/site_set/p_array.hh>
+
+
+namespace mln
+{
+
+ namespace morpho
+ {
+
+ namespace tree
+ {
+
+ template <typename T, typename I>
+ bool
+ is_root(const Image<T>& parent, const mln_psite(T)& p,
+ const Image<I>& f);
+
+
+ template <typename T, typename I>
+ bool
+ is_a_node(const Image<T>& parent, const mln_psite(T)& p,
+ const Image<I>& f);
+
+
+
+ template <typename T, typename I, typename S>
+ p_array<mln_psite(T)>
+ nodes(const Image<T>& parent, const Image<I>& f, const Site_Set<S>& s);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ template <typename T, typename I>
+ inline
+ bool
+ is_root(const Image<T>& parent_, const mln_psite(T)& p,
+ const Image<I>& f_)
+ {
+ mlc_equal(mln_value(T), mln_psite(T))::check();
+
+ const T& parent = exact(parent_);
+ const I& f = exact(f_);
+
+ mln_precondition(parent.has_data());
+ mln_precondition(f.has_data());
+ mln_precondition(parent.domain() == f.domain());
+
+ return parent(p) == p;
+ }
+
+
+ template <typename T, typename I>
+ inline
+ bool
+ is_a_node(const Image<T>& parent_, const mln_psite(T)& p,
+ const Image<I>& f_)
+ {
+ mlc_equal(mln_value(T), mln_psite(T))::check();
+
+ const T& parent = exact(parent_);
+ const I& f = exact(f_);
+
+ mln_precondition(parent.has_data());
+ mln_precondition(f.has_data());
+ mln_precondition(parent.domain() == f.domain());
+
+ return parent(p) == p || f(parent(p)) != f(p);
+ }
+
+
+ template <typename T, typename I, typename S>
+ inline
+ p_array<mln_psite(T)>
+ nodes(const Image<T>& parent_, const Image<I>& f_, const Site_Set<S>& s_)
+ {
+ mlc_equal(mln_value(T), mln_psite(T))::check();
+
+ const T& parent = exact(parent_);
+ const I& f = exact(f_);
+ const S& s = exact(s_);
+
+ mln_precondition(parent.has_data());
+ mln_precondition(f.has_data());
+ mln_precondition(f.domain() == parent.domain());
+ mln_precondition(s == f.domain());
+
+ p_array<mln_psite(T)> arr;
+ mln_bkd_piter(S) p(exact(s));
+ for_all(p)
+ if (is_a_node(parent, p, f))
+ arr.insert(p);
+
+ return arr;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::morpho::tree
+
+ } // end of namespace mln::morpho
+
+} // end of namespace mln
+
+
+#endif // ! MLN_MORPHO_TREE_MAX_HH
Index: mln/morpho/all.hh
--- mln/morpho/all.hh (revision 2938)
+++ mln/morpho/all.hh (working copy)
@@ -1,4 +1,5 @@
// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
+// (LRDE)
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -28,10 +29,9 @@
#ifndef MLN_MORPHO_ALL_HH
# define MLN_MORPHO_ALL_HH
-/*! \file mln/morpho/all.hh
- *
- * \brief File that includes all morpho-related routines.
- */
+/// \file mln/morpho/all.hh
+///
+/// File that includes all morpho-related routines.
namespace mln
@@ -82,7 +82,11 @@
# include <mln/morpho/thinning.hh>
# include <mln/morpho/top_hat.hh>
+
+// Sub-directories.
+
# include <mln/morpho/elementary/all.hh>
+# include <mln/morpho/tree/all.hh>
1
0