Index: olena/ChangeLog
from Astrid Wang <astrid(a)lrde.epita.fr>
* oln/snakes/snakes_base.hh,
* oln/snakes/snakes_base.hxx,
* oln/snakes/segment.hh,
* oln/snakes/segment.hxx,
* oln/snakes/node.hh,
* oln/snakes/node.hxx,
* oln/snakes/energies.hh,
* oln/snakes/energies.hxx,
* oln/snakes/greedy.hh,
* oln/snakes/greedy.hxx: New.
Index: olena/oln/snakes/snakes_base.hxx
--- olena/oln/snakes/snakes_base.hxx Wed, 21 Jan 2004 05:10:14 +0100 astrid ()
+++ olena/oln/snakes/snakes_base.hxx Wed, 21 Jan 2004 04:36:32 +0100 astrid
(oln/f/11_snakes_bas 644)
@@ -0,0 +1,84 @@
+// Copyright (C) 2004 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, 59 Temple Place - Suite 330, 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 OLENA_SNAKES_SNAKES_BASE_HXX
+# define OLENA_SNAKES_SNAKES_BASE_HXX
+
+#include <oln/morpho/gradient.hh>
+
+namespace oln {
+
+ namespace snakes {
+
+ template <class algorithm>
+ snake<algorithm>::snake(const image_type& image,
+ std::list<point_type> initial_contour,
+ ntg::float_s alpha,
+ ntg::float_s beta,
+ ntg::float_s gamma,
+ ntg::float_s khi = 0.0f) :
+ s(initial_contour), a(alpha, beta, gamma, khi),
+ alpha(alpha), beta(beta), gamma(gamma), khi(khi)
+ {
+ gradient = morpho::fast::beucher_gradient(image, win_c8p());
+ };
+
+ template <class algorithm>
+ std::list<typename snake<algorithm>::point_type>
+ snake<algorithm>::contour(void) const
+ {
+ return s.contour();
+ }
+
+ template <class algorithm>
+ ntg::float_s
+ snake<algorithm>::energy(void) const
+ {
+ return s.energy(gradient);
+ }
+
+ template <class algorithm>
+ inline
+ int
+ snake<algorithm>::update_snake(void)
+ {
+ return a.update_snake(gradient, *this);
+ }
+
+ template <class algorithm>
+ inline
+ void
+ snake<algorithm>::converge(void)
+ {
+ a.converge(gradient, *this);
+ }
+
+ } // end snakes
+
+} // end oln
+
+#endif // !OLENA_SNAKES_SNAKES_BASE_HXX
Index: olena/oln/snakes/snakes_base.hh
--- olena/oln/snakes/snakes_base.hh Wed, 21 Jan 2004 05:10:14 +0100 astrid ()
+++ olena/oln/snakes/snakes_base.hh Wed, 21 Jan 2004 04:38:34 +0100 astrid
(oln/f/50_snakes_bas 644)
@@ -0,0 +1,124 @@
+// Copyright (C) 2004 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, 59 Temple Place - Suite 330, 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 OLENA_SNAKES_SNAKES_BASE_HH
+# define OLENA_SNAKES_SNAKES_BASE_HH
+
+#include <oln/snakes/segment.hh>
+
+namespace oln {
+
+ namespace snakes {
+
+ template <class algorithm>
+ class snake
+ {
+ public:
+ typedef typename algorithm::image_type image_type;
+ typedef typename image_type::point_type point_type;
+
+ public:
+ snake(const image_type& image,
+ std::list<point_type> initial_contour,
+ ntg::float_s alpha,
+ ntg::float_s beta,
+ ntg::float_s gamma,
+ ntg::float_s khi);
+
+ public:
+ std::list<point_type>
+ contour(void) const;
+ ///< Return the points of the snake.
+
+ ntg::float_s
+ energy(void) const;
+ ///< Return the snake energy. This is not algorithm-dependant.
+
+ public:
+ int
+ update_snake(void);
+ ///< Calling this method causes the snake to execute one
+ ///< step. If the method is not iterative, it should fail
+ ///< to compile.
+
+ void
+ converge(void);
+ ///< Calling this method causes the snake to converge. It
+ ///< does so by delegating the method to the algorithm.
+
+ private:
+ segment<image_type> s;
+ ///< The current point list, I mean the one that is returned
+ ///< when nodes() is called and the one on which energy() computes
+ ///< the global energy. Implementations that use several segments
+ ///< should just do so in the algorithm class.
+
+ algorithm a;
+ ///< This one is just the instance that holds algorithm-specific
+ //< information, that is to say nearly every information.
+
+ private:
+ ///< Image gradient.
+ image_type gradient;
+
+ private:
+ ///< Each energy is weighted by a its own coefficient.
+ ntg::float_s alpha; ///< Weight of the continuity energy.
+ ntg::float_s beta; ///< Weight of the curvature energy.
+ ntg::float_s gamma; ///< Weight of the image energy.
+ ntg::float_s khi; ///< Weight of the image energy.
+
+ private:
+ friend
+ int
+ algorithm::update_snake(const typename algorithm::image_type&, snake&);
+
+ friend
+ void
+ algorithm::converge(const typename algorithm::image_type&, snake&);
+
+ friend
+ std::ostream&
+ ::operator<< <>(std::ostream&, const snake&);
+ };
+
+ } // end snakes
+
+} // end oln
+
+template <class algorithm>
+std::ostream& operator<<(std::ostream& os,
+ const oln::snakes::snake<algorithm>& s)
+{
+ os << "Snake:" << std::endl;
+ os << s.s;
+ return os;
+}
+
+#include <oln/snakes/snakes_base.hxx>
+
+#endif // !OLENA_SNAKES_SNAKES_BASE_HH
Index: olena/oln/snakes/energies.hxx
--- olena/oln/snakes/energies.hxx Wed, 21 Jan 2004 05:10:14 +0100 astrid ()
+++ olena/oln/snakes/energies.hxx Wed, 21 Jan 2004 04:40:31 +0100 astrid
(oln/j/21_energies.h 644)
@@ -0,0 +1,82 @@
+// Copyright (C) 2004 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, 59 Temple Place - Suite 330, 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 OLENA_SNAKES_ENERGIES_HXX
+# define OLENA_SNAKES_ENERGIES_HXX
+
+namespace oln {
+
+ namespace snakes {
+
+
+ template <class I>
+ inline
+ ntg::float_s
+ continuity_energy<I>::compute(const I&,
+ const node<I>& prev,
+ const node<I>& current,
+ const node<I>&)
+ {
+ ntg::float_s d = *average_dist - (current - prev).norm2();
+ return d > 0 ? d : -d;
+ }
+
+ template <class I>
+ inline
+ ntg::float_s
+ curvature_energy<I>::compute(const I&,
+ const node<I>& prev,
+ const node<I>& current,
+ const node<I>& next)
+ {
+ typename I::point_type twice_current;
+
+ twice_current.row() = 2 * current.row();
+ twice_current.col() = 2 * current.col();
+ return (next + (prev - twice_current) -
+ typename I::point_type(0,0)).norm2();
+ }
+
+ template <class I>
+ inline
+ ntg::float_s
+ image_energy<I>::compute(const I& gradient,
+ const node<I>&,
+ const node<I>& current,
+ const node<I>&)
+ {
+ // FIXME: Add magic trick: if there is very little gradient difference,
+ // don't pay too much attention to it.
+ // If max_gradient < min_gradient + 5: max_gradient = min_gradient + 5
+ return ntg_sup_val(oln_value_type(I)) - gradient[current];
+ }
+
+ } // end snakes
+
+} // end oln
+
+#endif // !OLENA_SNAKES_ENERGIES_HXX
Index: olena/oln/snakes/energies.hh
--- olena/oln/snakes/energies.hh Wed, 21 Jan 2004 05:10:14 +0100 astrid ()
+++ olena/oln/snakes/energies.hh Wed, 21 Jan 2004 04:42:52 +0100 astrid
(oln/j/22_energies.h 644)
@@ -0,0 +1,163 @@
+// Copyright (C) 2004 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, 59 Temple Place - Suite 330, 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 OLENA_SNAKES_ENERGIES_HH
+# define OLENA_SNAKES_ENERGIES_HH
+
+namespace oln {
+
+ namespace snakes {
+
+ template <class I>
+ class energy
+ {
+ public:
+ energy() {}
+ energy(void *) {}
+
+ public:
+ ntg::float_s
+ compute(const I&, const node<I>&, const node<I>&, const
node<I>&)
+ {
+ // This is intended to cause an error. The user must define a
+ // member function named `compute()' for each external energy,
+ // otherwise the following method will be compiled and cause an
+ // error.
+ user_defined_external_energy_functor::compute();
+ return 0.f;
+ }
+
+ public:
+ static void* cookie() { return 0; };
+
+ private:
+ struct user_defined_external_energy_functor{};
+ };
+
+
+ template <class I>
+ class continuity_energy : public energy<I>
+ {
+ public:
+ typedef I image_type;
+
+ public:
+ continuity_energy(ntg::float_s* average_dist) :
+ average_dist(average_dist) {}
+
+ public:
+ inline
+ ntg::float_s
+ compute(const I&,
+ const node<I>& prev,
+ const node<I>& current,
+ const node<I>&);
+
+ private:
+ ntg::float_s* average_dist;
+ };
+
+
+ template <class I>
+ class curvature_energy : public energy<I>
+ {
+ public:
+ typedef I image_type;
+
+ public:
+ curvature_energy(void *) {}
+
+ public:
+ static inline
+ ntg::float_s
+ compute(const I&,
+ const node<I>& prev,
+ const node<I>& current,
+ const node<I>& next);
+ };
+
+
+ template <class I>
+ class image_energy : public energy<I>
+ {
+ public:
+ typedef I image_type;
+
+ public:
+ image_energy(void*) {}
+
+ public:
+ static inline
+ ntg::float_s
+ compute(const I& gradient,
+ const node<I>&,
+ const node<I>& current,
+ const node<I>&);
+ };
+
+
+ // This macro allows the user to define his own external energy.
+#define oln_snakes_define_external_energy(Energy, Gradient, PrevNode, CurrentNode,
NextNode) \
+ \
+template<class I> \
+class Energy : public energy<I> \
+{ \
+public: \
+ typedef I image_type; \
+ \
+public: \
+ Energy(void*) {} \
+ \
+public: \
+ ::ntg::float_s \
+ compute(const I& gradient, \
+ const ::oln::snakes::node<I>&, \
+ const ::oln::snakes::node<I>&, \
+ const ::oln::snakes::node<I>&); \
+}; \
+ \
+template<class I> \
+::ntg::float_s \
+Energy<I>::compute(const I& Gradient, \
+ const ::oln::snakes::node<I>& PrevNode, \
+ const ::oln::snakes::node<I>& CurrentNode, \
+ const ::oln::snakes::node<I>& NextNode)
+
+
+ // Default external energy.
+ oln_snakes_define_external_energy(dummy_energy,,,,)
+ {
+ return 0;
+ }
+
+ } // end snakes
+
+} // end oln
+
+#include <oln/snakes/energies.hxx>
+
+#endif // !OLENA_SNAKES_ENERGIES_HH
Index: olena/oln/snakes/segment.hxx
--- olena/oln/snakes/segment.hxx Wed, 21 Jan 2004 05:10:14 +0100 astrid ()
+++ olena/oln/snakes/segment.hxx Wed, 21 Jan 2004 04:44:03 +0100 astrid
(oln/j/23_segment.hx 644)
@@ -0,0 +1,132 @@
+// Copyright (C) 2004 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, 59 Temple Place - Suite 330, 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 OLENA_SNAKES_SEGMENT_HXX
+# define OLENA_SNAKES_SEGMENT_HXX
+
+namespace oln {
+
+ namespace snakes {
+
+ template <class I>
+ segment<I>::segment(std::list<point_type>& initial_contour) :
+ prev_segment(*this), next_segment(*this)
+ {
+ for (typename std::list<point_type>::const_iterator
+ it = initial_contour.begin();
+ it != initial_contour.end();
+ ++it)
+ nodes.push_back(*it);
+ }
+
+ template <class I>
+ inline
+ ntg::float_s
+ segment<I>::energy(const I& gradient) const
+ {
+ ntg::float_s e = 0.f;
+ typename segment<I>::const_iter_type p = nodes.begin();
+ typename segment<I>::const_iter_type c = nodes.begin();
+ typename segment<I>::const_iter_type n = nodes.begin();
+
+ ++n;
+ e += c->energy(gradient, prev_node(), *n);
+ for (++c, ++n; n != nodes.end(); ++p, ++c, ++n)
+ e += c->energy(gradient, *p, *n);
+ e += c->energy(gradient, *p, next_node());
+ return e;
+ }
+
+ template <class I>
+ std::list<typename segment<I>::point_type>
+ segment<I>::contour(void) const
+ {
+ std::list<point_type> result;
+
+ for (typename segment<I>::const_iter_type it = nodes.begin();
+ it != nodes.end(); ++it)
+ result.push_back(*it);
+ return result;
+ }
+
+ template <class I>
+ typename segment<I>::const_iter_type
+ segment<I>::begin(void) const
+ {
+ return nodes.begin();
+ }
+ template <class I>
+ typename segment<I>::iter_type
+ segment<I>::begin(void)
+ {
+ return nodes.begin();
+ }
+
+ template <class I>
+ typename segment<I>::const_iter_type
+ segment<I>::end(void) const
+ {
+ return nodes.end();
+ }
+ template <class I>
+ typename segment<I>::iter_type
+ segment<I>::end(void)
+ {
+ return nodes.end();
+ }
+
+ template <class I>
+ const node<I>
+ segment<I>::prev_node(void) const
+ {
+ return prev_segment.back();
+ }
+ template <class I>
+ const node<I>
+ segment<I>::next_node(void) const
+ {
+ return next_segment.front();
+ }
+
+ template <class I>
+ const node<I>
+ segment<I>::front(void) const
+ {
+ return nodes.front();
+ }
+ template <class I>
+ const node<I>
+ segment<I>::back(void) const
+ {
+ return nodes.back();
+ }
+
+ } // end snakes
+
+} // end oln
+
+#endif // !OLENA_SNAKES_SEGMENT_HXX
Index: olena/oln/snakes/greedy.hxx
--- olena/oln/snakes/greedy.hxx Wed, 21 Jan 2004 05:10:14 +0100 astrid ()
+++ olena/oln/snakes/greedy.hxx Wed, 21 Jan 2004 04:59:29 +0100 astrid
(oln/j/24_greedy.hxx 644)
@@ -0,0 +1,210 @@
+// Copyright (C) 2004 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, 59 Temple Place - Suite 330, 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 OLENA_SNAKES_GREEDY_HXX
+# define OLENA_SNAKES_GREEDY_HXX
+
+namespace oln {
+
+ namespace snakes {
+
+
+ template <int N, class I, template<typename> class external_energy>
+ greedy<N, I, external_energy>::greedy(ntg::float_s alpha,
+ ntg::float_s beta,
+ ntg::float_s gamma,
+ ntg::float_s khi) :
+ continuity_e(&average_dist),
+ curvature_e(curvature_energy<I>::cookie()),
+ image_e(image_energy<I>::cookie()),
+ external_e(external_energy<I>::cookie()),
+ alpha(alpha), beta(beta), gamma(gamma), khi(khi)
+ {
+ }
+
+
+ template <int N, class I, template<typename> class external_energy>
+ int
+ greedy<N, I, external_energy>::
+ update_snake(const I& gradient, snake<greedy<N, I, external_energy>
>& s)
+ {
+ /// This place is left void to make room for a future extension
+ /// where a snake will be able to hold several segments.
+ average_dist = compute_average_dist(s.s);
+ return update_segment(gradient, s.s);
+ }
+
+ template <int N, class I, template<typename> class external_energy>
+ void
+ greedy<N, I, external_energy>::
+ converge(const I& gradient, snake<greedy<N, I, external_energy>
>& s)
+ {
+ // FIXME: think of a real stop condition.
+ unsigned i = 0;
+ while (threshold < update_segment(gradient, s.s))
+ {
+ average_dist = compute_average_dist(s.s);
+ std::cout << i << ' ' << s.s << std::endl;
+ ++i;
+ };
+ }
+
+ template <int N, class I, template<typename> class external_energy>
+ int
+ greedy<N, I, external_energy>::update_segment(const I& gradient,
+ segment<I>& s)
+ {
+ int nb_updates = 0;
+ typename segment<I>::iter_type p = s.begin();
+ typename segment<I>::iter_type c = s.begin();
+ typename segment<I>::iter_type n = s.begin();
+
+ ++n;
+ nb_updates += update_node(gradient, s.prev_node(), *c, *n) ? 1 : 0;
+ for (++c, ++n; n != s.end(); ++p, ++c, ++n)
+ nb_updates += update_node(gradient, *p, *c, *n) ? 1 : 0;
+ nb_updates += update_node(gradient, *p, *c, s.next_node()) ? 1 : 0;
+ return nb_updates;
+ }
+
+ template <int N, class I, template<typename> class external_energy>
+ bool
+ greedy<N, I, external_energy>::update_node(const I& gradient,
+ const node<I>& prev,
+ node<I>& current,
+ const node<I>& next)
+ ///< Return whether the point has changed or not.
+ {
+ store_type energy;
+ ntg::float_s minimum = ntg_sup_val(ntg::float_s);
+ dpoint2d minimum_location;
+
+ energy = compute_and_normalize_energy<continuity_energy<I> >
+ (gradient, prev, current, next, continuity_e) * alpha;
+ energy += compute_and_normalize_energy<curvature_energy<I> >
+ (gradient, prev, current, next, curvature_e) * beta;
+ energy += compute_and_normalize_energy<image_energy<I> >
+ (gradient, prev, current, next, image_e) * gamma;
+ energy += compute_and_normalize_energy<external_energy<I> >
+ (gradient, prev, current, next, external_e) * khi;
+
+ window2d::iter_type it(neighborhood);
+ for_all(it)
+ {
+ if (minimum > energy(it.cur().col(), it.cur().row()))
+ {
+ minimum = energy(it.cur().col(), it.cur().row());
+ minimum_location = it;
+ }
+ }
+ if (0 != minimum_location.col() || 0 != minimum_location.row())
+ {
+ current += minimum_location;
+ return true;
+ }
+ return false;
+ }
+
+
+ template <int N, class I, template<typename> class external_energy>
+ template <class energy_functor>
+ inline
+ typename greedy<N, I, external_energy>::store_type
+ greedy<N, I, external_energy>::
+ compute_and_normalize_energy
+ (const typename energy_functor::image_type& gradient,
+ const node<typename energy_functor::image_type>& prev,
+ const node<typename energy_functor::image_type>& current,
+ const node<typename energy_functor::image_type>& next,
+ energy_functor functor)
+ {
+ store_type energy;
+ ntg::float_s energy_min = ntg_sup_val(ntg::float_s);
+ ntg::float_s energy_max = ntg_inf_val(ntg::float_s);
+
+ // Compute energy of each point of the neighborhood. Those are
+ // not normalized yet.
+ window2d::iter_type it(neighborhood);
+ for_all(it)
+ {
+ ntg::float_s e = functor.compute(gradient, prev, current + it, next);
+
+ // Find minimal and maximal energy on the fly, for we need them
+ // thereafter.
+ if (e > energy_max) energy_max = e;
+ if (e < energy_min) energy_min = e;
+ // Store it in a temporary location.
+ energy(it.cur().col(), it.cur().row()) = e;
+ }
+ if (energy_max > 0)
+ {
+ ntg::float_s invmax = 1 / (energy_max - energy_min);
+ window2d::iter_type itw(neighborhood);
+ for_all(itw)
+ {
+ ntg::float_s tmp = energy(itw.cur().col(), itw.cur().row()) -
+ energy_min;
+ tmp *= invmax;
+ energy(itw.cur().col(), itw.cur().row()) = tmp;
+ }
+ }
+ return energy;
+ }
+
+
+ template <int N, class I, template<typename> class external_energy>
+ ntg::float_s
+ greedy<N, I, external_energy>::compute_average_dist(const segment<I>&
s)
+ {
+ ntg::float_s mean = 0.f;
+
+ typename segment<I>::const_iter_type prev = s.begin();
+ typename segment<I>::const_iter_type cur = s.begin();
+ unsigned card = 0;
+ for (++cur; cur != s.end(); ++prev, ++cur)
+ {
+ mean += (*cur - *prev).norm2();
+ ++card;
+ }
+ return mean / (ntg::float_s)card;
+ }
+
+
+ template <int N, class I, template<typename> class external_energy>
+ const int greedy<N, I, external_energy>::threshold = 3; // FIXME:
+
+
+ template <int N, class I, template<typename> class external_energy>
+ window2d greedy<N, I, external_energy>::neighborhood = mk_win_square(N);
+
+
+ } // end snakes
+
+} // end oln
+
+
+#endif // !OLENA_SNAKES_GREEDY_HXX
Index: olena/oln/snakes/greedy.hh
--- olena/oln/snakes/greedy.hh Wed, 21 Jan 2004 05:10:14 +0100 astrid ()
+++ olena/oln/snakes/greedy.hh Wed, 21 Jan 2004 05:05:18 +0100 astrid (oln/j/25_greedy.hh
644)
@@ -0,0 +1,121 @@
+// Copyright (C) 2004 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, 59 Temple Place - Suite 330, 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 OLENA_SNAKES_GREEDY_HH
+# define OLENA_SNAKES_GREEDY_HH
+
+#include <oln/snakes/snakes_base.hh>
+#include <oln/snakes/energies.hh>
+#include <mlc/array/2d.hh>
+
+namespace oln {
+
+ namespace snakes {
+
+ /// N is the size of the neighborhood.
+ template <int N, class I, template<typename> class external_energy =
dummy_energy>
+ class greedy
+ {
+ public:
+ typedef I image_type;
+ typedef typename I::point_type point_type;
+ typedef mlc::array2d<mlc::array2d_info<N,N>, ntg::float_s> store_type;
+ // FIXME: why only 2d?
+
+ public:
+ greedy(ntg::float_s alpha,
+ ntg::float_s beta,
+ ntg::float_s gamma,
+ ntg::float_s khi);
+
+ public:
+ inline
+ int
+ update_snake(const I& gradient, snake<greedy>& s);
+ ///< Asynchronous update for more efficient convergence.
+
+ void
+ converge(const I& gradient, snake<greedy>& s);
+
+
+ private:
+ inline
+ int
+ update_segment(const I& gradient, segment<I>& s);
+
+ inline
+ bool
+ update_node(const I& gradient,
+ const node<I>& prev, node<I>& n, const node<I>& next);
+
+ private:
+ template <class energy_functor>
+ inline
+ store_type
+ compute_and_normalize_energy
+ (const typename energy_functor::image_type& gradient,
+ const node<typename energy_functor::image_type>& prev,
+ const node<typename energy_functor::image_type>& current,
+ const node<typename energy_functor::image_type>& next,
+ energy_functor functor);
+
+ private:
+ ntg::float_s average_dist;
+ ///< Average distance between the points of the contour.
+
+ inline
+ ntg::float_s
+ compute_average_dist(const segment<I>& s);
+
+ private:
+ continuity_energy<I> continuity_e;
+ curvature_energy<I> curvature_e;
+ image_energy<I> image_e;
+ external_energy<I> external_e;
+
+ private:
+ ///< Each energy is weighted by a its own coefficient.
+ ntg::float_s alpha; ///< Weight of the continuity energy.
+ ntg::float_s beta; ///< Weight of the curvature energy.
+ ntg::float_s gamma; ///< Weight of the image energy.
+ ntg::float_s khi; ///< Weight of the image energy.
+
+ private:
+ static const int threshold;
+ // FIXME: think about a real stop condition.
+ private:
+ static window2d neighborhood;
+ // FIXME: better write an iterator on arrays.
+ };
+
+ } // end snakes
+
+} // end oln
+
+#include <oln/snakes/greedy.hxx>
+
+#endif // !OLENA_SNAKES_GREEDY_HH
Index: olena/oln/snakes/node.hh
--- olena/oln/snakes/node.hh Wed, 21 Jan 2004 05:10:14 +0100 astrid ()
+++ olena/oln/snakes/node.hh Wed, 21 Jan 2004 05:06:18 +0100 astrid (oln/j/32_node.hh
644)
@@ -0,0 +1,74 @@
+// Copyright (C) 2004 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, 59 Temple Place - Suite 330, 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 OLENA_SNAKES_NODE_HH
+# define OLENA_SNAKES_NODE_HH
+
+#include <oln/basics2d.hh> // FIXME: Why only 2d?
+
+namespace oln {
+
+ namespace snakes {
+
+ template<class I>
+ class node : public I::point_type
+ {
+ public:
+ typedef typename I::point_type point_type;
+ typedef typename I::dpoint_type dpoint_type;
+
+ public:
+ node(point_type point) :
+ I::point_type(point)
+ {
+ }
+
+ public:
+ inline
+ ntg::float_s
+ energy(const I& gradient, point_type prev, point_type next) const;
+
+ private:
+ friend std::ostream&
+ ::operator<< <>(std::ostream&, const node&);
+ };
+
+ } // end snakes
+
+} // end oln
+
+
+template <class I>
+std::ostream& operator<<(std::ostream& os, const
oln::snakes::node<I>& n)
+{
+ os << "Node:" << static_cast<typename
oln::snakes::node<I>::point_type>(n);
+ return os;
+}
+
+#include <oln/snakes/node.hxx>
+
+#endif // !OLENA_SNAKES_NODE_HH
Index: olena/oln/snakes/node.hxx
--- olena/oln/snakes/node.hxx Wed, 21 Jan 2004 05:10:14 +0100 astrid ()
+++ olena/oln/snakes/node.hxx Wed, 21 Jan 2004 05:06:50 +0100 astrid (oln/j/33_node.hxx
644)
@@ -0,0 +1,46 @@
+// Copyright (C) 2004 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, 59 Temple Place - Suite 330, 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 OLENA_SNAKES_NODE_HXX
+# define OLENA_SNAKES_NODE_HXX
+
+namespace oln {
+
+ namespace snakes {
+
+ template <class I>
+ ntg::float_s
+ node<I>::energy(const I& gradient, point_type prev, point_type next) const
+ {
+ return 42; // FIXME: compute the real value.
+ }
+
+ } // end snakes
+
+} // end oln
+
+#endif // !OLENA_SNAKES_NODE_HXX
Index: olena/oln/snakes/segment.hh
--- olena/oln/snakes/segment.hh Wed, 21 Jan 2004 05:10:14 +0100 astrid ()
+++ olena/oln/snakes/segment.hh Wed, 21 Jan 2004 05:08:53 +0100 astrid
(oln/j/34_segment.hh 644)
@@ -0,0 +1,107 @@
+// Copyright (C) 2004 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, 59 Temple Place - Suite 330, 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 OLENA_SNAKES_SEGMENT_HH
+# define OLENA_SNAKES_SEGMENT_HH
+
+#include <oln/snakes/node.hh>
+
+#include <vector>
+#include <list>
+
+namespace oln {
+
+ namespace snakes {
+
+ template <class I>
+ class segment
+ {
+ public:
+ typedef typename std::vector<node<I> >::iterator iter_type;
+ typedef typename std::vector<node<I> >::const_iterator
const_iter_type;
+ typedef typename I::point_type point_type;
+
+ public:
+ segment(std::list<point_type>& initial_contour);
+
+ public:
+ inline
+ ntg::float_s
+ energy(const I& gradient) const;
+ ///< Just iterate through the vector and sums up point energies.
+
+ public:
+ std::list<point_type>
+ contour(void) const;
+ ///< Return the points of the segment.
+
+ public:
+ const_iter_type begin(void) const;
+ iter_type begin(void);
+ ///< Return an iterator on the first node of the segment.
+ const_iter_type end(void) const;
+ iter_type end(void);
+ ///< Return an iterator on the last node of the segment.
+
+ public:
+ const node<I> prev_node(void) const;
+ ///< Node before the first node of this segment.
+ const node<I> next_node(void) const;
+ ///< Node after the next node of this segment.
+
+ private:
+ std::vector<node<I> > nodes;
+ segment& prev_segment;
+ segment& next_segment;
+
+ const node<I> front(void) const;
+ const node<I> back(void) const;
+
+ friend
+ std::ostream&
+ ::operator<< <>(std::ostream&, const segment&);
+ };
+
+ } // end snakes
+
+} // end oln
+
+
+template <class I>
+std::ostream& operator<<(std::ostream& os, const
oln::snakes::segment<I>& s)
+{
+ os << "Segment:" << std::endl;
+ for (typename oln::snakes::segment<I>::const_iter_type it = s.begin();
+ it != s.end();
+ ++it)
+ os << *it << std::endl;
+ return os;
+}
+
+#include <oln/snakes/segment.hxx>
+
+#endif // !OLENA_SNAKES_SEGMENT_HH
--
astrid