cartodata 6.0.0
lightresampler.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#ifndef CARTODATA_TRANSFORMATION_LIGHTRESAMPLER_H
35#define CARTODATA_TRANSFORMATION_LIGHTRESAMPLER_H
36
38#include <soma-io/transformation/affinetransformation3d_base.h>
39#include <cartobase/containers/nditerator.h>
40
41
42namespace carto
43{
44
52 template <typename T>
54 {
55 public:
57 const Volume<T> & vol, const AffineTransformationBase & tr );
58 static void resampleVolume(
59 const Volume<T> & input, Volume<T> & output,
60 const AffineTransformationBase & tr, const T & background = 0 );
62 static Object transformHeader( const Object & header,
63 const AffineTransformationBase & tr );
64 static std::vector<int> getTransformedDims(
65 const std::vector<int> & dims, const AffineTransformationBase & tr );
66 static std::vector<float> getTransformedVoxelSize(
67 const std::vector<float> & vs, const AffineTransformationBase & tr );
68 };
69
70
71 template <typename T>
73 const std::vector<int> & dims, const AffineTransformationBase & tr )
74 {
75 int d, n = dims.size(), i;
76 std::vector<int> out_dims( n, 0 );
77 for( d=0; d<n; ++d )
78 {
79 std::vector<int> p( n, 0 );
80 p[d] = dims[d];
81 p = tr.transformVector( p );
82 for( i=0; i<n; ++i )
83 out_dims[i] += p[i];
84 }
85 for( d=0; d<n; ++d )
86 out_dims[d] = fabs( out_dims[d] );
87
88 return out_dims;
89 }
90
91
92 template <typename T>
94 const std::vector<float> & vs, const AffineTransformationBase & tr )
95 {
96 unsigned d, n = tr.order(), nv = vs.size(), i;
97 n = std::max( n, nv );
98 std::vector<float> out_vs( n, 0.f );
99 for( d=0; d<n; ++d )
100 {
101 std::vector<float> p( n, 0.f );
102 if( d < nv )
103 p[d] = vs[d];
104 else
105 p[d] = 1.f;
106 p = tr.transformVector( p );
107 for( i=0; i<n; ++i )
108 out_vs[i] += p[i];
109 }
110 for( d=0; d<n; ++d )
111 out_vs[d] = fabs( out_vs[d] );
112
113 return out_vs;
114 }
115
116
117 template <typename T>
119 const Volume<T> & vol, const AffineTransformationBase & tr )
120 {
121 std::vector<int> odim = getTransformedDims( vol.getSize(), tr );
122 VolumeRef<T> res( odim );
123 Object reshdr = transformHeader( Object::reference( vol.header() ), tr );
124 res.copyHeaderFrom( reshdr );
126
127 return res;
128 }
129
130
131 template <typename T>
133 const Object & header, const AffineTransformationBase & tr )
134 {
135 Object out_hdr;
136 return out_hdr;
137 }
138
139
140 template <typename T>
142 const Volume<T> & input, Volume<T> & output,
143 const AffineTransformationBase & tr, const T & background )
144 {
145 std::vector<float> ovs = output.getVoxelSize();
146 while( ovs.size() < 3 )
147 ovs.push_back( 1. );
148 std::vector<float> vs = input.getVoxelSize();
149 while( vs.size() < 3 )
150 vs.push_back( 1. );
151
152 std::unique_ptr<AffineTransformationBase> trinv = tr.inverse();
153 // embed voxel size in trinv
154 AffineTransformationBase ivs( tr.order() );
155 unsigned i, n = vs.size();
156 for( i=0; i<n; ++i )
157 ivs.matrix()( i, i ) = 1.f / vs[i];
158 *trinv = ivs * *trinv;
159
160 line_NDIterator<T> oit( &output.at( 0 ), output.getSize(),
161 output.getStrides(), true );
162
163 n = output.getSize().size();
164 std::vector<float> ipos( n, 0.f );
165 ipos[oit.line_direction()] = ovs[oit.line_direction()];
166 std::vector<float> xoff = trinv->transformVector( ipos );
167 std::vector<int> vipos;
168 std::vector<int> idims = input.getSize();
169 int dx = idims[0], dy = idims[1], dz = idims[2];
170 unsigned m = idims.size();
171
172 T *p, *pp;
173
174 for( ; !oit.ended(); ++oit )
175 {
176 p = &*oit;
177 vipos = oit.position();
178 ipos.clear();
179 ipos.insert( ipos.end(), vipos.begin(), vipos.end() );
180 for( i=0; i<n; ++i )
181 ipos[i] *= ovs[i];
182
183 ipos = trinv->transform( ipos );
184 for( pp=p + oit.line_length(); p!=pp; oit.inc_line_ptr( p ) )
185 {
186 bool doit = true;
187 for( i=0; i<m; ++i )
188 {
189 vipos[i] = int(rint(ipos[i]));
190 if( vipos[i] < 0 || vipos[i] >= idims[i] )
191 {
192 *p = background;
193 doit = false;
194 break;
195 }
196 }
197 if( doit )
198 *p = input.at( vipos );
199 for( i=0; i<m; ++i )
200 ipos[i] += xoff[i];
201 }
202 }
203 }
204
205}
206
207
208#endif
209
const PropertySet & header() const
Light, simple resampler used for flipping operations.
static void resampleVolume(const Volume< T > &input, Volume< T > &output, const AffineTransformationBase &tr, const T &background=0)
static std::vector< int > getTransformedDims(const std::vector< int > &dims, const AffineTransformationBase &tr)
static std::vector< float > getTransformedVoxelSize(const std::vector< float > &vs, const AffineTransformationBase &tr)
static VolumeRef< T > allocateResampledVolume(const Volume< T > &vol, const AffineTransformationBase &tr)
static Object transformHeader(const Object &header, const AffineTransformationBase &tr)
adapt info in header (referential, transformations)
const std::vector< int > & position() const
Object reference(Object &value)
std::vector< float > getVoxelSize() const
get the voxel size from the header, with 4 values defaulting to 1.mm if not present
std::vector< int > getSize() const
get the 4 dimensions in a vector
Convenient handle for a Volume - this is normally the entry point for all volumes handling.
Definition volumeref.h:60
void setVoxelSize(float vx, float vy=1., float vz=1., float vt=1.)
virtual void copyHeaderFrom(const PropertySet &other)
N-D Volume main class.
Definition volumebase.h:120
std::vector< long > getStrides() const
Get strides for the volume.
const T & at(long x, long y=0, long z=0, long t=0) const
std::ptrdiff_t line_length() const
void inc_line_ptr(T *&p) const