aimsalgo 6.0.0
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>
40#include <cartobase/config/verbose.h>
41
42namespace 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>
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
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
void setBasisFunction(const BasisFunction &func)
Change the basis functions.
void setQuiet()
Equivalent to setVerbose(0)
const std::vector< bool > & directions() const
Parameters.
void setDirections(const std::vector< bool > &dir)
Set the directions along which the filter is applied.
carto::VolumeRef< OUT > execute(const carto::VolumeRef< IN > &in) const
Execution.
void setVerbose(int verbose=1)
Verbosity level.
ConvolutionFilter & operator=(const ConvolutionFilter &other)
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
const T & at(const carto::VolumeRef< T > &vol, const Point4dl &p, const Point4dl &fullsize, const Point4dl &binf)
long selectCoeff(long i, long fullsize, long binf)
long mirrorCoeff(long i, long size)
ProgressInfo< double, double > Progression
std::string toString(const T &object)
int verbose
AimsVector< int64_t, 4 > Point4dl