aimsalgo 6.0.0
Neuroimaging image processing
convolutionsubsampler_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#ifndef AIMS_PYRAMID_CONVOLUTIONSUBSAMPLER_D_H
35#define AIMS_PYRAMID_CONVOLUTIONSUBSAMPLER_D_H
36
38#include <aims/utility/progress.h>
39#include <cartobase/config/verbose.h>
40
41namespace aims {
42
43 //==========================================================================
44 // CONSTRUCTOR/DESTRUCTOR/COPY
45 //==========================================================================
46
47 template <typename F>
49 _verbose( carto::verbose),
50 _dir( 4, true ),
51 _factor( r, r, r, r )
52 {
53 _dir[3] = false;
54 }
55
56 template <typename F>
58 _verbose( carto::verbose),
59 _dir( 4, true ),
61 {
62 _dir[3] = false;
63 }
64
65 template <typename F>
67 _func( std::vector<F>( 1, f ) ),
68 _verbose( carto::verbose),
69 _dir( 4, true ),
70 _factor( r, r, r, r )
71 {
72 _dir[3] = false;
73 }
74
75 template <typename F>
77 const Point4du & r ):
78 _func( f ),
79 _verbose( carto::verbose),
80 _dir( 4, true ),
81 _factor( r )
82 {
83 _dir[3] = false;
84 }
86 template <typename F>
88 _func( other._func ),
89 _verbose( other._verbose ),
90 _dir( other._dir )
91 {}
92
93 template <typename F>
95 {}
96
97 template <typename F>
99 {
100 if( this != &other )
102 _func = other._func;
103 _verbose = other._verbose;
104 _dir = other._dir;
105 _factor = other._factor;
106 }
107 return *this;
108 }
109
110 //==========================================================================
111 // HELPERS
112 //==========================================================================
113
115
116 inline
117 long mirrorCoeff( long i, long size )
118 {
119 i = std::abs( i );
120
121 if ( i < size )
122 return i;
123 if ( size == 1 )
124 return 0;
125
126 long size2 = ( size << 1 ) - 2;
127 ldiv_t modOp = std::ldiv( i, size2 );
128 return ( modOp.rem < size ) ? modOp.rem : ( size2 - modOp.rem );
129 }
130
131 inline
132 long selectCoeff( long i, long fullsize, long binf )
133 {
134 return mirrorCoeff( i + binf, fullsize ) - binf;
135 }
136
137 template <typename T>
138 inline
139 const T & at( const carto::VolumeRef<T> & vol,
140 long px, long py, long pz, long pt,
141 const Point4dl & fullsize,
142 const Point4dl & binf )
143 {
144 return vol( selectCoeff( px, fullsize[0], binf[0] ),
145 selectCoeff( py, fullsize[1], binf[1] ),
146 selectCoeff( pz, fullsize[2], binf[2] ),
147 selectCoeff( pt, fullsize[3], binf[3] ) );
148 }
149
150
151 } // namespace convolutionsubsampler
152
153 //==========================================================================
154 // EXECUTION
155 //==========================================================================
156
157 template <typename F>
158 template <typename OUT, typename IN>
160 {
161 bool doT = in.getSizeT() > 1 && _dir[3];
162 bool doZ = in.getSizeZ() > 1 && _dir[2];
163 bool doY = in.getSizeY() > 1 && _dir[1];
164 bool doX = in.getSizeX() > 1 && _dir[0];
165
166 unsigned rX = ( doX ? _factor[0] : 1 );
167 unsigned rY = ( doY ? _factor[1] : 1 );
168 unsigned rZ = ( doZ ? _factor[2] : 1 );
169 unsigned rT = ( doT ? _factor[3] : 1 );
170
171 carto::VolumeRef<OUT> out( in.getSizeX() / rX,
172 in.getSizeY() / rY,
173 in.getSizeZ() / rZ,
174 in.getSizeT() / rT );
175 out.copyHeaderFrom( in.header() );
176 std::vector<float> vs( 4, 1. );
177 out.header().getProperty( "voxel_size", vs );
178 vs[0] *= rX;
179 vs[1] *= rY;
180 vs[2] *= rZ;
181 vs[3] *= rT;
182 out.header().setProperty( "voxel_size", vs );
183
184 return execute( in, out );
185 }
186
187 template <typename F>
188 template <typename OUT, typename IN>
190 {
191 if( _verbose > 1 )
192 {
193 std::cout << ( _dir[0] ? std::string("X (") + carto::toString(_factor[0]) + std::string(") ") : "" )
194 << ( _dir[1] ? std::string("Y (") + carto::toString(_factor[1]) + std::string(") ") : "" )
195 << ( _dir[2] ? std::string("Z (") + carto::toString(_factor[2]) + std::string(") ") : "" )
196 << ( _dir[3] ? std::string("T (") + carto::toString(_factor[3]) + std::string(") ") : "" )
197 << std::flush;
198 }
199
200 carto::VolumeRef<IN> tmp = in;
201
202 std::vector<int> b = tmp.getBorders();
203 std::vector<int> s = tmp.getSize();
204 Point4dl binf( b[0], b[2], b[4], b[6] );
205 Point4dl fullsize( s[0] + b[0] + b[1], s[1] + b[2] + b[3],
206 s[2] + b[4] + b[5], s[3] + b[6] + b[7] );
207
208 const F & fx = _func[0];
209 const F & fy = ( _func.size() > 1 ? _func[1] : _func[0] );
210 const F & fz = ( _func.size() > 2 ? _func[2] : _func[0] );
211 const F & ft = ( _func.size() > 3 ? _func[3] : _func[0] );
212
213 bool doT = tmp.getSizeT() > 1 && _dir[3];
214 bool doZ = tmp.getSizeZ() > 1 && _dir[2];
215 bool doY = tmp.getSizeY() > 1 && _dir[1];
216 bool doX = tmp.getSizeX() > 1 && _dir[0];
217
218 unsigned rX = ( doX ? _factor[0] : 1 );
219 unsigned rY = ( doY ? _factor[1] : 1 );
220 unsigned rZ = ( doZ ? _factor[2] : 1 );
221 unsigned rT = ( doT ? _factor[3] : 1 );
222
223 long linf = ( doT ? (long)ft.support()[0] : 0 );
224 long lsup = ( doT ? (long)ft.support()[1] : 0 );
225 long kinf = ( doZ ? (long)fz.support()[0] : 0 );
226 long ksup = ( doZ ? (long)fz.support()[1] : 0 );
227 long jinf = ( doY ? (long)fy.support()[0] : 0 );
228 long jsup = ( doY ? (long)fy.support()[1] : 0 );
229 long iinf = ( doX ? (long)fx.support()[0] : 0 );
230 long isup = ( doX ? (long)fx.support()[1] : 0 );
231
232 Progression prg( (long)out.getSizeT() * (long)out.getSizeZ() *
233 (long)out.getSizeY() * (long)out.getSizeX() );
234 if( _verbose > 0 )
235 prg.print();
236
237 for( long t = 0, ot = 0; ot < out.getSizeT(); t += rT, ++ot )
238 for( long z = 0, oz = 0; oz < out.getSizeZ(); z += rZ, ++oz )
239 for( long y = 0, oy = 0; oy < out.getSizeY(); y += rY, ++oy )
240 for( long x = 0, ox = 0; ox < out.getSizeX(); x += rX, ++ox )
241 {
242 if( _verbose > 0 )
243 (++prg).print();
244 double value = 0;
245 for( long l = linf; l <= lsup; ++l )
246 for( long k = kinf; k <= ksup; ++k )
247 for( long j = jinf; j <= jsup; ++j )
248 for( long i = iinf; i <= isup; ++i )
249 {
250 double ct = doT ? ft( l ) : 1.;
251 double cz = doZ ? fz( k ) : 1.;
252 double cy = doY ? fy( j ) : 1.;
253 double cx = doX ? fx( i ) : 1.;
254 value += double( convolutionsubsampler::at( tmp, x+i, y+j, z+k, t+l,
255 fullsize, binf ) )
256 * cx * cy * cz * ct;
257 }
258 out( ox, oy, oz, ot ) = value;
259 }
260
261 if( _verbose > 0 )
262 std::cout << std::endl;
263
264 return out;
265 }
266
267 //==========================================================================
268 // PARAMETERS
269 //==========================================================================
270
271 template <typename F>
272 const std::vector<bool> & ConvolutionSubSampler<F>::directions() const
273 {
274 return _dir;
275 }
276
277 template <typename F>
279 {
280 return _factor;
281 }
282
283 template <typename F>
284 void ConvolutionSubSampler<F>::setBasisFunction( const F & func )
285 {
286 _func.assign( 4, func );
287 }
288
289 template <typename F>
290 void ConvolutionSubSampler<F>::setBasisFunction( const std::vector<F> & func )
291 {
292 _func = func;
293 }
294
295 template <typename F>
297 {
298 _factor = Point4du( r, r, r, r );
299 }
300
301 template <typename F>
303 {
304 _factor = r;
305 }
306
307 template <typename F>
308 void ConvolutionSubSampler<F>::setDirections( const std::vector<bool> & dir )
309 {
310 _dir.assign( 4, true );
311 _dir[3] = false;
312 for( std::vector<bool>::size_type i = 0; i < dir.size() && i < _dir.size(); ++i )
313 _dir[i] = dir[i];
314 }
315
316 template <typename F>
317 void ConvolutionSubSampler<F>::setDirections( bool dirx, bool diry, bool dirz, bool dirt )
318 {
319 _dir[0] = dirx;
320 _dir[1] = diry;
321 _dir[2] = dirz;
322 _dir[3] = dirt;
323 }
324
325 template <typename F>
327 {
328 _verbose = verbose;
329 }
330
331 template <typename F>
333 {
334 _verbose = 0;
335 }
336
337} // namespace aims
338
339#endif // AIMS_PYRAMID_CONVOLUTIONSUBSAMPLER_D_H
carto::VolumeRef< OUT > execute(const carto::VolumeRef< IN > &in) const
Execution.
void setBasisFunction(const BasisFunction &func)
ConvolutionSubSampler(unsigned r=2)
Constructor / Destructor / Copy.
ConvolutionSubSampler & operator=(const ConvolutionSubSampler &other)
const std::vector< bool > & directions() const
Parameters.
void setDirections(const std::vector< bool > &dir)
virtual void print(const bool force=false)
void setProperty(const std::string &, const T &)
bool getProperty(const std::string &, T &) const
int getSizeZ() const
std::vector< int > getBorders() const
virtual void copyHeaderFrom(const PropertySet &other)
int getSizeT() const
std::vector< int > getSize() const
int getSizeY() const
const PropertySet & header() const
int getSizeX() const
long mirrorCoeff(long i, long size)
const T & at(const carto::VolumeRef< T > &vol, long px, long py, long pz, long pt, const Point4dl &fullsize, const Point4dl &binf)
long selectCoeff(long i, long fullsize, long binf)
ProgressInfo< double, double > Progression
std::string toString(const T &object)
STL namespace.
AimsVector< int64_t, 4 > Point4dl
AimsVector< uint32_t, 4 > Point4du