labeled_image.hh 6.62 KB
Newer Older
Roland Levillain's avatar
Roland Levillain committed
1
// Copyright (C) 2009, 2010 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_CORE_IMAGE_IMORPH_LABELED_IMAGE_HH
# define MLN_CORE_IMAGE_IMORPH_LABELED_IMAGE_HH

29
/// \file
Guillaume Lazzara's avatar
Guillaume Lazzara committed
30
///
31
/// \brief Definition of a morpher on a labeled image.
Guillaume Lazzara's avatar
Guillaume Lazzara committed
32

33
# include <mln/core/internal/labeled_image_base.hh>
Guillaume Lazzara's avatar
Guillaume Lazzara committed
34

35
# include <mln/core/routine/duplicate.hh>
Guillaume Lazzara's avatar
Guillaume Lazzara committed
36
37
38

# include <mln/util/array.hh>

39
# include <mln/accu/center.hh>
40
# include <mln/accu/shape/bbox.hh>
41
# include <mln/accu/stat/max.hh>
42

Roland Levillain's avatar
Roland Levillain committed
43
44
# include <mln/data/compute.hh>

45
# include <mln/labeling/compute.hh>
46

Guillaume Lazzara's avatar
Guillaume Lazzara committed
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
namespace mln
{

  // Forward declarations.
  template <typename I> struct labeled_image;
  namespace accu
  {
    template <typename T> struct nil;
    template <typename T> struct bbox;
  }


  namespace internal
  {

    /// Data structure for \c mln::labeled_image<I>.
    template <typename I>
    struct data< labeled_image<I> >
65
      : data< labeled_image_base<I, labeled_image<I> > >
Guillaume Lazzara's avatar
Guillaume Lazzara committed
66
    {
67
68
      typedef data< labeled_image_base<I, labeled_image<I> > > super_;

Guillaume Lazzara's avatar
Guillaume Lazzara committed
69
      data(const I& ima, const mln_value(I)& nlabels);
70
71
      data(const I& ima, const mln_value(I)& nlabels,
	   const util::array<mln_box(I)>& bboxes);
Guillaume Lazzara's avatar
Guillaume Lazzara committed
72
73
74
75
76
77
78
79
80
    };

  } // end of namespace mln::internal


  namespace trait
  {

    template <typename I>
81
82
    struct image_< labeled_image<I> >
      : image_< labeled_image_base<I, labeled_image<I> > >
Guillaume Lazzara's avatar
Guillaume Lazzara committed
83
84
85
86
87
88
89
90
91
92
93
    {
    };

  } // end of namespace mln::trait



  /// Morpher providing an improved interface for labeled image.
  ///
  /// \tparam I The label image type.
  ///
94
95
  /// This image type allows to access every site set at a given
  /// label.
Guillaume Lazzara's avatar
Guillaume Lazzara committed
96
  ///
97
98
  /// This image type guaranties that labels are contiguous (from 1 to
  /// n).
Guillaume Lazzara's avatar
Guillaume Lazzara committed
99
100
101
102
103
  ///
  /// \ingroup modimageidmorpher
  //
  template <typename I>
  class labeled_image
104
    : public labeled_image_base<I, labeled_image<I> >
Guillaume Lazzara's avatar
Guillaume Lazzara committed
105
  {
106
    typedef labeled_image_base<I, labeled_image<I> > super_;
Guillaume Lazzara's avatar
Guillaume Lazzara committed
107
108
109
110
111
112
113
114
115
116
117
118
119

  public:

    /// Skeleton.
    typedef labeled_image< tag::image_<I> > skeleton;

    /// Constructors
    /// @{
    /// Constructor without argument.
    labeled_image();

    /// Constructor from an image \p ima and the number of labels \p nlabels.
    labeled_image(const I& ima, const mln_value(I)& nlabels);
120
121
122
123
124

    /// Constructor from an image \p ima, the number of labels \p
    /// nlabels and the object bounding boxes.
    labeled_image(const I& ima, const mln_value(I)& nlabels,
		  const util::array<mln_box(I)>& bboxes);
Guillaume Lazzara's avatar
Guillaume Lazzara committed
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
    /// @}

    /// Deferred initialization from a labeled image \p ima and the number
    /// of labels \p nlabels.
    void init_(const I& ima, const mln_value(I)& nlabels);

    /// Duplicate the underlying image and create a new labeled_image.
    void init_from_(const labeled_image<I>& model);

  };


  // init_

  //FIXME: not enough generic? We would like 'J' instead of
  // 'labeled_image<I>'.
  template <typename I, typename J>
  void init_(tag::image_t, labeled_image<I>& target,
143
	     const labeled_image<J>& model);
Guillaume Lazzara's avatar
Guillaume Lazzara committed
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172



  namespace make
  {

    template <typename I>
    mln::labeled_image<I>
    labeled_image(const Image<I>& ima, const mln_value(I)& nlabels);

  } // end of namespace mln::make




# ifndef MLN_INCLUDE_ONLY


  // internal::data< labeled_image<I> >

  namespace internal
  {


    // data< labeled_image<I> >

    template <typename I>
    inline
    data< labeled_image<I> >::data(const I& ima, const mln_value(I)& nlabels)
173
      : super_(ima, nlabels)
Guillaume Lazzara's avatar
Guillaume Lazzara committed
174
175
176
    {
    }

177
178
179
180
    template <typename I>
    inline
    data< labeled_image<I> >::data(const I& ima, const mln_value(I)& nlabels,
				   const util::array<mln_box(I)>& bboxes)
181
      : super_(ima, nlabels, bboxes)
182
183
184
185
    {
    }


Guillaume Lazzara's avatar
Guillaume Lazzara committed
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
  } // end of namespace mln::internal


  template <typename I>
  inline
  labeled_image<I>::labeled_image()
  {
  }

  template <typename I>
  inline
  labeled_image<I>::labeled_image(const I& ima, const mln_value(I)& nlabels)
  {
    init_(ima, nlabels);
  }

202
203
204
205
206
207
208
209
210
211
  template <typename I>
  inline
  labeled_image<I>::labeled_image(const I& ima, const mln_value(I)& nlabels,
				  const util::array<mln_box(I)>& bboxes)
  {
    mln_precondition(data::compute(accu::meta::stat::max(), ima) == nlabels);
    this->data_ = new internal::data< labeled_image<I> >(ima, nlabels, bboxes);
  }


Guillaume Lazzara's avatar
Guillaume Lazzara committed
212
213
214
215
216
  template <typename I>
  inline
  void
  labeled_image<I>::init_(const I& ima, const mln_value(I)& nlabels)
  {
217
    mln_precondition(data::compute(accu::meta::stat::max(), ima) == nlabels);
Guillaume Lazzara's avatar
Guillaume Lazzara committed
218
    this->data_ = new internal::data< labeled_image<I> >(ima, nlabels);
219
220
221
    this->data_->bboxes_ = labeling::compute(accu::meta::shape::bbox(),
					     this->data_->ima_,
					     this->data_->nlabels_);
222
 }
Guillaume Lazzara's avatar
Guillaume Lazzara committed
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269

  template <typename I>
  inline
  void
  labeled_image<I>::init_from_(const labeled_image<I>& model)
  {
    this->data_
      = new internal::data< labeled_image<I> >(duplicate(model.hook_data_()->ima_),
						 model.nlabels());
    this->data_->bboxes_ = model.hook_data_()->bboxes_;
  }

  // init_

  template <typename I, typename J>
  void init_(tag::image_t, labeled_image<I>& target,
	     const labeled_image<J>& model)
  {
    I ima;
    init_(tag::image, ima, model);
    target.init_(ima, model.nlabels());
  }


  // Make routines.

  namespace make
  {

    template <typename I>
    mln::labeled_image<I>
    labeled_image(const Image<I>& ima, const mln_value(I)& nlabels)
    {
      mln_precondition(exact(ima).is_valid());
      mln::labeled_image<I> tmp(exact(ima), nlabels);
      return tmp;
    }

  } // end of namespace mln::make


# endif // ! MLN_INCLUDE_ONLY

} // end of namespace mln


#endif // ! MLN_CORE_IMAGE_IMORPH_LABELED_IMAGE_HH