$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
link_several_dmax_base.hh
1 // Copyright (C) 2009, 2010, 2011 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 SCRIBO_PRIMITIVE_LINK_INTERNAL_LINK_SEVERAL_DMAX_HH_
28 # define SCRIBO_PRIMITIVE_LINK_INTERNAL_LINK_SEVERAL_DMAX_HH_
29 
37 
38 
39 # include <mln/accu/center.hh>
40 # include <mln/labeling/compute.hh>
41 # include <mln/math/abs.hh>
42 # include <mln/util/array.hh>
43 
44 # include <scribo/core/macros.hh>
45 # include <scribo/core/tag/anchor.hh>
46 # include <scribo/core/object_links.hh>
47 
48 # include <scribo/primitive/link/internal/find_link.hh>
49 # include <scribo/primitive/link/internal/link_functor_base.hh>
50 
51 # include <scribo/primitive/link/compute.hh>
52 
53 
54 namespace scribo
55 {
56 
57  namespace primitive
58  {
59 
60  namespace link
61  {
62 
63  namespace internal
64  {
65 
68  //
69  template <typename L, typename E>
71  : public link_functor_base<L, E>
72  {
73  typedef mln_site(L) P;
75  typedef mln_result(accu::center<mln_psite(L)>) ms_t;
77 
78  public:
79 
81  unsigned neighb_max_distance);
82 
83 
84 
85  bool verify_link_criterion_(unsigned current_object,
86  const P& start_point,
87  const P& p,
88  anchor::Type anchor) const;
89 
90  void start_processing_object_(unsigned current_object);
91 
92  void validate_link_(unsigned current_object, const P& start_point,
93  const P& p, anchor::Type anchor);
94 
95  void initialize_link_(unsigned current_object);
96  couple_t finalize_link_(unsigned current_object);
97 
98  unsigned nanchors() const;
99  const util::array<anchor::Type>& anchors() const;
100 
101  protected:
103  mln::util::array<couple_t> potential_links_;
104  float dmax_;
105  float neighb_max_distance_;
106  anchor::Direction direction_;
107 
108  using super_::labeled_image_;
109  };
110 
111 
112 # ifndef MLN_INCLUDE_ONLY
113 
114 
115  template <typename L, typename E>
116  inline
118  const component_set<L>& comps,
119  unsigned neighb_max_distance)
120 
121  : super_(comps),
122  dmax_(0),
123  neighb_max_distance_(neighb_max_distance),
124  direction_(anchor::Horizontal) // FIXME: make it an
125  // argument when this
126  // functor is generic
127  // enough..
128  {
129  }
130 
131  template <typename L, typename E>
132  inline
133  bool
134  link_several_dmax_base<L, E>::verify_link_criterion_(
135  unsigned current_object,
136  const P& start_point,
137  const P& p,
138  anchor::Type anchor) const
139  {
140  (void) current_object;
141  (void) anchor;
142 
143  float dist = math::abs(p[direction_] - start_point[direction_]);
144  return dist <= dmax_; // Not too far
145  }
146 
147 
148  template <typename L, typename E>
149  inline
150  void
151  link_several_dmax_base<L, E>::start_processing_object_(
152  unsigned current_object)
153  {
154  float
155  midcol = (this->components_(current_object).bbox().pmax()[direction_]
156  - this->components_(current_object).bbox().pmin()[direction_]) / 2;
157  dmax_ = midcol + neighb_max_distance_;
158  }
159 
160 
161  template <typename L, typename E>
162  inline
163  void
164  link_several_dmax_base<L, E>::validate_link_(unsigned current_object,
165  const P& start_point,
166  const P& p,
167  anchor::Type anchor)
168  {
169  (void) current_object;
170  (void) start_point;
171  this->potential_links_.append(mln::make::couple(anchor, p));
172  }
173 
174 
175  template <typename L, typename E>
176  inline
177  void
178  link_several_dmax_base<L, E>::initialize_link_(unsigned current_object)
179  {
180  (void) current_object;
181  this->potential_links_.clear();
182  }
183 
184 
185  template <typename L, typename E>
186  inline
188  link_several_dmax_base<L, E>::finalize_link_(unsigned current_object)
189  {
190  //TODO
192  unsigned
193  min = mln_max(unsigned),
194  tmp;
195 
196  if (this->potential_links_.nelements() > 0)
197  {
198  for(unsigned i = 0; i < this->potential_links_.nelements(); ++i)
199  {
200  tmp = math::abs(this->components_(current_object).bbox().pmax()[direction_]
201  - this->potential_links_(i).second()[direction_]);
202  dist.append(tmp);
203  if (tmp < min)
204  min = tmp;
205  }
206 
207  mln_assertion(min != mln_max(unsigned));
208 
209  // Keep closest links and compute vertical overlap.
210  //
211  // FIXME: not using direction_ attribute. This code is not
212  // generic enough!
213  unsigned
214  nratio = 0,
215  id_max_ratio = 0;
216  mln_value(L) nbh_id;
217  mln::util::array<float> overlap;
218  for(unsigned i = 0; i < this->potential_links_.nelements(); ++i)
219  if (dist[i] < (1.2 * min))
220  {
221  unsigned
222  other_object = labeled_image_(potential_links_(i).second());
223  nbh_id = other_object;
224 
225  float
226  dr
227  = math::min(this->components_(current_object).bbox().pmax().row(),
228  this->components_(other_object).bbox().pmax().row())
229  - math::min(this->components_(current_object).bbox().pmin().row(),
230  this->components_(other_object).bbox().pmin().row()),
231  dh = this->components_(other_object).bbox().pmax().row()
232  - this->components_(other_object).bbox().pmin().row(),
233  ratio = dr / dh;
234 
235  overlap.append(ratio);
236  if (ratio > overlap(id_max_ratio) || nratio == 0)
237  {
238  id_max_ratio = i;
239  nratio = 1;
240  nbh_id = other_object;
241  }
242  else if (ratio == overlap(id_max_ratio)
243  && other_object != nbh_id)
244  ++nratio;
245  }
246  else
247  overlap.append(0);
248 
249  if (nratio == 1)
250  {
251  this->links_.update(current_object,
252  labeled_image_(potential_links_(id_max_ratio).second()));
253 
254  return potential_links_(id_max_ratio);
255  }
256 
257  }
258 
259  this->links_.clear(current_object);
260  return mln::make::couple(anchor::Invalid, P());
261  }
262 
263 
264  template <typename L, typename E>
265  inline
266  const util::array<anchor::Type>&
267  link_several_dmax_base<L, E>::anchors() const
268  {
269  return anchors_;
270  }
271 
272  template <typename L, typename E>
273  inline
274  unsigned
275  link_several_dmax_base<L,E>::nanchors() const
276  {
277  return anchors_.nelements();
278  }
279 
280 
281 
282 # endif // ! MLN_INCLUDE_ONLY
283 
284 
285  } // end of namespace scribo::primitive::link::internal
286 
287  } // end of namespace scribo::primitive::link
288 
289  } // end of namespace scribo::primitive
290 
291 } // end of namespace scribo
292 
293 
294 #endif // SCRIBO_PRIMITIVE_LINK_INTERNAL_LINK_SEVERAL_DMAX_HH_