oln 10.51: Add snakes (greedy version).

Index: olena/ChangeLog from Astrid Wang <astrid@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

Index: olena/ChangeLog from Astrid Wang <astrid@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.
Ça manque d'une mention dans NEWS.
participants (2)
-
Akim Demaille
-
Astrid Wang