aimsalgo  5.1.2
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>
40 
41 namespace 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 ),
60  _factor( r )
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>
76  ConvolutionSubSampler<F>::ConvolutionSubSampler( const std::vector<F> & 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  }
85 
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 )
101  {
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 
114  namespace convolutionsubsampler {
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
std::vector< BasisFunction > _func
ConvolutionSubSampler(unsigned r=2)
Constructor / Destructor / Copy.
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)
long selectCoeff(long i, long fullsize, long binf)
const T & at(const carto::VolumeRef< T > &vol, long px, long py, long pz, long pt, const Point4dl &fullsize, const Point4dl &binf)
std::string toString(const T &object)
int verbose
const AlgorithmCaller::LaunchExecution execute