---
milena/mln/core/site_set/p_vertices.hh | 281 ++++++++++++++++++++++++
milena/mln/util/internal/graph_vertex_psite.hh | 190 ++++++++++++++++
milena/tests/core/site_set/Makefile.am | 4 +-
milena/tests/core/site_set/p_vertices.cc | 91 ++++++++
4 files changed, 565 insertions(+), 1 deletions(-)
create mode 100644 milena/mln/core/site_set/p_vertices.hh
create mode 100644 milena/mln/util/internal/graph_vertex_psite.hh
create mode 100644 milena/tests/core/site_set/p_vertices.cc
diff --git a/milena/mln/core/site_set/p_vertices.hh b/milena/mln/core/site_set/p_vertices.hh
new file mode 100644
index 0000000..461bd51
--- /dev/null
+++ b/milena/mln/core/site_set/p_vertices.hh
@@ -0,0 +1,281 @@
+ // Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE)
+ //
+ // This file is part of the Olena Library. This library is free
+ // software; you can redistribute it and/or modify it under the terms
+ // of the GNU General Public License version 2 as published by the
+ // Free Software Foundation.
+ //
+ // This library is distributed in the hope that it will be useful,
+ // but WITHOUT ANY WARRANTY; without even the implied warranty of
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ // General Public License for more details.
+ //
+ // You should have received a copy of the GNU General Public License
+ // along with this library; see the file COPYING. If not, write to
+ // the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+ // Boston, MA 02111-1307, USA.
+ //
+ // As a special exception, you may use this file as part of a free
+ // software library without restriction. Specifically, if other files
+ // instantiate templates or use macros or inline functions from this
+ // file, or you compile this file and link it with other files to
+ // produce an executable, this file does not by itself cause the
+ // resulting executable to be covered by the GNU General Public
+ // License.
+ // reasons why the executable file might be covered by the GNU General
+ // Public License.
+
+#ifndef MLN_CORE_SITE_SET_P_VERTICES_HH
+# define MLN_CORE_SITE_SET_P_VERTICES_HH
+
+ /// \file mln/core/site_set/p_vertices.hh
+ /// \brief Definition of a point set based on a graph.
+
+# include <mln/core/internal/site_set_base.hh>
+# include <mln/core/site_set/p_graph_piter.hh>
+# include <mln/util/internal/graph_vertex_psite.hh>
+# include <mln/util/graph.hh>
+
+ //# include <mln/util/tracked_ptr.hh>
+
+ //# include <mln/core/image/graph_psite.hh>
+ //# include <mln/core/site_set/p_vertices_piter.hh>
+
+namespace mln
+{
+ // Forward declaration.
+ template <typename G, typename F> struct p_vertices;
+
+ namespace trait
+ {
+ template <typename G, typename F>
+ struct site_set_< p_vertices<G, F> >
+ {
+ typedef trait::site_set::nsites::known nsites;
+ // FIXME: !
+ typedef trait::site_set::bbox::unknown bbox;
+ typedef trait::site_set::contents::fixed contents;
+ typedef trait::site_set::arity::unique arity;
+ };
+ } // end of namespace mln::trait
+
+
+ template <typename G, typename F>
+ class p_vertices
+ : public internal::site_set_base_< typename F::result, p_vertices<G, F> >
+ {
+ typedef util::vertex<G> vertex_t;
+
+ typedef p_vertices<G, F> self_;
+ typedef internal::site_set_base_< typename F::result, self_ > super_;
+
+ typedef G graph_t;
+
+ public:
+ /// \brief Construct a graph psite set from a graph of points.
+ ///
+ /// \param gr The graph upon which the graph psite set is built.
+ ///
+ /// \a gr is \em copied internally, so that the graph psite set is
+ /// still valid after the initial graph has been removed.
+ p_vertices(const graph_t& gr, const F& f);
+
+ /// Associated types.
+ /// \{
+ /// Element associated type.
+ typedef mln_site(super_) element;
+ /// Point_Site associated type.
+ typedef internal::vertex_psite<G, F> psite;
+
+ /// Forward Site_Iterator associated type.
+ typedef p_graph_piter< self_, mln_vertex_fwd_iter(G) > fwd_piter;
+
+ /// Backward Site_Iterator associated type.
+ typedef p_graph_piter< self_, mln_vertex_bkd_iter(G) > bkd_piter;
+
+ /// Site_Iterator associated type.
+ typedef fwd_piter piter;
+ /// \}
+
+ /// \brief Return The number of points (sites) of the set, i.e.,
+ /// the number of \em vertices.
+ ///
+ /// Required by the mln::Point_Set concept.
+ /* FIXME: Return type should be std::size_t (see
+ mln/core/concept/site_set.hh). */
+ size_t nsites() const;
+
+ /// Return The number of vertices in the graph.
+ std::size_t nvertices() const;
+
+ /// Is this site set valid?
+ bool is_valid() const;
+ /// Invalidate this site set.
+ void invalidate();
+
+ /// Does this site set has \a p?
+ bool has(const psite& p) const;
+
+ /// Does this site set has \a v?
+ template <typename G2>
+ bool has(const util::vertex<G2>& p) const;
+
+ // FIXME: Dummy.
+ std::size_t memory_size() const;
+
+ /// Accessors.
+ /// \{
+ /// Return the graph associated to this site set (const version)
+ const graph_t& g() const;
+ /// Return the association function.
+ F function() const;
+ /// \}
+
+ private:
+ mlc_const(graph_t)* g_;
+ F f_;
+ };
+
+
+ /// \brief Comparison between two mln::p_vertices's.
+ ///
+ /// Two mln::p_vertices's are considered equal if they share the
+ /// same graph.
+ template <typename G, typename F>
+ bool
+ operator==(const p_vertices<G, F>& lhs, const p_vertices<G, F>& rhs);
+
+
+ /* FIXME: Extend the `ord' mechanism instead of this ill-defined
+ pseudo-order. */
+
+ /// \brief Inclusion of a mln::p_vertices in another one.
+ ///
+ /// This inclusion relation is very strict for the moment, since our
+ /// infrastructure for graphs is simple: a mln::p_vertices is included
+ /// in another one if their are equal.
+ ///
+ /// \todo Refine this later, when we are able to express subgraph
+ /// relations.
+ template <typename G, typename F>
+ bool
+ operator<=(const p_vertices<G, F>& lhs, const p_vertices<G, F>& rhs);
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename G, typename F>
+ inline
+ p_vertices<G, F>::p_vertices(const graph_t& g, const F& f)
+ : g_ (&g), f_(f)
+ {
+ }
+
+ template <typename G, typename F>
+ inline
+ size_t
+ p_vertices<G, F>::nsites() const
+ {
+ return nvertices();
+ }
+
+ template <typename G, typename F>
+ inline
+ std::size_t
+ p_vertices<G, F>::nvertices() const
+ {
+ return this->g_->v_nmax();
+ }
+
+ template <typename G, typename F>
+ inline
+ bool
+ p_vertices<G, F>::is_valid() const
+ {
+ return g_ != 0;
+ }
+
+ template <typename G, typename F>
+ inline
+ void
+ p_vertices<G, F>::invalidate()
+ {
+ g_ = 0;
+ }
+
+ template <typename G, typename F>
+ inline
+ bool
+ p_vertices<G, F>::has(const psite& p) const
+ {
+ mln_precondition(is_valid());
+ return has(p.v());
+ }
+
+ template <typename G, typename F>
+ template <typename G2>
+ inline
+ bool
+ p_vertices<G, F>::has(const util::vertex<G2>& p) const
+ {
+ mln_precondition(is_valid());
+ return
+ // Check whether P is compatible with this psite set.
+ (p.g() == g_) &&
+ // Check that the vertex id of P belongs to the range of valid
+ // vertex ids.
+ (p.is_valid());
+ }
+
+ template <typename G, typename F>
+ inline
+ std::size_t
+ p_vertices<G, F>::memory_size() const
+ {
+ // FIXME: Dummy; implement (see other site sets).
+ abort();
+ return 0;
+ }
+
+ template <typename G, typename F>
+ inline
+ const typename p_vertices<G, F>::graph_t&
+ p_vertices<G, F>::g() const
+ {
+ mln_precondition(is_valid());
+ return *g_;
+ }
+
+ template <typename G, typename F>
+ inline
+ F
+ p_vertices<G, F>::function() const
+ {
+ return f_;
+ }
+
+ template <typename G, typename F>
+ bool
+ operator==(const p_vertices<G, F>& lhs, const p_vertices<G, F>& rhs)
+ {
+ /* FIXME: We should not rely on pointer equality here, as graph
+ will soon become shells using (shared) tracked pointers to
+ actual data. So, delegate the equality test to the graphs
+ themselves. */
+ return (*lhs.g_) == (*rhs.g_);
+ }
+
+ template <typename G, typename F>
+ bool
+ operator<=(const p_vertices<G, F>& lhs, const p_vertices<G, F>& rhs)
+ {
+ return lhs == rhs;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+} // end of mln
+
+
+#endif // MLN_CORE_SITE_SET_P_VERTICES_HH
diff --git a/milena/mln/util/internal/graph_vertex_psite.hh b/milena/mln/util/internal/graph_vertex_psite.hh
new file mode 100644
index 0000000..b2fadf9
--- /dev/null
+++ b/milena/mln/util/internal/graph_vertex_psite.hh
@@ -0,0 +1,190 @@
+// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License.
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef MLN_UTIL_INTERNAL_GRAPH_VERTEX_PSITE_HH
+# define MLN_UTIL_INTERNAL_GRAPH_VERTEX_PSITE_HH
+
+# include <mln/core/concept/pseudo_site.hh>
+
+namespace mln
+{
+
+ template <typename G, typename F> class p_vertices;
+
+} // end of namespace mln
+
+/// \file mln/util/internal/graph_vertex_psite.hh
+/// \brief Implementation of p_vertices psite.
+
+namespace mln
+{
+
+ namespace internal
+ {
+
+ template <typename G, typename F>
+ class vertex_psite : public mln::Pseudo_Site< vertex_psite<G, F> >,
+ public internal::proxy_impl< const typename F::result&, vertex_psite<G, F> >
+ {
+ typedef Pseudo_Site< vertex_psite<G, F> > super;
+
+ public:
+ typedef p_vertices<G, F> site_set;
+ typedef mlc_const(site_set) target;
+ typedef typename F::result site;
+
+ vertex_psite();
+ vertex_psite(const target& t);
+
+ void change_target(const target& new_target);
+ void change_vertex_id(unsigned id_v);
+ void update_id(unsigned v_id);
+
+ const target* target_() const; // Hook to the target.
+
+ bool is_valid() const;
+ void invalidate();
+
+ typedef const site& q_subject;
+ const site& subj_();
+ const site& to_site() const;
+
+ const util::vertex<G>& v() const;
+
+ protected:
+ target* t_;
+ util::vertex<G> v_;
+ };
+
+ } // end of namespace internal
+
+} // end of namespace mln
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+namespace mln
+{
+
+ namespace internal
+ {
+
+ template <typename G, typename F>
+ inline
+ vertex_psite<G, F>::vertex_psite()
+ : t_(0)
+ {
+ }
+
+ template <typename G, typename F>
+ inline
+ vertex_psite<G, F>::vertex_psite(const target& t)
+ : t_(0)
+ {
+ change_target(t);
+ }
+
+ template <typename G, typename F>
+ inline
+ void
+ vertex_psite<G, F>::change_target(const target& new_target)
+ {
+ t_ = &new_target;
+ v_.change_graph(new_target.g());
+ }
+
+ template <typename G, typename F>
+ inline
+ void
+ vertex_psite<G, F>::change_vertex_id(unsigned id_v)
+ {
+ v_.update_id(id_v);
+ }
+
+ template <typename G, typename F>
+ inline
+ void
+ vertex_psite<G, F>::update_id(unsigned v_id)
+ {
+ v_.update_id(v_id);
+ }
+
+ template <typename G, typename F>
+ inline
+ const typename vertex_psite<G, F>::target*
+ vertex_psite<G, F>::target_() const
+ {
+ return t_;
+ }
+
+ template <typename G, typename F>
+ inline
+ bool
+ vertex_psite<G, F>::is_valid() const
+ {
+ return t_ != 0 && t_->is_valid();
+ }
+
+ template <typename G, typename F>
+ inline
+ void
+ vertex_psite<G, F>::invalidate()
+ {
+ t_ = 0;
+ }
+
+ template <typename G, typename F>
+ inline
+ const typename vertex_psite<G, F>::site&
+ vertex_psite<G, F>::subj_()
+ {
+ return to_site();
+ }
+
+ template <typename G, typename F>
+ inline
+ const typename vertex_psite<G, F>::site&
+ vertex_psite<G, F>::to_site() const
+ {
+ return t_->function()(v_);
+ }
+
+ template <typename G, typename F>
+ inline
+ const util::vertex<G>&
+ vertex_psite<G, F>::v() const
+ {
+ return v_;
+ }
+
+ } // end of namespace internal
+
+} // end of namespace mln
+# endif // !MLN_INCLUDE_ONLY
+
+#endif // !MLN_UTIL_INTERNAL_GRAPH_VERTEX_PSITE_HH
+
diff --git a/milena/tests/core/site_set/Makefile.am b/milena/tests/core/site_set/Makefile.am
index c1f1e14..d1b2cf6 100644
--- a/milena/tests/core/site_set/Makefile.am
+++ b/milena/tests/core/site_set/Makefile.am
@@ -10,7 +10,8 @@ check_PROGRAMS = \
p_queue \
p_queue_fast \
p_set \
- pset_if
+ pset_if \
+ p_vertices
p_array_SOURCES = p_array.cc
##p_bgraph_SOURCES = p_bgraph.cc
@@ -20,5 +21,6 @@ p_queue_SOURCES = p_queue.cc
p_queue_fast_SOURCES = p_queue_fast.cc
p_set_SOURCES = p_set.cc
pset_if_SOURCES = pset_if.cc
+p_vertices_SOURCES = p_vertices.cc
TESTS = $(check_PROGRAMS)
diff --git a/milena/tests/core/site_set/p_vertices.cc b/milena/tests/core/site_set/p_vertices.cc
new file mode 100644
index 0000000..6db4609
--- /dev/null
+++ b/milena/tests/core/site_set/p_vertices.cc
@@ -0,0 +1,91 @@
+// Copyright (C) 2008 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+/*! \file tests/core/site_set/p_vertices.cc
+ *
+ * \brief Tests on mln::p_vertices.
+ */
+
+#include <mln/util/graph.hh>
+#include <mln/core/alias/point2d.hh>
+#include <mln/core/site_set/p_vertices.hh>
+
+template <typename G>
+struct my_fun
+{
+ typedef mln::point2d result;
+
+ const result& operator()(const mln::util::vertex<G>& v) const
+ {
+ static mln::point2d res(0, 0);
+ res.row() = v.id();
+ return res;
+ }
+
+};
+
+int main()
+{
+ using namespace mln;
+
+ util::graph g;
+ g.add_vertex (); // 0
+ g.add_vertex (); // 1
+ g.add_vertex (); // 2
+ g.add_vertex (); // 3
+ g.add_vertex (); // 4
+ g.add_vertex (); // 5
+ g.add_edge (0, 1);
+ g.add_edge (0, 2);
+ g.add_edge (3, 4);
+ g.add_edge (4, 5);
+ g.add_edge (5, 4);
+ g.add_edge (1, 0);
+ g.add_edge (5, 3);
+ g.add_edge (2, 1);
+
+// typedef point2d (*fun_t)(const util::vertex<util::graph>&);
+ typedef p_vertices<util::graph, my_fun<util::graph> > p_vertices;
+ p_vertices pv(g, my_fun<util::graph>());
+
+ {
+ mln_fwd_piter_(p_vertices) p(pv);
+ unsigned i = 0;
+ for_all(p)
+ mln_assertion(p.p_hook_().v().id() == i++);
+ mln_assertion(i == g.v_nmax());
+ }
+ {
+ mln_bkd_piter_(p_vertices) p(pv);
+ unsigned i = g.v_nmax() - 1;
+ for_all(p)
+ mln_assertion(p.p_hook_().v().id() == i--);
+ mln_assertion(i == UINT_MAX);
+ }
+
+ return 0;
+}
--
1.5.6.5
https://svn.lrde.epita.fr/svn/oln/branches/cleanup-2008/milena
Index: ChangeLog
from Ugo Jardonnet <ugo.jardonnet(a)lrde.epita.fr>
Start to integrate registration in Milena.
* mln/binarization/binarization.hh: Remove whitesapce.
* mln/registration: New.
* mln/registration/multiscale.hh: Multiscale registration of tow images.
* mln/registration/registration.hh: Simple registration of tow images.
* mln/registration/icp.hh: ICP registration of two p_array.
icp.hh | 159 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
multiscale.hh | 114 ++++++++++++++++++++++++++++++++++++++++
registration.hh | 119 +++++++++++++++++++++++++++++++++++++++++
3 files changed, 392 insertions(+)
Index: mln/binarization/binarization.hh
Index: mln/registration/multiscale.hh
--- mln/registration/multiscale.hh (revision 0)
+++ mln/registration/multiscale.hh (revision 0)
@@ -0,0 +1,114 @@
+// Copyright (C) 2008 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef MLN_REGISTRATION_MULTISCALE_HH
+# define MLN_REGISTRATION_MULTISCALE_HH
+
+# include <mln/registration/icp.hh>
+
+namespace mln
+{
+
+ namespace registration
+ {
+
+ template <typename I, typename J>
+ inline
+ composed< rotation<I::psite::dim, float>, translation<I::Psite::dim, float> >
+ multiscale(const Image<I>& cloud,
+ const Image<J>& surface,
+ const float q,
+ const unsigned nb_it);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace impl
+ {
+
+ template <typename I, typename J>
+ inline
+ composed< rotation<P::dim, float>, translation<P::dim, float> >
+ multiscale_(const Image<I>& cloud,
+ const Image<J>& surface,
+ const float q,
+ const unsigned nb_it)
+ {
+ // Shuffle cloud
+ shuffle(cloud);
+
+ //working box
+ const box<point2d> working_box =
+ enlarge(bigger(geom::bbox(c), geom::bbox(x)), 100);
+
+ //make a lazy_image map via function closest_point
+ closest_point<mln_psite_(image2db)> fun(x, working_box); //FIXME: to port
+ lazy_image<image2d<bool>, closest_point<mln_psite_(image2db)>, box2d >
+ map(fun, fun.domain());
+
+ //init rigid transform qk
+ composed< rotation<I::psite::dim, float>, translation<I::psite::dim, float> > qk;
+
+ //run registration
+ for (int e = nb_it-1; e >= 0; e--)
+ {
+ unsigned l = cloud.nsites() / std::pow(q, e);
+ l = (l<1) ? 1 : l;
+ impl::registration_(cloud, map, qk, l, 1e-3);
+ }
+ return qk;
+ }
+
+ }
+
+ template <typename I, typename J>
+ inline
+ composed< rotation<P::dim, float>, translation<P::dim, float> >
+ multiscale(const Image<I>& cloud,
+ const Image<J>& surface,
+ const float q,
+ const unsigned nb_it)
+ {
+ trace::entering("registration::registration");
+
+ mln_precondition(P::dim == 3 || P::dim == 2);
+
+ impl::multiscale_(cloud, surface, q, nb_it);
+
+ trace::exiting("registration::registration");
+
+ return qk;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::registration
+
+} // end of namespace mln
+
+
+#endif // ! MLN_REGISTRATION_MULTISCALE_HH
Index: mln/registration/registration.hh
--- mln/registration/registration.hh (revision 0)
+++ mln/registration/registration.hh (revision 0)
@@ -0,0 +1,119 @@
+// Copyright (C) 2008 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef MLN_REGISTRATION_REGISTRATION_HH
+# define MLN_REGISTRATION_REGISTRATION_HH
+
+/*! \file mln/registration/registration.hh
+ *
+ * \brief image registration
+ */
+
+# include <mln/registration/icp.hh>
+# include <mln/core/image/lazy_image.hh>
+
+namespace mln
+{
+
+ namespace registration
+ {
+
+
+ using namespace fun::x2x::geom;
+
+ /*! Register an image \p cloud over the image \p surface.
+ */
+ template <typename I, typename J>
+ inline
+ composed< rotation<I::psite::dim, float>, translation<I::psite::dim, float> >
+ registration(const Image<I>& cloud,
+ const Image<J>& surface);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace impl
+ {
+
+ template <typename I, typename J>
+ inline
+ composed< rotation<I::psite::dim, float>, translation<I::psite::dim, float> >
+ registration_(const Image<I>& cloud,
+ const Image<J>& surface)
+ {
+ p_array<mln_psite(I)> c = convert::to< p_array<mln_psite(I)> >(cloud);
+ p_array<mln_psite(J)> x = convert::to< p_array<mln_psite(I)> >(surface);
+
+ //init rigid transform qk
+ composed< rotation<I::P::dim, float>, translation<I::P::dim, float> > qk;
+
+ //working box
+ const box<point2d> working_box =
+ enlarge(bigger(geom::bbox(c), geom::bbox(x)), 100);
+
+ //make a lazy_image map via function closest_point
+ closest_point<mln_psite(I)> fun(x, working_box); //FIXME: to port
+ lazy_image<mln_ch_value(I,bool), closest_point<mln_psite(I)>, box2d >
+ map(fun, fun.domain());
+
+ //run registration
+ registration::icp(c, map, qk, l, 1e-3);
+
+ }
+
+ }
+
+ template <typename I, typename J>
+ inline
+ composed< rotation<I::psite::dim, float>, translation<I::psite::dim, float> >
+ registration(const Image<I>& cloud,
+ const Image<J>& surface)
+ {
+ trace::entering("registration::registration");
+
+ mln_precondition(I::psite::dim == J::psite::dim);
+ mln_precondition(I::psite::dim == 3 || J::psite::dim == 2);
+
+ composed< rotation<I::psite::dim, float>, translation<I::psite::dim, float> >
+ qk = impl::registration_(cloud, surface);
+
+ trace::exiting("registration::registration");
+
+ return qk;
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+
+ } // end of namespace mln::registration
+
+
+} // end of namespace mln
+
+
+#endif // ! MLN_REGISTRATION_REGISTRATION_HH
Index: mln/registration/icp.hh
--- mln/registration/icp.hh (revision 0)
+++ mln/registration/icp.hh (revision 0)
@@ -0,0 +1,159 @@
+// Copyright (C) 2008 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef MLN_REGISTRATION_ICP_HH
+# define MLN_REGISTRATION_ICP_HH
+
+/*! \file mln/registration/icp.hh
+ *
+ * \brief Register an image over an another using the ICP algorithm.
+ */
+
+#include <mln/fun/x2x/all.hh>
+
+namespace mln
+{
+
+ namespace registration
+ {
+
+ using namespace fun::x2x::geom;
+
+ /*! Register point in \p c using a map of closest points \p map
+ *
+ * \param[in] c The cloud of points.
+ * \param[in] map The map of closest points.
+ * \param[in] epsilon ICP stops if sqr_norm(qk - qk-1) /
+ * sqr_norm(qk) > epsilon
+ * \param[out] qk The rigid transformation obtained.
+ *
+ * \pre \p ima has to be initialized.
+ */
+ template <typename P, typename M>
+ inline
+ composed<rotation<2u, float>, translation<2u, float> >
+ icp(const p_array<P>& c, const M& map,
+ const float epsilon = 1e-3);
+
+ /*!
+ * \fixme
+ */
+ template <typename P, typename M, typename T>
+ inline
+ void
+ icp_subset(const p_array<P>& c,
+ const M& map,
+ T& qk,
+ const unsigned c_length,
+ const float epsilon = 1e-3);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace impl
+ {
+
+ template <typename P, typename M, typename T>
+ inline
+ void
+ icp_(const p_array<P>& c,
+ const unsigned c_length,
+ const M& map,
+ T& qk,
+ const float epsilon = 1e-3)
+ {
+ trace::entering("registration::impl::icp_");
+
+ buffer<4,T> buf_qk;
+ buffer<3,float> buf_dk;
+
+ float d_k = 10000;
+ p_array<P> Ck(c);
+
+ algebra::vec<P::dim,float> mu_C = center(c, c_length), mu_Xk;
+
+ buf_qk.store(qk);
+
+ qk.apply_on(c, Ck, c_length);
+
+ unsigned int k = 0;
+ do {
+ buf_dk.store(d_k);
+
+ //compute qk
+ qk = match(c, mu_C, Ck, map, c_length);
+ buf_qk.store(qk);
+
+ //Ck+1 = qk(c)
+ qk.apply_on(c, Ck, c_length);
+
+ // d_k = d(Yk, Pk+1)
+ // = d(closest(qk-1(P)), qk(P))
+ d_k = rms(c, map, c_length, buf_qk[1], qk);
+
+ k++;
+ } while ((qk - buf_qk[1]).sqr_norm() / qk.sqr_norm() > epsilon);
+
+ trace::exiting("registration::impl::icp_");
+ }
+
+ } // end of namespace mln::registration::impl
+
+
+ template <typename P, typename M, typename T>
+ inline
+ T
+ icp(const p_array<P>& c,
+ const M& map,
+ const float epsilon = 1e-3)
+ {
+ T qk;
+ impl::icp_(c, map, qk, c.length(), epsilon);
+ return qk;
+ }
+
+ template <typename P, typename M, typename T>
+ inline
+ void
+ icp_subset(const p_array<P>& c,
+ const unsigned c_length,
+ const M& map,
+ T& qk,
+ const float epsilon = 1e-3)
+ {
+ impl::icp_(c, map, qk, c_length, epsilon);
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::registration
+
+} // end of namespace mln
+
+
+
+#endif // ! MLN_REGISTRATION_ICP_HH