$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
is_simple_point.hh
1 // Copyright (C) 2009, 2011, 2012 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_SKELETON_IS_SIMPLE_POINT_HH
28 # define MLN_TOPO_SKELETON_IS_SIMPLE_POINT_HH
29 
37 
38 # include <mln/core/concept/image.hh>
39 # include <mln/core/alias/point2d.hh>
40 # include <mln/core/alias/neighb2d.hh>
41 
42 namespace mln
43 {
44 
45  namespace topo
46  {
47 
48  namespace skeleton
49  {
50 
67  template <typename N>
69  {
70 
71  is_simple_point(const Neighborhood<N>& nbh);
72 
73  template <typename I>
74  bool check(const I& ima, const mln_psite(I)& p) const;
75  template <typename I>
76  bool check__(const I& ima, unsigned p) const;
77 
78  protected:
79  const N& nbh_;
80  bool is_c8_;
81 
82  template <typename I, typename N2>
83  unsigned nb_connexity2d(const I&, const N2 nbh,
84  const mln_psite(I)& p, bool object) const;
85  template <typename I, typename N2>
86  unsigned nb_connexity2d__(const I&, const N2 nbh,
87  unsigned p, bool object) const;
88 
89  };
90 
91 # ifndef MLN_INCLUDE_ONLY
92 
93 
94  namespace internal
95  {
96  static const unsigned char nb_connexity_c8[256] =
97  {
98  0, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1,
99  1, 2, 1, 1, 1, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1,
100  1, 2, 2, 2, 2, 3, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1,
101  2, 3, 2, 2, 2, 3, 2, 2, 2, 2, 1, 1, 2, 2, 1, 1,
102 
103  1, 2, 2, 2, 2, 3, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1,
104  1, 2, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
105  1, 2, 2, 2, 2, 3, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1,
106  1, 2, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
107 
108  1, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 3, 3, 2, 2,
109  1, 2, 1, 1, 1, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1,
110  2, 3, 3, 3, 3, 4, 3, 3, 2, 2, 2, 2, 3, 3, 2, 2,
111  2, 3, 2, 2, 2, 3, 2, 2, 2, 2, 1, 1, 2, 2, 1, 1,
112 
113  1, 2, 2, 2, 2, 3, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1,
114  1, 2, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
115  1, 2, 2, 2, 2, 3, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1,
116  1, 2, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
117  };
118 
119  static const unsigned char nb_connexity_c4[256] =
120  {
121  0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 2, 1, 1, 1, 2, 1,
122  1, 1, 2, 2, 1, 1, 1, 1, 2, 2, 3, 2, 2, 2, 2, 1,
123  0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 2, 1, 1, 1, 2, 1,
124  1, 1, 2, 2, 1, 1, 1, 1, 2, 2, 3, 2, 2, 2, 2, 1,
125 
126  1, 1, 2, 2, 1, 1, 2, 2, 2, 2, 3, 2, 2, 2, 3, 2,
127  2, 2, 3, 3, 2, 2, 2, 2, 3, 3, 4, 3, 3, 3, 3, 2,
128  1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 1, 1, 1, 2, 1,
129  2, 2, 3, 3, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 1,
130 
131  0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 2, 1, 1, 1, 2, 1,
132  1, 1, 2, 2, 1, 1, 1, 1, 2, 2, 3, 2, 2, 2, 2, 1,
133  0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 2, 1, 1, 1, 2, 1,
134  1, 1, 2, 2, 1, 1, 1, 1, 2, 2, 3, 2, 2, 2, 2, 1,
135 
136  1, 1, 2, 2, 1, 1, 2, 2, 2, 2, 3, 2, 2, 2, 3, 2,
137  1, 1, 2, 2, 1, 1, 1, 1, 2, 2, 3, 2, 2, 2, 2, 1,
138  1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 1, 1, 1, 2, 1,
139  1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1
140  };
141 
142  } // end of namespace internal
143 
144  template <typename N>
145  is_simple_point<N>::is_simple_point(const Neighborhood<N>& nbh)
146  : nbh_(exact(nbh))
147  {
148  mln_precondition(nbh_.is_valid());
149  }
150 
151 
152  template <typename N>
153  template <typename I, typename N2>
154  unsigned
156  const N2 nbh,
157  const mln_psite(I)& p,
158  bool object) const
159  {
160  unsigned res = 0;
161 
162  // Note: bkd here but fwd in is_simple_2d.hh...
163  mln_bkd_niter(N2) n(c8(), p);
164  for_all(n)
165  {
166  res = (res << 1);
167  if (ima.domain().has(n) && ima(n) == object)
168  res = res | 1;
169  }
170 
171  switch (nbh.size())
172  {
173  case 4: // C4
174  return internal::nb_connexity_c4[res];
175  case 8: // C8
176  return internal::nb_connexity_c8[res];
177  default:
178  mln_assertion(0);
179 
180  }
181  }
182 
183 
184  template <typename N>
185  template <typename I, typename N2>
186  unsigned
188  const N2 nbh,
189  unsigned p,
190  bool object) const
191  {
192  unsigned res = 0;
193 
194  static util::array<int>
195  noffset = mln::offsets_wrt(ima, c8());
196 
197  for (int i = noffset.nelements() - 1; i >= 0; --i)
198  {
199  res = (res << 1);
200  if (ima.element(p + noffset[i]) == object)
201  res = res | 1;
202  }
203 
204  switch (nbh.size())
205  {
206  case 4: // C4
207  return internal::nb_connexity_c4[res];
208  case 8: // C8
209  return internal::nb_connexity_c8[res];
210  default:
211  mln_assertion(0);
212  }
213  return 0;
214  }
215 
216 
217  template <typename N>
218  template <typename I>
219  inline
220  bool
221  is_simple_point<N>::check(const I& ima,
222  const mln_psite(I)& p) const
223  {
224  mln_precondition(ima.is_valid());
225  return (nb_connexity2d(ima, nbh_.foreground(), p, true) == 1) // Consider neighbor.
226  && (nb_connexity2d(ima, nbh_.background(), p, false) == 1); // Consider complement neighbor.
227  }
228 
229 
230 
231 
232  template <typename N>
233  template <typename I>
234  inline
235  bool
236  is_simple_point<N>::check__(const I& ima,
237  unsigned p) const
238  {
239  mln_precondition(ima.is_valid());
240  return (nb_connexity2d__(ima, nbh_.foreground(), p, true) == 1) // Consider neighbor
241  && (nb_connexity2d__(ima, nbh_.background(), p, false) == 1); // Consider complement neighbor.
242  }
243 
244 
245 # endif // MLN_TOPO_SKELETON_INCLUDE_ONLY
246 
247  } // end of namespace mln::topo::skeleton
248 
249  } // end of namespace mln::topo
250 
251 } // end of namespace mln
252 
253 #endif // ! MLN_TOPO_SKELETON_IS_SIMPLE_POINT_HH