Olena-patches
Threads by month
- ----- 2025 -----
- 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
October 2009
- 7 participants
- 111 discussions

[PATCH 1/7] Include headers missing from mln/world/inter_pixel/compute.hh.
by Roland Levillain 19 Oct '09
by Roland Levillain 19 Oct '09
19 Oct '09
* mln/world/inter_pixel/compute.hh: Include
mln/core/image/dmorph/image_if.hh and mln/trait/ch_value.hh.
---
milena/ChangeLog | 7 +++++++
milena/mln/world/inter_pixel/compute.hh | 4 ++++
2 files changed, 11 insertions(+), 0 deletions(-)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 58b58ff..eb1d50a 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,3 +1,10 @@
+2009-09-23 Roland Levillain <roland(a)lrde.epita.fr>
+
+ Include headers missing from mln/world/inter_pixel/compute.hh.
+
+ * mln/world/inter_pixel/compute.hh: Include
+ mln/core/image/dmorph/image_if.hh and mln/trait/ch_value.hh.
+
2009-09-24 Roland Levillain <roland(a)lrde.epita.fr>
Improve the integration of the topological watershed transform.
diff --git a/milena/mln/world/inter_pixel/compute.hh b/milena/mln/world/inter_pixel/compute.hh
index 35a94e2..0d7ad12 100644
--- a/milena/mln/world/inter_pixel/compute.hh
+++ b/milena/mln/world/inter_pixel/compute.hh
@@ -32,6 +32,10 @@
# include <mln/core/concept/image.hh>
# include <mln/core/concept/function.hh>
+
+# include <mln/core/image/dmorph/image_if.hh>
+# include <mln/trait/ch_value.hh>
+
# include <mln/world/inter_pixel/is_separator.hh>
# include <mln/world/inter_pixel/separator_to_pixels.hh>
--
1.6.4.4
1
0
* mln/world/inter_pixel/neighb2d.hh
(mln::world::inter_pixel::c2c)
(mln::world::inter_pixel::c2e)
(mln::world::inter_pixel::e2c):
Rename as...
(mln::world::inter_pixel::v2v)
(mln::world::inter_pixel::v2e)
(mln::world::inter_pixel::e2v):
...this.
* mln/world/inter_pixel/dim2/make_edge_image.hh
(mln::world::inter_pixel::dim2::make_edge_image): Adjust.
---
milena/ChangeLog | 16 ++++++++++
.../mln/world/inter_pixel/dim2/make_edge_image.hh | 2 +-
milena/mln/world/inter_pixel/neighb2d.hh | 31 ++++++++++---------
3 files changed, 33 insertions(+), 16 deletions(-)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 1d88171..c3cf6b5 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,3 +1,19 @@
+2009-09-24 Roland Levillain <roland(a)lrde.epita.fr>
+
+ Rename 2D inter-pixel neighborhoods.
+
+ * mln/world/inter_pixel/neighb2d.hh
+ (mln::world::inter_pixel::c2c)
+ (mln::world::inter_pixel::c2e)
+ (mln::world::inter_pixel::e2c):
+ Rename as...
+ (mln::world::inter_pixel::v2v)
+ (mln::world::inter_pixel::v2e)
+ (mln::world::inter_pixel::e2v):
+ ...this.
+ * mln/world/inter_pixel/dim2/make_edge_image.hh
+ (mln::world::inter_pixel::dim2::make_edge_image): Adjust.
+
2009-09-23 Roland Levillain <roland(a)lrde.epita.fr>
Complete mln/world/inter_pixel/neighb2d.hh.
diff --git a/milena/mln/world/inter_pixel/dim2/make_edge_image.hh b/milena/mln/world/inter_pixel/dim2/make_edge_image.hh
index 21e6bf8..8012b60 100644
--- a/milena/mln/world/inter_pixel/dim2/make_edge_image.hh
+++ b/milena/mln/world/inter_pixel/dim2/make_edge_image.hh
@@ -68,7 +68,7 @@ namespace mln
edges_ext_t edges_ext = extend(edges, input);
mln_piter(edges_ext_t) p(edges_ext.domain());
- dbl_neighb2d nbh = e2c();
+ dbl_neighb2d nbh = e2v();
mln_niter(dbl_neighb2d) n(nbh, p);
mln_value(I) vs[2];
diff --git a/milena/mln/world/inter_pixel/neighb2d.hh b/milena/mln/world/inter_pixel/neighb2d.hh
index 048eb9b..d262c3e 100644
--- a/milena/mln/world/inter_pixel/neighb2d.hh
+++ b/milena/mln/world/inter_pixel/neighb2d.hh
@@ -27,8 +27,7 @@
# define MLN_WORLD_INTER_PIXEL_NEIGHB2D_HH
/// \file
-///
-/// \brief Common neighborhood on inter-pixel images.
+/// \brief Common neighborhoods on inter-pixel images.
# include <mln/core/alias/neighb2d.hh>
# include <mln/make/double_neighb2d.hh>
@@ -47,22 +46,24 @@ namespace mln
/// Double neighborhood used for inter-pixel images.
typedef neighb< win::multiple<window2d, dim2::is_row_odd> > dbl_neighb2d;
- // Pixel to neighboring pixels.
- const neighb2d& c2c();
- // Pixel to neighboring edges.
- const neighb2d& c2e();
+ /// Vertex (pixel) to neighboring vertices (pixels).
+ const neighb2d& v2v();
- // Edge to neighborhood pixels.
- const dbl_neighb2d& e2c();
+ /// Vertex (pixel) to neighboring edges (inter-pixels).
+ const neighb2d& v2e();
- // Edge to neighboring edges.
+ /// Edge (inter-pixel) to neighborhood vertices (pixels).
+ const dbl_neighb2d& e2v();
+
+ /// Edge (inter-pixel) to neighboring edges (inter-pixels).
const dbl_neighb2d& e2e();
+
# ifndef MLN_INCLUDE_ONLY
- const neighb2d& c2c()
+ const neighb2d& v2v()
{
static neighb2d it;
if (it.size() == 0)
@@ -77,23 +78,23 @@ namespace mln
return it;
}
- const neighb2d& c2e()
+ const neighb2d& v2e()
{
return c4();
}
- const dbl_neighb2d& e2c()
+ const dbl_neighb2d& e2v()
{
- static const bool e2c_h[] = { 0, 1, 0,
+ static const bool e2v_h[] = { 0, 1, 0,
0, 0, 0,
0, 1, 0 };
- static const bool e2c_v[] = { 0, 0, 0,
+ static const bool e2v_v[] = { 0, 0, 0,
1, 0, 1,
0, 0, 0 };
static dbl_neighb2d nbh =
- make::double_neighb2d(dim2::is_row_odd(), e2c_h, e2c_v);
+ make::double_neighb2d(dim2::is_row_odd(), e2v_h, e2v_v);
return nbh;
}
--
1.6.4.4
1
0
* mln/world/inter_pixel/neighb2d.hh
(mln::world::inter_pixel::c2c, mln::world::inter_pixel::c2e):
New functions.
---
milena/ChangeLog | 8 ++++++++
milena/mln/world/inter_pixel/neighb2d.hh | 26 ++++++++++++++++++++++++++
2 files changed, 34 insertions(+), 0 deletions(-)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index db4d604..1d88171 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,5 +1,13 @@
2009-09-23 Roland Levillain <roland(a)lrde.epita.fr>
+ Complete mln/world/inter_pixel/neighb2d.hh.
+
+ * mln/world/inter_pixel/neighb2d.hh
+ (mln::world::inter_pixel::c2c, mln::world::inter_pixel::c2e):
+ New functions.
+
+2009-09-23 Roland Levillain <roland(a)lrde.epita.fr>
+
Fix documentation in mln/world/inter_pixel/neighb2d.hh.
* mln/world/inter_pixel/neighb2d.hh
diff --git a/milena/mln/world/inter_pixel/neighb2d.hh b/milena/mln/world/inter_pixel/neighb2d.hh
index 21233ef..048eb9b 100644
--- a/milena/mln/world/inter_pixel/neighb2d.hh
+++ b/milena/mln/world/inter_pixel/neighb2d.hh
@@ -47,6 +47,12 @@ namespace mln
/// Double neighborhood used for inter-pixel images.
typedef neighb< win::multiple<window2d, dim2::is_row_odd> > dbl_neighb2d;
+ // Pixel to neighboring pixels.
+ const neighb2d& c2c();
+
+ // Pixel to neighboring edges.
+ const neighb2d& c2e();
+
// Edge to neighborhood pixels.
const dbl_neighb2d& e2c();
@@ -56,6 +62,26 @@ namespace mln
# ifndef MLN_INCLUDE_ONLY
+ const neighb2d& c2c()
+ {
+ static neighb2d it;
+ if (it.size() == 0)
+ {
+ static const bool vals[] = { 0, 0, 1, 0, 0,
+ 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 1,
+ 0, 0, 0, 0, 0,
+ 0, 0, 1, 0, 0 };
+ convert::from_to(vals, it);
+ }
+ return it;
+ }
+
+ const neighb2d& c2e()
+ {
+ return c4();
+ }
+
const dbl_neighb2d& e2c()
{
static const bool e2c_h[] = { 0, 1, 0,
--
1.6.4.4
1
0
URL: https://svn.lrde.epita.fr/svn/oln/trunk
ChangeLog:
2009-10-16 Edwin Carlinet <carlinet(a)lrde.epita.fr>
Update configure.ac with AVS IO tests Makefile.
* configure.ac: Update.
---
configure.ac | 1 +
1 file changed, 1 insertion(+)
Index: trunk/configure.ac
===================================================================
--- trunk/configure.ac (revision 4637)
+++ trunk/configure.ac (revision 4638)
@@ -320,6 +320,7 @@
milena/tests/io/dicom/Makefile
milena/tests/io/dump/Makefile
milena/tests/io/fits/Makefile
+ milena/tests/io/fld/Makefile
milena/tests/io/magick/Makefile
milena/tests/io/off/Makefile
milena/tests/io/pbm/Makefile
1
0
URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena
ChangeLog:
2009-10-16 Edwin Carlinet <carlinet(a)lrde.epita.fr>
Add AVS field file support.
* mln/io/all.hh: Update.
* mln/io/fld/all.hh: New.
* mln/io/fld/header.hh: New.
* mln/io/fld/load.hh: New.
* mln/io/fld/load_header.hh: New.
* mln/io/fld/max_components.hh: New.
* mln/io/fld/save.hh: New.
* mln/io/fld/write_header.hh: New.
* mln/io/fld: New.
* tests/io/Makefile.am: Add rules.
* tests/io/fld/Makefile.am: New.
* tests/io/fld/fld1d.cc: New.
* tests/io/fld/fld2d.cc: New.
* tests/io/fld/fld3d.cc: New.
* tests/io/fld: New.
---
mln/io/all.hh | 1
mln/io/fld/all.hh | 49 ++++++++
mln/io/fld/header.hh | 94 ++++++++++++++++
mln/io/fld/load.hh | 242 +++++++++++++++++++++++++++++++++++++++++++
mln/io/fld/load_header.hh | 220 +++++++++++++++++++++++++++++++++++++++
mln/io/fld/max_components.hh | 102 ++++++++++++++++++
mln/io/fld/save.hh | 173 ++++++++++++++++++++++++++++++
mln/io/fld/write_header.hh | 129 ++++++++++++++++++++++
tests/io/Makefile.am | 3
tests/io/fld/Makefile.am | 31 +++++
tests/io/fld/fld1d.cc | 57 ++++++++++
tests/io/fld/fld2d.cc | 108 +++++++++++++++++++
tests/io/fld/fld3d.cc | 59 ++++++++++
13 files changed, 1267 insertions(+), 1 deletion(-)
Index: trunk/milena/mln/io/fld/write_header.hh
===================================================================
--- trunk/milena/mln/io/fld/write_header.hh (revision 0)
+++ trunk/milena/mln/io/fld/write_header.hh (revision 4637)
@@ -0,0 +1,129 @@
+// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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_IO_FLD_WRITE_HEADER_HH
+# define MLN_IO_FLD_WRITE_HEADER_HH
+
+///
+/// \brief Write AVS headers in a file.
+///
+///
+///
+
+
+# include <mln/io/fld/header.hh>
+# include <iostream>
+
+namespace mln
+{
+
+ namespace io
+ {
+
+ namespace fld
+ {
+ /// Write the AVS header in a file.
+ ///
+ /// \param file The file to write.
+ /// \param h The AVS header.
+ ///
+ void write_header(std::ostream& file, const fld_header& h);
+
+# ifndef MLN_INCLUDE_ONLY
+
+ inline
+ void
+ write_header(std::ostream& file, const fld_header& h)
+ {
+ file << "# AVS field file" << std::endl;
+ file << "# Generated by Milena 1.0 http://olena.lrde.epita.fr" << std::endl;
+ file << "# EPITA Research and Development Laboratory (LRDE)" << std::endl;
+
+ file << "ndim=" << h.ndim << std::endl;
+ for (int i = 0; i < h.ndim; i++)
+ file << "dim" << (i + 1) << "=" << h.dim[i] << std::endl;
+ file << "nspace=" << h.nspace << std::endl
+ << "veclen=" << h.veclen << std::endl;
+
+ switch (h.data)
+ {
+ case data_type::BYTE :
+ file << "data=byte" << std::endl;
+ break;
+ case data_type::SHORT :
+ file << "data=short" << std::endl;
+ break;
+ case data_type::INTEGER :
+ file << "data=integer" << std::endl;
+ break;
+ case data_type::FLOAT :
+ file << "data=float" << std::endl;
+ break;
+ case data_type::DOUBLE :
+ file << "data=double" << std::endl;
+ break;
+ default:
+ std::cerr << "Data type not supported: abort().";
+ abort();
+ }
+
+ switch (h.field)
+ {
+ case field_type::UNIFORM :
+ file << "field=uniform" << std::endl;
+ break;
+ case field_type::IRREGULAR :
+ file << "field=irregular" << std::endl;
+ break;
+ case field_type::RECTILINEAR :
+ file << "field=rectilinear" << std::endl;
+ break;
+ default:
+ std::cerr << "Field type not suported: abort().";
+ abort();
+ }
+
+ file << "min_ext=";
+ for (int i = 0; i < h.nspace; i++)
+ file << h.min_ext[i] << " ";
+ file << std::endl;
+
+ file << "max_ext=";
+ for (int i = 0; i < h.nspace; i++)
+ file << h.max_ext[i] << " ";
+ file << std::endl;
+
+ file << "\f\f";
+ }
+
+#endif // !MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::io::fld
+
+ } // end of namespace mln::io
+
+} // end of namespace mln
+
+#endif // !MLN_IO_FLD_WRITE_HEADER_HH
Index: trunk/milena/mln/io/fld/load_header.hh
===================================================================
--- trunk/milena/mln/io/fld/load_header.hh (revision 0)
+++ trunk/milena/mln/io/fld/load_header.hh (revision 4637)
@@ -0,0 +1,220 @@
+// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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_IO_FLD_LOAD_HEADER_HH
+# define MLN_IO_FLD_LOAD_HEADER_HH
+
+///
+/// \brief Read AVS header from a file.
+///
+///
+
+# include <mln/io/fld/header.hh>
+# include <cstdlib>
+# include <locale>
+# include <iostream>
+# include <sstream>
+# include <string>
+
+namespace mln
+{
+
+ namespace io
+ {
+
+ namespace fld
+ {
+
+ /// Read the header form an AVS field file.
+ ///
+ /// \param ins The file to read.
+ ///
+ /// \return The header.
+ ///
+ fld_header read_header(std::istream& ins);
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace internal
+ {
+ void
+ abort_fld_reader(const char* msg, unsigned line = 0)
+ {
+ std::cerr << "AVS field file reader: " << msg << " on line " << line << std::endl;
+ abort();
+ }
+
+ }
+
+ inline
+ fld_header
+ read_header(std::istream& file)
+ {
+ std::stringstream ins;
+ std::string line_str, lhs, rhs;
+ fld_header header;
+ unsigned line;
+
+ std::getline(file, line_str);
+ line = 1;
+ if (line_str.compare(0, 5, "# AVS"))
+ internal::abort_fld_reader("Invalid format", line);
+
+ while (file.good() && file.peek() != '\f')
+ {
+ std::getline(file, line_str);
+ ++line;
+
+ ins.clear();
+ ins.str(line_str);
+ rhs.clear();
+ lhs.clear();
+
+ { // Parse the line
+ char c = ins.get();
+ while (isspace(c))
+ ins.get(c);
+ if (c == '#') // Comments
+ continue;
+ while (isalnum(c) || c == '_')
+ {
+ lhs.push_back(c);
+ ins.get(c);
+ }
+ while (isspace(c))
+ ins.get(c);
+ if (c != '=')
+ internal::abort_fld_reader("Parse error", line);
+ while (isspace(ins.peek()))
+ ins.ignore();
+ }
+
+ if (lhs == "ndim")
+ {
+ ins >> header.ndim;
+ if (header.ndim < 1)
+ internal::abort_fld_reader("Invalid dimension", line);
+ header.dim = new int[header.ndim];
+ std::fill(header.dim, header.dim + header.ndim, -1);
+ }
+ else if (lhs.compare(0, 3, "dim") == 0)
+ {
+ std::stringstream ss(lhs.substr(3));
+ int dim;
+ ss >> dim;
+ if (dim < 1 || dim > header.ndim)
+ internal::abort_fld_reader("Invalid dimension", line);
+ if (!ss.eof())
+ internal::abort_fld_reader("Parse error", line);
+ ins >> header.dim[dim - 1];
+ if (header.dim[dim - 1] < 1)
+ internal::abort_fld_reader("Invalid dimension", line);
+ }
+ else if (lhs == "nspace")
+ {
+ ins >> header.nspace;
+ if (header.nspace < 1)
+ internal::abort_fld_reader("Invalid space dimension", line);
+ header.min_ext = new float[header.nspace];
+ header.max_ext = new float[header.nspace];
+ }
+ else if (lhs == "veclen")
+ {
+ ins >> header.veclen;
+ if (header.veclen == -1)
+ internal::abort_fld_reader("Invalid vector length", line);
+ }
+ else if (lhs == "data")
+ {
+ ins >> rhs;
+ if (rhs == "byte")
+ header.data = data_type::BYTE;
+ else if (rhs == "short")
+ header.data = data_type::SHORT;
+ else if (rhs == "integer")
+ header.data = data_type::INTEGER;
+ else if (rhs == "float")
+ header.data = data_type::FLOAT;
+ else if (rhs == "double")
+ header.data = data_type::DOUBLE;
+ else
+ internal::abort_fld_reader("Invalid data type", line);
+ }
+ else if (lhs == "field")
+ {
+ ins >> rhs;
+ if (rhs != "uniform")
+ internal::abort_fld_reader("Unhandled field type", line);
+ header.field = field_type::UNIFORM;
+ }
+ else if (lhs == "min_ext")
+ {
+ for (int i = 0; i < header.ndim; ++i)
+ {
+ ins >> header.min_ext[i];
+ if (ins.peek() == ',')
+ ins.ignore();
+ }
+ }
+ else if (lhs == "max_ext")
+ {
+ for (int i = 0; i < header.ndim; ++i)
+ {
+ ins >> header.max_ext[i];
+ if (ins.peek() == ',')
+ ins.ignore();
+ }
+ }
+ else
+ internal::abort_fld_reader("Parse error", line);
+
+ rhs.clear();
+ ins >> rhs;
+ if (!rhs.empty() && rhs[0] != '#')
+ internal::abort_fld_reader("Parse error", line);
+ }
+
+ file.ignore();
+ if (file.get() != '\f')
+ internal::abort_fld_reader("Parse error", line);
+
+ if (header.ndim == -1 || header.nspace == -1 || header.veclen == -1 ||
+ header.data == data_type::UNKNOWN || header.field == field_type::UNKNOWN)
+ internal::abort_fld_reader("Invalid format", line);
+ for (int i = 0; i < header.ndim; ++i)
+ if (header.dim[i] == -1)
+ internal::abort_fld_reader("Invalid format", line);
+ return header;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::io::fld
+
+ } // end of namespace mln::io
+
+} // end of namespace mln
+
+#endif // !MLN_IO_FLD_LOAD_HEADER_HH
Index: trunk/milena/mln/io/fld/all.hh
===================================================================
--- trunk/milena/mln/io/fld/all.hh (revision 0)
+++ trunk/milena/mln/io/fld/all.hh (revision 4637)
@@ -0,0 +1,49 @@
+// Copyright (C) 2007, 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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_IO_FLD_ALL_HH
+# define MLN_IO_FLD_ALL_HH
+
+/// \file
+/// \brief Inclusion of all AVS field file I/O routines.
+
+
+namespace mln
+{
+
+ namespace io
+ {
+ /// Namespace of pgm input/output handling.
+ namespace fld {}
+ }
+
+}
+
+# include <mln/io/fld/load_header.hh>
+# include <mln/io/fld/write_header.hh>
+# include <mln/io/fld/load.hh>
+# include <mln/io/fld/save.hh>
+
+#endif // ! MLN_IO_FLD_ALL_HH
Index: trunk/milena/mln/io/fld/header.hh
===================================================================
--- trunk/milena/mln/io/fld/header.hh (revision 0)
+++ trunk/milena/mln/io/fld/header.hh (revision 4637)
@@ -0,0 +1,94 @@
+// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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_IO_FLD_HEADER_HH
+# define MLN_IO_FLD_HEADER_HH
+
+namespace mln
+{
+
+ namespace io
+ {
+
+ namespace fld
+ {
+
+
+ struct data_type { enum E { UNKNOWN, BYTE, SHORT, INTEGER, FLOAT, DOUBLE }; };
+ struct field_type { enum E { UNKNOWN, UNIFORM, RECTILINEAR, IRREGULAR }; };
+
+ ///
+ /// \brief Define the header structure of an AVS field data file.
+ ///
+ struct fld_header
+ {
+ int ndim; // The number of computational dimensions in the field.
+ int* dim; // The dimension size of each axis.
+ int nspace; // The number of physical coordinates per field element.
+ int veclen; // The number of data values for each field element.
+ data_type::E data; // The primitive data type of all the data values.
+ field_type::E field; // The field type.
+ float* min_ext; // The minimum coordinate value that any member data point occupies in space.
+ float* max_ext; // The maximum coordinate value that any member data point occupies in space.
+ // std::vector<std::string> label; // Not handled.
+ // std::vector<std::string> unit; // Not handled.
+ // void* min_val; // The minimum data value in the field. (Not used)
+ // void* max_val; // The maximum data value in the field. (Not used)
+ // struct {...} variable; // Not handled.
+ // struct {...} coord; // Not handled.
+
+ fld_header();
+ ~fld_header();
+ };
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ fld_header::fld_header()
+ : ndim (-1),
+ dim (0),
+ nspace (-1),
+ veclen (-1),
+ data (data_type::UNKNOWN),
+ field (field_type::UNKNOWN)
+ {
+ }
+
+ fld_header::~fld_header()
+ {
+ delete [] dim;
+ delete [] max_ext;
+ delete [] min_ext;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::io::fld
+
+ } // end of namespace mln::io
+
+} // end of namespace mln
+
+#endif // !MLN_IO_FLD_HEADER_HH
Index: trunk/milena/mln/io/fld/max_components.hh
===================================================================
--- trunk/milena/mln/io/fld/max_components.hh (revision 0)
+++ trunk/milena/mln/io/fld/max_components.hh (revision 4637)
@@ -0,0 +1,102 @@
+// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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_IO_FLD_MAX_COMPONENTS_HH
+# define MLN_IO_FLD_MAX_COMPONENTS_HH
+
+# include <mln/algebra/vec.hh>
+# include <mln/value/rgb.hh>
+# include <mln/io/fld/header.hh>
+
+namespace mln
+{
+
+ namespace io
+ {
+
+ namespace fld
+ {
+
+ template <typename V>
+ inline
+ unsigned int max_component(const V&);
+
+ template <unsigned n, typename V>
+ inline
+ unsigned int max_component(const algebra::vec<n, V>& v);
+
+ template <unsigned n>
+ inline
+ unsigned int max_component(const value::rgb<n>&);
+
+ inline
+ unsigned int max_component(const fld::data_type::E& t);
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename V>
+ inline
+ unsigned int max_component(const V&)
+ {
+ return mln_max(V);
+ }
+
+
+ template <unsigned n, typename V>
+ inline
+ unsigned int max_component(const algebra::vec<n, V>& v)
+ {
+ return mln_max(V);
+ }
+
+ template <unsigned n>
+ inline
+ unsigned int max_component(const value::rgb<n>&)
+ {
+ return mln_max(mln::value::int_u<n>);
+ }
+
+ inline
+ unsigned int max_component(const fld::data_type::E& t)
+ {
+ switch (t)
+ {
+ case data_type::BYTE: return mln_max(unsigned char);
+ case data_type::SHORT: return mln_max(unsigned short);
+ case data_type::INTEGER: return mln_max(unsigned);
+ case data_type::FLOAT: return mln_max(float);
+ case data_type::DOUBLE: return mln_max(double);
+ default: return 0;
+ }
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+ }
+
+ }
+
+}
+
+#endif // !MLN_IO_FLD_MAX_COMPONENTS_HH
Index: trunk/milena/mln/io/fld/save.hh
===================================================================
--- trunk/milena/mln/io/fld/save.hh (revision 0)
+++ trunk/milena/mln/io/fld/save.hh (revision 4637)
@@ -0,0 +1,173 @@
+// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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_IO_FLD_SAVE_HH
+# define MLN_IO_FLD_SAVE_HH
+/// \file
+/// \brief Save an image to AVS field file format.
+///
+/// \todo Handle not high speed images.
+
+# include <mln/core/concept/image.hh>
+# include <mln/core/concept/gpoint.hh>
+# include <mln/io/fld/header.hh>
+# include <mln/io/fld/write_header.hh>
+# include <mln/io/fld/max_components.hh>
+
+# include <mln/algebra/vec.hh>
+
+# include <mln/geom/nsites.hh>
+# include <fstream>
+# include <iostream>
+
+namespace mln
+{
+
+ namespace io
+ {
+
+ namespace fld
+ {
+
+ template <typename I>
+ void save(const Image<I>& ima_, const char* filename);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace internal
+ {
+ template <typename I>
+ inline
+ void save_data_contiguous(std::ofstream& file, const I& ima)
+ {
+ typedef mln_site(I) P;
+ typedef mln_value(I) V;
+ enum { dim = P::dim };
+
+ P pmin = ima.domain().pmin();
+ P pmax = ima.domain().pmax();
+
+ std::size_t len = pmax[dim - 1] - pmin[dim - 1] + 1;
+ std::size_t n = len * sizeof(V);
+ P p = pmin;
+ if (dim == 1)
+ {
+ file.write((char*)(&ima(p)), n);
+ return;
+ }
+
+ while (true)
+ {
+ file.write((char*)(&ima(p)), n);
+ ++p[dim - 2];
+
+ for (int i = dim - 2; p[i] > pmax[i]; --i)
+ {
+ if (i == 0)
+ return;
+ p[i] = pmin[i];
+ ++p[i - 1];
+ }
+ }
+ }
+
+ template <typename I>
+ inline
+ fld::fld_header make_header(const I& ima)
+ {
+ fld_header hdr;
+ typedef mln_site(I) P;
+ typedef mln_value(I) V;
+ enum { dim = P::dim };
+
+ hdr.ndim = dim;
+ hdr.nspace = dim;
+ hdr.veclen = mln_dim(V);
+ hdr.dim = new int[dim];
+ hdr.min_ext = new float[dim];
+ hdr.max_ext = new float[dim];
+
+ box<P> bbox = geom::bbox(ima);
+ P pmin = bbox.pmin();
+ P pmax = bbox.pmax();
+
+ for (unsigned i = 0; i < dim; i++)
+ {
+ hdr.dim[i] = pmax[i] - pmin[i] + 1;
+ hdr.min_ext[i] = pmin[i];
+ hdr.max_ext[i] = pmax[i];
+ }
+
+ unsigned max_c = max_component(V ());
+ if (max_c == max_component(data_type::BYTE))
+ hdr.data = data_type::BYTE;
+ else if (max_c == max_component(data_type::SHORT))
+ hdr.data = data_type::SHORT;
+ else if (max_c == max_component(data_type::INTEGER))
+ hdr.data = data_type::INTEGER;
+ else if (max_c == max_component(data_type::FLOAT))
+ hdr.data = data_type::FLOAT;
+ else if (max_c == max_component(data_type::DOUBLE))
+ hdr.data = data_type::DOUBLE;
+ else
+ hdr.data = data_type::UNKNOWN;
+
+ hdr.field = field_type::UNIFORM;
+
+ return hdr;
+ }
+
+ } // end of namespace mln::io::fld::internal
+
+ template <typename I>
+ void save(const Image<I>& ima_, const char* filename)
+ {
+ trace::entering("mln::io::fld::save");
+ // For the moment, just the fast version.
+ mlc_is(mln_trait_image_speed(I), trait::image::speed::fastest)::check();
+
+ const I& ima = exact(ima_);
+ mln_precondition(ima.is_valid());
+
+ std::ofstream file(filename);
+ fld_header hdr = internal::make_header(ima);
+
+ write_header(file, hdr);
+ internal::save_data_contiguous(file, ima);
+
+ file.close();
+ trace::exiting("mln::io::fld::save");
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::io::fld
+
+ } // end of namespace mln::io
+
+} // end of namespace mln
+#endif // !MLN_IO_FLD_SAVE_HH
Index: trunk/milena/mln/io/fld/load.hh
===================================================================
--- trunk/milena/mln/io/fld/load.hh (revision 0)
+++ trunk/milena/mln/io/fld/load.hh (revision 4637)
@@ -0,0 +1,242 @@
+// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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_IO_FLD_LOAD_HH
+# define MLN_IO_FLD_LOAD_HH
+
+/// \file
+///
+/// \brief Load an image from an AVS field file.
+///
+/// \note The current loader does not follow the whole specifications
+/// of the format. Actually, it has the following restrictions:
+/// - the dimension of the field and the space must be the same.
+/// - the number of dimension is limited to 1D, 2D and 3D.
+/// - the data format must be native (float, integer...) (XDR extension is not supported)
+/// - the field must uniform (regular grid).
+/// - dim1, dim2... dimn are parsed but ignored.
+/// - min_ext and max_ext (pmin and pmax of the bbox) are not computed and are compulsory.
+/// - label and unit keyword are not supported.
+/// - external data source ('coord', and 'variable') is not supported.
+///
+/// FIXME: pnm::load uses special implementation if sizeof(int_u8) != 1 ?? what ??
+
+# include <mln/core/concept/image.hh>
+# include <mln/io/fld/header.hh>
+# include <mln/io/fld/load_header.hh>
+# include <mln/io/fld/max_components.hh>
+
+# include <mln/algebra/vec.hh>
+# include <mln/value/rgb.hh>
+# include <mln/value/int_u8.hh>
+
+# include <mln/geom/nsites.hh>
+
+# include <fstream>
+# include <iostream>
+
+namespace mln
+{
+
+ namespace io
+ {
+
+ namespace fld
+ {
+
+ /// Load an image from an AVS field file.
+ ///
+ /// \param[in,out] ima_ The image to load.
+ /// \param[in] filename The path to the AVS file.
+ ///
+ template <typename I>
+ inline
+ void
+ load(Image<I>& ima_, const char* filename);
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace internal
+ {
+
+ void
+ abort_load(const char* msg, const char* filename)
+ {
+ std::cerr << "Error: file '" << filename << "'"
+ << "cannot be loaded." << std::endl
+ << "Error description: " << msg << std::endl;
+ abort();
+ }
+
+ // Read a Milena rgb value (sizeof(int_u8) != 1).
+ template <unsigned int n>
+ inline
+ void read_value(std::ifstream& file, value::rgb<n>& v)
+ {
+ typedef typename value::int_u<n>::enc E;
+
+ E c;
+ file.read((char*)(&c), sizeof(E));
+ v.red() = c;
+ file.read((char*)(&c), sizeof(E));
+ v.green() = c;
+ file.read((char*)(&c), sizeof(E));
+ v.blue() = c;
+ }
+
+ // Read a Milena scalar value (sizeof(int_u8) != 1).
+ template <class V>
+ inline
+ void read_value(std::ifstream& file, value::Scalar<V>& v)
+ {
+ typedef typename V::enc E;
+
+ E c;
+ file.read((char*)(&c), sizeof(E));
+ exact(v) = c;
+ }
+
+ // Read a builtin scalar value.
+ template <typename V>
+ inline
+ void read_value(std::ifstream& file, V& v)
+ {
+ V c;
+ file.read((char*)(&c), sizeof(V));
+ v = c;
+ }
+
+ // used when (sizeof(int_u8) != 1)
+ template <typename I>
+ inline
+ void load_raw_uncontiguous(std::ifstream& file, I& ima)
+ {
+ mln_piter(I) p(ima.domain());
+ read_value(file, ima(p));
+ }
+
+ // used in g++ > 2.95
+ template <typename I>
+ inline
+ void load_raw_contiguous(std::ifstream& file, I& ima)
+ {
+ mln_site(I) pmin = ima.domain().pmin();
+ mln_site(I) pmax = ima.domain().pmax();
+
+ typedef mln_site(I) P;
+ enum { dim = P::dim };
+
+ // The first array index varies most quickly (FORTRAN-style).
+ typedef mln_value(I) V;
+
+
+ std::size_t len = pmax[dim - 1] - pmin[dim - 1] + 1;
+ std::size_t n = len * sizeof(V);
+
+ P p = pmin;
+ if (dim == 1)
+ {
+ file.read((char*)(&ima(p)), n);
+ return;
+ }
+
+ while (true)
+ {
+ file.read((char*)(&ima(p)), n);
+ ++p[dim - 2];
+
+ for (int i = dim - 2; p[i] > pmax[i]; --i)
+ {
+ if (i == 0)
+ return;
+ p[i] = pmin[i];
+ ++p[i - 1];
+ }
+ }
+ }
+
+ template <typename I>
+ inline
+ void load_raw(std::ifstream& file, I& ima)
+ {
+ if (sizeof(value::int_u8) == 1)
+ load_raw_contiguous(file, ima);
+ else
+ load_raw_uncontiguous(file, ima);
+ }
+
+ } // end of mln::io::internal
+
+ template <typename I>
+ inline
+ void
+ load(Image<I>& ima_, const char* filename)
+ {
+ trace::entering("mln::io::fld::load");
+
+ std::ifstream file(filename);
+ if (! file)
+ internal::abort_load("Fail to open the file.", filename);
+
+ typedef mln_value(I) V;
+ typedef mln_site(I) P;
+
+ I& ima = exact(ima_);
+ fld_header hder = fld::read_header(file);
+ int nspace = P::dim;
+ int veclen = mln_dim(V);
+
+ if (nspace != hder.nspace)
+ internal::abort_load("The dimension of the input does not match the one from the file.", filename);
+ if (nspace > 3)
+ internal::abort_load("The loader does not handle image dimension greater than three.", filename);
+ if (veclen != hder.veclen)
+ internal::abort_load("The dimension of the value does not match the one from the file.", filename);
+ if (max_component(V ()) != max_component(hder.data))
+ internal::abort_load("The data type of the input mismatches the one from the file.", filename);
+
+ box<mln_site(I)> bbox;
+ for (int i = 0; i < hder.ndim; ++i)
+ {
+ bbox.pmin()[i] = hder.min_ext[i];
+ bbox.pmax()[i] = hder.max_ext[i];
+ }
+
+ ima.init_(bbox);
+ internal::load_raw(file, ima);
+
+ file.close();
+ trace::exiting("mln::io::fld::load");
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::io::fld
+
+ } // end of namespace mln::io
+
+} // end of namespace mln
+
+#endif // !MLN_IO_FLD_LOAD_HH
Index: trunk/milena/mln/io/all.hh
===================================================================
--- trunk/milena/mln/io/all.hh (revision 4636)
+++ trunk/milena/mln/io/all.hh (revision 4637)
@@ -57,6 +57,7 @@
# include <mln/io/ppm/all.hh>
# include <mln/io/txt/all.hh>
# include <mln/io/off/all.hh>
+# include <mln/io/fld/all.hh>
/*--------------------------------------------------.
Index: trunk/milena/tests/io/fld/fld2d.cc
===================================================================
--- trunk/milena/tests/io/fld/fld2d.cc (revision 0)
+++ trunk/milena/tests/io/fld/fld2d.cc (revision 4637)
@@ -0,0 +1,108 @@
+// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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.
+
+///
+/// \brief Test fld IO on 2D images.
+///
+
+#include <mln/core/image/image2d.hh>
+
+#include <mln/io/pgm/load.hh>
+#include <mln/io/ppm/load.hh>
+#include <mln/io/fld/load.hh>
+#include <mln/io/fld/save.hh>
+#include <mln/value/int_u8.hh>
+#include <mln/value/int_u16.hh>
+#include <mln/data/compare.hh>
+#include "tests/data.hh"
+
+#include <stdio.h>
+#include <float.h>
+#include <time.h>
+
+int main()
+{
+ using namespace mln;
+ using value::int_u8;
+ using value::int_u16;
+
+ // Test on int_u8.
+ // Veclen = 1, data = byte
+ {
+ image2d<int_u8> ori, test;
+ io::pgm::load(ori, MLN_IMG_DIR "/lena.pgm");
+
+ io::fld::save(ori, "out.fld");
+ io::fld::load(test, "out.fld");
+
+ // Clean output.
+ std::remove("out.fld");
+
+ mln_assertion(ori == test);
+ }
+
+ // Test on RGB 16
+ // Veclen = 3, data = short
+ {
+ image2d<int_u16> ori, test;
+ io::ppm::load(ori, MLN_IMG_DIR "/lena_16.ppm");
+
+ io::fld::save(ori, "out.fld");
+ io::fld::load(test, "out.fld");
+
+ // Clean output.
+ std::remove("out.fld");
+
+ mln_assertion(ori == test);
+ }
+
+ // Test on 32-bits data type
+ // Veclen = 1, data = float
+ {
+ image2d<float> ori, test;
+ box<point2d> domain(8, 9);
+
+ srand(time(NULL));
+ ori.init_(domain);
+ {
+ mln_piter_(image2d<float>) p(domain);
+ for_all(p)
+ ori(p) = random() / RAND_MAX;
+ }
+
+ io::fld::save(ori, "out.fld");
+ io::fld::load(test, "out.fld");
+
+ // Clean output.
+ std::remove("out.fld");
+
+ {
+ mln_piter_(image2d<float>) p(domain);
+ for_all(p)
+ mln_assertion(fabs(ori(p) - test(p)) < FLT_EPSILON);
+ }
+ }
+
+}
Index: trunk/milena/tests/io/fld/fld3d.cc
===================================================================
--- trunk/milena/tests/io/fld/fld3d.cc (revision 0)
+++ trunk/milena/tests/io/fld/fld3d.cc (revision 4637)
@@ -0,0 +1,59 @@
+// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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.
+
+///
+/// \brief Test AVS field file IO with 3D image.
+///
+///
+///
+
+#include <mln/core/image/image3d.hh>
+#include <mln/io/fld/load.hh>
+#include <mln/io/fld/save.hh>
+#include <mln/value/int_u8.hh>
+#include <mln/debug/iota.hh>
+#include <mln/debug/println.hh>
+#include <mln/data/compare.hh>
+
+
+int main()
+{
+ using namespace mln;
+ using value::int_u8;
+
+
+ image3d<int_u8> ori, test;
+ box<point3d> b(8, 9, 10);
+ ori.init_(b);
+ debug::iota(ori);
+
+ io::fld::save(ori, "out.fld");
+ io::fld::load(test, "out.fld");
+
+ // Clean output.
+ std::remove("out.fld");
+
+ mln_assertion(ori == test);
+}
Index: trunk/milena/tests/io/fld/Makefile.am
===================================================================
--- trunk/milena/tests/io/fld/Makefile.am (revision 0)
+++ trunk/milena/tests/io/fld/Makefile.am (revision 4637)
@@ -0,0 +1,31 @@
+# Copyright (C) 2007, 2009 EPITA Research and Development Laboratory (LRDE).
+#
+# This file is part of Olena.
+#
+# Olena is free software: you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free
+# Software Foundation, version 2 of the License.
+#
+# Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+#
+
+## Process this file through Automake to create Makefile.in.
+
+include $(top_srcdir)/milena/tests/tests.mk
+
+check_PROGRAMS = \
+ fld2d \
+ fld1d \
+ fld3d
+
+fld2d_SOURCES = fld2d.cc
+fld3d_SOURCES = fld3d.cc
+fld1d_SOURCES = fld1d.cc
+
+TESTS = $(check_PROGRAMS)
\ No newline at end of file
Index: trunk/milena/tests/io/fld/fld1d.cc
===================================================================
--- trunk/milena/tests/io/fld/fld1d.cc (revision 0)
+++ trunk/milena/tests/io/fld/fld1d.cc (revision 4637)
@@ -0,0 +1,57 @@
+// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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.
+
+///
+/// \brief Test AVS field file IO with 1D image.
+///
+///
+///
+
+#include <mln/core/image/image1d.hh>
+#include <mln/io/fld/load.hh>
+#include <mln/io/fld/save.hh>
+#include <mln/value/int_u8.hh>
+#include <mln/debug/iota.hh>
+#include <mln/data/compare.hh>
+
+int main()
+{
+ using namespace mln;
+ using value::int_u8;
+
+
+ image1d<int_u8> ori, test;
+ box<point1d> b(9);
+ ori.init_(b);
+ debug::iota(ori);
+
+ io::fld::save(ori, "out.fld");
+ io::fld::load(test, "out.fld");
+
+ // Clean output.
+ std::remove("out.fld");
+
+ mln_assertion(ori == test);
+}
Index: trunk/milena/tests/io/Makefile.am
===================================================================
--- trunk/milena/tests/io/Makefile.am (revision 4636)
+++ trunk/milena/tests/io/Makefile.am (revision 4637)
@@ -33,7 +33,8 @@
pgms \
pnm \
ppm \
- ppms
+ ppms \
+ fld
## ------------------------------------------------- ##
## I/O routines depending on a third-party library. ##
1
0
https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Some fixes.
* mln/data/transform.spe.hh: Layout.
* mln/data/transform_inplace.hh (transform_tests): Rename as...
(transform_inplace_tests): ...this; it is a naming bug fix.
* mln/convert/to.hh: Remove trace and add a tech note about it.
convert/to.hh | 6 ++++--
data/transform.spe.hh | 1 -
data/transform_inplace.hh | 20 ++++++++++----------
3 files changed, 14 insertions(+), 13 deletions(-)
Index: mln/data/transform.spe.hh
--- mln/data/transform.spe.hh (revision 4635)
+++ mln/data/transform.spe.hh (working copy)
@@ -233,7 +233,6 @@
{
trace::entering("data::impl::transform_fast");
-
const I& input = exact(input_);
const F& f = exact(f_);
data::internal::transform_tests(input, f);
Index: mln/data/transform_inplace.hh
--- mln/data/transform_inplace.hh (revision 4635)
+++ mln/data/transform_inplace.hh (working copy)
@@ -106,9 +106,9 @@
template <typename I1, typename I2, typename F>
inline
- void transform_tests(const Image<I1>& ima,
+ void transform_inplace_tests(Image<I1>& ima,
const Image<I2>& aux,
- const Function_v2v<F>& f)
+ const Function_vv2v<F>& f)
{
// Properties checks.
mlc_or(mlc_is(mln_trait_image_pw_io(I1),
@@ -156,7 +156,7 @@
I& ima = exact(ima_);
const F& f = exact(f_);
- data::internal::transform_inplace_tests(ima, f);
+ internal::transform_inplace_tests(ima, f);
mln_piter(I) p(ima.domain());
for_all(p)
@@ -185,7 +185,7 @@
const I2& aux = exact(aux_);
const F& f = exact(f_);
- data::internal::transform_inplace_tests(ima, aux, f);
+ internal::transform_inplace_tests(ima, aux, f);
mln_piter(I1) p(ima.domain());
for_all(p)
@@ -211,7 +211,7 @@
I& input = exact(input_);
const F& f = exact(f_);
- data::internal::transform_inplace_tests(input, f);
+ internal::transform_inplace_tests(input, f);
value::lut_vec<mln_vset(I), mln_result(F)>
lut(input.values_eligible(), f);
@@ -236,7 +236,7 @@
I& input = exact(input_);
const F& f = exact(f_);
- data::internal::transform_inplace_tests(input, f);
+ internal::transform_inplace_tests(input, f);
value::lut_vec<mln_vset(I), mln_result(F)>
lut(input.taken_values(), f);
@@ -259,7 +259,7 @@
I& input = exact(input_);
const F& f = exact(f_);
- data::internal::transform_inplace_tests(input, f);
+ internal::transform_inplace_tests(input, f);
opt::value(input) = f(opt::value(input));
@@ -275,7 +275,7 @@
I& ima = exact(ima_);
const F& f = exact(f_);
- data::internal::transform_inplace_tests(ima, f);
+ internal::transform_inplace_tests(ima, f);
mln_pixter(I) p(ima);
for_all(p)
@@ -295,7 +295,7 @@
I& input = exact(input_);
const F& f = exact(f_);
- data::internal::transform_inplace_tests(input, f);
+ internal::transform_inplace_tests(input, f);
value::lut_vec<mln_vset(I), mln_result(F)>
lut(input.values_eligible(), f);
@@ -322,7 +322,7 @@
const I2& aux = exact(aux_);
const F& f = exact(f_);
- data::internal::transform_inplace_tests(ima, aux, f);
+ internal::transform_inplace_tests(ima, aux, f);
mln_pixter(I1) pi(ima);
mln_pixter(const I2) pa(aux);
Index: mln/convert/to.hh
--- mln/convert/to.hh (revision 4635)
+++ mln/convert/to.hh (working copy)
@@ -62,14 +62,16 @@
T
to(const O& from)
{
+ // Technical note:
+ // No trace should be produced by this routine since it can be
+ // applied on large sets of data.
+
mlc_equal(T, mln_exact(T))::check();
mlc_equal(O, mln_exact(O))::check();
- trace::entering("convert::to");
T tmp;
from_to(from, tmp);
- trace::exiting("convert::to");
return tmp;
}
1
0
https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Add a 1st version of some morpho geodesic ops.
* theo/mln/morpho: New directory.
* theo/mln/morpho/geodesic: New directory.
* theo/mln/morpho/geodesic/dilation.hh: New.
* theo/mln/morpho/geodesic/dilation_permissive.hh: New.
* theo/mln/morpho/geodesic/dilation.cc: New.
* theo/mln/morpho/geodesic/dilation_permissive_n.cc: New.
* theo/mln/morpho/geodesic/dilation_permissive_bench.cc: New.
* theo/mln/morpho/geodesic/dilation_permissive.cc: New.
dilation.cc | 31 ++
dilation.hh | 88 ++++++++
dilation_permissive.cc | 47 ++++
dilation_permissive.hh | 446 +++++++++++++++++++++++++++++++++++++++++++
dilation_permissive_bench.cc | 60 +++++
dilation_permissive_n.cc | 35 +++
6 files changed, 707 insertions(+)
Index: theo/mln/morpho/geodesic/dilation.hh
--- theo/mln/morpho/geodesic/dilation.hh (revision 0)
+++ theo/mln/morpho/geodesic/dilation.hh (revision 0)
@@ -0,0 +1,88 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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_GEODESIC_DILATION_HH
+# define MLN_MORPHO_GEODESIC_DILATION_HH
+
+/// \file
+///
+/// Morphological geodesic dilation; strict version.
+
+// # include <mln/morpho/geodesic/dilation_permissive.hh>
+# include "dilation_permissive.hh"
+
+
+namespace mln
+{
+
+ namespace morpho
+ {
+
+ namespace geodesic
+ {
+
+ /// Morphological geodesic dilation of size n; strict version.
+ template <typename I, typename J, typename N>
+ mln_concrete(I)
+ dilation(const Image<I>& f, const Image<J>& g,
+ const Neighborhood<N>& nbh,
+ unsigned n = 1);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename I, typename J, typename N>
+ inline
+ mln_concrete(I)
+ dilation(const Image<I>& f, const Image<J>& g,
+ const Neighborhood<N>& nbh,
+ unsigned n)
+ {
+ trace::entering("morpho::geodesic::dilation");
+
+ mln_precondition(n != 0);
+ internal::dilation_permissive_tests(f, g, nbh);
+ mln_precondition(f <= g);
+
+ mln_concrete(I) output;
+ output = internal::dilation_permissive_dispatch(f, g, nbh, n);
+
+ mln_precondition(output >= f);
+ mln_precondition(output <= g);
+
+ trace::exiting("morpho::geodesic::dilation");
+ return output;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::geodesic
+
+ } // end of namespace mln::morpho
+
+} // end of namespace mln
+
+
+#endif // ! MLN_MORPHO_GEODESIC_DILATION_HH
Index: theo/mln/morpho/geodesic/dilation_permissive.hh
--- theo/mln/morpho/geodesic/dilation_permissive.hh (revision 0)
+++ theo/mln/morpho/geodesic/dilation_permissive.hh (revision 0)
@@ -0,0 +1,446 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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_GEODESIC_DILATION_PERMISSIVE_HH
+# define MLN_MORPHO_GEODESIC_DILATION_PERMISSIVE_HH
+
+/// \file
+///
+/// Morphological geodesic dilation; permissive version.
+
+# include <mln/morpho/includes.hh>
+# include <mln/morpho/elementary/dilation.hh>
+# include <mln/logical/and.hh>
+# include <mln/data/transform_inplace.hh>
+# include <mln/fun/vv2v/max.hh>
+# include <mln/border/equalize.hh>
+
+
+namespace mln
+{
+
+ namespace morpho
+ {
+
+ namespace geodesic
+ {
+
+ /// Morphological geodesic dilation of size n; permissive version.
+ template <typename I, typename J, typename N>
+ mln_concrete(I)
+ dilation_permissive(const Image<I>& f, const Image<J>& g,
+ const Neighborhood<N>& nbh,
+ unsigned n = 1);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ // Tests.
+
+ namespace internal
+ {
+
+ template <typename I, typename J, typename N>
+ inline
+ void
+ dilation_permissive_tests(const Image<I>& f_, const Image<J>& g_,
+ const Neighborhood<N>& nbh_)
+ {
+ const I& f = exact(f_);
+ const J& g = exact(g_);
+ const N& nbh = exact(nbh_);
+
+ mln_precondition(f.is_valid());
+ mln_precondition(g.is_valid());
+ mln_precondition(nbh.is_valid());
+
+ mln_precondition(f.domain() == g.domain());
+
+ (void) f;
+ (void) g;
+ (void) nbh;
+ }
+
+ } // end of namespace morpho::geodesic::internal
+
+
+ // Implementations.
+
+ namespace impl
+ {
+
+
+ template <typename I, typename J, typename N>
+ inline
+ mln_concrete(I)
+ dilation_strict_1_set_formula(const Image<I>& f, const Image<J>& g,
+ const Neighborhood<N>& nbh)
+ {
+ trace::entering("morpho::geodesic::impl::dilation_strict_1_set_formula");
+
+ internal::dilation_permissive_tests(f, g, nbh);
+
+ mln_concrete(I) output = morpho::elementary::dilation(f, nbh);
+ logical::and_inplace(output, g);
+
+ trace::exiting("morpho::geodesic::impl::dilation_strict_1_set_formula");
+ return output;
+ }
+
+
+ template <typename I, typename J, typename N>
+ inline
+ mln_concrete(I)
+ dilation_strict_1_function_formula(const Image<I>& f, const Image<J>& g,
+ const Neighborhood<N>& nbh)
+ {
+ trace::entering("morpho::geodesic::impl::dilation_strict_1_function_formula");
+
+ internal::dilation_permissive_tests(f, g, nbh);
+
+ mln_concrete(I) output = morpho::elementary::dilation(f, nbh);
+ fun::vv2v::max<mln_value(I)> max_;
+ data::transform_inplace(output, g, max_);
+
+ trace::exiting("morpho::geodesic::impl::dilation_strict_1_function_formula");
+ return output;
+ }
+
+
+ template <typename I, typename J, typename N>
+ inline
+ mln_concrete(I)
+ dilation_permissive_n(const Image<I>& f, const Image<J>& g,
+ const Neighborhood<N>& nbh,
+ unsigned n)
+ {
+ trace::entering("morpho::geodesic::impl::dilation_permissive_n");
+
+ mln_precondition(n != 0);
+ internal::dilation_permissive_tests(f, g, nbh);
+
+ mln_concrete(I) work = duplicate(f);
+ for (unsigned i = 0; i < n; ++i)
+ work = dilation_permissive(work, g, nbh, 1);
+
+ trace::exiting("morpho::geodesic::impl::dilation_permissive_n");
+ return work;
+ }
+
+
+ template <typename I, typename J, typename N>
+ inline
+ mln_concrete(I)
+ dilation_permissive_1_set_generic(const Image<I>& f_, const Image<J>& g_,
+ const Neighborhood<N>& nbh_)
+ {
+ trace::entering("morpho::geodesic::impl::dilation_permissive_1_set_generic");
+
+ const I& f = exact(f_);
+ const J& g = exact(g_);
+ const N& nbh = exact(nbh_);
+
+ internal::dilation_permissive_tests(f, g, nbh);
+
+ mln_piter(I) p(f.domain());
+ mln_niter(N) n(nbh, p);
+
+ // We dilate from the inner boundary of f.
+
+ mln_concrete(I) output = duplicate(f);
+ for_all(p)
+ {
+ if (! f(p))
+ continue;
+ for_all(n) if (f.domain().has(n))
+ {
+ if (output(n)) // already at true
+ continue;
+ if (g(n)) // conditioning
+ output(n) = true;
+ }
+ }
+
+ trace::exiting("morpho::geodesic::impl::dilation_permissive_1_set_generic");
+ return output;
+ }
+
+
+ template <typename I, typename J, typename N>
+ inline
+ mln_concrete(I)
+ dilation_permissive_1_set_fastest(const Image<I>& f_, const Image<J>& g_,
+ const Neighborhood<N>& nbh_)
+ {
+ trace::entering("morpho::geodesic::impl::dilation_permissive_1_set_fastest");
+
+ const I& f = exact(f_);
+ const J& g = exact(g_);
+ const N& nbh = exact(nbh_);
+
+ internal::dilation_permissive_tests(f, g, nbh);
+
+ border::equalize(f, g, nbh.delta());
+ typedef mln_concrete(I) O;
+ O output = duplicate(f);
+ border::fill(output, true);
+
+ util::array<int> dp = offsets_wrt(f, nbh);
+ const unsigned n_nbhs = dp.nelements();
+
+ mln_box_runstart_piter(I) s(f.domain());
+ s.start();
+ const unsigned len = s.run_length();
+
+ // We dilate from the inner boundary of f.
+
+ for (; s.is_valid(); s.next())
+ {
+ unsigned p = f.index_of_point(s);
+ for (unsigned i = 0; i < len; ++i, ++p)
+ {
+ if (! f.element(p))
+ continue;
+ for (unsigned j = 0; j < n_nbhs; ++j)
+ {
+ unsigned n = p + dp[j];
+ if (output.element(n)) // already at true
+ continue;
+ if (g.element(n)) // conditioning
+ output.element(n) = true;
+ }
+ }
+ }
+
+ trace::exiting("morpho::geodesic::impl::dilation_permissive_1_set_fastest");
+ return output;
+ }
+
+
+ template <typename I, typename J, typename N>
+ inline
+ mln_concrete(I)
+ dilation_permissive_1_set_generic_alt(const Image<I>& f_, const Image<J>& g_,
+ const Neighborhood<N>& nbh_)
+ {
+ trace::entering("morpho::geodesic::impl::dilation_permissive_1_set_generic_alt");
+
+ const I& f = exact(f_);
+ const J& g = exact(g_);
+ const N& nbh = exact(nbh_);
+
+ internal::dilation_permissive_tests(f, g, nbh);
+
+ mln_piter(I) p(f.domain());
+ mln_niter(N) n(nbh, p);
+
+ // We browse the "(not f) and g" domain.
+
+ mln_concrete(I) output = duplicate(f);
+ for_all(p)
+ {
+ if (f(p) // output(p) is already at true...
+ || ! g(p) // ...or conditioning by g not satisfied
+ )
+ continue;
+ for_all(n) if (f.domain().has(n))
+ if (f(n)) // p is in the outer boundary of f
+ {
+ output(p) = true;
+ break; // we are done for p
+ }
+ }
+
+ trace::exiting("morpho::geodesic::impl::dilation_permissive_1_set_generic_alt");
+ return output;
+ }
+
+
+
+ template <typename I, typename J, typename N>
+ inline
+ mln_concrete(I)
+ dilation_permissive_1_set_fastest_alt(const Image<I>& f_, const Image<J>& g_,
+ const Neighborhood<N>& nbh_)
+ {
+ trace::entering("morpho::geodesic::impl::dilation_permissive_1_set_fastest_alt");
+
+ const I& f = exact(f_);
+ const J& g = exact(g_);
+ const N& nbh = exact(nbh_);
+
+ internal::dilation_permissive_tests(f, g, nbh);
+
+ border::equalize(f, g, nbh.delta());
+ typedef mln_concrete(I) O;
+ O output = duplicate(f);
+ border::fill(f, false);
+
+ util::array<int> dp = offsets_wrt(f, nbh);
+ const unsigned n_nbhs = dp.nelements();
+
+ mln_box_runstart_piter(I) s(f.domain());
+ s.start();
+ const unsigned len = s.run_length();
+
+ // We browse the "(not f) and g" domain.
+
+ for (; s.is_valid(); s.next())
+ {
+ unsigned p = f.index_of_point(s);
+ for (unsigned i = 0; i < len; ++i, ++p)
+ {
+ if (f.element(p) // output.element(p) is already at true...
+ || ! g.element(p) // ...or conditioning by g not satisfied
+ )
+ continue;
+ for (unsigned j = 0; j < n_nbhs; ++j)
+ {
+ unsigned n = p + dp[j];
+ if (f.element(n)) // p is in the outer boundary of f
+ {
+ output.element(p) = true;
+ break; // we are done for p
+ }
+ }
+ }
+ }
+
+ trace::exiting("morpho::geodesic::impl::dilation_permissive_1_set_fastest_alt");
+ return output;
+ }
+
+
+ } // end of namespace morpho::geodesic::impl
+
+
+
+ // Dispatch.
+
+ namespace internal
+ {
+
+
+ // For size 1.
+
+ template <typename M,
+ typename I, typename J, typename N>
+ inline
+ mln_concrete(I)
+ dilation_permissive_1_dispatch(trait::image::kind::any,
+ M,
+ const Image<I>& f, const Image<J>& g,
+ const Neighborhood<N>& nbh)
+ {
+ // FIXME
+ std::cerr << "NYI: replace by strict version!" << std::endl;
+ return impl::dilation_strict_1_function_formula(f, g, nbh);
+ }
+
+ template <typename I, typename J, typename N>
+ inline
+ mln_concrete(I)
+ dilation_permissive_1_dispatch(trait::image::kind::binary,
+ metal::false_,
+ const Image<I>& f, const Image<J>& g,
+ const Neighborhood<N>& nbh)
+ {
+ return impl::dilation_permissive_1_set_generic(f, g, nbh);
+ }
+
+ template <typename I, typename J, typename N>
+ inline
+ mln_concrete(I)
+ dilation_permissive_1_dispatch(trait::image::kind::binary,
+ metal::true_,
+ const Image<I>& f, const Image<J>& g,
+ const Neighborhood<N>& nbh)
+ {
+ return impl::dilation_permissive_1_set_fastest(f, g, nbh);
+ }
+
+
+
+ // Entry point.
+
+ template <typename I, typename J, typename N>
+ inline
+ mln_concrete(I)
+ dilation_permissive_dispatch(const Image<I>& f, const Image<J>& g,
+ const Neighborhood<N>& nbh,
+ unsigned n)
+ {
+ enum {
+ is_fastest = (mlc_equal(mln_trait_image_speed(I),
+ trait::image::speed::fastest)::value &&
+ mlc_equal(mln_trait_image_speed(J),
+ trait::image::speed::fastest)::value &&
+ mln_is_simple_neighborhood(N)::value)
+ };
+ if (n == 1)
+ return dilation_permissive_1_dispatch(mln_trait_image_kind(I)(),
+ metal::bool_<is_fastest>(),
+ f, g, nbh);
+ else
+ return impl::dilation_permissive_n(f, g, nbh, n);
+ }
+
+
+ } // end of namespace morpho::geodesic::internal
+
+
+
+ // Facade.
+
+ template <typename I, typename J, typename N>
+ inline
+ mln_concrete(I)
+ dilation_permissive(const Image<I>& f, const Image<J>& g,
+ const Neighborhood<N>& nbh,
+ unsigned n)
+ {
+ trace::entering("morpho::geodesic::dilation_permissive");
+
+ mln_precondition(n != 0);
+ internal::dilation_permissive_tests(f, g, nbh);
+
+ mln_concrete(I) output;
+ output = internal::dilation_permissive_dispatch(f, g, nbh, n);
+
+ trace::exiting("morpho::geodesic::dilation_permissive");
+ return output;
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::geodesic
+
+ } // end of namespace mln::morpho
+
+} // end of namespace mln
+
+
+#endif // ! MLN_MORPHO_GEODESIC_DILATION_PERMISSIVE_HH
Index: theo/mln/morpho/geodesic/dilation.cc
--- theo/mln/morpho/geodesic/dilation.cc (revision 0)
+++ theo/mln/morpho/geodesic/dilation.cc (revision 0)
@@ -0,0 +1,31 @@
+#include <mln/core/image/image2d.hh>
+#include <mln/core/alias/neighb2d.hh>
+#include <mln/logical/and.hh>
+
+#include "dilation.hh"
+
+
+int main()
+{
+ using namespace mln;
+
+ image2d<bool> f, g, o;
+ neighb2d nbh = c4();
+
+ bool gvals[] = { 1, 1, 0, 0, 1,
+ 1, 1, 1, 1, 0,
+ 0, 1, 1, 1, 0,
+ 0, 1, 1, 1, 0,
+ 0, 1, 0, 0, 0 };
+ g = make::image2d(gvals);
+
+ bool fvals[] = { 0, 0, 0, 0, 0,
+ 0, 0, 1, 1, 1,
+ 1, 1, 1, 1, 0,
+ 1, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0 };
+ f = make::image2d(fvals);
+
+
+ o = morpho::geodesic::dilation(logical::and_(f, g), g, nbh);
+}
Index: theo/mln/morpho/geodesic/dilation_permissive_n.cc
--- theo/mln/morpho/geodesic/dilation_permissive_n.cc (revision 0)
+++ theo/mln/morpho/geodesic/dilation_permissive_n.cc (revision 0)
@@ -0,0 +1,35 @@
+#include <cstdlib>
+#include <mln/core/image/image2d.hh>
+#include <mln/core/alias/neighb2d.hh>
+#include <mln/io/pbm/load.hh>
+#include <mln/io/pbm/save.hh>
+#include <mln/logical/and.hh>
+#include <mln/util/timer.hh>
+
+#include "dilation_permissive.hh"
+
+
+int main(int argc, char* argv[])
+{
+ using namespace mln;
+
+
+ image2d<bool>
+ f = io::pbm::load("./+f.pbm"),
+ g = io::pbm::load("./+g.pbm"),
+ o;
+ neighb2d nbh = c8();
+
+ int n = std::atoi(argv[1]);
+
+// image2d<bool> f_g = logical::and_(f, g);
+// io::pbm::save(f_g, "f_g.pbm");
+// o = morpho::geodesic::dilation_permissive(f_g, g, nbh, n);
+
+ util::timer t;
+ t.start();
+ o = morpho::geodesic::dilation_permissive(f, g, nbh, n);
+ std::cout << t.stop() << std::endl;
+
+ io::pbm::save(o, "o.pbm");
+}
Index: theo/mln/morpho/geodesic/dilation_permissive_bench.cc
--- theo/mln/morpho/geodesic/dilation_permissive_bench.cc (revision 0)
+++ theo/mln/morpho/geodesic/dilation_permissive_bench.cc (revision 0)
@@ -0,0 +1,60 @@
+#include <mln/core/image/image2d.hh>
+#include <mln/core/alias/neighb2d.hh>
+#include <mln/debug/println.hh>
+#include <mln/io/pbm/load.hh>
+#include <mln/io/pbm/save.hh>
+#include <mln/util/timer.hh>
+
+#include "dilation_permissive.hh"
+
+
+int main()
+{
+ using namespace mln;
+
+ image2d<bool>
+ f = io::pbm::load("./+f.pbm"),
+ g = io::pbm::load("./+g.pbm"),
+ o;
+ neighb2d nbh = c4();
+
+ util::timer t;
+ const unsigned n = 20;
+
+ {
+ t.start();
+ for (unsigned i = 0; i < n; ++i)
+ o = morpho::geodesic::impl::dilation_strict_1_set_formula(f, g, nbh);
+ std::cout << "dilation_strict_1_set_formula " << t.stop() << std::endl;
+ io::pbm::save(o, "o.pbm");
+ }
+
+ {
+ t.start();
+ for (unsigned i = 0; i < n; ++i)
+ o = morpho::geodesic::impl::dilation_permissive_1_set_generic(f, g, nbh);
+ std::cout << "dilation_permissive_1_set_generic " << t.stop() << std::endl;
+ }
+
+ {
+ t.start();
+ for (unsigned i = 0; i < n; ++i)
+ o = morpho::geodesic::impl::dilation_permissive_1_set_fastest(f, g, nbh);
+ std::cout << "dilation_permissive_1_set_fastest " << t.stop() << std::endl;
+// io::pbm::save(o, "o.pbm");
+ }
+
+ {
+ t.start();
+ for (unsigned i = 0; i < n; ++i)
+ o = morpho::geodesic::impl::dilation_permissive_1_set_generic_alt(f, g, nbh);
+ std::cout << "dilation_permissive_1_set_generic_alt " << t.stop() << std::endl;
+ }
+
+ {
+ t.start();
+ for (unsigned i = 0; i < n; ++i)
+ o = morpho::geodesic::impl::dilation_permissive_1_set_fastest_alt(f, g, nbh);
+ std::cout << "dilation_permissive_1_set_fastest_alt " << t.stop() << std::endl;
+ }
+}
Index: theo/mln/morpho/geodesic/dilation_permissive.cc
--- theo/mln/morpho/geodesic/dilation_permissive.cc (revision 0)
+++ theo/mln/morpho/geodesic/dilation_permissive.cc (revision 0)
@@ -0,0 +1,47 @@
+#include <mln/core/image/image2d.hh>
+#include <mln/core/alias/neighb2d.hh>
+#include <mln/debug/println.hh>
+
+#include "dilation_permissive.hh"
+
+
+int main()
+{
+ using namespace mln;
+
+ image2d<bool> f, g, d_ref, d_gen, d_fast, d_gen_alt, d_fast_alt;
+ neighb2d nbh = c4();
+
+ bool gvals[] = { 1, 1, 0, 0, 1,
+ 1, 1, 1, 1, 0,
+ 0, 1, 1, 1, 0,
+ 0, 1, 1, 1, 0,
+ 0, 1, 0, 0, 0 };
+ g = make::image2d(gvals);
+ debug::println("g", g);
+
+ bool fvals[] = { 0, 0, 0, 0, 0,
+ 0, 0, 1, 1, 1,
+ 1, 1, 1, 1, 0,
+ 1, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0 };
+ f = make::image2d(fvals);
+ debug::println("f", f);
+
+
+ d_ref = morpho::geodesic::impl::dilation_strict_1_set_formula(f, g, nbh);
+ debug::println("d", d_ref);
+
+ d_gen = morpho::geodesic::impl::dilation_permissive_1_set_generic(f, g, nbh);
+ mln_assertion(logical::and_(d_gen, g) == d_ref);
+
+ d_fast = morpho::geodesic::impl::dilation_permissive_1_set_fastest(f, g, nbh);
+ mln_assertion(d_fast == d_gen);
+
+ d_gen_alt = morpho::geodesic::impl::dilation_permissive_1_set_generic_alt(f, g, nbh);
+ mln_assertion(logical::and_(d_gen_alt, g) == d_ref);
+ mln_assertion(d_gen_alt == d_gen);
+
+ d_fast_alt = morpho::geodesic::impl::dilation_permissive_1_set_fastest_alt(f, g, nbh);
+ mln_assertion(d_fast_alt == d_gen_alt);
+}
1
0
* green/demo/labeling/regional_maxima/Makefile.am: New Makefile.
* green/demo/labeling/regional_maxima/regional_maxima.cc: New file.
---
trunk/milena/sandbox/ChangeLog | 7 +
.../demo/labeling/regional_maxima/Makefile.am | 148 +++++++++
.../labeling/regional_maxima/regional_maxima.cc | 333 ++++++++++++++++++++
3 files changed, 488 insertions(+), 0 deletions(-)
create mode 100644 trunk/milena/sandbox/green/demo/labeling/regional_maxima/Makefile.am
create mode 100644 trunk/milena/sandbox/green/demo/labeling/regional_maxima/regional_maxima.cc
diff --git a/trunk/milena/sandbox/ChangeLog b/trunk/milena/sandbox/ChangeLog
index ea973fa..e895f0a 100644
--- a/trunk/milena/sandbox/ChangeLog
+++ b/trunk/milena/sandbox/ChangeLog
@@ -1,5 +1,12 @@
2009-10-15 Yann Jacquelet <jacquelet(a)lrde.epita.fr>
+ Work on regional labeling chain in the rgb space.
+
+ * green/demo/labeling/regional_maxima/Makefile.am: New Makefile.
+ * green/demo/labeling/regional_maxima/regional_maxima.cc: New file.
+
+2009-10-15 Yann Jacquelet <jacquelet(a)lrde.epita.fr>
+
Correct kmean3d documentation.
* green/mln/clustering/kmean3d.hh: Fix mistakes in documentation.
diff --git a/trunk/milena/sandbox/green/demo/labeling/regional_maxima/Makefile.am b/trunk/milena/sandbox/green/demo/labeling/regional_maxima/Makefile.am
new file mode 100644
index 0000000..91230b6
--- /dev/null
+++ b/trunk/milena/sandbox/green/demo/labeling/regional_maxima/Makefile.am
@@ -0,0 +1,148 @@
+#
+# Generic Makefile
+#
+
+#########
+# TOOLS #
+#########
+
+INCLUDES= -I$(HOME)/svn/oln/trunk/milena/sandbox/green
+CXXFLAGS= -ggdb -O0 -Wall -W -pedantic -ansi -pipe $(INCLUDES)
+ECHO= echo
+RM= rm
+MKDIR= mkdir -p
+CP= cp
+
+SOURCE_PATTERN= green/demo
+BUILD__PATTERN= green/build/demo
+
+
+ifeq ($(findstring $(BUILD__PATTERN),$(PWD)), $(BUILD__PATTERN))
+# Case where make is done from build directory.
+SOURCE_DIR= $(subst $(BUILD__PATTERN),$(SOURCE_PATTERN),$(PWD))
+BUILD__DIR= $(PWD)/
+else
+# Case where make is done from source directory.
+SOURCE_DIR= $(PWD)/
+BUILD__DIR= $(subst $(SOURCE_PATTERN),$(BUILD__PATTERN),$(PWD))
+endif
+
+SRC= $(notdir $(wildcard $(SOURCE_DIR)/*.cc))
+OLD= $(notdir $(wildcard $(SOURCE_DIR)/*~))
+OBJ= $(patsubst %.cc,%.o,$(SRC))
+SOURCE_MAKEFILE=Makefile.am
+BUILD__MAKEFILE=Makefile
+TARGET_FILE= $(notdir $(PWD))
+SOURCE_FILES= $(notdir $(wildcard $(SOURCE_DIR)/*.*))
+BUILD__FILES= $(filter-out $(SRC) $(SOURCE_MAKEFILE), $(SOURCE_FILES))
+
+BUILD__F_PATH= $(addprefix $(BUILD__DIR)/,$(BUILD__FILES))
+SOURCE_F_PATH= $(addprefix $(SOURCE_DIR)/,$(SOURCE_FILES))
+
+BUILD__M_PATH= $(addprefix $(BUILD__DIR)/,$(BUILD__MAKEFILE))
+SOURCE_M_PATH= $(addprefix $(SOURCE_DIR)/,$(SOURCE_MAKEFILE))
+
+TARGET_F_PATH= $(addprefix $(BUILD__DIR)/,$(TARGET_FILE))
+OBJ_F_PATH= $(addprefix $(BUILD__DIR)/,$(OBJ))
+SRC_F_PATH= $(addprefix $(SOURCE_DIR)/,$(SRC))
+OLD_F_PATH= $(addprefix $(SOURCE_DIR)/,$(OLD))
+
+#############
+# BOOTSTRAP #
+#############
+
+
+bootstrap: $(BUILD__DIR) $(BUILD__F_PATH) $(BUILD__M_PATH)
+
+# Create, if nessary, the destination directory
+$(BUILD__DIR):
+ $(MKDIR) $(BUILD__DIR)
+
+# Copy, if nessary, all the files, except the Makefile.am
+$(BUILD__F_PATH): $(SOURCE_F_PATH)
+ $(CP) $(addprefix $(SOURCE_DIR),$(@F)) $@
+
+# Copy if nessary, the Makefile.am into Makefile
+$(BUILD__M_PATH): $(SOURCE_M_PATH)
+ $(CP) $(SOURCE_M_PATH) $(BUILD__M_PATH)
+
+
+#######
+# ALL #
+#######
+
+# We assume that the call is done from the build directory.
+# With the directive vpath, hidden files are found in the source directory.
+
+all: $(TARGET_F_PATH)
+
+
+$(TARGET_F_PATH): $(OBJ_F_PATH)
+ $(LINK.cc) $< $(LOADLIBES) $(LDLIBS) -o $@
+
+$(OBJ_F_PATH):$(SRC_F_PATH)
+ $(COMPILE.cc) $(OUTPUT_OPTION) $<
+
+
+#########
+# CLEAN #
+#########
+
+# Force every time the deletion
+clean: clean_target clean_obj clean_dst clean_old #clean_make
+
+
+clean_target:
+ -@$(RM) $(TARGET_F_PATH) &> /dev/null
+
+clean_obj:
+ -@$(RM) $(OBJ_F_PATH) &> /dev/null
+
+clean_dst:
+ -@$(RM) $(BUILD_F_PATH) &> /dev/null
+
+clean_make:
+ -@$(RM) $(BUILD_M_PATH) &> /dev/null
+
+clean_old:
+ -@$(RM) $(OLD_F_PATH) &> /dev/null
+
+
+#########
+# PRINT #
+#########
+
+print: print_tools print_bootstrap
+
+print_tools:
+ @$(ECHO) "HOME = $(HOME)"
+ @$(ECHO) "INCLUDES = $(INCLUDES)"
+ @$(ECHO) "CXXFLAGS = $(CXXFLAGS)"
+ @$(ECHO) "ECHO = $(ECHO)"
+ @$(ECHO) "RM = $(RM)"
+ @$(ECHO) "MKDIR = $(MKDIR)"
+ @$(ECHO) "CP = $(CP)"
+ @$(ECHO)
+
+print_bootstrap:
+ @$(ECHO) "PWD = $(PWD)"
+ @$(ECHO) "SOURCE_PATTERN = $(SOURCE_PATTERN)"
+ @$(ECHO) "BUILD__PATTERN = $(BUILD__PATTERN)"
+ @$(ECHO) "SOURCE_DIR = $(SOURCE_DIR)"
+ @$(ECHO) "BUILD__DIR = $(BUILD__DIR)"
+ @$(ECHO) "SOURCE_MAKEFILE = $(SOURCE_MAKEFILE)"
+ @$(ECHO) "BUILD__MAKEFILE = $(BUILD__MAKEFILE)"
+ @$(ECHO) "TARGET_FILE = $(TARGET_FILE)"
+ @$(ECHO) "SOURCE_FILES = $(SOURCE_FILES)"
+ @$(ECHO) "SOURCE_F_PATH = $(SOURCE_F_PATH)"
+ @$(ECHO) "BUILD__FILES = $(BUILD__FILES)"
+ @$(ECHO) "BUILD__F_PATH = $(BUILD__F_PATH)"
+ @$(ECHO) "BUILD__M_PATH = $(BUILD__M_PATH)"
+ @$(ECHO) "SOURCE_M_PATH = $(SOURCE_M_PATH)"
+ @$(ECHO) "SRC = $(SRC)"
+ @$(ECHO) "OBJ = $(OBJ)"
+ @$(ECHO) "OLD = $(OLD)"
+ @$(ECHO) "SRC_F_PATH = $(SRC_F_PATH)"
+ @$(ECHO) "OBJ_F_PATH = $(OBJ_F_PATH)"
+ @$(ECHO) "OLD_F_PATH = $(OLD_F_PATH)"
+ @$(ECHO)
diff --git a/trunk/milena/sandbox/green/demo/labeling/regional_maxima/regional_maxima.cc b/trunk/milena/sandbox/green/demo/labeling/regional_maxima/regional_maxima.cc
new file mode 100644
index 0000000..34801ed
--- /dev/null
+++ b/trunk/milena/sandbox/green/demo/labeling/regional_maxima/regional_maxima.cc
@@ -0,0 +1,333 @@
+// DEMO ON REGIONAL MAXIMA
+
+#include <mln/clustering/kmean2d.hh>
+
+#include <iostream>
+#include <sstream>
+
+#include <mln/img_path.hh>
+#include <mln/pw/value.hh>
+
+#include <mln/value/label_8.hh>
+#include <mln/value/rgb8.hh>
+
+#include <mln/core/macros.hh>
+#include <mln/core/image/image2d.hh>
+#include <mln/core/image/image3d.hh>
+
+#include <mln/data/transform.hh>
+#include <mln/fun/v2v/rgb8_to_rgbn.hh>
+
+#include <mln/io/ppm/load.hh>
+#include <mln/io/pgm/load.hh>
+#include <mln/io/pgm/save.hh>
+#include <mln/io/ppm/save.hh>
+#include <mln/io/plot/save_image_sh.hh>
+
+#include <mln/accu/stat/histo3d_rgb.hh>
+#include <mln/data/compute.hh>
+
+#include <mln/arith/revert.hh>
+#include <mln/labeling/regional_maxima.hh>
+#include <mln/core/alias/neighb3d.hh>
+#include <mln/core/routine/initialize.hh>
+#include <mln/literal/colors.hh>
+#include <mln/morpho/watershed/flooding.hh>
+#include <mln/morpho/opening/volume.hh>
+#include <mln/morpho/elementary/dilation.hh>
+#include <mln/data/stretch.hh>
+
+#include <mln/display/display_histo.hh>
+#include <mln/labeling/mean_values.hh>
+
+mln::image2d<mln::value::label_8>
+label_image(const mln::image2d<mln::value::rgb<5> >& input,
+ const mln::image3d<mln::value::label_8>& label)
+{
+ mln::image2d<mln::value::label_8> output(input.nrows(),
+ input.ncols());
+
+ mln_piter_(mln::image2d<mln::value::label_8>) po(output.domain());
+ mln_piter_(mln::image2d<mln::value::rgb<5> >) pi(input.domain());
+
+ for_all_2(po, pi)
+ {
+ output(po) = label(mln::point3d(input(pi).blue(),
+ input(pi).red(),
+ input(pi).green()));
+ }
+
+ return output;
+}
+
+
+
+void print_count(const mln::image3d<unsigned>& histo,
+ const mln::image3d<mln::value::label_8>& label,
+ const unsigned n_labels)
+{
+ unsigned count[255];
+ unsigned red[255];
+ unsigned green[255];
+ unsigned blue[255];
+
+ for (unsigned i = 0; i < n_labels; ++i)
+ {
+ count[i] = 0;
+ red[i] = 0.0;
+ green[i] = 0.0;
+ blue[i] = 0.0;
+ }
+
+ mln_piter_(mln::image3d<unsigned>) ph(histo.domain());
+ mln_piter_(mln::image3d<mln::value::label_8>) pl(label.domain());
+
+ for_all_2(ph, pl)
+ {
+ count[label(pl)] += histo(ph);
+ red[label(pl)] += histo(ph) * pl.row();
+ green[label(pl)] += histo(ph) * pl.col();
+ blue[label(pl)] += histo(ph) * pl.sli();
+ }
+
+ std::cout << std::endl;
+
+ for (unsigned i = 0; i < n_labels; ++i)
+ {
+ red[i] = red[i] / count[i];
+ green[i] = green[i] / count[i];
+ blue[i] = blue[i] / count[i];
+
+ std::cout << "count[" << i << "]("
+ << red[i] << ", " << green[i] << ", "
+ << blue[i] << ") = " << count[i] << std::endl;
+ }
+
+ std::cout << std::endl;
+}
+
+mln::image2d<mln::value::rgb<5> >
+merge(const mln::image2d<mln::value::rgb<5> >& input,
+ const mln::image3d<mln::value::label_8>& label)
+{
+ mln::image2d<mln::value::rgb<5> > output;
+
+ mln::initialize(output, input);
+
+ mln_piter_(mln::image2d<mln::value::rgb<5> >) pi(input.domain());
+ mln_piter_(mln::image2d<mln::value::rgb<5> >) po(output.domain());
+
+ for_all_2(pi, po)
+ {
+ if (0 < label(mln::point3d(input(pi).blue(),
+ input(pi).red(),
+ input(pi).green())))
+ {
+ output(po).red() = input(pi).red();
+ output(po).green() = input(pi).green();
+ output(po).blue() = input(pi).blue();
+ }
+ else
+ output(po) = mln::literal::red;
+ //output(po) = mln::literal::black;
+ }
+
+ return output;
+}
+
+
+//
+// Regional maxima image processing chain.
+// RGB8
+//
+void do_demo(const std::string& image)
+{
+ typedef mln::value::label_8 t_lbl8;
+ typedef mln::value::int_u8 t_int_u8;
+ typedef mln::value::rgb8 t_rgb8;
+ typedef mln::value::rgb<5> t_rgb5;
+ typedef mln::image3d<t_lbl8> t_image3d_lbl8;
+ typedef mln::image2d<t_lbl8> t_image2d_lbl8;
+ typedef mln::image2d<t_rgb8> t_image2d_rgb8;
+ typedef mln::image2d<t_rgb5> t_image2d_rgb5;
+ typedef mln::image2d<t_int_u8> t_image2d_int_u8;
+ typedef mln::image3d<unsigned> t_histo3d;
+ typedef mln::image2d<unsigned> t_histo2d;
+ typedef mln::fun::v2v::rgb8_to_rgbn<5> t_rgb8_to_rgbn;
+ typedef mln::accu::meta::stat::histo3d_rgb t_histo3d_fun;
+
+ t_image2d_rgb8 input_rgb8;
+ t_image2d_rgb5 input_rgb5;
+ t_image2d_rgb5 output_rgb5;
+ t_image2d_rgb5 mean_rgb5;
+ t_histo3d histo;
+ t_image2d_int_u8 projected;
+ t_image2d_int_u8 filtered;
+ t_histo3d opened;
+ t_image3d_lbl8 label;
+ t_image2d_lbl8 label_img;
+ t_image3d_lbl8 dilated;
+ t_lbl8 n_labels;
+ t_rgb5 value_rgb5;
+
+
+ // IMAGE LOADING PHASE
+ std::cout << "Image loading phase ..." << std::endl;
+ mln::io::ppm::load(input_rgb8, image.c_str());
+ input_rgb5 = mln::data::transform(input_rgb8, t_rgb8_to_rgbn());
+ mln::io::ppm::save(input_rgb5, "input_rgb5.ppm");
+
+
+ // HISTO COMPUTING PHASE
+ std::cout << "Histo computing phase ..." << std::endl;
+ histo = mln::data::compute(t_histo3d_fun(), input_rgb5);
+ projected = mln::display::display_histo3d_unsigned(histo);
+
+ mln::io::pgm::save(projected, "histo.pgm");
+ //mln::io::plot::save_image_sh(histo, "histo.sh");
+
+ // HISTO FILTERING PHASE
+ std::cout << "Histo filtering phase ..." << std::endl;;
+ opened = mln::morpho::opening::volume(histo, mln::c6(), 1000);
+ mln::io::plot::save_image_sh(opened, "opened.sh");
+ filtered = mln::display::display_histo3d_unsigned(opened);
+ mln::io::pgm::save(filtered, "filtered.pgm");
+
+
+ // HISTO LABELING PHASE
+ std::cout << "Histo labeling phase ..." << std::endl;
+ label = mln::labeling::regional_maxima(opened, mln::c6(), n_labels);
+ mln::io::plot::save_image_sh(label, "label.sh");
+
+
+ // HISTO DILATING PHASE
+ std::cout << "Histo dilating phase ..." << std::endl;
+ dilated = mln::morpho::elementary::dilation(label, mln::c18());
+ mln::io::plot::save_image_sh(dilated, "dilated.sh");
+
+ // PRINTING PHASE
+ std::cout << "Labels : " << n_labels << std::endl;
+ print_count(histo, dilated, n_labels);
+
+ // OUTPUT PHASE
+ std::cout << "Output phase ..." << std::endl;
+ output_rgb5 = merge(input_rgb5, dilated);
+ //mln::io::ppm::save(output_rgb5, "output_rgb5.ppm");
+ mln::io::plot::save_image_sh(output_rgb5, "output_rgb5.sh");
+
+
+ // LABELING IMG OUTPUT
+ std::cout << "Labeling img output phase ..." << std::endl;
+ label_img = label_image(input_rgb5, dilated);
+ mln::io::pgm::save(label_img, "label_img.pgm");
+
+
+ // BUILDING MEAN VALUES
+ std::cout << "Building mean values phase ..." << std::endl;
+ mean_rgb5 = mln::labeling::mean_values(input_rgb5, label_img, n_labels);
+ mln::io::ppm::save(mean_rgb5, "mean.ppm");
+}
+
+
+void demo(const std::string& image = SCRIBO_PPM_IMG_PATH"/mp00082c_50p.ppm",
+ //const std::string& image = OLENA_IMG_PATH"/house.ppm",
+ const unsigned k_center = 2,
+ //const unsigned k_center = 3,
+ const unsigned n_times = 10,
+ const unsigned watch_dog = 10)
+{
+ std::cout << "----------------------------------------" << std::endl;
+ std::cout << "Launching the demo with these parameters" << std::endl;
+ std::cout << "image : " << image << std::endl;
+ std::cout << "k_center : " << k_center << std::endl;
+ std::cout << "n_times : " << n_times << std::endl;
+ std::cout << "watch_dog : " << watch_dog << std::endl;
+ std::cout << "----------------------------------------" << std::endl;
+
+ do_demo(image);
+}
+
+void usage(const int argc, const char *args[])
+{
+ std::cout << "----------------------------------------" << std::endl;
+ std::cout << "argc : " << argc << std::endl;
+
+ for (int i = 0; i < argc; ++i)
+ std::cout << "args[" << i << "] : " << args[i] << std::endl;
+
+ std::cout << "----------------------------------------" << std::endl;
+ std::cout << "usage: kmean2d [image [k_center [n_times [watch_dog]]]]"
+ << std::endl;
+ std::cout << "pbm image (points to work with)" << std::endl;
+ std::cout << "unsigned k_center (number of centers)" << std::endl;
+ std::cout << "unsigned n_times (number of launching)" << std::endl;
+ std::cout << "unsigned watch_dog (convergence loop)" << std::endl;
+ std::cout << "----------------------------------------" << std::endl;
+}
+
+bool char_to_unsigned(const bool status, const char *arg, unsigned& val)
+{
+ bool result = false;
+
+ if (status)
+ {
+ std::istringstream arg_stream(arg);
+
+ arg_stream >> val;
+
+ result = !arg_stream.fail();
+ }
+
+ return result;
+}
+
+bool char_to_string(const bool status, const char *arg, std::string& val)
+{
+ bool result = false;
+
+ if (status)
+ {
+ std::istringstream arg_stream(arg);
+
+ arg_stream >> val;
+
+ return !arg_stream.fail();
+ }
+
+ return result;
+}
+
+int main(const int argc, const char *args[])
+{
+ std::string image("top");
+ unsigned k_center;
+ unsigned watch_dog;
+ unsigned n_times;
+ bool status = true;
+
+ switch (argc)
+ {
+ case 5: status = char_to_unsigned(status, args[4], watch_dog);
+ case 4: status = char_to_unsigned(status, args[3], n_times);
+ case 3: status = char_to_unsigned(status, args[2], k_center);
+ case 2: status = char_to_string(status, args[1], image); break;
+ case 1: status = true; break;
+ default: status = false;
+ }
+
+ if (status)
+ {
+ switch (argc)
+ {
+ case 1: demo(); break;
+ case 2: demo(image); break;
+ case 3: demo(image, k_center); break;
+ case 4: demo(image, k_center, n_times); break;
+ case 5: demo(image, k_center, n_times, watch_dog); break;
+ }
+ }
+ else
+ usage(argc, args);
+
+ return 0;
+}
--
1.5.6.5
1
0
* green/mln/clustering/kmean3d.hh: Fix mistakes in documentation.
---
trunk/milena/sandbox/ChangeLog | 6 +++
.../milena/sandbox/green/mln/clustering/kmean3d.hh | 33 +++++++++-----------
2 files changed, 21 insertions(+), 18 deletions(-)
diff --git a/trunk/milena/sandbox/ChangeLog b/trunk/milena/sandbox/ChangeLog
index eac8803..ea973fa 100644
--- a/trunk/milena/sandbox/ChangeLog
+++ b/trunk/milena/sandbox/ChangeLog
@@ -1,5 +1,11 @@
2009-10-15 Yann Jacquelet <jacquelet(a)lrde.epita.fr>
+ Correct kmean3d documentation.
+
+ * green/mln/clustering/kmean3d.hh: Fix mistakes in documentation.
+
+2009-10-15 Yann Jacquelet <jacquelet(a)lrde.epita.fr>
+
Make Théo projection for histogram available.
* green/mln/display: New directory.
diff --git a/trunk/milena/sandbox/green/mln/clustering/kmean3d.hh b/trunk/milena/sandbox/green/mln/clustering/kmean3d.hh
index 6aebefc..fb1a8df 100644
--- a/trunk/milena/sandbox/green/mln/clustering/kmean3d.hh
+++ b/trunk/milena/sandbox/green/mln/clustering/kmean3d.hh
@@ -31,11 +31,11 @@
/// \brief Implements the optimized kmean algorithm.
///
/// This algorithm is optimized in the way it proceeds directly with
-/// the greylevel attribute inspite of the pixel attribute. The
+/// the rgb values inspite of the pixel attribute. The
/// algorithm is independant from the image dimension. But, we have to
/// compute one time the histogram. In fact, we move a recurrent cost
-/// to a fix cost in the complexity. This version is very adapted to
-/// images with small quantification.
+/// to a fix cost in the complexity. This version is adapted to
+/// image with small quantification.
#include <limits.h>
#include <iostream>
@@ -86,12 +86,12 @@ namespace mln
{
/// \brief Implements the kmean algorithm in a specific way.
///
- /// This version of the kmean algorithm uses a greyscale image as input,
+ /// This version of the kmean algorithm uses a rgb image as input,
/// temporary images for computations and produces images as result. Images
- /// play the role of matrix or vector in standard statistic algoritm.
+ /// play the role of matrix or vector in standard statistic algorithm.
///
/// T is the type used for computations (float or double).
- /// n is the quantification for the image grayscale.
+ /// n is the quantification for the rgb image.
template <typename T, unsigned n>
struct kmean3d
{
@@ -208,7 +208,7 @@ namespace mln
/// \brief Two ways: Regular greylevel tick or random greylevel value or.
///
/// There is two way to proceed the initialization. First of all, we
- /// divide the greyscale in regular tick and we assigne them to the mean
+ /// divide the rgb space in regular tick and we assigne them to the mean
/// of the centers. Finaly, we can ask random initialization along the
/// greyscale axis. The second process is needed to launch_n_times the
/// kmean and converge to the best descent.
@@ -388,17 +388,17 @@ namespace mln
/// \}
- /// Greylevels description.
+ /// rgb image description.
/// \{
- /// \brief The information are concerned with the greylevel input image.
+ /// \brief The information are concerned with the rgb input image.
///
- /// The group image allow us to decide which greylevel (and of course
+ /// The group image allow us to decide which rgb color (and of course
/// which pixel) is assigned to a center. The distance image give us a
/// clue on how a greylevel could contribute to a center. The summation
- /// over the greylevels of a center give us the within variance.
+ /// over the rgb space of a center give us the within variance.
- t_group_img _group; // g x 1 because dim(t_value) = 1
- t_distance_img _distance; // label x graylevel
+ t_group_img _group; // g x 3 because dim(t_value) = 3
+ t_distance_img _distance; // label x rgb space
/// \}
@@ -1008,8 +1008,6 @@ namespace mln
{
trace::entering("mln::clustering::kmean3d::update_mean");
- /// FIXME VERIFIER QUE L'ON PEUT OBTENIR UNE IMAGE EN NDG SIGNE
-
// avec g le niveau de gris (signed or not signed)
// w[g] la classe de g sous forme d'image
// h[g] l'histogramme de l'image sous forme d'image
@@ -1035,7 +1033,6 @@ namespace mln
for_all(rgb)
{
- // peut être faut-il le decomposer par composantes
_mean[_group(rgb)][0] += rgb.row() * _histo(rgb);
_mean[_group(rgb)][1] += rgb.col() * _histo(rgb);
_mean[_group(rgb)][2] += rgb.sli() * _histo(rgb);
@@ -1275,8 +1272,8 @@ namespace mln
// Debugging code
update_cnv();
- std::cout << "_current_step : " << _current_step << std::endl;
- std::cout << "_within_variance : " << _within_variance << std::endl;
+ //std::cout << "_current_step : " << _current_step << std::endl;
+ //std::cout << "_within_variance : " << _within_variance << std::endl;
++_current_step;
}
--
1.5.6.5
1
0
* green/mln/display: New directory.
* green/mln/display/display_histo.hh: New library file.
* green/mln/display/project_histo.hh: New library file.
* green/mln/fun/v2v/log.hh: New library file.
---
trunk/milena/sandbox/ChangeLog | 9 ++
.../sandbox/green/mln/display/display_histo.hh | 92 +++++++++++++++++++
.../sandbox/green/mln/display/project_histo.hh | 97 ++++++++++++++++++++
trunk/milena/sandbox/green/mln/fun/v2v/log.hh | 70 ++++++++++++++
4 files changed, 268 insertions(+), 0 deletions(-)
create mode 100644 trunk/milena/sandbox/green/mln/display/display_histo.hh
create mode 100644 trunk/milena/sandbox/green/mln/display/project_histo.hh
create mode 100644 trunk/milena/sandbox/green/mln/fun/v2v/log.hh
diff --git a/trunk/milena/sandbox/ChangeLog b/trunk/milena/sandbox/ChangeLog
index 2ab7bd8..eac8803 100644
--- a/trunk/milena/sandbox/ChangeLog
+++ b/trunk/milena/sandbox/ChangeLog
@@ -1,3 +1,12 @@
+2009-10-15 Yann Jacquelet <jacquelet(a)lrde.epita.fr>
+
+ Make Th�o projection for histogram available.
+
+ * green/mln/display: New directory.
+ * green/mln/display/display_histo.hh: New library file.
+ * green/mln/display/project_histo.hh: New library file.
+ * green/mln/fun/v2v/log.hh: New library file.
+
2009-10-14 Yann Jacquelet <jacquelet(a)lrde.epita.fr>
Add spaces to conform to the LRDE coding norm.
diff --git a/trunk/milena/sandbox/green/mln/display/display_histo.hh b/trunk/milena/sandbox/green/mln/display/display_histo.hh
new file mode 100644
index 0000000..d34914c
--- /dev/null
+++ b/trunk/milena/sandbox/green/mln/display/display_histo.hh
@@ -0,0 +1,92 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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_DISPLAY_DISPLAY_HISTO_HH
+# define MLN_DISPLAY_DISPLAY_HISTO_HH
+
+# include <mln/data/stretch.hh>
+# include <mln/fun/v2v/log.hh>
+# include <mln/display/project_histo.hh>
+# include <mln/accu/math/sum.hh>
+
+/// \file
+///
+/// \brief Allow the complete visualization of a 3d histogram by projection.
+///
+/// The 3d histogram is projected in red/green space by accumulating around the
+/// the blue dimension (green and blue composantes are being correlated). In
+/// fact, we sum in along the blue direction. Then, we stretch value to feet
+/// pgm format.
+
+
+namespace mln
+{
+
+ namespace display
+ {
+
+ // Forward declaration.
+ image2d<value::int_u8>
+ display_histo3d_unsigned(const image3d<unsigned>& histo);
+
+#ifndef MLN_INCLUDE_ONLY
+
+ /// \brief Allow the visualization of a 3d histogram by projection.
+ ///
+ /// The 3d histogram is projected in red/green space by
+ /// accumulating around the the blue dimension (green and blue
+ /// composantes are being correlated). In fact, we sum in along
+ /// the blue direction. Then, we stretch value to feet pgm
+ /// format.
+ ///
+ /// \parameter[in] histo the histogram in 3d.
+ /// \result return a equivalent 2d image.
+
+
+ image2d<value::int_u8>
+ display_histo3d_unsigned(const image3d<unsigned>& histo)
+ {
+ typedef accu::math::sum<unsigned,unsigned> t_sum;
+ typedef value::int_u8 t_int_u8;
+ typedef fun::v2v::log<float> t_log;
+
+ image2d<unsigned> proj = project_histo<t_sum,2>(histo);
+ image2d<t_int_u8> proj_int = data::stretch(t_int_u8(),
+ data::transform(proj,
+ t_log()));
+ return proj_int;
+ }
+
+#endif // ! MLN_INCLUDE_ONLY
+
+
+ } // end of namespace mln::transform
+
+} // end of namespace mln
+
+
+#endif // ! MLN_DISPLAY_DISPLAY_HISTO_HH
diff --git a/trunk/milena/sandbox/green/mln/display/project_histo.hh b/trunk/milena/sandbox/green/mln/display/project_histo.hh
new file mode 100644
index 0000000..63ea84e
--- /dev/null
+++ b/trunk/milena/sandbox/green/mln/display/project_histo.hh
@@ -0,0 +1,97 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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_DISPLAY_PROJECT_HISTO_HH
+# define MLN_DISPLAY_PROJECT_HISTO_HH
+
+# include <mln/core/image/image2d.hh>
+# include <mln/core/image/image3d.hh>
+# include <mln/core/image/dmorph/unproject_image.hh>
+# include <mln/fun/v2v/projection.hh>
+
+# include <mln/accu/image/init.hh>
+# include <mln/accu/image/take.hh>
+# include <mln/accu/image/to_result.hh>
+
+/// \file
+///
+/// \brief Allow the visualization of 3d histogram.
+/// The 3d histogram is projected in 2d such as the data in that direction
+/// are accumulated to the two others.
+
+namespace mln
+{
+
+ namespace display
+ {
+
+ // Forward declaration.
+ template <typename A, unsigned direction, typename V>
+ image2d<mln_result(A)>
+ project_histo(const image3d<V>& histo);
+
+#ifndef MLN_INCLUDE_ONLY
+
+ /// \brief Allow the visualization of 3d histogram.
+ ///
+ /// The 3d histogram is projected in 2d such as the data in that direction
+ /// are accumulated to the two others.
+ ///
+ /// Parameter A is the type of accumulator, for instance, accu::math::sum.
+ /// Parameter direction is the way of the projection, for instance blue one.
+ /// Parameter V is the value we use to accumulate information.
+ ///
+ /// \prameter[in] the histogram 3d.
+ /// \result the 2d projection of the 3d histogram.
+
+ template <typename A, unsigned direction, typename V>
+ image2d<mln_result(A)>
+ project_histo(const image3d<V>& histo)
+ {
+ typedef fun::v2v::projection<point3d,direction> t_projection;
+
+ image2d<A> histo_accu(histo.nrows(), histo.ncols());
+
+ accu::image::init(histo_accu);
+
+ accu::image::take(unproject(histo_accu,
+ histo.domain(),
+ t_projection()).rw(),
+ histo);
+
+ return accu::image::to_result(histo_accu);
+ }
+
+#endif // ! MLN_INCLUDE_ONLY
+
+
+ } // end of namespace mln::transform
+
+} // end of namespace mln
+
+
+#endif // ! MLN_DISPLAY_PROJECT_HISTO_HH
diff --git a/trunk/milena/sandbox/green/mln/fun/v2v/log.hh b/trunk/milena/sandbox/green/mln/fun/v2v/log.hh
new file mode 100644
index 0000000..d6905fa
--- /dev/null
+++ b/trunk/milena/sandbox/green/mln/fun/v2v/log.hh
@@ -0,0 +1,70 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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_FUN_V2V_LOG_HH
+# define MLN_FUN_V2V_LOG_HH
+
+/// \file
+///
+/// \brief Take the logarithm of each pixel value.
+
+namespace mln
+{
+
+ namespace fun
+ {
+
+ namespace v2v
+ {
+
+ /// \brief Take the logarithm of each pixel value.
+ ///
+ /// \ingroup modfunv2v
+
+ template <typename T>
+ struct log : Function_v2v< log<T> >
+ {
+ typedef T argument;
+ typedef T result;
+
+ result operator()(const argument v) const
+ {
+ mln_precondition(v > -1);
+
+ result tmp = std::log(v+1);
+
+ return tmp;
+ }
+ };
+
+ } // end of namespace mln::fun::v2v
+
+ } // end of namespace mln::fun
+
+} // end of namespace mln
+
+#endif // ! MLN_FUN_V2V_LOG_HH
--
1.5.6.5
1
0