aimsdata  5.1.2
Neuroimaging data handling
linearInterpolator.h
Go to the documentation of this file.
1 /* This software and supporting documentation are distributed by
2  * Institut Federatif de Recherche 49
3  * CEA/NeuroSpin, Batiment 145,
4  * 91191 Gif-sur-Yvette cedex
5  * France
6  *
7  * This software is governed by the CeCILL-B license under
8  * French law and abiding by the rules of distribution of free software.
9  * You can use, modify and/or redistribute the software under the
10  * terms of the CeCILL-B license as circulated by CEA, CNRS
11  * and INRIA at the following URL "http://www.cecill.info".
12  *
13  * As a counterpart to the access to the source code and rights to copy,
14  * modify and redistribute granted by the license, users are provided only
15  * with a limited warranty and the software's author, the holder of the
16  * economic rights, and the successive licensors have only limited
17  * liability.
18  *
19  * In this respect, the user's attention is drawn to the risks associated
20  * with loading, using, modifying and/or developing or reproducing the
21  * software by the user in light of its specific status of free software,
22  * that may mean that it is complicated to manipulate, and that also
23  * therefore means that it is reserved for developers and experienced
24  * professionals having in-depth computer knowledge. Users are therefore
25  * encouraged to load and test the software's suitability as regards their
26  * requirements in conditions enabling the security of their systems and/or
27  * data to be ensured and, more generally, to use and operate it in the
28  * same conditions as regards security.
29  *
30  * The fact that you are presently reading this means that you have had
31  * knowledge of the CeCILL-B license and that you accept its terms.
32  */
33 
34 /*
35  * 3D linear image interpolation
36  */
37 
38 #ifndef AIMS_LINEAR_INTERPOLATOR
39 #define AIMS_LINEAR_INTERPOLATOR
40 
41 #include <cassert>
42 
44 #include <cartobase/smart/rcptr.h>
45 #include <vector>
46 
47 namespace aims {
48 
49 
50  //----------------//
51  // Interpolator //
52 //----------------//
53 
54 //-----------------------------------------------------------------------------
56 {
57 public:
58 
59  typedef float Coordinate_t;
60  typedef Point3df Point_t;
61  typedef double Scalar_t;
62 
63  virtual ~Interpolator();
64 
68  virtual bool isValid( Coordinate_t x, Coordinate_t y,
69  Coordinate_t z ) const = 0;
73  inline bool isValid( const Interpolator::Point_t &point ) const
74  {
75  return isValid( point[ 0 ], point[ 1 ], point[ 2 ] );
76  }
77 
80  Coordinate_t z ) const
81  __attribute__((__deprecated__("use value() method instead")))
82  {
83  return do_interpolation( x, y, z );
84  }
86  inline Scalar_t operator()( const Interpolator::Point_t &point ) const
87  __attribute__((__deprecated__("use value() method instead")))
88  {
89  return do_interpolation( point[ 0 ], point[ 1 ], point[ 2 ] );
90  }
93  std::vector<Scalar_t> & v ) const
94  __attribute__((__deprecated__("use values() method instead")))
95  {
96  do_interpolations( x, y, z, v );
97  }
99  inline void operator()( const Interpolator::Point_t &point,
100  std::vector<Scalar_t> &v ) const
101  __attribute__((__deprecated__("use values() method instead")))
102  {
103  do_interpolations( point[ 0 ], point[ 1 ], point[ 2 ], v );
104  }
105 
108  Coordinate_t z ) const
109  {
110  return do_interpolation(x, y, z);
111  }
113  inline Scalar_t value( const Interpolator::Point_t &point ) const
114  {
115  return do_interpolation( point[ 0 ], point[ 1 ], point[ 2 ] );
116  }
119  std::vector<Scalar_t> &v ) const
120  {
121  do_interpolations(x, y, z, v);
122  }
124  inline void values( const Interpolator::Point_t &point,
125  std::vector<Scalar_t> &v ) const
126  {
127  do_interpolations( point[ 0 ], point[ 1 ], point[ 2 ], v );
128  }
131  virtual const carto::PropertySet &header() const = 0;
132 private:
133  virtual Scalar_t do_interpolation( Coordinate_t x, Coordinate_t y,
134  Coordinate_t z ) const = 0;
135  virtual void do_interpolations( Coordinate_t x,
136  Coordinate_t y,
137  Coordinate_t z,
138  std::vector<Scalar_t> &v ) const = 0;
139 };
140 
141 
142  //--------------------------------//
143  // linear interpolator factories //
144 //--------------------------------//
145 //-----------------------------------------------------------------------------
147 template <typename T>
149  const carto::rc_ptr<carto::Volume<T> > & );
150 
151 
152  //--------------------------//
153  // LinearInterpolator<T> //
154 //--------------------------//
155 
156 class LinearInterpolatorFactory;
157 
158 //-----------------------------------------------------------------------------
159 template <typename T>
161 {
162 
163 public:
164  LinearInterpolator( const carto::VolumeRef<T> & image );
165  virtual ~LinearInterpolator();
166 
167  bool isValid( Coordinate_t x, Coordinate_t y, Coordinate_t z ) const;
168 
169  virtual const carto::PropertySet &header() const;
170 
171 private:
172  const carto::VolumeRef<T> _image;
173 
174  Scalar_t do_interpolation( Coordinate_t x, Coordinate_t y,
175  Coordinate_t z ) const;
176  void do_interpolations( Coordinate_t x, Coordinate_t y, Coordinate_t z,
177  std::vector<Scalar_t> & ) const;
178 
179  inline static
180  void _interpolationCoefficients( Coordinate_t xx,
181  int &x,
182  int &X,
183  Coordinate_t &ax,
184  int dx, float sx );
185 
186  inline static
187  Scalar_t linint(Scalar_t a, Scalar_t b, Scalar_t x) { return a + x*(b-a); }
188 
189 
190  int _dimX, _dimY, _dimZ;
191  float _invsizeX, _invsizeY, _invsizeZ;
192 };
193 
194 //-----------------------------------------------------------------------------
195 extern template class LinearInterpolator<uint8_t>;
196 extern template class LinearInterpolator<int8_t>;
197 extern template class LinearInterpolator<uint16_t>;
198 extern template class LinearInterpolator<int16_t>;
199 extern template class LinearInterpolator<uint32_t>;
200 extern template class LinearInterpolator<int32_t>;
201 extern template class LinearInterpolator<float>;
202 extern template class LinearInterpolator<double>;
203 
204 
205  //--------------------------------//
206  // linear interpolator factories //
207 //--------------------------------//
208 
209 //-----------------------------------------------------------------------------
210 template <typename T>
211 inline
213  const carto::rc_ptr<carto::Volume<T> > &image )
214 {
216 }
217 
218 
219 //-----------------------------------------------------------------------------
220 extern template carto::rc_ptr< Interpolator >
222 extern template carto::rc_ptr< Interpolator >
224 extern template carto::rc_ptr< Interpolator >
226 extern template carto::rc_ptr< Interpolator >
228 extern template carto::rc_ptr< Interpolator >
230 extern template carto::rc_ptr< Interpolator >
232 extern template carto::rc_ptr< Interpolator >
234 extern template carto::rc_ptr< Interpolator >
236 extern template carto::rc_ptr< Interpolator >
238 
239 
240  //--------------------------//
241  // LinearInterpolator<T> //
242 //--------------------------//
243 
244 //-----------------------------------------------------------------------------
245 template <typename T>
246 inline
248  const carto::VolumeRef<T> & image ) :
249  _image( image )
250 {
251  _dimX = _image->getSizeX();
252  _dimY = _image->getSizeY();
253  _dimZ = _image->getSizeZ();
254 
255  std::vector<float> vs( 3, 1. );
256  try
257  {
258  carto::Object o = _image->header().getProperty( "voxel_size" );
259  vs[0] = o->getArrayItem( 0 )->getScalar();
260  vs[1] = o->getArrayItem( 1 )->getScalar();
261  vs[2] = o->getArrayItem( 2 )->getScalar();
262  }
263  catch( ... )
264  {
265  }
266 
267  assert( vs[0] > 0 );
268  _invsizeX = float( 1.0 / vs[0] );
269  assert( vs[1] > 0 );
270  _invsizeY = float( 1.0 / vs[1] );
271  assert( vs[2] > 0 );
272  _invsizeZ = float( 1.0 / vs[2] );
273 }
274 
275 
276 //-----------------------------------------------------------------------------
277 template <typename T>
278 inline
280 {
281 }
282 
283 //-----------------------------------------------------------------------------
284 template <typename T>
285 inline
289 {
290  std::vector<float> vs( 3, 1. );
291  try
292  {
293  carto::Object o = _image->header().getProperty( "voxel_size" );
294  vs[0] = o->getArrayItem( 0 )->getScalar();
295  vs[1] = o->getArrayItem( 1 )->getScalar();
296  vs[2] = o->getArrayItem( 2 )->getScalar();
297  }
298  catch( ... )
299  {
300  }
301 
302  const Interpolator::Coordinate_t hx = - vs[0] / 2;
303  const Interpolator::Coordinate_t hy = - vs[1] / 2;
304  const Interpolator::Coordinate_t hz = - vs[2] / 2;
305  return x >= hx && y >= hy && z >= hz &&
306  x < _dimX * vs[0] + hx &&
307  y < _dimY * vs[1] + hy &&
308  z < _dimZ * vs[2] + hz;
309 }
310 
311 
312 //-----------------------------------------------------------------------------
313 template <typename T>
314 inline
317  int & x,
318  int & X,
320  int dx, float isx)
321 {
322  const Interpolator::Coordinate_t px = xx * isx;
323 
324  x = int(px);
325  X = x+1;
326  if ( px < 0 )
327  {
328  x = X = 0;
329  ax = 1;
330  }
331  else if (X >= dx)
332  {
333  X = x = dx - 1;
334  ax = 0;
335  }
336  else
337  {
338  ax = px - x;
339  assert(ax >= 0);
340  assert(ax <= 1);
341  }
342 }
343 
344 
345 //-----------------------------------------------------------------------------
346 template <typename T>
348 LinearInterpolator<T>::do_interpolation( Interpolator::Coordinate_t xx,
350  Interpolator::Coordinate_t zz ) const
351 {
352  int x, X, y, Y, z, Z;
353  Interpolator::Coordinate_t ax, ay, az;
354  _interpolationCoefficients(xx, x, X, ax, _dimX, _invsizeX);
355  _interpolationCoefficients(yy, y, Y, ay, _dimY, _invsizeY);
356  _interpolationCoefficients(zz, z, Z, az, _dimZ, _invsizeZ);
357 
358  return
359  linint(
360  linint(
361  linint(_image( x, y, z ), _image( X, y, z ), ax),
362  linint(_image( x, Y, z ), _image( X, Y, z ), ax), ay),
363  linint(
364  linint(_image( x, y, Z ), _image( X, y, Z ), ax),
365  linint(_image( x, Y, Z ), _image( X, Y, Z ), ax), ay), az);
366 }
367 
368 
369 //-----------------------------------------------------------------------------
370 template <typename T>
371 void LinearInterpolator<T>::
372  do_interpolations( Interpolator::Coordinate_t xx,
375  std::vector< Interpolator::Scalar_t > &values ) const
376 {
377  values.resize( _image->getSizeT() );
378  int x, X, y, Y, z, Z;
379  Interpolator::Coordinate_t ax, ay, az;
380  _interpolationCoefficients(xx, x, X, ax, _dimX, _invsizeX);
381  _interpolationCoefficients(yy, y, Y, ay, _dimY, _invsizeY);
382  _interpolationCoefficients(zz, z, Z, az, _dimZ, _invsizeZ);
383 
384  for( int t = 0; t < _image->getSizeT(); ++t ) {
385  values[ t ] =
386  linint(
387  linint(
388  linint(_image( x, y, z, t ), _image( X, y, z, t ), ax),
389  linint(_image( x, Y, z, t ), _image( X, Y, z, t ), ax),
390  ay),
391  linint(
392  linint(_image( x, y, Z, t ), _image( X, y, Z, t ), ax),
393  linint(_image( x, Y, Z, t ), _image( X, Y, Z, t ), ax),
394  ay), az);
395  }
396 }
397 
398 
399 //-----------------------------------------------------------------------------
400 template <typename T>
401 inline
403 {
404  return _image->header();
405 }
406 
407 } // namespace aims
408 
409 #endif // ifdef AIMS_LINEAR_INTERPOLATOR
#define __deprecated__(msg)
#define __attribute__(a)
virtual ~Interpolator()
void values(Coordinate_t x, Coordinate_t y, Coordinate_t z, std::vector< Scalar_t > &v) const
Interpolate to get a series of values from point ( x, y ,z )
void operator()(Coordinate_t x, Coordinate_t y, Coordinate_t z, std::vector< Scalar_t > &v) const __attribute__((__deprecated__("use values() method instead")))
void operator()(const Interpolator::Point_t &point, std::vector< Scalar_t > &v) const __attribute__((__deprecated__("use values() method instead")))
Scalar_t value(Coordinate_t x, Coordinate_t y, Coordinate_t z) const
Interpolate to get a value from point ( x, y ,z ).
virtual bool isValid(Coordinate_t x, Coordinate_t y, Coordinate_t z) const =0
Return true if point ( x, y, z ) can be used for interpolation.
virtual const carto::PropertySet & header() const =0
Return the header of the image.
Scalar_t value(const Interpolator::Point_t &point) const
Interpolate to get a value from point.
void values(const Interpolator::Point_t &point, std::vector< Scalar_t > &v) const
Interpolate to get a series of values from point ( x, y ,z )
bool isValid(const Interpolator::Point_t &point) const
Return true if point can be used for interpolation.
Scalar_t operator()(Coordinate_t x, Coordinate_t y, Coordinate_t z) const __attribute__((__deprecated__("use value() method instead")))
Scalar_t operator()(const Interpolator::Point_t &point) const __attribute__((__deprecated__("use value() method instead")))
LinearInterpolator(const carto::VolumeRef< T > &image)
bool isValid(Coordinate_t x, Coordinate_t y, Coordinate_t z) const
Return true if point ( x, y, z ) can be used for interpolation.
virtual const carto::PropertySet & header() const
Return the header of the image.
bool getProperty(const std::string &, T &) const
int getSizeZ() const
int getSizeY() const
const PropertySet & header() const
int getSizeX() const
The class for EcatSino data write operation.
Definition: borderfiller.h:13
carto::rc_ptr< Interpolator > getLinearInterpolator(const std::string &)