$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
is_not_1d_isthmus.hh
1 // Copyright (C) 2011, 2013, 2014 EPITA Research and Development
2 // Laboratory (LRDE).
3 //
4 // This file is part of Olena.
5 //
6 // Olena is free software: you can redistribute it and/or modify it under
7 // the terms of the GNU General Public License as published by the Free
8 // Software Foundation, version 2 of the License.
9 //
10 // Olena is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with Olena. If not, see <http://www.gnu.org/licenses/>.
17 //
18 // As a special exception, you may use this file as part of a free
19 // software project without restriction. Specifically, if other files
20 // instantiate templates or use macros or inline functions from this
21 // file, or you compile this file and link it with other files to produce
22 // an executable, this file does not by itself cause the resulting
23 // executable to be covered by the GNU General Public License. This
24 // exception does not however invalidate any other reasons why the
25 // executable file might be covered by the GNU General Public License.
26 
27 #ifndef MLN_TOPO_IS_NOT_1D_ISTHMUS_HH
28 # define MLN_TOPO_IS_NOT_1D_ISTHMUS_HH
29 
32 
33 # include <mln/core/concept/function.hh>
34 # include <mln/core/concept/image.hh>
35 # include <mln/core/concept/neighborhood.hh>
36 
37 # include <mln/topo/connectivity_number_2d.hh>
38 # include <mln/topo/connectivity_number_3d.hh>
39 
40 
41 namespace mln
42 {
43 
44  namespace topo
45  {
46 
47  template <typename I, typename N>
49  : public Function_v2b< is_not_1d_isthmus<I, N> >
50  {
55  is_not_1d_isthmus(const Neighborhood<N>& nbh_fg,
56  const Neighborhood<N>& nbh_bg);
57 
63  is_not_1d_isthmus(const Neighborhood<N>& nbh_fg,
64  const Neighborhood<N>& nbh_bg,
65  const Image<I>& ima);
66 
68  void set_image(Image<I>& ima);
69 
70  // Is \a p not a 1D isthmus point?
71  bool operator()(const mln_psite(I)& p) const;
72 
73  private:
75  const N& nbh_fg_;
77  const N& nbh_bg_;
79  const I* ima_;
80 
83  typedef conn_number_t (*connectivity_number_fun_t)(const Image<I>&,
84  const mln_psite(I)&,
85  bool);
88  connectivity_number_fun_t connectivity_number_fg_;
89  };
90 
91 
92 
93 # ifndef MLN_INCLUDE_ONLY
94 
95  /* FIXME: This is way too complicated. Maybe the simplest thing
96  is to create two functors is_not_1d_isthmus_point2d and
97  is_not_1d_isthmus_point3d and factor common parts. */
98  namespace internal
99  {
100 
101  template <typename I>
102  struct conn_number_fun
103  {
104  typedef conn_number_t (*connectivity_number_fun_t)(const Image<I>&,
105  const mln_psite(I)&,
106  bool);
107 
108  // Default case.
109  template <typename N>
110  static connectivity_number_fun_t get(const N& /* nbh_fg */,
111  const N& /* nbh_bg */)
112  {
113  // We only handle the cases where N is either neighb2d or neighb3d.
114  abort();
115  return 0;
116  }
117 
118  // 2D cases.
119  static connectivity_number_fun_t get(const neighb2d& nbh_fg,
120  const neighb2d& nbh_bg)
121  {
122  // 2D neighborhoods.
123  if (nbh_fg == c4() && nbh_bg == c8())
124  return connectivity_number_2d_c4<I>;
125  else if (nbh_fg == c8() && nbh_bg == c4())
126  return connectivity_number_2d_c8<I>;
127  else
128  {
129  // Bad or unknown combination.
130  abort();
131  return 0;
132  }
133  }
134 
135  // 3D cases.
136  static connectivity_number_fun_t get(const neighb3d& nbh_fg,
137  const neighb3d& nbh_bg)
138  {
139  // 3D neighborhoods.
140  if (nbh_fg == c6() && nbh_bg == c26())
141  return connectivity_number_3d_c6<I>;
142  else if (nbh_fg == c26() && nbh_bg == c6())
143  return connectivity_number_3d_c26<I>;
144  else if (nbh_fg == c6() && nbh_bg == c18())
145  return connectivity_number_3d_c6p<I>;
146  else if (nbh_fg == c18() && nbh_bg == c6())
147  return connectivity_number_3d_c18<I>;
148  else
149  {
150  // Bad or unknown combination.
151  abort();
152  return 0;
153  }
154  }
155 
156  };
157 
158 
159  } // end of namespace mln::io::topo::internal
160 
161 
162  template <typename I, typename N>
163  inline
164  is_not_1d_isthmus<I, N>::is_not_1d_isthmus(const Neighborhood<N>& nbh_fg,
165  const Neighborhood<N>& nbh_bg)
166  : nbh_fg_(exact(nbh_fg)),
167  nbh_bg_(exact(nbh_bg)),
168  connectivity_number_fg_(internal::conn_number_fun<I>::get(nbh_fg_,
169  nbh_bg_))
170  {
171  }
172 
173  template <typename I, typename N>
174  inline
175  is_not_1d_isthmus<I, N>::is_not_1d_isthmus(const Neighborhood<N>& nbh_fg,
176  const Neighborhood<N>& nbh_bg,
177  const Image<I>& ima)
178  : nbh_fg_(exact(nbh_fg)),
179  nbh_bg_(exact(nbh_bg)),
180  ima_(exact(&ima)),
181  connectivity_number_fg_(internal::conn_number_fun<I>::get(nbh_fg_,
182  nbh_bg_))
183  {
184  }
185 
186  template <typename I, typename N>
187  inline
188  void
190  {
191  ima_ = exact(&ima);
192  }
193 
194  template <typename I, typename N>
195  inline
196  bool
197  is_not_1d_isthmus<I, N>::operator()(const mln_psite(I)& p) const
198  {
199  mln_precondition(ima_);
200  return connectivity_number_fg_(*ima_, p, true) < 2u;
201  }
202 
203 # endif // MLN_INCLUDE_ONLY
204 
205  } // end of namespace topo
206 
207 } // end of namespace mln
208 
209 #endif // ! MLN_TOPO_IS_NOT_1D_ISTHMUS_HH