interpolated.hh 6.27 KB
Newer Older
1
2
// Copyright (C) 2007, 2008, 2009, 2012, 2013 EPITA Research and
// Development Laboratory (LRDE)
3
//
4
// This file is part of Olena.
5
//
6
7
8
9
10
// 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,
11
12
13
14
15
// 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
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
22
23
24
25
// 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.
26

27
28
#ifndef MLN_CORE_IMAGE_IMORPH_INTERPOLATED_HH
# define MLN_CORE_IMAGE_IMORPH_INTERPOLATED_HH
29

30
/// \file
Guillaume Lazzara's avatar
Guillaume Lazzara committed
31
///
32
/// \brief Definition of a morpher that makes an image become readable
Guillaume Lazzara's avatar
Guillaume Lazzara committed
33
34
35
36
/// with floating coordinates.
///
/// \todo think having has(algebra::vec v) as a method

37
38
39

# include <cmath>

40
# include <mln/core/internal/image_identity.hh>
41
# include <mln/algebra/vec.hh>
42
# include <mln/value/set.hh>
43
44
45
46

namespace mln
{

Guillaume Lazzara's avatar
Guillaume Lazzara committed
47
  // Forward declaration.
48
  template <typename I, template <class> class F> struct interpolated;
49
50
51
52

  namespace internal
  {

53
54
55
    /*!
      \brief Data structure for \c mln::interpolated<I, F>.
    */
56
57
    template <typename I, template <class> class F>
    struct data< interpolated<I,F> >
58
    {
Matthieu Garrigues's avatar
Matthieu Garrigues committed
59
      data(I& ima);
60

61
      I& ima_;
62
63
64
65
    };

  } // end of namespace mln::internal

66
67
68
69
70
71
72
73
74
75
76
77
78
79
80

  namespace trait
  {

    template <typename I, template <class> class F>
    struct image_< interpolated<I,F> >
      : public image_<I> // Same as I except...
    {
      // ...these changes.
      typedef trait::image::value_io::read_only value_io;
    };

  } // end of namespace mln::trait


81
  /// Makes the underlying image being accessed with floating coordinates.
Guillaume Lazzara's avatar
Guillaume Lazzara committed
82
  ///
Guillaume Lazzara's avatar
Guillaume Lazzara committed
83
  /// \ingroup modimageidentity
84
  //
85
  template <typename I, template <class> class F>
86
  struct interpolated :
87
    public mln::internal::image_identity< I, mln_domain(I), interpolated<I,F> >
88
  {
89

90
    typedef mln::internal::image_identity< I, mln_domain(I),
91
					   interpolated<I,F> > super_;
92

93
94
95
96
97
98
99
    /// Point_Site associated type.
    typedef mln_psite(I) psite;

    /// Value associated type.
    typedef mln_value(I) value;

    /// Return type of read-write access.
100
    typedef mln_lvalue(I) lvalue; // FIXME: Depends on lvalue presence in I.
101
102
103
104

    /// Return type of read-only access.
    typedef mln_rvalue(I) rvalue;

Thierry Geraud's avatar
Thierry Geraud committed
105
    /// Skeleton.
106
    typedef interpolated< tag::image_<I>, F > skeleton;
Thierry Geraud's avatar
Thierry Geraud committed
107

108

109
    /// Constructors.
110
    ///FIXME: don't we want a 'const' here?
111
    interpolated(I& ima);
112
    interpolated();
113

114
    /// \cond INTERNAL_API
Guillaume Lazzara's avatar
Guillaume Lazzara committed
115
116
    /// Initialize an empty image.
    void init_(I& ima);
117
    /// \endcond
Guillaume Lazzara's avatar
Guillaume Lazzara committed
118

119
120

    /// Test if this image has been initialized.
121
    bool is_valid() const;
122
123

    /// Test if a pixel value is accessible at \p p.
Thierry Geraud's avatar
Thierry Geraud committed
124
    using super_::has;
125

Simon Nivault's avatar
Simon Nivault committed
126
    /// Test if a pixel value is accessible at \p v.
127
128
    template <typename C>
    bool has(const mln::algebra::vec<I::psite::dim, C>& v) const;
Simon Nivault's avatar
Simon Nivault committed
129

130
131
    /// Read-only access of pixel value at point site \p p.
    /// Mutable access is only OK for reading (not writing).
132
    using super_::operator();
133

134
135
    mln_value(I) operator()(const mln::algebra::vec<psite::dim, float>& v) const;
    mln_value(I) operator()(const mln::algebra::vec<psite::dim, float>& v);
136

137
    const F<I> fun_;
138
139
140
  };


141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
  /** \brief Helper routine to create an mln::interpolated morphed
      image.

      Careful, the order of the template parameters is inverted
      compared to mln::interpolated.  This is so that the routine can
      be used this way:

      \code
      mln::interpolate<mln::fun::x2v::bilinear>(ima);
      \encode

      (i.e., so that parameter I can be deduced from \a ima).  */
  template <template <class> class F, typename I>
  interpolated<I, F> interpolate(Image<I>& ima);


157
158
159

# ifndef MLN_INCLUDE_ONLY

160
161
162
  namespace internal
  {

Matthieu Garrigues's avatar
Matthieu Garrigues committed
163
    // internal::data< interpolated<I,S> >
164

165
    template <typename I, template <class> class F>
166
    inline
167
    data< interpolated<I,F> >::data(I& ima)
168
169
170
171
172
173
      : ima_(ima)
    {
    }

  } // end of namespace mln::internal

174
  template <typename I, template <class> class F>
175
  inline
176
177
  interpolated<I,F>::interpolated(I& ima)
    : fun_(ima)
178
  {
179
    mln_precondition(ima.is_valid());
Guillaume Lazzara's avatar
Guillaume Lazzara committed
180
    init_(ima);
181
182
  }

183
  template <typename I, template <class> class F>
184
  inline
185
  interpolated<I,F>::interpolated()
186
  {
187
188
  }

189
  template <typename I, template <class> class F>
Guillaume Lazzara's avatar
Guillaume Lazzara committed
190
191
  inline
  void
192
  interpolated<I, F >::init_(I& ima)
Guillaume Lazzara's avatar
Guillaume Lazzara committed
193
  {
194
    mln_precondition(ima.is_valid());
195
    this->data_ = new internal::data< interpolated<I,F> >(ima);
Guillaume Lazzara's avatar
Guillaume Lazzara committed
196
197
  }

198
  template <typename I, template <class> class F>
199
  inline
200
  bool interpolated<I,F>::is_valid() const
201
  {
202
    mln_invariant(this->data_->ima_.is_valid());
203
204
205
    return true;
  }

206
  template <typename I, template <class> class F>
207
  template <typename C>
208
  inline
209
  bool interpolated<I,F>::has(const mln::algebra::vec<I::psite::dim, C>& v) const
Simon Nivault's avatar
Simon Nivault committed
210
  {
211
    mln_psite(I) p;
212
    for (unsigned i = 0; i < I::psite::dim; ++i)
Simon Nivault's avatar
Simon Nivault committed
213
      p[i] = static_cast<int>(round(v[i]));
Thierry Geraud's avatar
Thierry Geraud committed
214
    return this->data_->ima_.has(p);
215
216
  }

217

218
  template <typename I, template <class> class F>
219
  inline
220
  mln_value(I)
221
  interpolated<I,F>::operator()(const mln::algebra::vec<psite::dim, float>& v) const
222
  {
223
224
225
226
227
228
    return fun_(v);
  }

  template <typename I, template <class> class F>
  inline
  mln_value(I)
229
  interpolated<I,F>::operator()(const mln::algebra::vec<psite::dim, float>& v)
230
  {
231
    return fun_(v);
232
233
  }

234

235
236
237
238
239
240
241
242
243
  // interpolate.

  template <template <class> class F, typename I>
  interpolated<I, F> interpolate(Image<I>& ima)
  {
    interpolated<I, F> tmp(exact(ima));
    return tmp;
  }

244
245
246
247
248
# endif // ! MLN_INCLUDE_ONLY

} // end of namespace mln


249
#endif // ! MLN_CORE_IMAGE_IMORPH_INTERPOLATED_HH