aimsalgo  5.0.5
Neuroimaging image processing
resampler_d.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_RESAMPLER_D_H
36 #define AIMS_RESAMPLING_RESAMPLER_D_H
37 
39 
42 #include <aims/utility/progress.h>
43 #include <stdexcept>
44 
45 
46 namespace { // anonymous namespace for file-local symbols
47 
48 template <class T>
49 carto::const_ref<T> external_ref(const T& object)
50 {
51  return carto::const_ref<T>(&object, true);
52 }
53 
54 } // anonymous namespace
55 
56 
57 namespace aims
58 {
59 
60 template <typename T>
62  : _ref( 0 ), _defval( T() )
63 {
64 }
65 
66 
67 template <typename T>
68 void Resampler<T>::
70  const soma::Transformation3d& inverse_transform_to_vox,
71  const T& outBackground,
72  carto::Volume< T > & outVolume,
73  bool verbose ) const
74 {
75 
76  Point3df outResolution;
77  std::vector<float> vs = outVolume.getVoxelSize();
78  outResolution[0] = vs[0];
79  outResolution[1] = vs[1];
80  outResolution[2] = vs[2];
81 
82  std::vector<int> sz = outVolume.getSize();
83  int outSizeX = sz[0];
84  int outSizeY = sz[1];
85  int outSizeZ = sz[2];
86  int outSizeT = sz[3];
87  if( outSizeT > inVolume.getSizeT() )
88  outSizeT = inVolume.getSizeT();
89 
90  T* o;
91 
92  aims::Progression progress(0, static_cast<size_t>(outSizeX)
93  * outSizeY * outSizeZ * outSizeT);
94  int x, y, z, t;
95  for ( t = 0; t < outSizeT; t++ )
96  {
97  updateParameters( inVolume, t, verbose );
98 
99  for ( z = 0; z < outSizeZ; z++ )
100  {
101 
102  for ( y = 0; y < outSizeY; y++ )
103  {
104  o = &outVolume.at( 0, y, z, t );
105 
106  for ( x = 0; x < outSizeX; x++ )
107  {
108  const Point3df outLoc ( x * outResolution[0],
109  y * outResolution[1],
110  z * outResolution[2] );
111 
112  doResample( inVolume, inverse_transform_to_vox, outBackground,
113  outLoc, *o, t );
114  ++ o;
115  ++progress;
116  }
117 
118  if(verbose) {
119  progress.print();
120  }
121  }
122  }
123  }
124 }
125 
126 
127 template <typename T>
128 void Resampler<T>::
129 resample_inv( const carto::Volume< T >& input_data,
130  const soma::Transformation3d& inverse_transform_to_mm,
131  const T& background,
132  carto::Volume< T > & output_volume,
133  bool verbose ) const
134 {
135 
136  Point3df in_voxel_size( input_data.getVoxelSize() );
137 
138  aims::AffineTransformation3d mm_to_voxel_transform;
139  mm_to_voxel_transform.scale( Point3df( 1, 1, 1 ), in_voxel_size );
140 
141  aims::TransformationChain3d transform_chain;
142  transform_chain.push_back(external_ref(inverse_transform_to_mm));
143  transform_chain.push_back(external_ref(mm_to_voxel_transform));
144 
145  resample_inv_to_vox(input_data, transform_chain, background,
146  output_volume, verbose);
147 }
148 
149 template <typename T>
150 void Resampler<T>::
151 resample_inv( const carto::Volume< T >& input_data,
152  const soma::Transformation3d& inverse_transform_to_mm,
153  const T& background,
154  const Point3df& output_location,
155  T &output_value,
156  int timestep ) const
157 {
158 
159  Point3df in_voxel_size( input_data.getVoxelSize() );
160 
161  aims::AffineTransformation3d mm_to_voxel_transform;
162  mm_to_voxel_transform.scale( Point3df( 1, 1, 1 ), in_voxel_size );
163 
164  aims::TransformationChain3d transform_chain;
165  transform_chain.push_back(external_ref(inverse_transform_to_mm));
166  transform_chain.push_back(external_ref(mm_to_voxel_transform));
167 
168  resample_inv_to_vox(input_data, transform_chain, background,
169  output_location, output_value, timestep);
170 }
171 
172 
173 template < typename T >
174 void
176  const aims::AffineTransformation3d& transform3d,
177  const T& outBackground,
178  carto::Volume< T > & outVolume,
179  bool verbose ) const
180 {
181 
182  Point3df inResolution( inVolume.getVoxelSize() );
183 
184  aims::AffineTransformation3d normTransform3d;
185 
186  normTransform3d.scale( inResolution, Point3df( 1, 1, 1 ) );
187  normTransform3d = transform3d * normTransform3d;
188  normTransform3d = normTransform3d.inverse();
189 
190  resample_inv_to_vox(inVolume, normTransform3d, outBackground, outVolume,
191  verbose);
192 
193 }
194 
195 
196 template < typename T >
197 void
199  const aims::AffineTransformation3d& transform3d,
200  const T& outBackground,
201  const Point3df& outLocation,
202  T& outValue, int t ) const
203 {
204 
205  Point3df inResolution( inVolume.getVoxelSize() );
206 
207  aims::AffineTransformation3d normTransform3d;
208 
209  normTransform3d.scale( inResolution, Point3df( 1, 1, 1 ) );
210  normTransform3d = transform3d * normTransform3d;
211  normTransform3d = normTransform3d.inverse();
212 
213  updateParameters( inVolume, t, carto::verbose );
214 
215  doResample( inVolume, normTransform3d, outBackground, outLocation,
216  outValue, t );
217 
218 }
219 
220 
221 template <typename T>
223  carto::Volume<T> & thing ) const
224 {
225  if( _ref.isNull() )
226  throw std::runtime_error( "Resampler used without a ref volume to resample"
227  );
228  resample( *_ref, motion, _defval, thing, carto::verbose );
229 }
230 
231 
232 template <typename T>
234  const aims::AffineTransformation3d& motion,
235  int dimX, int dimY, int dimZ,
236  const Point3df& resolution ) const
237 {
238  if( _ref.isNull() )
239  throw std::runtime_error( "Resampler used without a ref volume to resample"
240  );
241  carto::VolumeRef<T> thing( dimX, dimY, dimZ, _ref->getSizeT() );
242  std::vector<float> vs( 4, 1. );
243  vs[0] = resolution[0];
244  vs[1] = resolution[1];
245  vs[2] = resolution[2];
246  vs[3] = _ref->getVoxelSize()[3];
247  thing->header().setProperty( "voxel_size", vs );
248 
249  resample( *_ref, motion, _defval, *thing, carto::verbose );
250  thing->copyHeaderFrom( _ref->header() );
251  thing->header().setProperty( "voxel_size", vs );
252  if( !motion.isIdentity() )
253  {
254  carto::PropertySet & ph = thing->header();
255  try
256  {
257  // remove any referential ID since we are no longer in the same ref
258  ph.removeProperty( "referential" );
259  }
260  catch( ... )
261  {
262  }
263  try
264  {
265  carto::Object trs = ph.getProperty( "transformations" );
266  carto::Object tit = trs->objectIterator();
267  aims::AffineTransformation3d motioninv = motion.inverse();
268  std::vector<std::vector<float> > trout;
269  trout.reserve( trs->size() );
270  for( ; tit->isValid(); tit->next() )
271  {
272  aims::AffineTransformation3d m( tit->currentValue() );
273  m *= motioninv;
274  trout.push_back( m.toVector() );
275  }
276  ph.setProperty( "transformations", trout );
277  }
278  catch( ... )
279  {
280  // setup a new transformations list
281  std::vector<std::vector<float> > trout;
282  std::vector<std::string> refsout;
283  const carto::PropertySet & iph = _ref->header();
284  try
285  {
286  carto::Object iref = iph.getProperty( "referential" );
287  std::string refid = iref->getString();
288  refsout.push_back( refid );
289  }
290  catch( ... )
291  {
292  }
293  if( refsout.empty() )
294  refsout.push_back( "Coordinates aligned to another file or to "
295  "anatomical truth" );
296 
297  trout.push_back( motion.inverse().toVector() );
298  ph.setProperty( "transformations", trout );
299  ph.setProperty( "referentials", refsout );
300  }
301  }
302  return thing;
303 }
304 
305 
306 template <typename T>
308 {
309  _ref = ref;
310 }
311 
312 } // namespace aims
313 
314 #endif
const T & at(long x, long y=0, long z=0, long t=0) const
virtual void print(const bool force=false)
std::vector< float > toVector() const
virtual bool removeProperty(const std::string &key)
std::vector< int > getSize() const
int verbose
void setProperty(const std::string &, const T &)
std::vector< float > getVoxelSize() const
bool isIdentity() const CARTO_OVERRIDE
Resampling of data from a volume, applying a transformation.
Definition: resampler.h:75
void push_back(const carto::const_ref< Transformation3d > &transformation)
std::vector< float > getVoxelSize() const
virtual void scale(const Point3df &sizeFrom, const Point3df &sizeTo)
int getSizeT() const
bool getProperty(const std::string &, T &) const
AffineTransformation3d inverse() const
reference_wrapper< T > ref(T &ref)