aimsalgo  5.1.2
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() ), _verbose_stream( &std::cout )
63 {
64 }
65 
66 
67 template <typename 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  std::ostream *stream = _verbose_stream;
93  if( !stream )
94  stream = &std::cout;
95  aims::Progression progress(0, static_cast<size_t>(outSizeX)
96  * outSizeY * outSizeZ * outSizeT, 0, 100, "%", 3,
97  *stream );
98  int x, y, z, t;
99  for ( t = 0; t < outSizeT; t++ )
100  {
101  updateParameters( inVolume, t, verbose );
102 
103  for ( z = 0; z < outSizeZ; z++ )
104  {
105 
106  for ( y = 0; y < outSizeY; y++ )
107  {
108  o = &outVolume.at( 0, y, z, t );
109 
110  for ( x = 0; x < outSizeX; x++ )
111  {
112  const Point3df outLoc ( x * outResolution[0],
113  y * outResolution[1],
114  z * outResolution[2] );
115 
116  doResample( inVolume, inverse_transform_to_vox, outBackground,
117  outLoc, *o, t );
118  ++ o;
119  ++progress;
120  }
121 
122  if(verbose || _verbose_stream) {
123  progress.print();
124  }
125  }
126  }
127  }
128 }
129 
130 
131 template <typename T>
133 resample_inv( const carto::Volume< T >& input_data,
134  const soma::Transformation3d& inverse_transform_to_mm,
135  const T& background,
136  carto::Volume< T > & output_volume,
137  bool verbose ) const
138 {
139 
140  Point3df in_voxel_size( input_data.getVoxelSize() );
141 
142  aims::AffineTransformation3d mm_to_voxel_transform;
143  mm_to_voxel_transform.scale( Point3df( 1, 1, 1 ), in_voxel_size );
144 
145  aims::TransformationChain3d transform_chain;
146  transform_chain.push_back(external_ref(inverse_transform_to_mm));
147  transform_chain.push_back(external_ref(mm_to_voxel_transform));
148 
149  resample_inv_to_vox(input_data, transform_chain, background,
150  output_volume, verbose);
151 }
152 
153 template <typename T>
155 resample_inv( const carto::Volume< T >& input_data,
156  const soma::Transformation3d& inverse_transform_to_mm,
157  const T& background,
158  const Point3df& output_location,
159  T &output_value,
160  int timestep ) const
161 {
162 
163  Point3df in_voxel_size( input_data.getVoxelSize() );
164 
165  aims::AffineTransformation3d mm_to_voxel_transform;
166  mm_to_voxel_transform.scale( Point3df( 1, 1, 1 ), in_voxel_size );
167 
168  aims::TransformationChain3d transform_chain;
169  transform_chain.push_back(external_ref(inverse_transform_to_mm));
170  transform_chain.push_back(external_ref(mm_to_voxel_transform));
171 
172  resample_inv_to_vox(input_data, transform_chain, background,
173  output_location, output_value, timestep);
174 }
175 
176 
177 template < typename T >
178 void
180  const aims::AffineTransformation3d& transform3d,
181  const T& outBackground,
182  carto::Volume< T > & outVolume,
183  bool verbose ) const
184 {
185 
186  Point3df inResolution( inVolume.getVoxelSize() );
187 
188  aims::AffineTransformation3d normTransform3d;
189 
190  normTransform3d.scale( inResolution, Point3df( 1, 1, 1 ) );
191  normTransform3d = transform3d * normTransform3d;
192  normTransform3d = normTransform3d.inverse();
193 
194  resample_inv_to_vox(inVolume, normTransform3d, outBackground, outVolume,
195  verbose);
196 
197 }
198 
199 
200 template < typename T >
201 void
203  const aims::AffineTransformation3d& transform3d,
204  const T& outBackground,
205  const Point3df& outLocation,
206  T& outValue, int t ) const
207 {
208 
209  Point3df inResolution( inVolume.getVoxelSize() );
210 
211  aims::AffineTransformation3d normTransform3d;
212 
213  normTransform3d.scale( inResolution, Point3df( 1, 1, 1 ) );
214  normTransform3d = transform3d * normTransform3d;
215  normTransform3d = normTransform3d.inverse();
216 
217  updateParameters( inVolume, t, carto::verbose );
218 
219  doResample( inVolume, normTransform3d, outBackground, outLocation,
220  outValue, t );
221 
222 }
223 
224 
225 template <typename T>
227  carto::Volume<T> & thing ) const
228 {
229  if( _ref.isNull() )
230  throw std::runtime_error( "Resampler used without a ref volume to resample"
231  );
232  resample( *_ref, motion, _defval, thing, carto::verbose );
233 }
234 
235 
236 template <typename T>
238  const aims::AffineTransformation3d& motion,
239  int dimX, int dimY, int dimZ,
240  const Point3df& resolution ) const
241 {
242  if( _ref.isNull() )
243  throw std::runtime_error( "Resampler used without a ref volume to resample"
244  );
245  carto::VolumeRef<T> thing( dimX, dimY, dimZ, _ref->getSizeT() );
246  std::vector<float> vs( 4, 1. );
247  vs[0] = resolution[0];
248  vs[1] = resolution[1];
249  vs[2] = resolution[2];
250  vs[3] = _ref->getVoxelSize()[3];
251  thing->header().setProperty( "voxel_size", vs );
252 
253  resample( *_ref, motion, _defval, *thing, carto::verbose );
254  thing->copyHeaderFrom( _ref->header() );
255  thing->header().setProperty( "voxel_size", vs );
256  if( !motion.isIdentity() )
257  {
258  carto::PropertySet & ph = thing->header();
259  try
260  {
261  // remove any referential ID since we are no longer in the same ref
262  ph.removeProperty( "referential" );
263  }
264  catch( ... )
265  {
266  }
267  try
268  {
269  carto::Object trs = ph.getProperty( "transformations" );
270  carto::Object tit = trs->objectIterator();
271  aims::AffineTransformation3d motioninv = motion.inverse();
272  std::vector<std::vector<float> > trout;
273  trout.reserve( trs->size() );
274  for( ; tit->isValid(); tit->next() )
275  {
276  aims::AffineTransformation3d m( tit->currentValue() );
277  m *= motioninv;
278  trout.push_back( m.toVector() );
279  }
280  ph.setProperty( "transformations", trout );
281  }
282  catch( ... )
283  {
284  // setup a new transformations list
285  std::vector<std::vector<float> > trout;
286  std::vector<std::string> refsout;
287  const carto::PropertySet & iph = _ref->header();
288  try
289  {
290  carto::Object iref = iph.getProperty( "referential" );
291  std::string refid = iref->getString();
292  refsout.push_back( refid );
293  }
294  catch( ... )
295  {
296  }
297  if( refsout.empty() )
298  refsout.push_back( "Coordinates aligned to another file or to "
299  "anatomical truth" );
300 
301  trout.push_back( motion.inverse().toVector() );
302  ph.setProperty( "transformations", trout );
303  ph.setProperty( "referentials", refsout );
304  }
305  }
306  return thing;
307 }
308 
309 
310 template <typename T>
312 {
313  _ref = ref;
314 }
315 
316 } // namespace aims
317 
318 #endif
AffineTransformation3d inverse() const
void resample_inv(const carto::Volume< T > &input_data, const soma::Transformation3d &inverse_transform_to_mm, const T &background, const Point3df &output_location, T &output_value, int timestep) const
Resample a volume at a single location.
Definition: resampler_d.h:155
void setRef(const carto::rc_ptr< carto::Volume< T > > &ref)
Set the input data to be resampled by the doit() methods.
Definition: resampler_d.h:311
virtual void resample(const carto::Volume< T > &input_data, const aims::AffineTransformation3d &transform, const T &background, carto::Volume< T > &output_data, bool verbose=false) const
Resample a volume into an existing output volume.
Definition: resampler_d.h:179
void doit(const aims::AffineTransformation3d &transform, carto::Volume< T > &output_data) const
Resample the input volume set with setRef() into an existing volume.
Definition: resampler_d.h:226
void resample_inv_to_vox(const carto::Volume< T > &input_data, const soma::Transformation3d &inverse_transform_to_vox, const T &background, const Point3df &output_location, T &output_value, int timestep) const
Resample a volume at a single location.
Definition: resampler.h:271
void push_back(const carto::const_ref< Transformation3d > &transformation)
void setProperty(const std::string &, const T &)
virtual bool removeProperty(const std::string &key)
bool getProperty(const std::string &, T &) const
std::vector< float > getVoxelSize() const
std::vector< int > getSize() const
int getSizeT() const
virtual void copyHeaderFrom(const PropertySet &other)
const PropertySet & header() const
const T & at(long x, long y=0, long z=0, long t=0) const
virtual void scale(const Point3df &sizeFrom, const Point3df &sizeTo)
bool isIdentity() const CARTO_OVERRIDE
std::vector< float > toVector() const
reference_wrapper< T > ref(T &ref)
int verbose