aimsalgo  5.1.2
Neuroimaging image processing
convolutionfilter_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_SIGNALFILTER_CONVOLUTIONFILTER_D_H
35 #define AIMS_SIGNALFILTER_CONVOLUTIONFILTER_D_H
36 
38 #include <aims/utility/progress.h>
39 #include <aims/vector/vector.h>
41 
42 namespace aims {
43 
44  //==========================================================================
45  // CONSTRUCTOR/DESTRUCTOR/COPY
46  //==========================================================================
47 
48  template <typename F>
50  _func( std::vector<F>( 1, f ) ),
51  _verbose( carto::verbose),
52  _dir( 4, true )
53  {
54  _dir[3] = false;
55  }
56 
57  template <typename F>
58  ConvolutionFilter<F>::ConvolutionFilter( const std::vector<F> & f ):
59  _func( f ),
60  _verbose( carto::verbose),
61  _dir( 4, true )
62  {
63  _dir[3] = false;
64  }
65 
66  template <typename F>
68  _func( other._func ),
69  _verbose( other._verbose ),
70  _dir( other._dir )
71  {}
72 
73  template <typename F>
75  {}
76 
77  template <typename F>
79  {
80  if( this != &other )
81  {
82  _func = other._func;
83  _verbose = other._verbose;
84  _dir = other._dir;
85  }
86  return *this;
87  }
88 
89  //==========================================================================
90  // HELPERS
91  //==========================================================================
92 
93  namespace convolutionfilter {
94 
95  inline
96  long mirrorCoeff( long i, long size )
97  {
98  i = std::abs( i );
99 
100  if ( i < size )
101  return i;
102  if ( size == 1 )
103  return 0;
104 
105  long size2 = ( size << 1 ) - 2;
106  ldiv_t modOp = std::ldiv( i, size2 );
107  return ( modOp.rem < size ) ? modOp.rem : ( size2 - modOp.rem );
108  }
109 
110  inline
111  long selectCoeff( long i, long fullsize, long binf )
112  {
113  return mirrorCoeff( i + binf, fullsize ) - binf;
114  }
115 
116  template <typename T>
117  inline
118  const T & at( const carto::VolumeRef<T> & vol,
119  const Point4dl & p,
120  const Point4dl & fullsize,
121  const Point4dl & binf )
122  {
123  return vol( selectCoeff( p[0], fullsize[0], binf[0] ),
124  selectCoeff( p[1], fullsize[1], binf[1] ),
125  selectCoeff( p[2], fullsize[2], binf[2] ),
126  selectCoeff( p[3], fullsize[3], binf[3] ) );
127  }
128 
129  } // namespace convolutionfilter
130 
131  //==========================================================================
132  // EXECUTION
133  //==========================================================================
134 
135  template <typename F>
136  template <typename OUT, typename IN>
138  {
139  carto::VolumeRef<OUT> out = carto::copyStructure<OUT,IN>( in );
140  return execute( in, out );
141  }
142 
143  template <typename F>
144  template <typename OUT, typename IN>
146  {
147  carto::VolumeRef<IN> tmp = in;
148 
149  std::vector<int> b = tmp.getBorders();
150  std::vector<int> s = tmp.getSize();
151  Point4dl binf( b[0], b[2], b[4], b[6] );
152  Point4dl fullsize( s[0] + b[0] + b[1], s[1] + b[2] + b[3],
153  s[2] + b[4] + b[5], s[3] + b[6] + b[7] );
154 
155  const F & fx = _func[0];
156  const F & fy = ( _func.size() > 1 ? _func[1] : _func[0] );
157  const F & fz = ( _func.size() > 2 ? _func[2] : _func[0] );
158  const F & ft = ( _func.size() > 3 ? _func[3] : _func[0] );
159 
160  bool doT = tmp.getSizeT() > 1 && _dir[3];
161  bool doZ = tmp.getSizeZ() > 1 && _dir[2];
162  bool doY = tmp.getSizeY() > 1 && _dir[1];
163  bool doX = tmp.getSizeX() > 1 && _dir[0];
164 
165  long linf = ( doT ? (long)ft.support()[0] : 0 );
166  long lsup = ( doT ? (long)ft.support()[1] : 0 );
167  long kinf = ( doZ ? (long)fz.support()[0] : 0 );
168  long ksup = ( doZ ? (long)fz.support()[1] : 0 );
169  long jinf = ( doY ? (long)fy.support()[0] : 0 );
170  long jsup = ( doY ? (long)fy.support()[1] : 0 );
171  long iinf = ( doX ? (long)fx.support()[0] : 0 );
172  long isup = ( doX ? (long)fx.support()[1] : 0 );
173 
174  if( _verbose > 1 )
175  {
176  std::cout << ( _dir[0] ? std::string("X (") + carto::toString(isup - iinf + 1) + std::string(") ") : "" )
177  << ( _dir[1] ? std::string("Y (") + carto::toString(jsup - jinf + 1) + std::string(") ") : "" )
178  << ( _dir[2] ? std::string("Z (") + carto::toString(ksup - kinf + 1) + std::string(") ") : "" )
179  << ( _dir[3] ? std::string("T (") + carto::toString(lsup - linf + 1) + std::string(") ") : "" )
180  << std::flush;
181  }
182 
183 
184  Progression prg( (long)out.getSizeT() * (long)out.getSizeZ() *
185  (long)out.getSizeY() * (long)out.getSizeX() );
186  if( _verbose > 0 )
187  prg.print();
188 
189  for( long t = 0; t < out.getSizeT(); ++t )
190  for( long z = 0; z < out.getSizeZ(); ++z )
191  for( long y = 0; y < out.getSizeY(); ++y )
192  for( long x = 0; x < out.getSizeX(); ++x )
193  {
194  if( _verbose > 0 )
195  (++prg).print();
196 
197  double value = 0;
198  for( long l = linf; l <= lsup; ++l )
199  for( long k = kinf; k <= ksup; ++k )
200  for( long j = jinf; j <= jsup; ++j )
201  for( long i = iinf; i <= isup; ++i )
202  {
203  Point4dl p( x+i, y+j, z+k, t+l );
204  double ct = doT ? ft( l ) : 1.;
205  double cz = doZ ? fz( k ) : 1.;
206  double cy = doY ? fy( j ) : 1.;
207  double cx = doX ? fx( i ) : 1.;
208  value += double( convolutionfilter::at( tmp, p, fullsize, binf ) )
209  * cx * cy * cz * ct;
210  }
211  out( x, y, z, t ) = value;
212  }
213 
214  if( _verbose > 0 )
215  std::cout << std::endl;
216 
217  return out;
218  }
219 
220  //==========================================================================
221  // PARAMETERS
222  //==========================================================================
223 
224  template <typename F>
225  const std::vector<bool> & ConvolutionFilter<F>::directions() const
226  {
227  return _dir;
228  }
229 
230  template <typename F>
231  void ConvolutionFilter<F>::setBasisFunction( const F & func )
232  {
233  _func.assign( 4, func );
234  }
235 
236  template <typename F>
237  void ConvolutionFilter<F>::setBasisFunction( const std::vector<F> & func )
238  {
239  _func = func;
240  }
241 
242  template <typename F>
243  void ConvolutionFilter<F>::setDirections( const std::vector<bool> & dir )
244  {
245  _dir.assign( 4, true );
246  _dir[3] = false;
247  for( size_t i = 0; (i < dir.size()) && (i < _dir.size()); ++i )
248  _dir[i] = dir[i];
249  }
250 
251  template <typename F>
252  void ConvolutionFilter<F>::setDirections( bool dirx, bool diry, bool dirz, bool dirt )
253  {
254  _dir[0] = dirx;
255  _dir[1] = diry;
256  _dir[2] = dirz;
257  _dir[3] = dirt;
258  }
259 
260  template <typename F>
262  {
263  _verbose = verbose;
264  }
265 
266  template <typename F>
268  {
269  _verbose = 0;
270  }
271 
272 } // namespace aims
273 
274 #endif // AIMS_SIGNALFILTER_CONVOLUTIONFILTER_D_H
Convolution Filter.
std::vector< BasisFunction > _func
std::vector< bool > _dir
ConvolutionFilter(const BasisFunction &bfunc)
Constructor / Destructor / Copy.
virtual void print(const bool force=false)
int getSizeZ() const
std::vector< int > getBorders() const
int getSizeT() const
std::vector< int > getSize() const
int getSizeY() const
int getSizeX() const
long selectCoeff(long i, long fullsize, long binf)
const T & at(const carto::VolumeRef< T > &vol, const Point4dl &p, const Point4dl &fullsize, const Point4dl &binf)
long mirrorCoeff(long i, long size)
std::string toString(const T &object)
int verbose
const AlgorithmCaller::LaunchExecution execute