aimsalgo 6.0.0
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
40#include <cartobase/config/verbose.h>
41#include <aims/transformation/transformation_chain.h>
42#include <aims/utility/progress.h>
43#include <stdexcept>
44
45
46namespace { // anonymous namespace for file-local symbols
47
48template <class T>
49carto::const_ref<T> external_ref(const T& object)
50{
51 return carto::const_ref<T>(&object, true);
52}
53
54} // anonymous namespace
55
56
57namespace aims
58{
59
60template <typename T>
62 : _ref( 0 ), _defval( T() ), _verbose_stream( &std::cout )
63{
64}
65
66
67template <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 );
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
131template <typename T>
133resample_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
153template <typename T>
155resample_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
177template < typename T >
178void
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
198
199
200template < typename T >
201void
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 );
222}
223
224
225template <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
236template <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 std::unique_ptr<aims::AffineTransformation3d> motioninv
272 = motion.inverse();
273 std::vector<std::vector<float> > trout;
274 trout.reserve( trs->size() );
275 for( ; tit->isValid(); tit->next() )
276 {
277 aims::AffineTransformation3d m( tit->currentValue() );
278 m *= *motioninv;
279 trout.push_back( m.toVector() );
280 }
281 ph.setProperty( "transformations", trout );
282 }
283 catch( ... )
284 {
285 // setup a new transformations list
286 std::vector<std::vector<float> > trout;
287 std::vector<std::string> refsout;
288 const carto::PropertySet & iph = _ref->header();
289 try
290 {
291 carto::Object iref = iph.getProperty( "referential" );
292 std::string refid = iref->getString();
293 refsout.push_back( refid );
294 }
295 catch( ... )
296 {
297 }
298 if( refsout.empty() )
299 refsout.push_back( "Coordinates aligned to another file or to "
300 "anatomical truth" );
301
302 trout.push_back( motion.inverse()->toVector() );
303 ph.setProperty( "transformations", trout );
304 ph.setProperty( "referentials", refsout );
305 }
306 }
307 return thing;
308}
309
310
311template <typename T>
316
317} // namespace aims
318
319#endif
std::unique_ptr< AffineTransformation3d > inverse() const
virtual void updateParameters(const carto::Volume< float > &, int, bool) const
Definition resampler.h:354
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.
virtual void doResample(const carto::Volume< float > &input_data, const soma::Transformation3d &inverse_transform, const float &background, const Point3df &output_location, float &output_value, int timestep) const=0
void setRef(const carto::rc_ptr< carto::Volume< T > > &ref)
Set the input data to be resampled by the doit() methods.
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.
void doit(const aims::AffineTransformation3d &transform, carto::Volume< T > &output_data) const
Resample the input volume set with setRef() into an existing volume.
carto::rc_ptr< carto::Volume< T > > _ref
Definition resampler.h:358
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
std::ostream * _verbose_stream
Definition resampler.h:360
const carto::rc_ptr< carto::Volume< T > > & ref() const
Input data to be resampled by the doit() methods.
Definition resampler.h:317
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
ProgressInfo< double, double > Progression
int verbose
STL namespace.
AimsVector< float, 3 > Point3df