aimsalgo  5.1.2
Neuroimaging image processing
sampler.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 #ifndef AIMS_RESAMPLING_SAMPLER_H
36 #define AIMS_RESAMPLING_SAMPLER_H
37 
38 #include <aims/def/assert.h>
40 #include <aims/vector/vector.h>
41 #include <aims/resampling/motion.h>
42 #include <aims/bucket/bucketMap.h>
43 #include <vector>
44 
45 
46 typedef struct {
47  unsigned short x, y, z;
48  int offset;
49 } PVItem;
50 
51 
52 namespace carto
53 {
54  extern template class Volume<PVItem>;
55 }
56 
57 
58 template <class T>
59 class Sampler
60 {
61  public:
62 
63  Sampler( ) : _ref( 0 ) { };
64  virtual ~Sampler() { }
65 
66  virtual void doit(
67  const Motion& motion,
68  carto::rc_ptr<carto::Volume<PVItem> >& thing ) const;
69 
70 
71  void setRef( const carto::rc_ptr<carto::Volume<T> >& ref ) { _ref = &ref; }
72 
73  protected:
74 
75  void _sliceResamp( carto::rc_ptr<carto::Volume<PVItem> >& resamp,
76  PVItem* out,
77  const Point3df& start, int t,
78  const carto::rc_ptr<carto::Volume<float> >& Rinv ) const;
80 };
81 
82 
83 typedef struct {
84  unsigned short x, y, z ;
85  int offset ;
86 } PVVectorItem;
87 
88 template <class T>
90 {
91  public:
92 
93  BucketSampler( ) : _ref(0) { }
94  virtual ~BucketSampler() { }
95 
96  virtual void doit( const Motion& motion,
97  std::vector< PVVectorItem >& thing,
98  const aims::BucketMap<T>& model ) const;
99 
100  void setRef( const carto::rc_ptr<carto::Volume<T> >& ref ) { _ref = &ref; }
101 
102  protected:
104 };
105 
106 
107 
108 
109 template <class T> inline
110 void
112 {
113 
114  ASSERT( _ref );
115  ASSERT( thing->getSizeT() == (*_ref)->getSizeT() && thing->getBorders()[0] == 0 );
116 
117  Motion dirMotion = motion;
118  Motion invMotion = motion.inverse();
119 
120  // scale motion
121  Point3df sizeFrom( (*_ref)->getVoxelSize() );
122  Point3df sizeTo( thing->getVoxelSize() );
123  dirMotion.scale( sizeFrom, sizeTo );
124  invMotion.scale( sizeTo, sizeFrom );
125 
126  PVItem *it;
127 
128 #ifdef DEBUG
129  std::cout << "Sampling volume [ 0] / slice [ 0]" << std::flush;
130 #endif
131  for (int t = 0; t < thing->getSizeT(); t++ )
132  {
133  Point3df start = invMotion.translation();
134  for ( int s = 0; s < thing->getSizeZ(); s++ )
135  {
136 #ifdef DEBUG
137  std::cout << "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"
138  << std::setw( 3 ) << t << "] / slice ["
139  << std::setw( 3 ) << s << "]" << std::flush;
140 #endif
141  it = &thing->at( 0, 0, s, t );
142  _sliceResamp( thing, it, start, t, invMotion.rotation() );
143  start[ 0 ] += invMotion.rotation()( 0, 2 );
144  start[ 1 ] += invMotion.rotation()( 1, 2 );
145  start[ 2 ] += invMotion.rotation()( 2, 2 );
146  }
147  }
148  //cout << endl;
149 
150 }
151 
152 
153 template <class T> inline
155  PVItem* out,
156  const Point3df& start, int t,
157  const carto::rc_ptr<carto::Volume<float> >& Rinv )
158  const
159 {
160  int dimX1 = (*_ref)->getSizeX();
161  int dimX2 = resamp->getSizeX();
162  int dimY2 = resamp->getSizeY();
163 
164  const int SIXTEEN = 16;
165  const int TWO_THEN_SIXTEEN = 65536;
166 
167  int maxX = TWO_THEN_SIXTEEN * ( dimX1 - 1 );
168  int maxY = TWO_THEN_SIXTEEN * ( (*_ref)->getSizeY() - 1 );
169  int maxZ = TWO_THEN_SIXTEEN * ( (*_ref)->getSizeZ() - 1 );
170 
171  int xLinCurrent = ( int )( 65536.0 * start[ 0 ] );
172  int yLinCurrent = ( int )( 65536.0 * start[ 1 ] );
173  int zLinCurrent = ( int )( 65536.0 * start[ 2 ] );
174 
175  int xu = ( int )( 65536.0 * Rinv->at( 0, 0 ) );
176  int yu = ( int )( 65536.0 * Rinv->at( 1, 0 ) );
177  int zu = ( int )( 65536.0 * Rinv->at( 2, 0 ) );
178  int xv = ( int )( 65536.0 * Rinv->at( 0, 1 ) );
179  int yv = ( int )( 65536.0 * Rinv->at( 1, 1 ) );
180  int zv = ( int )( 65536.0 * Rinv->at( 2, 1 ) );
181 
182  int xCurrent, yCurrent, zCurrent;
183  const T *it;
184  int incr_vois[8] = { 0,
185  int( &(*_ref)->at( 1 ) - &(*_ref)->at( 0 ) ),
186  int( &(*_ref)->at( 1, 1 ) - &(*_ref)->at( 0 ) ),
187  int( &(*_ref)->at( 0, 1 ) - &(*_ref)->at( 0 ) ),
188  int( &(*_ref)->at( 0, 0, 1 ) - &(*_ref)->at( 0 ) ),
189  int( &(*_ref)->at( 1, 0, 1 ) - &(*_ref)->at( 0 ) ),
190  int( &(*_ref)->at( 1, 1, 1 ) - &(*_ref)->at( 0 ) ),
191  int( &(*_ref)->at( 0, 1, 1 ) - &(*_ref)->at( 0 ) ) };
192  for ( int v = dimY2; v--; )
193  {
194  xCurrent = xLinCurrent;
195  yCurrent = yLinCurrent;
196  zCurrent = zLinCurrent;
197 
198  for ( int u = dimX2; u--; )
199  {
200  if ( xCurrent >= 0 && xCurrent < maxX &&
201  yCurrent >= 0 && yCurrent < maxY &&
202  zCurrent >= 0 && zCurrent < maxZ )
203  {
204  it = &(*_ref)->at( xCurrent >> SIXTEEN, yCurrent >> SIXTEEN, zCurrent >> SIXTEEN, t );
205 
206  if (*(it + incr_vois[0]) == -32768 ||
207  *(it + incr_vois[1]) == -32768 ||
208  *(it + incr_vois[2]) == -32768 ||
209  *(it + incr_vois[3]) == -32768 ||
210  *(it + incr_vois[4]) == -32768 ||
211  *(it + incr_vois[5]) == -32768 ||
212  *(it + incr_vois[6]) == -32768 ||
213  *(it + incr_vois[7]) == -32768 )
214  {
215  out->offset = -1;
216  }
217  else
218  {
219  out->x = xCurrent & 0xffff;
220  out->y = yCurrent & 0xffff;
221  out->z = zCurrent & 0xffff;
222  out->offset = &(*_ref)->at( xCurrent >> SIXTEEN, yCurrent >> SIXTEEN,
223  zCurrent >> SIXTEEN ) - &(*_ref)->at( 0 );
224  }
225  }
226  else
227  {
228  out->offset = -1;
229  }
230  out++;
231  xCurrent += xu;
232  yCurrent += yu;
233  zCurrent += zu;
234  }
235  xLinCurrent += xv;
236  yLinCurrent += yv;
237  zLinCurrent += zv;
238  }
239 }
240 
241 template <class T> inline
242 void
244  std::vector< PVVectorItem >& thing,
245  const aims::BucketMap<T>& model ) const
246 {
247  const int TWO_THEN_SIXTEEN = 65536;
248 
249 
250  thing.clear() ;
251 
252  ASSERT( _ref );
253 
254  Motion dirMotion; dirMotion = motion;
255  Motion invMotion; invMotion = motion.inverse();
256 
257 
258  // scale motion
259  Point3df sizeFrom( (*_ref)->getVoxelSize() );
260  Point3df sizeTo( model.sizeX(), model.sizeY(), model.sizeZ() );
261 
262  dirMotion.scale( sizeFrom, sizeTo );
263  invMotion.scale( sizeTo, sizeFrom );
264 
266  it = model.begin()->second.begin() ;
267 
268  PVVectorItem item ;
269  int nbOfVoxels = model.begin()->second.size() ;
270 
271  thing.reserve(nbOfVoxels) ;
272  thing.resize(nbOfVoxels) ;
273 
274  Point3df x, y, z;
275 
276  float transl0 = invMotion.translation()[0];
277  float transl1 = invMotion.translation()[1];
278  float transl2 = invMotion.translation()[2];
279 
280  invMotion.setTranslation( 0. );
281 
282  x = invMotion.transform( 1.F, 0.F, 0.F ) ;
283  y = invMotion.transform( 0.F, 1.F, 0.F ) ;
284  z = invMotion.transform( 0.F, 0.F, 1.F ) ;
285 
286  int maxX = (*_ref)->getSizeX() - 1;
287  int maxY = (*_ref)->getSizeY() - 1;
288  int maxZ = (*_ref)->getSizeZ() - 1;
289  int oS= &(*_ref)->at( 0, 0, 1 ) - &(*_ref)->at( 0 ),
290  dX = &(*_ref)->at( (*_ref)->getSizeX() ) - &(*_ref)->at( 0 );
291 
292  for(int i = 0 ; i < nbOfVoxels ; ++i , ++it )
293  {
294  float current0, current1, current2;
295  current0 = static_cast<float>( (it->first)[0] ) ;
296  current1 = static_cast<float>( (it->first)[1] ) ;
297  current2 = static_cast<float>( (it->first)[2] ) ;
298 
299  float tmp0 = current0 * x[0] + current1 * y[0] + current2 * z[0] + transl0 ;
300  float tmp1 = current0 * x[1] + current1 * y[1] + current2 * z[1] + transl1 ;
301  float tmp2 = current0 * x[2] + current1 * y[2] + current2 * z[2] + transl2 ;
302 
303 
304  if ( tmp0 >= 0 && tmp0 < maxX &&
305  tmp1 >= 0 && tmp1 < maxY &&
306  tmp2 >= 0 && tmp2 < maxZ)
307  {
308  item.x = (unsigned short) (( tmp0 - int(tmp0) ) * TWO_THEN_SIXTEEN);
309  item.y = (unsigned short) (( tmp1 - int(tmp1) ) * TWO_THEN_SIXTEEN);
310  item.z = (unsigned short) (( tmp2 - int(tmp2) ) * TWO_THEN_SIXTEEN);
311  item.offset = int(tmp2) * oS +
312  int(tmp1) * dX +
313  int(tmp0);
314  }
315  else
316  {
317  item.offset = -1;
318  }
319 
320  thing[i] = item ;
321  }
322 }
323 
324 #endif
#define ASSERT(EX)
virtual ~BucketSampler()
Definition: sampler.h:94
BucketSampler()
Definition: sampler.h:93
void setRef(const carto::rc_ptr< carto::Volume< T > > &ref)
Definition: sampler.h:100
virtual void doit(const Motion &motion, std::vector< PVVectorItem > &thing, const aims::BucketMap< T > &model) const
Definition: sampler.h:243
const carto::rc_ptr< carto::Volume< T > > * _ref
Definition: sampler.h:103
Sampler()
Definition: sampler.h:63
const carto::rc_ptr< carto::Volume< T > > * _ref
Definition: sampler.h:79
virtual void doit(const Motion &motion, carto::rc_ptr< carto::Volume< PVItem > > &thing) const
Definition: sampler.h:111
virtual ~Sampler()
Definition: sampler.h:64
void _sliceResamp(carto::rc_ptr< carto::Volume< PVItem > > &resamp, PVItem *out, const Point3df &start, int t, const carto::rc_ptr< carto::Volume< float > > &Rinv) const
Definition: sampler.h:154
void setRef(const carto::rc_ptr< carto::Volume< T > > &ref)
Definition: sampler.h:71
carto::VolumeRef< float > rotation()
AffineTransformation3d inverse() const
float sizeZ() const
float sizeY() const
float sizeX() const
virtual void scale(const Point3df &sizeFrom, const Point3df &sizeTo)
void setTranslation(Point3df trans)
Point3dd transform(double x, double y, double z) const
reference_wrapper< T > ref(T &ref)
Definition: sampler.h:46
unsigned short x
Definition: sampler.h:47
int offset
Definition: sampler.h:48
unsigned short z
Definition: sampler.h:47
unsigned short y
Definition: sampler.h:47
unsigned short x
Definition: sampler.h:84
unsigned short z
Definition: sampler.h:84
int offset
Definition: sampler.h:85
unsigned short y
Definition: sampler.h:84