compute.hh 12.4 KB
Newer Older
1
// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE)
Guillaume Lazzara's avatar
Guillaume Lazzara committed
2
//
3
// This file is part of Olena.
Guillaume Lazzara's avatar
Guillaume Lazzara committed
4
//
5
6
7
8
9
// Olena is free software: you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, version 2 of the License.
//
// Olena is distributed in the hope that it will be useful,
Guillaume Lazzara's avatar
Guillaume Lazzara committed
10
11
12
13
14
// 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
15
// along with Olena.  If not, see <http://www.gnu.org/licenses/>.
Guillaume Lazzara's avatar
Guillaume Lazzara committed
16
17
//
// As a special exception, you may use this file as part of a free
18
// software project without restriction.  Specifically, if other files
Guillaume Lazzara's avatar
Guillaume Lazzara committed
19
// instantiate templates or use macros or inline functions from this
20
21
22
23
24
// 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.
Guillaume Lazzara's avatar
Guillaume Lazzara committed
25
26
27
28

#ifndef MLN_LABELING_COMPUTE_HH
# define MLN_LABELING_COMPUTE_HH

29
/// \file
30
///
31
32
/// \brief Compute accumulators onto sites/values of each labeled
/// component of an image.
Guillaume Lazzara's avatar
Guillaume Lazzara committed
33
34
///
/// \todo write fastest version.
35
///
Guillaume Lazzara's avatar
Guillaume Lazzara committed
36
37
///
/// TODO: Move versions without 'input' as arg into mln::set
38
/// and change 'input' from Image to Site_Set!
Guillaume Lazzara's avatar
Guillaume Lazzara committed
39
40
/// ==> NO, see below. (Z)
///
Guillaume Lazzara's avatar
Guillaume Lazzara committed
41
42
43
44
45
/// The overload not taking 'input' as argument works on sites and
/// would be a good candidate for set::compute. However, the fact that
/// this version of compute is in the namespace 'labeling' means that
/// it produces several results at the same time for each labels which
/// is not the case of other implementations of compute.
Guillaume Lazzara's avatar
Guillaume Lazzara committed
46

Guillaume Lazzara's avatar
Guillaume Lazzara committed
47
48
# include <mln/core/concept/image.hh>
# include <mln/core/concept/accumulator.hh>
Guillaume Lazzara's avatar
Guillaume Lazzara committed
49
50
# include <mln/core/concept/meta_accumulator.hh>
# include <mln/util/array.hh>
Thierry Geraud's avatar
Thierry Geraud committed
51
# include <mln/convert/from_to.hh>
Guillaume Lazzara's avatar
Guillaume Lazzara committed
52
53
54
55
56
57
58
59


namespace mln
{

  namespace labeling
  {

60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
    /// Compute an accumulator onto the pixel values of the image \p input.
    /// for each component of the image \p label.
    ///
    /// \param[in] a An array of accumulator.
    /// \param[in] input The input image.
    /// \param[in] label The labeled image.
    /// \param[in] nlabels The number of labels in \p label.
    /// \return A mln::p_array of accumulator result (one result per label).
    //
    template <typename A, typename I, typename L>
    util::array<mln_result(A)>
    compute(util::array<A>& a,
	    const Image<I>& input,
	    const Image<L>& label,
	    const mln_value(L)& nlabels);


Guillaume Lazzara's avatar
Guillaume Lazzara committed
77
78
79
80
81
82
    /// Compute an accumulator onto the pixel values of the image \p input.
    /// for each component of the image \p label.
    ///
    /// \param[in] a An accumulator.
    /// \param[in] input The input image.
    /// \param[in] label The labeled image.
83
84
85
    /// \param[in] nlabels The number of labels in \p label.
    /// \return A mln::p_array of accumulator result (one result per label).
    //
Guillaume Lazzara's avatar
Guillaume Lazzara committed
86
    template <typename A, typename I, typename L>
87
    util::array<mln_result(A)>
Guillaume Lazzara's avatar
Guillaume Lazzara committed
88
89
    compute(const Accumulator<A>& a,
	    const Image<I>& input,
Guillaume Lazzara's avatar
Guillaume Lazzara committed
90
91
	    const Image<L>& label,
	    const mln_value(L)& nlabels);
Guillaume Lazzara's avatar
Guillaume Lazzara committed
92

93

Guillaume Lazzara's avatar
Guillaume Lazzara committed
94
95
96
97
98
99
    /// Compute an accumulator onto the pixel values of the image \p input.
    ///  for each component of the image \p label.
    ///
    /// \param[in] a A meta-accumulator.
    /// \param[in] input The input image.
    /// \param[in] label The labeled image.
100
101
102
    /// \param[in] nlabels The number of labels in \p label.
    /// \return A mln::p_array of accumulator result (one result per label).
    //
Guillaume Lazzara's avatar
Guillaume Lazzara committed
103
    template <typename A, typename I, typename L>
104
    util::array<mln_meta_accu_result(A, mln_value(I))>
Guillaume Lazzara's avatar
Guillaume Lazzara committed
105
106
    compute(const Meta_Accumulator<A>& a,
	    const Image<I>& input,
Guillaume Lazzara's avatar
Guillaume Lazzara committed
107
108
	    const Image<L>& label,
	    const mln_value(L)& nlabels);
Guillaume Lazzara's avatar
Guillaume Lazzara committed
109

110

Guillaume Lazzara's avatar
Guillaume Lazzara committed
111
112
113
114
115
    /// Compute an accumulator onto the pixel sites of each component domain of
    /// \p label.
    ///
    /// \param[in] a An accumulator.
    /// \param[in] label The labeled image.
116
117
118
    /// \param[in] nlabels The number of labels in \p label.
    /// \return A mln::p_array of accumulator result (one result per label).
    //
Guillaume Lazzara's avatar
Guillaume Lazzara committed
119
    template <typename A, typename L>
120
    util::array<mln_result(A)>
Guillaume Lazzara's avatar
Guillaume Lazzara committed
121
    compute(const Accumulator<A>& a,
Guillaume Lazzara's avatar
Guillaume Lazzara committed
122
123
	    const Image<L>& label,
	    const mln_value(L)& nlabels);
Guillaume Lazzara's avatar
Guillaume Lazzara committed
124

125

Guillaume Lazzara's avatar
Guillaume Lazzara committed
126
127
128
129
130
    /// Compute an accumulator onto the pixel sites of each component domain of
    /// \p label.
    ///
    /// \param[in] a A meta-accumulator.
    /// \param[in] label The labeled image.
131
132
133
    /// \param[in] nlabels The number of labels in \p label.
    /// \return A mln::p_array of accumulator result (one result per label).
    //
Guillaume Lazzara's avatar
Guillaume Lazzara committed
134
    template <typename A, typename L>
135
    util::array<mln_meta_accu_result(A, mln_psite(L))>
Guillaume Lazzara's avatar
Guillaume Lazzara committed
136
    compute(const Meta_Accumulator<A>& a,
Guillaume Lazzara's avatar
Guillaume Lazzara committed
137
138
	    const Image<L>& label,
	    const mln_value(L)& nlabels);
Guillaume Lazzara's avatar
Guillaume Lazzara committed
139
140
141
142
143



# ifndef MLN_INCLUDE_ONLY

Guillaume Lazzara's avatar
Guillaume Lazzara committed
144
145
146
    namespace internal
    {

Guillaume Lazzara's avatar
Guillaume Lazzara committed
147
      template <typename A, typename L>
Guillaume Lazzara's avatar
Guillaume Lazzara committed
148
      inline
Guillaume Lazzara's avatar
Guillaume Lazzara committed
149
150
      void
      compute_tests(const Accumulator<A>& a,
Guillaume Lazzara's avatar
Guillaume Lazzara committed
151
152
		    const Image<L>& label,
		    const mln_value(L)& nlabels)
Guillaume Lazzara's avatar
Guillaume Lazzara committed
153
      {
154
	mln_precondition(exact(label).is_valid());
155
	// mlc_is_a(mln_value(L), mln::value::Symbolic)::check();
Guillaume Lazzara's avatar
Guillaume Lazzara committed
156
	(void) a;
Guillaume Lazzara's avatar
Guillaume Lazzara committed
157
	(void) label;
Guillaume Lazzara's avatar
Guillaume Lazzara committed
158
	(void) nlabels;
Guillaume Lazzara's avatar
Guillaume Lazzara committed
159
160
161
      }


Guillaume Lazzara's avatar
Guillaume Lazzara committed
162
      template <typename A, typename I, typename L>
Guillaume Lazzara's avatar
Guillaume Lazzara committed
163
      inline
Guillaume Lazzara's avatar
Guillaume Lazzara committed
164
165
166
      void
      compute_tests(const Accumulator<A>& a,
		    const Image<I>& input,
Guillaume Lazzara's avatar
Guillaume Lazzara committed
167
168
		    const Image<L>& label,
		    const mln_value(L)& nlabels)
Guillaume Lazzara's avatar
Guillaume Lazzara committed
169
      {
170
171
	mln_precondition(exact(input).is_valid());
	mln_precondition(exact(label).is_valid());
172
	// mlc_is_a(mln_value(L), mln::value::Symbolic)::check();
Guillaume Lazzara's avatar
Guillaume Lazzara committed
173
	(void) a;
Guillaume Lazzara's avatar
Guillaume Lazzara committed
174
175
	(void) input;
	(void) label;
Guillaume Lazzara's avatar
Guillaume Lazzara committed
176
	(void) nlabels;
Guillaume Lazzara's avatar
Guillaume Lazzara committed
177
178
      }

Guillaume Lazzara's avatar
Guillaume Lazzara committed
179
    } // end of namespace mln::labeling::internal
Guillaume Lazzara's avatar
Guillaume Lazzara committed
180
181
182
183
184
185
186
187
188



    namespace impl
    {

      namespace generic
      {

189
190
191
192
193
194
195
196
197

	/// Generic implementation of labeling::compute.
	///
	/// \param[in] a_      An accumulator.
	/// \param[in] label_  The labeled image.
	/// \param[in] nlabels The number of labels in \p label.
	///
	/// \return A mln::p_array of accumulator result (one result per label).
	//
Guillaume Lazzara's avatar
Guillaume Lazzara committed
198
	template <typename A, typename L>
Guillaume Lazzara's avatar
Guillaume Lazzara committed
199
200
	inline
	util::array<mln_result(A)>
Guillaume Lazzara's avatar
Guillaume Lazzara committed
201
	compute(const Accumulator<A>& a_,
Guillaume Lazzara's avatar
Guillaume Lazzara committed
202
203
		const Image<L>& label_,
		const mln_value(L)& nlabels)
Guillaume Lazzara's avatar
Guillaume Lazzara committed
204
205
	{
	  trace::entering("labeling::impl::generic::compute");
Guillaume Lazzara's avatar
Guillaume Lazzara committed
206
	  internal::compute_tests(a_, label_, nlabels);
Guillaume Lazzara's avatar
Guillaume Lazzara committed
207

Guillaume Lazzara's avatar
Guillaume Lazzara committed
208
	  const A& a = exact(a_);
Guillaume Lazzara's avatar
Guillaume Lazzara committed
209
	  const L& label = exact(label_);
Guillaume Lazzara's avatar
Guillaume Lazzara committed
210

Guillaume Lazzara's avatar
Guillaume Lazzara committed
211
	  util::array<A> accus(static_cast<unsigned>(nlabels) + 1, a);
Guillaume Lazzara's avatar
Guillaume Lazzara committed
212

Guillaume Lazzara's avatar
Guillaume Lazzara committed
213
	  mln_piter(L) p(label.domain());
Guillaume Lazzara's avatar
Guillaume Lazzara committed
214
215
216
	  for_all(p)
	    accus[label(p)].take(p);

Thierry Geraud's avatar
Thierry Geraud committed
217
218
219
	  util::array<mln_result(A)> res;
	  convert::from_to(accus, res);

Guillaume Lazzara's avatar
Guillaume Lazzara committed
220
	  trace::exiting("labeling::impl::generic::compute");
Thierry Geraud's avatar
Thierry Geraud committed
221
	  return res;
Guillaume Lazzara's avatar
Guillaume Lazzara committed
222
223
224
	}


225
226
227
228
229
230
231
232
233
	/// Generic implementation of labeling::compute.
	///
	/// \param[in] a_      An accumulator.
	/// \param[in] input_  The input image.
	/// \param[in] label_  The labeled image.
	/// \param[in] nlabels The number of labels in \p label.
	///
	/// \return A mln::p_array of accumulator result (one result per label).
	//
Guillaume Lazzara's avatar
Guillaume Lazzara committed
234
	template <typename A, typename I, typename L>
Guillaume Lazzara's avatar
Guillaume Lazzara committed
235
236
	inline
	util::array<mln_result(A)>
Guillaume Lazzara's avatar
Guillaume Lazzara committed
237
	compute(const Accumulator<A>& a_,
Guillaume Lazzara's avatar
Guillaume Lazzara committed
238
		const Image<I>& input_,
Guillaume Lazzara's avatar
Guillaume Lazzara committed
239
240
		const Image<L>& label_,
		const mln_value(L)& nlabels)
Guillaume Lazzara's avatar
Guillaume Lazzara committed
241
242
	{
	  trace::entering("labeling::impl::generic::compute");
Guillaume Lazzara's avatar
Guillaume Lazzara committed
243
	  internal::compute_tests(a_, input_, label_, nlabels);
Guillaume Lazzara's avatar
Guillaume Lazzara committed
244

Guillaume Lazzara's avatar
Guillaume Lazzara committed
245
	  const A& a = exact(a_);
Guillaume Lazzara's avatar
Guillaume Lazzara committed
246
	  const I& input = exact(input_);
Guillaume Lazzara's avatar
Guillaume Lazzara committed
247
	  const L& label = exact(label_);
Guillaume Lazzara's avatar
Guillaume Lazzara committed
248

Guillaume Lazzara's avatar
Guillaume Lazzara committed
249
	  util::array<A> accus(static_cast<unsigned>(nlabels) + 1, a);
Guillaume Lazzara's avatar
Guillaume Lazzara committed
250
251
252
253
254

	  mln_piter(I) p(input.domain());
	  for_all(p)
	    accus[label(p)].take(input(p));

Thierry Geraud's avatar
Thierry Geraud committed
255
256
257
	  util::array<mln_result(A)> res;
	  convert::from_to(accus, res);

Guillaume Lazzara's avatar
Guillaume Lazzara committed
258
	  trace::exiting("labeling::impl::generic::compute");
Thierry Geraud's avatar
Thierry Geraud committed
259
	  return res;
Guillaume Lazzara's avatar
Guillaume Lazzara committed
260
	}
Guillaume Lazzara's avatar
Guillaume Lazzara committed
261

262
263
264
265
266
267
268
269
270
271

	/// Generic implementation of labeling::compute.
	///
	/// \param[in] accus   An array of accumulators.
	/// \param[in] input_  The input image.
	/// \param[in] label_  The labeled image.
	/// \param[in] nlabels The number of labels in \p label.
	///
	/// \return A mln::p_array of accumulator result (one result per label).
	//
272
273
274
275
276
277
278
279
280
281
282
283
284
285
	template <typename A, typename I, typename L>
	inline
	util::array<mln_result(A)>
	compute(util::array<A>& accus,
		const Image<I>& input_,
		const Image<L>& label_,
		const mln_value(L)& nlabels)
	{
	  trace::entering("labeling::impl::generic::compute");
	  //internal::compute_tests(a_, input_, label_, nlabels);

	  //const A& a = exact(a_);
	  const I& input = exact(input_);
	  const L& label = exact(label_);
286
	  (void) nlabels;
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301

	  // FIXME: Check accus size with nlabels.
	  //util::array<A> accus(static_cast<unsigned>(nlabels) + 1, a);

	  mln_piter(I) p(input.domain());
	  for_all(p)
	    accus[label(p)].take(input(p));

	  util::array<mln_result(A)> res;
	  convert::from_to(accus, res);

	  trace::exiting("labeling::impl::generic::compute");
	  return res;
	}

302
      } // end of namespace mln::labeling::impl::generic
Guillaume Lazzara's avatar
Guillaume Lazzara committed
303
304
305
306
307
308
309
310

    } // end of namespace mln::labeling::impl



    namespace internal
    {

311

Guillaume Lazzara's avatar
Guillaume Lazzara committed
312
      template <typename A, typename L>
Guillaume Lazzara's avatar
Guillaume Lazzara committed
313
314
315
      inline
      util::array<mln_result(A)>
      compute_dispatch(const Accumulator<A>& a,
Guillaume Lazzara's avatar
Guillaume Lazzara committed
316
317
		       const Image<L>& label,
		       const mln_value(L)& nlabels)
Guillaume Lazzara's avatar
Guillaume Lazzara committed
318
319
320
321
322
      {
	return impl::generic::compute(a, label, nlabels);
      }


Guillaume Lazzara's avatar
Guillaume Lazzara committed
323
      template <typename A, typename I, typename L>
Guillaume Lazzara's avatar
Guillaume Lazzara committed
324
325
326
327
      inline
      util::array<mln_result(A)>
      compute_dispatch(const Accumulator<A>& a,
		       const Image<I>& input,
Guillaume Lazzara's avatar
Guillaume Lazzara committed
328
329
		       const Image<L>& label,
		       const mln_value(L)& nlabels)
Guillaume Lazzara's avatar
Guillaume Lazzara committed
330
331
332
333
      {
	return impl::generic::compute(a, input, label, nlabels);
      }

334
335
336
337
338
339
340
341
342
343
344
345
346

      template <typename A, typename I, typename L>
      inline
      util::array<mln_result(A)>
      compute_dispatch(util::array<A>& a,
		       const Image<I>& input,
		       const Image<L>& label,
		       const mln_value(L)& nlabels)
      {
	return impl::generic::compute(a, input, label, nlabels);
      }


Guillaume Lazzara's avatar
Guillaume Lazzara committed
347
    } // end of namespace mln::labeling::internal
Guillaume Lazzara's avatar
Guillaume Lazzara committed
348
349
350



351
    // Facades.
Guillaume Lazzara's avatar
Guillaume Lazzara committed
352

353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
    template <typename A, typename I, typename L>
    inline
    util::array<mln_result(A)>
    compute(util::array<A>& a,
	    const Image<I>& input,
	    const Image<L>& label,
	    const mln_value(L)& nlabels)
    {
      trace::entering("labeling::compute");

      //internal::compute_tests(a, input, label, nlabels);

      typedef util::array<mln_result(A)> R;
      R res = internal::compute_dispatch(a, input, label, nlabels);

      trace::exiting("labeling::compute");
      return res;
    }

Guillaume Lazzara's avatar
Guillaume Lazzara committed
372
    template <typename A, typename I, typename L>
Guillaume Lazzara's avatar
Guillaume Lazzara committed
373
    inline
374
    util::array<mln_result(A)>
Guillaume Lazzara's avatar
Guillaume Lazzara committed
375
376
    compute(const Accumulator<A>& a,
	    const Image<I>& input,
Guillaume Lazzara's avatar
Guillaume Lazzara committed
377
378
	    const Image<L>& label,
	    const mln_value(L)& nlabels)
Guillaume Lazzara's avatar
Guillaume Lazzara committed
379
380
381
    {
      trace::entering("labeling::compute");

Guillaume Lazzara's avatar
Guillaume Lazzara committed
382
383
384
385
      internal::compute_tests(a, input, label, nlabels);

      typedef util::array<mln_result(A)> R;
      R res = internal::compute_dispatch(a, input, label, nlabels);
Guillaume Lazzara's avatar
Guillaume Lazzara committed
386
387

      trace::exiting("labeling::compute");
Guillaume Lazzara's avatar
Guillaume Lazzara committed
388
      return res;
Guillaume Lazzara's avatar
Guillaume Lazzara committed
389
390
    }

Guillaume Lazzara's avatar
Guillaume Lazzara committed
391
    template <typename A, typename I, typename L>
Guillaume Lazzara's avatar
Guillaume Lazzara committed
392
    inline
393
    util::array<mln_meta_accu_result(A, mln_value(I))>
394
    compute(const Meta_Accumulator<A>& a,
Guillaume Lazzara's avatar
Guillaume Lazzara committed
395
	    const Image<I>& input,
Guillaume Lazzara's avatar
Guillaume Lazzara committed
396
397
	    const Image<L>& label,
	    const mln_value(L)& nlabels)
Guillaume Lazzara's avatar
Guillaume Lazzara committed
398
    {
399
400
401
      typedef mln_accu_with(A, mln_value(I)) A_;
      A_ a_ = accu::unmeta(exact(a), mln_value(I)());

402
      return compute(a_, input, label, nlabels);
Guillaume Lazzara's avatar
Guillaume Lazzara committed
403
404
405
    }


Guillaume Lazzara's avatar
Guillaume Lazzara committed
406
    template <typename A, typename L>
Guillaume Lazzara's avatar
Guillaume Lazzara committed
407
    inline
408
    util::array<mln_result(A)>
Guillaume Lazzara's avatar
Guillaume Lazzara committed
409
    compute(const Accumulator<A>& a,
Guillaume Lazzara's avatar
Guillaume Lazzara committed
410
411
	    const Image<L>& label,
	    const mln_value(L)& nlabels)
Guillaume Lazzara's avatar
Guillaume Lazzara committed
412
413
414
    {
      trace::entering("labeling::compute");

Guillaume Lazzara's avatar
Guillaume Lazzara committed
415
416
417
418
      internal::compute_tests(a, label, nlabels);

      typedef util::array<mln_result(A)> R;
      R res = internal::compute_dispatch(a, label, nlabels);
Guillaume Lazzara's avatar
Guillaume Lazzara committed
419

Guillaume Lazzara's avatar
Guillaume Lazzara committed
420
      mln_postcondition(res.nelements() == static_cast<unsigned>(nlabels) + 1);
Guillaume Lazzara's avatar
Guillaume Lazzara committed
421

Guillaume Lazzara's avatar
Guillaume Lazzara committed
422
      trace::exiting("labeling::compute");
Guillaume Lazzara's avatar
Guillaume Lazzara committed
423
      return res;
Guillaume Lazzara's avatar
Guillaume Lazzara committed
424
425
426
    }


Guillaume Lazzara's avatar
Guillaume Lazzara committed
427
    template <typename A, typename L>
Guillaume Lazzara's avatar
Guillaume Lazzara committed
428
    inline
429
    util::array<mln_meta_accu_result(A, mln_psite(L))>
430
    compute(const Meta_Accumulator<A>& a,
Guillaume Lazzara's avatar
Guillaume Lazzara committed
431
432
	    const Image<L>& label,
	    const mln_value(L)& nlabels)
Guillaume Lazzara's avatar
Guillaume Lazzara committed
433
    {
Guillaume Lazzara's avatar
Guillaume Lazzara committed
434
435
      typedef mln_accu_with(A, mln_psite(L)) A_;
      A_ a_ = accu::unmeta(exact(a), mln_psite(L)());
436

437
      return compute(a_, label, nlabels);
Guillaume Lazzara's avatar
Guillaume Lazzara committed
438
439
440
441
442
443
444
445
446
447
448
    }


# endif // ! MLN_INCLUDE_ONLY

  } // end of namespace mln::labeling

} // end of namespace mln


#endif // ! MLN_LABELING_COMPUTE_HH