$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
with_several_right_closest_links.hh
1 // Copyright (C) 2009, 2010 EPITA Research and Development Laboratory
2 // (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_WITH_SEVERAL_RIGHT_CLOSEST_LINKS_HH
28 # define SCRIBO_PRIMITIVE_LINK_WITH_SEVERAL_RIGHT_CLOSEST_LINKS_HH
29 
39 
40 # include <mln/core/concept/image.hh>
41 # include <mln/core/concept/neighborhood.hh>
42 
43 # include <mln/math/abs.hh>
44 
45 # include <mln/extension/fill.hh>
46 
47 # include <mln/util/array.hh>
48 
49 
50 # include <scribo/core/macros.hh>
51 # include <scribo/core/object_links.hh>
52 
53 
54 namespace scribo
55 {
56 
57  namespace primitive
58  {
59 
60  namespace link
61  {
62 
63  using namespace mln;
64 
65 
72  //
73  template <typename L>
74  inline
75  object_links<L>
76  with_several_right_closest_links(const component_set<L>& comps,
77  unsigned neighb_max_distance);
78 
80  template <typename L>
81  inline
82  object_links<L>
83  with_several_right_closest_links(const component_set<L>& comps);
84 
85 
86 # ifndef MLN_INCLUDE_ONLY
87 
88 
89 
90  namespace internal
91  {
92 
93  template <unsigned n, typename P>
94  inline
95  unsigned
96  find_closest(const algebra::vec<n,
98  const P& c)
99  {
100  algebra::vec<3, unsigned> dist;
101  for (unsigned j = 0; j < 3; ++j)
102  dist[j] = math::abs(res[j].second().col() - c.col());
103 
104  unsigned idx = 0;
105  for (unsigned i = 1; i < n; ++i)
106  if (dist[i] < dist[idx])
107  idx = i;
108 
109  return idx;
110  }
111 
112  } // end of namespace scribo::primitive::link::internal
113 
114 
115 
116  template <typename L>
117  inline
118  object_links<L>
119  with_several_right_closest_links(const component_set<L>& comps,
120  unsigned neighb_max_distance)
121  {
122  mln_trace("scribo::primitive::link::with_several_right_closest_links");
123 
124  extension::fill(comps.labeled_image_(), 0);
125 
126  object_links<L>
127  link_1(comps), link_2(comps), link_3(comps), final_link(comps);
128 
129  link_1.init();
130  link_2.init();
131  link_3.init();
132 
133  for_all_comps(i, comps)
134  {
135  // -------
136  // | a1------->
137  // | |
138  // | |
139  // | mc------->
140  // | |
141  // | |
142  // | a2------->
143  // -------
144 
145  float midcol = (comps(i).bbox().pmax().col()
146  - comps(i).bbox().pmin().col()) / 2;
147  float dmax = midcol + neighb_max_distance;
148 
149  mln_site(L) c = comps(i).bbox().center();
150 
151  algebra::vec<3, mln::util::couple<bool, mln_site(L)> > res;
152 
153  // Right link from the top anchor.
154  mln_site(L) a1 = c;
155  a1.row() = comps(i).bbox().pmin().row()
156  + (c.row() - comps(i).bbox().pmin().row()) / 4;
157  res[0] = primitive::internal::find_right_link(comps, link_1,
158  i, dmax, a1);
159 
160  // Right link from the central site
161  res[1] = primitive::internal::find_right_link(comps, link_2,
162  i, dmax,
163  comps(i).mass_center());
164 
165  // Right link from the bottom anchor.
166  mln_site(L) a2 = c;
167  a2.row() = comps(i).bbox().pmax().row()
168  - (c.row() - comps(i).bbox().pmin().row()) / 4;
169  res[2] = primitive::internal::find_right_link(comps, link_3,
170  i, dmax, a2);
171 
172  // Try to find the closest object.
173 
174  unsigned closest_idx = internal::find_closest(res, c);
175 
176 
177  // If there exists a link and the site is not outside the
178  // image domain.
179  if (res[closest_idx].first())
180  final_link[i] = comps(res[closest_idx].second());
181  else
182  final_link[i] = i;
183  }
184 
185  return final_link;
186  }
187 
188 
189  template <typename L>
190  inline
191  object_links<L>
192  with_several_right_closest_links(const component_set<L>& comps)
193  {
194  return with_several_right_closest_links(comps, mln_max(unsigned));
195  }
196 
197 
198 # endif // ! MLN_INCLUDE_ONLY
199 
200  } // end of namespace scribo::primitive::link
201 
202  } // end of namespace scribo::primitive
203 
204 } // end of namespace scribo
205 
206 #endif // ! SCRIBO_PRIMITIVE_LINK_WITH_SEVERAL_RIGHT_CLOSEST_LINKS_HH