
* mln/topo/is_not_1d_isthmus.hh: New. * headers.mk, tests/unit_test/unit-tests.mk: Regen. --- milena/ChangeLog | 7 + milena/headers.mk | 2 + milena/mln/topo/is_not_1d_isthmus.hh | 210 ++++++++++++++++++++++++++++++++++ milena/tests/unit_test/unit-tests.mk | 4 + 4 files changed, 223 insertions(+), 0 deletions(-) create mode 100644 milena/mln/topo/is_not_1d_isthmus.hh diff --git a/milena/ChangeLog b/milena/ChangeLog index 9c667b6..8c49faa 100644 --- a/milena/ChangeLog +++ b/milena/ChangeLog @@ -1,3 +1,10 @@ +2011-07-13 Roland Levillain <roland@lrde.epita.fr> + + Add a non 1D isthmus predicate for (2D and 3D) binary images. + + * mln/topo/is_not_1d_isthmus.hh: New. + * headers.mk, tests/unit_test/unit-tests.mk: Regen. + 2011-07-12 Roland Levillain <roland@lrde.epita.fr> Check the consistency of tools/simple_point3d_lut_26_6.hh. diff --git a/milena/headers.mk b/milena/headers.mk index 4dcc0fc..906bd32 100644 --- a/milena/headers.mk +++ b/milena/headers.mk @@ -999,6 +999,7 @@ mln/topo/center_only_iter.hh \ mln/topo/centered_iter_adapter.hh \ mln/topo/complex.hh \ mln/topo/complex_iterators.hh \ +mln/topo/connectivity_number_2d.hh \ mln/topo/connectivity_number_3d.hh \ mln/topo/detach_cell.hh \ mln/topo/detach_pair.hh \ @@ -1013,6 +1014,7 @@ mln/topo/internal/complex_relative_iterator_sequence.hh \ mln/topo/internal/complex_set_iterator_base.hh \ mln/topo/is_facet.hh \ mln/topo/is_n_face.hh \ +mln/topo/is_not_1d_isthmus.hh \ mln/topo/is_not_end_point.hh \ mln/topo/is_simple_2d.hh \ mln/topo/is_simple_cell.hh \ diff --git a/milena/mln/topo/is_not_1d_isthmus.hh b/milena/mln/topo/is_not_1d_isthmus.hh new file mode 100644 index 0000000..9ed7468 --- /dev/null +++ b/milena/mln/topo/is_not_1d_isthmus.hh @@ -0,0 +1,210 @@ +// Copyright (C) 2011 EPITA Research and Development Laboratory (LRDE) +// +// This file is part of the Milena 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_TOPO_IS_NOT_1D_ISTHMUS_HH +# define MLN_TOPO_IS_NOT_1D_ISTHMUS_HH + +/// \file +/// \brief Non 1D isthmus predicate for (2D and 3D) binary images. + +# include <mln/core/concept/function.hh> +# include <mln/core/concept/image.hh> +# include <mln/core/concept/neighborhood.hh> + +# include <mln/topo/connectivity_number_2d.hh> +# include <mln/topo/connectivity_number_3d.hh> + + +namespace mln +{ + + namespace topo + { + + template <typename I, typename N> + struct is_not_1d_isthmus + : public Function_v2b< is_not_1d_isthmus<I, N> > + { + /// Build a functor. + /// + /// \param nbh_fg The foreground neighborhood. + /// \param nbh_bg The background neighborhood. + is_not_1d_isthmus(const Neighborhood<N>& nbh_fg, + const Neighborhood<N>& nbh_bg); + + /// Build a functor, and assign an image to it. + /// + /// \param nbh_fg The foreground neighborhood. + /// \param nbh_bg The background neighborhood. + /// \apram ima The image. + is_not_1d_isthmus(const Neighborhood<N>& nbh_fg, + const Neighborhood<N>& nbh_bg, + const Image<I>& ima); + + /// Set the underlying image. + void set_image(Image<I>& ima); + + // Is \a p not a 1D isthmus point? + bool operator()(const mln_psite(I)& p) const; + + private: + /// The foreground neighborhood. + const N& nbh_fg_; + /// The background neighborhood. + const N& nbh_bg_; + /// The image. + const I* ima_; + + /// The type of pointer on function computing a 3D connectivity + /// number. + typedef conn_number_t (*connectivity_number_fun_t)(const Image<I>&, + const mln_psite(I)&, + bool); + /// The function (pointer) computing the (foreground) connectivity + /// number. + connectivity_number_fun_t connectivity_number_fg_; + }; + + + +# ifndef MLN_INCLUDE_ONLY + + /* FIXME: This is way too complicated. Maybe the simplest thing + is to create two functors is_not_1d_isthmus_point2d and + is_not_1d_isthmus_point3d and factor common parts. */ + namespace internal + { + + template <typename I> + struct conn_number_fun + { + typedef conn_number_t (*connectivity_number_fun_t)(const Image<I>&, + const mln_psite(I)&, + bool); + + // Default case. + template <typename N> + static connectivity_number_fun_t get(const N& /* nbh_fg */, + const N& /* nbh_bg */) + { + // We only handle the cases where N is either neighb2d or neighb3d. + abort(); + return 0; + } + + // 2D cases. + static connectivity_number_fun_t get(const neighb2d& nbh_fg, + const neighb2d& nbh_bg) + { + // 2D neighborhoods. + if (nbh_fg == c4() && nbh_bg == c8()) + return connectivity_number_2d_c4<I>; + else if (nbh_fg == c8() && nbh_bg == c4()) + return connectivity_number_2d_c8<I>; + else + { + // Bad or unknown combination. + abort(); + return 0; + } + } + + // 3D cases. + static connectivity_number_fun_t get(const neighb3d& nbh_fg, + const neighb3d& nbh_bg) + { + // 3D neighborhoods. + if (nbh_fg == c6() && nbh_bg == c26()) + return connectivity_number_3d_c6<I>; + else if (nbh_fg == c26() && nbh_bg == c6()) + return connectivity_number_3d_c26<I>; + else if (nbh_fg == c6() && nbh_bg == c18()) + return connectivity_number_3d_c6p<I>; + else if (nbh_fg == c18() && nbh_bg == c6()) + return connectivity_number_3d_c18<I>; + else + { + // Bad or unknown combination. + abort(); + return 0; + } + } + + }; + + + } // end of namespace mln::io::topo::internal + + + template <typename I, typename N> + inline + is_not_1d_isthmus<I, N>::is_not_1d_isthmus(const Neighborhood<N>& nbh_fg, + const Neighborhood<N>& nbh_bg) + : nbh_fg_(exact(nbh_fg)), + nbh_bg_(exact(nbh_bg)), + connectivity_number_fg_(internal::conn_number_fun<I>::get(nbh_fg_, + nbh_bg_)) + { + } + + template <typename I, typename N> + inline + is_not_1d_isthmus<I, N>::is_not_1d_isthmus(const Neighborhood<N>& nbh_fg, + const Neighborhood<N>& nbh_bg, + const Image<I>& ima) + : nbh_fg_(exact(nbh_fg)), + nbh_bg_(exact(nbh_bg)), + ima_(exact(&ima)), + connectivity_number_fg_(internal::conn_number_fun<I>::get(nbh_fg_, + nbh_bg_)) + { + } + + template <typename I, typename N> + inline + void + is_not_1d_isthmus<I, N>::set_image(Image<I>& ima) + { + ima_ = exact(&ima); + } + + template <typename I, typename N> + inline + bool + is_not_1d_isthmus<I, N>::operator()(const mln_psite(I)& p) const + { + mln_precondition(ima_); + return connectivity_number_fg_(*ima_, p, true) < 2; + } + +# endif // MLN_INCLUDE_ONLY + + } // end of namespace topo + +} // end of namespace mln + +#endif // ! MLN_TOPO_IS_NOT_1D_ISTHMUS_HH diff --git a/milena/tests/unit_test/unit-tests.mk b/milena/tests/unit_test/unit-tests.mk index 12795ff..b589365 100644 --- a/milena/tests/unit_test/unit-tests.mk +++ b/milena/tests/unit_test/unit-tests.mk @@ -1029,6 +1029,7 @@ mln_topo_center_only_iter \ mln_topo_centered_iter_adapter \ mln_topo_complex \ mln_topo_complex_iterators \ +mln_topo_connectivity_number_2d \ mln_topo_connectivity_number_3d \ mln_topo_detach_cell \ mln_topo_detach_pair \ @@ -1043,6 +1044,7 @@ mln_topo_internal_complex_relative_iterator_sequence \ mln_topo_internal_complex_set_iterator_base \ mln_topo_is_facet \ mln_topo_is_n_face \ +mln_topo_is_not_1d_isthmus \ mln_topo_is_not_end_point \ mln_topo_is_simple_2d \ mln_topo_is_simple_cell \ @@ -2340,6 +2342,7 @@ mln_topo_center_only_iter_SOURCES = mln_topo_center_only_iter.cc mln_topo_centered_iter_adapter_SOURCES = mln_topo_centered_iter_adapter.cc mln_topo_complex_SOURCES = mln_topo_complex.cc mln_topo_complex_iterators_SOURCES = mln_topo_complex_iterators.cc +mln_topo_connectivity_number_2d_SOURCES = mln_topo_connectivity_number_2d.cc mln_topo_connectivity_number_3d_SOURCES = mln_topo_connectivity_number_3d.cc mln_topo_detach_cell_SOURCES = mln_topo_detach_cell.cc mln_topo_detach_pair_SOURCES = mln_topo_detach_pair.cc @@ -2354,6 +2357,7 @@ mln_topo_internal_complex_relative_iterator_sequence_SOURCES = mln_topo_internal mln_topo_internal_complex_set_iterator_base_SOURCES = mln_topo_internal_complex_set_iterator_base.cc mln_topo_is_facet_SOURCES = mln_topo_is_facet.cc mln_topo_is_n_face_SOURCES = mln_topo_is_n_face.cc +mln_topo_is_not_1d_isthmus_SOURCES = mln_topo_is_not_1d_isthmus.cc mln_topo_is_not_end_point_SOURCES = mln_topo_is_not_end_point.cc mln_topo_is_simple_2d_SOURCES = mln_topo_is_simple_2d.cc mln_topo_is_simple_cell_SOURCES = mln_topo_is_simple_cell.cc -- 1.7.2.5